diff --git a/README.md b/README.md index c62e7c32..07850f9d 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,8 @@ pom.xml: | **Branches** | **Purpose** | **Latest Version** | |--------------|--------------------------------------------------|--------------------| -| **0.2.x** | Compatible with Spring Cloud 2022.0.x - 2025.0.x | 0.2.3 | -| **0.1.x** | Compatible with Spring Cloud Hoxton - 2021.0.x | 0.1.3 | +| **0.2.x** | Compatible with Spring Cloud 2022.0.x - 2025.0.x | 0.2.4 | +| **0.1.x** | Compatible with Spring Cloud Hoxton - 2021.0.x | 0.1.4 | Then add the specific modules you need: diff --git a/microsphere-spring-cloud-commons/pom.xml b/microsphere-spring-cloud-commons/pom.xml index f9869aca..be5392c8 100644 --- a/microsphere-spring-cloud-commons/pom.xml +++ b/microsphere-spring-cloud-commons/pom.xml @@ -67,6 +67,11 @@ true + + org.springframework.cloud + spring-cloud-loadbalancer + true + diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabled.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabled.java index 1ce3f27c..d7058b9b 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabled.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabled.java @@ -21,7 +21,6 @@ import org.springframework.cloud.client.CommonsClientAutoConfiguration; import org.springframework.cloud.client.actuator.FeaturesEndpoint; import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.core.annotation.AliasFor; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -47,15 +46,6 @@ @Retention(RUNTIME) @Target({TYPE, METHOD}) @Documented -@ConditionalOnProperty(name = FEATURES_ENABLED_PROPERTY_NAME) +@ConditionalOnProperty(name = FEATURES_ENABLED_PROPERTY_NAME, matchIfMissing = true) public @interface ConditionalOnFeaturesEnabled { - - /** - * Specify if the condition should match if the property is not set. Defaults to - * {@code true}. - * - * @return if the condition should match if the property is missing - */ - @AliasFor(annotation = ConditionalOnProperty.class, attribute = "matchIfMissing") - boolean matchIfMissing() default true; } diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java index 12f55e19..652ca766 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapter.java @@ -21,9 +21,13 @@ import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import java.util.List; +import static io.microsphere.lang.function.ThrowableSupplier.execute; +import static reactor.core.scheduler.Schedulers.isInNonBlockingThread; + /** * An adapter {@link DiscoveryClient} class based on {@link ReactiveDiscoveryClient} * @@ -67,6 +71,10 @@ public int getOrder() { } static List toList(Flux flux) { - return flux.collectList().block(); + Mono> mono = flux.collectList(); + if (isInNonBlockingThread()) { + return execute(() -> mono.toFuture().get()); + } + return mono.block(); } } \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java index ec164f29..26aa7b18 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/autoconfigure/ReactiveDiscoveryClientAutoConfiguration.java @@ -18,6 +18,7 @@ package io.microsphere.spring.cloud.client.discovery.autoconfigure; import io.microsphere.spring.cloud.client.discovery.ReactiveDiscoveryClientAdapter; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -30,6 +31,8 @@ import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_CLASS_NAME; import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.REACTIVE_COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; +import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.REACTIVE_COMPOSITE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; +import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.SIMPLE_REACTIVE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; /** * The Auto-Configuration class for {@link ReactiveDiscoveryClient} @@ -48,6 +51,10 @@ @AutoConfigureBefore(name = { REACTIVE_COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME }) +@AutoConfigureAfter(name = { + SIMPLE_REACTIVE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME, + REACTIVE_COMPOSITE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME +}) public class ReactiveDiscoveryClientAutoConfiguration { @Configuration(proxyBeanMethods = false) diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstants.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstants.java index 505c5a9d..5cce42f7 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstants.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstants.java @@ -20,6 +20,8 @@ import org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient; +import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration; /** * The constants for {@link DiscoveryClient} @@ -56,4 +58,18 @@ public interface DiscoveryClientConstants { * @see org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration */ String REACTIVE_COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME = "org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration"; + + /** + * The class name of {@link SimpleReactiveDiscoveryClientAutoConfiguration} + * + * @see org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration + */ + String SIMPLE_REACTIVE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME = "org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration"; + + /** + * The class name of {@link ReactiveCompositeDiscoveryClientAutoConfiguration} + * + * @see org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration + */ + String REACTIVE_COMPOSITE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME = "org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration"; } \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtils.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtils.java new file mode 100644 index 00000000..db3a521f --- /dev/null +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtils.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.client.discovery.util; + +import io.microsphere.annotation.Nonnull; +import io.microsphere.util.Utils; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties; + +import java.util.List; +import java.util.Map; + +import static io.microsphere.reflect.MethodUtils.invokeMethod; +import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.setProperties; + +/** + * The utilities class for Spring Cloud Discovery + * + * @author Mercy + * @see Utils + * @since 1.0.0 + */ +public abstract class DiscoveryUtils implements Utils { + + /** + * Get the instances map from {@link SimpleDiscoveryProperties} + * + * @param properties {@link SimpleDiscoveryProperties} + * @return the instances map + */ + @Nonnull + public static Map> getInstancesMap(@Nonnull SimpleDiscoveryProperties properties) { + return properties.getInstances(); + } + + /** + * Get the instances map from {@link SimpleReactiveDiscoveryProperties} + * + * @param properties {@link SimpleReactiveDiscoveryProperties} + * @return the instances map + */ + @Nonnull + public static Map> getInstancesMap(@Nonnull SimpleReactiveDiscoveryProperties properties) { + return invokeMethod(properties, "getInstances"); + } + + /** + * Convert {@link SimpleDiscoveryProperties} to {@link SimpleReactiveDiscoveryProperties} + * + * @param properties {@link SimpleDiscoveryProperties} + * @return {@link SimpleReactiveDiscoveryProperties} + */ + @Nonnull + public static SimpleReactiveDiscoveryProperties simpleReactiveDiscoveryProperties(@Nonnull SimpleDiscoveryProperties properties) { + SimpleReactiveDiscoveryProperties simpleReactiveDiscoveryProperties = new SimpleReactiveDiscoveryProperties(); + simpleReactiveDiscoveryProperties.setOrder(properties.getOrder()); + + DefaultServiceInstance local = properties.getLocal(); + DefaultServiceInstance targetLocal = simpleReactiveDiscoveryProperties.getLocal(); + setProperties(targetLocal, local); + + Map> instances = getInstancesMap(properties); + simpleReactiveDiscoveryProperties.setInstances(instances); + + return simpleReactiveDiscoveryProperties; + } + + /** + * Convert {@link SimpleReactiveDiscoveryProperties} to {@link SimpleDiscoveryProperties} + * + * @param properties {@link SimpleReactiveDiscoveryProperties} + * @return {@link SimpleDiscoveryProperties} + */ + @Nonnull + public static SimpleDiscoveryProperties simpleDiscoveryProperties(@Nonnull SimpleReactiveDiscoveryProperties properties) { + SimpleDiscoveryProperties simpleDiscoveryProperties = new SimpleDiscoveryProperties(); + simpleDiscoveryProperties.setOrder(properties.getOrder()); + + DefaultServiceInstance local = properties.getLocal(); + simpleDiscoveryProperties.setInstance(local.getServiceId(), local.getHost(), local.getPort()); + + Map> instances = invokeMethod(properties, "getInstances"); + simpleDiscoveryProperties.setInstances(instances); + + return simpleDiscoveryProperties; + } + + private DiscoveryUtils() { + } +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java index 262a4e05..6d90e12b 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistry.java @@ -19,23 +19,27 @@ import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import java.util.ArrayList; import java.util.List; import java.util.Map; +import static io.microsphere.spring.cloud.client.discovery.util.DiscoveryUtils.getInstancesMap; import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.getMetadata; import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.setMetadata; /** - * Simple {@link ServiceRegistry} class that is based on {@link SimpleDiscoveryProperties} to register + * Simple {@link ServiceRegistry} class that is based on {@link SimpleDiscoveryProperties} + * or {@link SimpleReactiveDiscoveryProperties} to register * {@link DefaultRegistration}. * * @author Mercy * @see ServiceRegistry * @see DefaultRegistration * @see SimpleDiscoveryProperties#getInstances() + * @see SimpleReactiveDiscoveryProperties#getInstances() * @since 1.0.0 */ public class SimpleServiceRegistry implements ServiceRegistry { @@ -44,8 +48,16 @@ public class SimpleServiceRegistry implements ServiceRegistry> instancesMap; - public SimpleServiceRegistry(SimpleDiscoveryProperties simpleDiscoveryProperties) { - this.instancesMap = simpleDiscoveryProperties.getInstances(); + public SimpleServiceRegistry(SimpleDiscoveryProperties properties) { + this(getInstancesMap(properties)); + } + + public SimpleServiceRegistry(SimpleReactiveDiscoveryProperties properties) { + this(getInstancesMap(properties)); + } + + public SimpleServiceRegistry(Map> instancesMap) { + this.instancesMap = instancesMap; } @Override diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtils.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtils.java index 2a45429f..71aab2bf 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtils.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtils.java @@ -51,6 +51,7 @@ import static io.microsphere.util.StringUtils.EMPTY_STRING; import static io.microsphere.util.StringUtils.EMPTY_STRING_ARRAY; import static io.microsphere.util.StringUtils.isBlank; +import static java.lang.String.valueOf; import static java.net.URI.create; import static java.util.Collections.emptyList; @@ -102,12 +103,16 @@ public static String getUriString(ServiceInstance instance) { boolean isSecure = instance.isSecure(); String prefix = isSecure ? "https://" : "http://"; String host = instance.getHost(); - String port = String.valueOf(instance.getPort()); - StringBuilder urlStringBuilder = new StringBuilder((isSecure ? 9 : 8) + host.length() + port.length()); + int port = instance.getPort(); + if (port <= 0) { + port = isSecure ? 443 : 80; + } + String portString = valueOf(port); + StringBuilder urlStringBuilder = new StringBuilder((isSecure ? 9 : 8) + host.length() + portString.length()); urlStringBuilder.append(prefix) .append(host) .append(COLON_CHAR) - .append(port); + .append(portString); return urlStringBuilder.toString(); } @@ -162,6 +167,23 @@ public static String removeMetadata(ServiceInstance serviceInstance, String meta return metadata.remove(metadataName); } + /** + * Set properties from source to target + * + * @param source source {@link ServiceInstance} + * @param target target {@link DefaultServiceInstance} + */ + public static void setProperties(ServiceInstance source, DefaultServiceInstance target) { + target.setInstanceId(source.getInstanceId()); + target.setServiceId(source.getServiceId()); + target.setSecure(source.isSecure()); + target.setHost(source.getHost()); + target.setPort(source.getPort()); + Map metadata = source.getMetadata(); + metadata.clear(); + metadata.putAll(source.getMetadata()); + } + static List parseWebEndpointMappings(String encodedJSON) { if (isBlank(encodedJSON)) { return emptyList(); diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabled.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabled.java new file mode 100644 index 00000000..a24ed4cb --- /dev/null +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabled.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.spring.cloud.commons.condition; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.commons.util.UtilAutoConfiguration; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.UTIL_ENABLED_PROPERTY_NAME; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * The conditional annotation meta-annotates {@link ConditionalOnProperty @ConditionalOnProperty} for + * {@link UtilAutoConfiguration} enabled. + * + * @author Mercy + * @see UtilAutoConfiguration + * @see ConditionalOnProperty + * @since 1.0.0 + */ +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +@Documented +@ConditionalOnProperty(name = UTIL_ENABLED_PROPERTY_NAME, matchIfMissing = true) +public @interface ConditionalOnUtilEnabled { +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstants.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstants.java index bcabfd50..0fce3f30 100644 --- a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstants.java +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstants.java @@ -20,6 +20,7 @@ import io.microsphere.annotation.ConfigurationProperty; import org.springframework.cloud.client.CommonsClientAutoConfiguration; import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; +import org.springframework.cloud.commons.util.UtilAutoConfiguration; import static io.microsphere.annotation.ConfigurationProperty.APPLICATION_SOURCE; import static io.microsphere.constants.PropertyConstants.ENABLED_PROPERTY_NAME; @@ -68,4 +69,29 @@ public interface SpringCloudPropertyConstants { source = APPLICATION_SOURCE ) String FEATURES_ENABLED_PROPERTY_NAME = SPRING_CLOUD_PROPERTY_PREFIX + "features." + ENABLED_PROPERTY_NAME; + + /** + * The property name for enabling Spring Cloud Load-Balancer : "spring.cloud.loadbalancer.enabled" + * + * @see org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration + */ + @ConfigurationProperty( + type = boolean.class, + defaultValue = "true", + source = APPLICATION_SOURCE + ) + String LOAD_BALANCER_ENABLED_PROPERTY_NAME = SPRING_CLOUD_PROPERTY_PREFIX + "loadbalancer." + ENABLED_PROPERTY_NAME; + + + /** + * The property name for enabling Spring Cloud Util : "spring.cloud.util.enabled" + * + * @see UtilAutoConfiguration + */ + @ConfigurationProperty( + type = boolean.class, + defaultValue = "true", + source = APPLICATION_SOURCE + ) + String UTIL_ENABLED_PROPERTY_NAME = SPRING_CLOUD_PROPERTY_PREFIX + "util." + ENABLED_PROPERTY_NAME; } \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabled.java b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabled.java new file mode 100644 index 00000000..5b04c06e --- /dev/null +++ b/microsphere-spring-cloud-commons/src/main/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabled.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.microsphere.spring.cloud.loadbalancer.condition; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.LOAD_BALANCER_ENABLED_PROPERTY_NAME; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * The conditional annotation meta-annotates {@link ConditionalOnProperty @ConditionalOnProperty} for + * LoadBalancer enabled. + * + * @author Mercy + * @see org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration + * @see ConditionalOnProperty + * @since 1.0.0 + */ +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +@Documented +@ConditionalOnProperty(name = LOAD_BALANCER_ENABLED_PROPERTY_NAME, havingValue = "true", matchIfMissing = true) +public @interface ConditionalOnLoadBalancerEnabled { +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabledTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabledTest.java index 6e57810c..80986d9b 100644 --- a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabledTest.java +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/condition/ConditionalOnFeaturesEnabledTest.java @@ -24,36 +24,8 @@ * @since 1.0.0 */ -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import io.microsphere.spring.cloud.test.ConditionalOnPropertyEnabledTest; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = { - ConditionalOnFeaturesEnabledTest.FeaturesConfiguration.class -}) -@TestPropertySource( - properties = { - "spring.cloud.features.enabled=true" - } -) -class ConditionalOnFeaturesEnabledTest { - - @ConditionalOnFeaturesEnabled - static class FeaturesConfiguration { - } - - @Autowired - private ObjectProvider featuresConfigurationProvider; - - @Test - void test() { - assertNotNull(featuresConfigurationProvider.getIfAvailable()); - } +@ConditionalOnFeaturesEnabled +class ConditionalOnFeaturesEnabledTest extends ConditionalOnPropertyEnabledTest { } diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapterTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapterTest.java index c6ae1384..2f65a00d 100644 --- a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapterTest.java +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/ReactiveDiscoveryClientAdapterTest.java @@ -26,15 +26,22 @@ import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClient; import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.scheduler.Scheduler; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import static io.microsphere.collection.Lists.ofList; +import static io.microsphere.spring.cloud.client.discovery.ReactiveDiscoveryClientAdapter.toList; import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtilsTest.createDefaultServiceInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; +import static reactor.core.scheduler.Schedulers.immediate; +import static reactor.core.scheduler.Schedulers.newSingle; /** * {@link ReactiveDiscoveryClientAdapter} @@ -97,4 +104,21 @@ void testProbe() { void testGetOrder() { assertEquals(this.client.getOrder(), this.adapter.getOrder()); } + + @Test + void testToList() throws Exception { + assertList(immediate(), "1,2,3"); + assertList(newSingle("test"), "1,2,3"); + } + + void assertList(Scheduler scheduler, T... values) throws Exception { + Flux flux = Flux.just(values); + Disposable disposable = scheduler.schedule(() -> { + List list = toList(flux); + assertEquals(ofList(values), list); + }); + if (disposable instanceof Callable) { + ((Callable) disposable).call(); + } + } } \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstantsTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstantsTest.java index b92ae186..131a2c1e 100644 --- a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstantsTest.java +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/constants/DiscoveryClientConstantsTest.java @@ -22,6 +22,8 @@ import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME; import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.DISCOVERY_CLIENT_CLASS_NAME; import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.REACTIVE_COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; +import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.REACTIVE_COMPOSITE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; +import static io.microsphere.spring.cloud.client.discovery.constants.DiscoveryClientConstants.SIMPLE_REACTIVE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -39,5 +41,7 @@ void testConstants() { assertEquals("org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient", COMPOSITE_DISCOVERY_CLIENT_CLASS_NAME); assertEquals("org.springframework.cloud.client.CommonsClientAutoConfiguration", COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME); assertEquals("org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration", REACTIVE_COMMONS_CLIENT_AUTO_CONFIGURATION_CLASS_NAME); + assertEquals("org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration", SIMPLE_REACTIVE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME); + assertEquals("org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration", REACTIVE_COMPOSITE_DISCOVERY_CLIENT_AUTO_CONFIGURATION_CLASS_NAME); } } \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtilsTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtilsTest.java new file mode 100644 index 00000000..c795655a --- /dev/null +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/discovery/util/DiscoveryUtilsTest.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.client.discovery.util; + + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.cloud.client.DefaultServiceInstance; +import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties; + +import java.util.List; +import java.util.Map; + +import static io.microsphere.collection.Lists.ofList; +import static io.microsphere.spring.cloud.client.discovery.util.DiscoveryUtils.getInstancesMap; +import static io.microsphere.spring.cloud.client.discovery.util.DiscoveryUtils.simpleDiscoveryProperties; +import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtilsTest.createDefaultServiceInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link DiscoveryUtils} Test + * + * @author Mercy + * @see DiscoveryUtils + * @since 1.0.0 + */ +class DiscoveryUtilsTest { + + private DefaultServiceInstance serviceInstance; + + private SimpleDiscoveryProperties properties; + + @BeforeEach + void setUp() { + this.serviceInstance = createDefaultServiceInstance(); + this.properties = new SimpleDiscoveryProperties(); + Map> instancesMap = this.properties.getInstances(); + instancesMap.put(this.serviceInstance.getInstanceId(), ofList(this.serviceInstance)); + } + + @Test + void testGetInstancesMap() { + Map> instancesMap = getInstancesMap(this.properties); + assertEquals(1, instancesMap.size()); + assertEquals(ofList(this.serviceInstance), instancesMap.get(this.serviceInstance.getInstanceId())); + } + + @Test + void testGetInstancesMapFromSimpleReactiveDiscoveryProperties() { + SimpleReactiveDiscoveryProperties properties = new SimpleReactiveDiscoveryProperties(); + Map> instancesMap = getInstancesMap(properties); + assertTrue(instancesMap.isEmpty()); + + properties.setInstances(this.properties.getInstances()); + instancesMap = getInstancesMap(properties); + assertEquals(1, instancesMap.size()); + assertEquals(ofList(this.serviceInstance), instancesMap.get(this.serviceInstance.getInstanceId())); + } + + @Test + void testSimpleDiscoveryProperties() { + SimpleReactiveDiscoveryProperties properties = new SimpleReactiveDiscoveryProperties(); + properties.setInstances(this.properties.getInstances()); + + SimpleDiscoveryProperties simpleDiscoveryProperties = simpleDiscoveryProperties(properties); + assertEquals(this.properties.getInstances(), simpleDiscoveryProperties.getInstances()); + } +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistryTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistryTest.java index 028a8781..1b11e19e 100644 --- a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistryTest.java +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/registry/SimpleServiceRegistryTest.java @@ -22,10 +22,12 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties; import java.util.List; import java.util.Map; +import static io.microsphere.spring.cloud.client.discovery.util.DiscoveryUtils.simpleReactiveDiscoveryProperties; import static io.microsphere.spring.cloud.client.service.registry.DefaultRegistrationTest.createDefaultRegistration; import static io.microsphere.spring.cloud.client.service.registry.SimpleServiceRegistry.STATUS_KEY; import static java.util.Collections.emptyList; @@ -55,6 +57,13 @@ void setUp() { this.registry = new SimpleServiceRegistry(this.properties); } + @Test + void testConstructor() { + SimpleReactiveDiscoveryProperties properties = simpleReactiveDiscoveryProperties(this.properties); + this.registry = new SimpleServiceRegistry(properties); + testDeregister(); + } + @Test void testRegister() { Map> instancesMap = this.properties.getInstances(); @@ -94,10 +103,8 @@ void testSetStatus() { @Test void testGetStatus() { - testRegister(); - String status = "UP"; - this.registry.setStatus(this.registration, status); - assertEquals(status, this.registry.getStatus(this.registration)); + testSetStatus(); + assertEquals(this.registration.getMetadata().get(STATUS_KEY), this.registry.getStatus(this.registration)); } List getInstances(String serviceId) { diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtilsTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtilsTest.java index a7f94f9c..ef194316 100644 --- a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtilsTest.java +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/client/service/util/ServiceInstanceUtilsTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test; import org.springframework.cloud.client.DefaultServiceInstance; +import java.net.URI; import java.util.Collection; import static io.microsphere.collection.Lists.ofList; @@ -39,6 +40,7 @@ import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.parseWebEndpointMappings; import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.removeMetadata; import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.setMetadata; +import static io.microsphere.spring.cloud.client.service.util.ServiceInstanceUtils.setProperties; import static io.microsphere.spring.web.metadata.WebEndpointMapping.Kind.SERVLET; import static io.microsphere.spring.web.metadata.WebEndpointMapping.servlet; import static io.microsphere.util.StringUtils.EMPTY_STRING; @@ -127,9 +129,28 @@ void testGetUriString() { assertEquals(uriString, getUriString(this.serviceInstance)); } + @Test + void testGetUriStringWithoutPort() { + String uriString = "http://localhost"; + this.serviceInstance.setUri(create(uriString)); + assertEquals(uriString + ":80", getUriString(this.serviceInstance)); + + uriString = "https://localhost"; + this.serviceInstance.setUri(create(uriString)); + assertEquals(uriString + ":443", getUriString(this.serviceInstance)); + } + @Test void testGetUri() { - assertEquals(create("http://localhost:8080"), getUri(this.serviceInstance)); + URI uri = getUri(this.serviceInstance); + assertEquals(create("http://localhost:8080"), uri); + assertEquals(DefaultServiceInstance.getUri(this.serviceInstance), uri); + + uri = create("https://localhost"); + this.serviceInstance.setUri(uri); + uri = getUri(this.serviceInstance); + assertEquals(create("https://localhost:443"), uri); + assertEquals(DefaultServiceInstance.getUri(this.serviceInstance), uri); } @Test @@ -144,6 +165,13 @@ void testMetadataOps() { assertNull(getMetadata(this.serviceInstance, WEB_CONTEXT_PATH_METADATA_NAME)); } + @Test + void testSetProperties() { + DefaultServiceInstance target = new DefaultServiceInstance(); + setProperties(this.serviceInstance, target); + assertEquals(this.serviceInstance, target); + } + private Collection createWebEndpointMappings() { return ofList(buildWebEndpointMapping(true)); } diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabledTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabledTest.java new file mode 100644 index 00000000..ce62854f --- /dev/null +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/condition/ConditionalOnUtilEnabledTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.commons.condition; + +import io.microsphere.spring.cloud.test.ConditionalOnPropertyEnabledTest; + +/** + * {@link ConditionalOnUtilEnabled} Test + * + * @author Mercy + * @see ConditionalOnUtilEnabled + * @since 1.0.0 + */ +@ConditionalOnUtilEnabled +public class ConditionalOnUtilEnabledTest extends ConditionalOnPropertyEnabledTest { +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstantsTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstantsTest.java new file mode 100644 index 00000000..41b9a193 --- /dev/null +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/commons/constants/SpringCloudPropertyConstantsTest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.commons.constants; + + +import org.junit.jupiter.api.Test; + +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.FEATURES_ENABLED_PROPERTY_NAME; +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.LOAD_BALANCER_ENABLED_PROPERTY_NAME; +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME; +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.SERVICE_REGISTRY_PROPERTY_PREFIX; +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.SPRING_CLOUD_PROPERTY_PREFIX; +import static io.microsphere.spring.cloud.commons.constants.SpringCloudPropertyConstants.UTIL_ENABLED_PROPERTY_NAME; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * {@link SpringCloudPropertyConstants} Test + * + * @author Mercy + * @see SpringCloudPropertyConstants + * @since 1.0.0 + */ +class SpringCloudPropertyConstantsTest { + + @Test + void testConstants() { + assertEquals("spring.cloud.", SPRING_CLOUD_PROPERTY_PREFIX); + assertEquals("spring.cloud.service-registry.", SERVICE_REGISTRY_PROPERTY_PREFIX); + assertEquals("spring.cloud.service-registry.auto-registration.enabled", SERVICE_REGISTRY_AUTO_REGISTRATION_ENABLED_PROPERTY_NAME); + assertEquals("spring.cloud.features.enabled", FEATURES_ENABLED_PROPERTY_NAME); + assertEquals("spring.cloud.loadbalancer.enabled", LOAD_BALANCER_ENABLED_PROPERTY_NAME); + assertEquals("spring.cloud.util.enabled", UTIL_ENABLED_PROPERTY_NAME); + } +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabledTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabledTest.java new file mode 100644 index 00000000..d251003f --- /dev/null +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/loadbalancer/condition/ConditionalOnLoadBalancerEnabledTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.loadbalancer.condition; + +import io.microsphere.spring.cloud.test.ConditionalOnPropertyEnabledTest; + +/** + * {@link ConditionalOnLoadBalancerEnabled @ConditionalOnLoadBalancerEnabled} Test + * + * @author Mercy + * @see ConditionalOnLoadBalancerEnabled + * @since 1.0.0 + */ +@ConditionalOnLoadBalancerEnabled +public class ConditionalOnLoadBalancerEnabledTest extends ConditionalOnPropertyEnabledTest { +} \ No newline at end of file diff --git a/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/test/ConditionalOnPropertyEnabledTest.java b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/test/ConditionalOnPropertyEnabledTest.java new file mode 100644 index 00000000..42ec97f3 --- /dev/null +++ b/microsphere-spring-cloud-commons/src/test/java/io/microsphere/spring/cloud/test/ConditionalOnPropertyEnabledTest.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.microsphere.spring.cloud.test; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; + +import java.util.Properties; +import java.util.Set; + +import static io.microsphere.collection.SetUtils.newLinkedHashSet; +import static io.microsphere.spring.beans.BeanUtils.isBeanPresent; +import static io.microsphere.spring.core.annotation.AnnotationUtils.getAnnotationAttributes; +import static io.microsphere.spring.test.util.SpringTestUtils.testInSpringContainer; +import static io.microsphere.util.ArrayUtils.isEmpty; +import static java.lang.String.valueOf; +import static java.lang.System.getProperties; +import static org.apache.commons.io.IOUtils.length; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.core.type.AnnotationMetadata.introspect; +import static org.springframework.util.StringUtils.hasText; + +/** + * Abstract test class for {@link ConditionalOnProperty @ConditionalOnProperty} On Enabled + * + * @author Mercy + * @see ConditionalOnProperty + * @since 1.0.0 + */ +public abstract class ConditionalOnPropertyEnabledTest { + + private AnnotationAttributes annotationAttributes; + + @BeforeEach + void setUp() { + AnnotationMetadata annotationMetadata = introspect(getClass()); + this.annotationAttributes = getAnnotationAttributes(annotationMetadata, ConditionalOnProperty.class); + } + + @Test + void testConditionalOnPropertyEnabled() { + if (matchIfMissing()) { + testBean(true); + } else { + testConditionalOnPropertyEnabled(true); + } + } + + @Test + void testConditionalOnPropertyDisabled() { + testConditionalOnPropertyEnabled(false); + } + + /** + * Whether match if missing + * + * @return {@code true} if match if missing + */ + protected boolean matchIfMissing() { + return this.annotationAttributes.getBoolean("matchIfMissing"); + } + + /** + * Get the property names of the {@link Conditional @Conditional} + * + * @return property names + */ + protected Set getPropertyNames() { + String prefix = this.annotationAttributes.getString("prefix"); + String[] names = this.annotationAttributes.getStringArray("name"); + if (isEmpty(names)) { + names = this.annotationAttributes.getStringArray("value"); + } + boolean hasPrefix = hasText(prefix); + Set propertyNames = newLinkedHashSet(length(names)); + for (String name : names) { + String propertyName = hasPrefix ? prefix + name : name; + propertyNames.add(propertyName); + } + return propertyNames; + } + + protected void testConditionalOnPropertyEnabled(boolean enabled) { + Set propertyNames = getPropertyNames(); + Properties properties = getProperties(); + try { + for (String propertyName : propertyNames) { + properties.setProperty(propertyName, valueOf(enabled)); + } + testBean(enabled); + } finally { + for (String propertyName : propertyNames) { + properties.remove(propertyName); + } + } + } + + protected void testBean(boolean present) { + testInSpringContainer(context -> { + assertEquals(present, isBeanPresent(context, getClass())); + }, getClass()); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index a43647f1..9ea2e813 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ - 0.2.3-SNAPSHOT + 0.2.4-SNAPSHOT 17