diff --git a/microsphere-multiactive-aws/pom.xml b/microsphere-multiactive-aws/pom.xml index 98847ed..072a474 100644 --- a/microsphere-multiactive-aws/pom.xml +++ b/microsphere-multiactive-aws/pom.xml @@ -20,30 +20,31 @@ - + io.github.microsphere-projects - microsphere-multiactive-spring-cloud - ${revision} + microsphere-annotation-processor true - + - org.springframework.boot - spring-boot-starter + io.github.microsphere-projects + microsphere-multiactive-spring-cloud + ${revision} true + org.springframework.boot - spring-boot-starter-web + spring-boot-starter true org.springframework.boot - spring-boot-starter-webflux + spring-boot-starter-actuator true @@ -55,7 +56,7 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-autoconfigure-processor true @@ -72,10 +73,10 @@ true - + - org.slf4j - slf4j-api + com.fasterxml.jackson.core + jackson-databind true @@ -86,10 +87,26 @@ test + - org.junit.jupiter - junit-jupiter-engine + org.springframework.boot + spring-boot-starter-test + test + + + + + io.github.microsphere-projects + microsphere-spring-boot-test test + + + + ch.qos.logback + logback-classic + test + + \ No newline at end of file diff --git a/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsContainerMetadataFileZoneLocator.java b/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsContainerMetadataFileZoneLocator.java index bd070b8..b7b0a03 100644 --- a/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsContainerMetadataFileZoneLocator.java +++ b/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsContainerMetadataFileZoneLocator.java @@ -67,7 +67,7 @@ public String locate(Environment environment) { logger.warn("The Amazon ECS Container metadata file [path : '{}' ] can't be read", metadataFile.getAbsolutePath()); } } else { - logger.debug("The environment variable [name : '{}' ] of Amazon ECS container metadata file can't be found", METADATA_FILE_ENV_NAME); + logger.trace("The environment variable [name : '{}' ] of Amazon ECS container metadata file can't be found", METADATA_FILE_ENV_NAME); } return zone; } diff --git a/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsTaskMetadataEndpointV4ZoneLocator.java b/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsTaskMetadataEndpointV4ZoneLocator.java index 28853a5..b7f5990 100644 --- a/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsTaskMetadataEndpointV4ZoneLocator.java +++ b/microsphere-multiactive-aws/src/main/java/io/microsphere/multiple/active/zone/spring/aws/EcsTaskMetadataEndpointV4ZoneLocator.java @@ -64,7 +64,7 @@ public String locate(Environment environment) { logger.error("Request Amazon ECS Task metadata endpoint version 4 [URL : '{}'] failed", taskURL, e); } } else { - logger.debug("The environment variable [name : '{}' ] of Amazon ECS Task metadata endpoint version 4 can't be found", + logger.trace("The environment variable [name : '{}' ] of Amazon ECS Task metadata endpoint version 4 can't be found", METADATA_URI_V4_ENV_NAME); } return zone; diff --git a/microsphere-multiactive-commons/pom.xml b/microsphere-multiactive-commons/pom.xml index 45202a9..6070bc9 100644 --- a/microsphere-multiactive-commons/pom.xml +++ b/microsphere-multiactive-commons/pom.xml @@ -19,16 +19,18 @@ Microsphere Multi-Active Commons - + + io.github.microsphere-projects - microsphere-java-core + microsphere-annotation-processor + true - + - org.slf4j - slf4j-api + io.github.microsphere-projects + microsphere-java-core true @@ -39,10 +41,19 @@ test + - org.junit.jupiter - junit-jupiter-engine + io.github.microsphere-projects + microsphere-java-test + test + + + + + ch.qos.logback + logback-classic test + \ No newline at end of file diff --git a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneConstants.java b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneConstants.java index 00fd8c8..ab9f609 100644 --- a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneConstants.java +++ b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneConstants.java @@ -1,6 +1,12 @@ package io.microsphere.multiple.active.zone; -import java.util.concurrent.TimeUnit; +import io.microsphere.annotation.ConfigurationProperty; + +import static io.microsphere.annotation.ConfigurationProperty.APPLICATION_SOURCE; +import static io.microsphere.constants.PropertyConstants.ENABLED_PROPERTY_NAME; +import static io.microsphere.constants.SymbolConstants.DOT; +import static java.lang.Boolean.parseBoolean; +import static java.lang.Integer.parseInt; /** * @author Mercy @@ -8,80 +14,228 @@ */ public interface ZoneConstants { - String ENABLED_PROPERTY_NAME_SUFFIX = ".enabled"; + // Zone Properties /** - * The property name of zone. + * The property name suffix of enabled : ".enabled" */ + String ENABLED_PROPERTY_NAME_SUFFIX = DOT + ENABLED_PROPERTY_NAME; + + /** + * The default value of zone that is compatible with Eureka zone. + * + * @see org.springframework.cloud.netflix.eureka.EurekaClientConfigBean#DEFAULT_ZONE + */ + String DEFAULT_ZONE = "defaultZone"; + + /** + * The value of zone is used to revert the original zone where + * {@link io.microsphere.multiple.active.zone.spring.ZoneLocator} locates + * + * @see io.microsphere.multiple.active.zone.spring.ZoneLocator + */ + String ORIGINAL_ZONE = "originalZone"; + + /** + * The property name of zone : "microsphere.availability.zone" + */ + @ConfigurationProperty( + defaultValue = DEFAULT_ZONE, + source = APPLICATION_SOURCE + ) String ZONE_PROPERTY_NAME = "microsphere.availability.zone"; /** - * The property name of current zone. + * The property name of current zone : "microsphere.current.availability.zone" */ + @ConfigurationProperty( + source = APPLICATION_SOURCE + ) String CURRENT_ZONE_PROPERTY_NAME = "microsphere.current.availability.zone"; /** - * The property name of zone that is enabled or not. + * The property value of default zone that is enabled or not. */ + String DEFAULT_ZONE_ENABLED_PROPERTY_VALUE = "true"; + + /** + * The default value of zone that is enabled or not. + */ + boolean DEFAULT_ZONE_ENABLED = parseBoolean(DEFAULT_ZONE_ENABLED_PROPERTY_VALUE); + + /** + * The property name of zone that is enabled or not : "microsphere.availability.zone.enabled" + */ + @ConfigurationProperty( + type = boolean.class, + defaultValue = DEFAULT_ZONE_ENABLED_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) String ZONE_ENABLED_PROPERTY_NAME = ZONE_PROPERTY_NAME + ENABLED_PROPERTY_NAME_SUFFIX; // Zone Preference Properties - String PREFERENCE_PROPERTY_NAME_PREFIX = ZONE_PROPERTY_NAME + ".preference"; - - String PREFERENCE_ENABLED_PROPERTY_NAME = PREFERENCE_PROPERTY_NAME_PREFIX + ENABLED_PROPERTY_NAME_SUFFIX; + /** + * The property name prefix of zone preference : "microsphere.availability.zone.preference." + */ + String PREFERENCE_PROPERTY_NAME_PREFIX = ZONE_PROPERTY_NAME + DOT + "preference" + DOT; - String PREFERENCE_FILER_PROPERTY_NAME_PREFIX = PREFERENCE_PROPERTY_NAME_PREFIX + ".filter"; + /** + * The porperty value of default value of zone preference that is enabled or not. + */ + String DEFAULT_PREFERENCE_ENABLED_PROPERTY_VALUE = "false"; - String PREFERENCE_FILTER_ORDER_PROPERTY_NAME = PREFERENCE_FILER_PROPERTY_NAME_PREFIX + ".order"; + /** + * The default value of zone preference that is enabled or not. + */ + boolean DEFAULT_ZONE_PREFERENCE_ENABLED = parseBoolean(DEFAULT_PREFERENCE_ENABLED_PROPERTY_VALUE); - String PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX = PREFERENCE_PROPERTY_NAME_PREFIX + ".upstream"; + /** + * The property name of zone preference enabled or not : "microsphere.availability.zone.preference.enabled" + */ + @ConfigurationProperty( + type = boolean.class, + defaultValue = DEFAULT_PREFERENCE_ENABLED_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String PREFERENCE_ENABLED_PROPERTY_NAME = PREFERENCE_PROPERTY_NAME_PREFIX + ENABLED_PROPERTY_NAME; - String PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + ".zone-ready-percentage"; + // Zone Preference Filter Properties - String PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + ".same-zone-min-available"; + /** + * The property name prefix of zone preference filter : "microsphere.availability.zone.preference.filter." + */ + String PREFERENCE_FILER_PROPERTY_NAME_PREFIX = PREFERENCE_PROPERTY_NAME_PREFIX + "filter" + DOT; - String PREFERENCE_UPSTREAM_DISABLED_ZONE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + ".disabled-zone"; + /** + * The property value of default zone preference filter order : "10" + */ + String DEFAULT_ZONE_PREFERENCE_FILTER_ORDER_PROPERTY_VALUE = "10"; - // Zone Locator Properties + /** + * The default value of zone preference filter order. + */ + int DEFAULT_ZONE_PREFERENCE_FILTER_ORDER = parseInt(DEFAULT_ZONE_PREFERENCE_FILTER_ORDER_PROPERTY_VALUE); - String LOCATOR_PROPERTY_NAME_PREFIX = ZONE_PROPERTY_NAME + ".locator"; + /** + * The property name of zone preference filter order : "microsphere.availability.zone.preference.filter.order" + */ + @ConfigurationProperty( + type = int.class, + defaultValue = DEFAULT_ZONE_PREFERENCE_FILTER_ORDER_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String PREFERENCE_FILTER_ORDER_PROPERTY_NAME = PREFERENCE_FILER_PROPERTY_NAME_PREFIX + "order"; - String LOCATOR_FAST_FAIL_PROPERTY_NAME = LOCATOR_PROPERTY_NAME_PREFIX + ".fast-fail"; + // Zone Preference Upstream Properties - String LOCATOR_TIMEOUT_PROPERTY_NAME = LOCATOR_PROPERTY_NAME_PREFIX + ".timeout"; + /** + * The property name prefix of zone preference upstream : "microsphere.availability.zone.preference.upstream." + */ + String PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX = PREFERENCE_PROPERTY_NAME_PREFIX + "upstream" + DOT; - // Default values + /** + * The property value of default zone preference upstream zone ready percentage : "100" + */ + String DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_VALUE = "100"; /** - * The default value of zone that is enabled or not. + * The default value of zone preference upstream zone ready percentage. */ - boolean DEFAULT_ZONE_ENABLED = true; + int DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE = parseInt(DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_VALUE); - boolean DEFAULT_ZONE_PREFERENCE_ENABLED = Boolean.getBoolean(PREFERENCE_ENABLED_PROPERTY_NAME); + /** + * The property name of zone preference upstream zone ready percentage : "microsphere.availability.zone.preference.upstream.zone-ready-percentage" + */ + @ConfigurationProperty( + type = int.class, + defaultValue = DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + "zone-ready-percentage"; - int DEFAULT_ZONE_PREFERENCE_FILTER_ORDER = 10; + // Zone Preference Upstream Same Zone Properties /** - * The default value of zone that is compatible with Eureka zone. - * - * @see org.springframework.cloud.netflix.eureka.EurekaClientConfigBean#DEFAULT_ZONE + * The property value of default zone preference upstream same zone min available : "5" */ - String DEFAULT_ZONE = "defaultZone"; + String DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_VALUE = "5"; /** - * The value of zone is used to revert the original zone where {@link ZoneLocator} locates + * The default value of zone preference upstream same zone min available. */ - String ORIGINAL_ZONE = "originalZone"; + int DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE = parseInt(DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_VALUE); - int DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE = 100; + /** + * The property name of zone preference upstream same zone min available : "microsphere.availability.zone.preference.upstream.same-zone-min-available" + */ + @ConfigurationProperty( + type = int.class, + defaultValue = DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + "same-zone-min-available"; - int DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE = 5; + // Zone Preference Upstream Disabled Zone Properties + /** + * The property value of default zone preference upstream disabled zone : null + */ String DEFAULT_PREFERENCE_UPSTREAM_DISABLED_ZONE = null; - boolean DEFAULT_LOCATOR_FAST_FAIL = false; + /** + * The property name of zone preference upstream disabled zone : "microsphere.availability.zone.preference.upstream.disabled-zone" + */ + @ConfigurationProperty( + source = APPLICATION_SOURCE + ) + String PREFERENCE_UPSTREAM_DISABLED_ZONE_PROPERTY_NAME = PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX + "disabled-zone"; + + // Zone Locator Properties + + /** + * The property name prefix of zone locator : "microsphere.availability.zone.locator." + */ + String LOCATOR_PROPERTY_NAME_PREFIX = ZONE_PROPERTY_NAME + DOT + "locator" + DOT; + + /** + * The property value of default zone locator fast fail : "false" + */ + String DEFAULT_LOCATOR_FAST_FAIL_PROPERTY_VALUE = "false"; + + /** + * The default value of zone locator fast fail. + */ + boolean DEFAULT_LOCATOR_FAST_FAIL = parseBoolean(DEFAULT_LOCATOR_FAST_FAIL_PROPERTY_VALUE); + + /** + * The property name of zone locator fast fail : "microsphere.availability.zone.locator.fast-fail" + */ + @ConfigurationProperty( + type = boolean.class, + defaultValue = DEFAULT_LOCATOR_FAST_FAIL_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String LOCATOR_FAST_FAIL_PROPERTY_NAME = LOCATOR_PROPERTY_NAME_PREFIX + "fast-fail"; + + /** + * The property value of default zone locator timeout : "3000" + */ + String DEFAULT_TIMEOUT_PROPERTY_VALUE = "3000"; - int DEFAULT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(3); + /** + * The default value of zone locator timeout. + */ + int DEFAULT_TIMEOUT = parseInt(DEFAULT_TIMEOUT_PROPERTY_VALUE); + + /** + * The property name of zone locator timeout : "microsphere.availability.zone.locator.timeout" + */ + @ConfigurationProperty( + type = int.class, + defaultValue = DEFAULT_TIMEOUT_PROPERTY_VALUE, + source = APPLICATION_SOURCE + ) + String LOCATOR_TIMEOUT_PROPERTY_NAME = LOCATOR_PROPERTY_NAME_PREFIX + "timeout"; } diff --git a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneContext.java b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneContext.java index 43ee95c..f56aaec 100644 --- a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneContext.java +++ b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZoneContext.java @@ -198,7 +198,7 @@ private boolean isPropertyChanged(String propertyName, Object previousPropertyVa propertyChangeSupport.firePropertyChange(propertyName, previousPropertyValue, newPropertyValue); logger.info("The property value [name : '{}'] is changed from '{}' to '{}'", propertyName, previousPropertyValue, newPropertyValue); } else { - logger.debug("The property value [name : '{}'] is not changed : '{}'", propertyName, previousPropertyValue); + logger.trace("The property value [name : '{}'] is not changed : '{}'", propertyName, previousPropertyValue); } return changed; } diff --git a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZonePreferenceFilter.java b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZonePreferenceFilter.java index 4aa727e..949cd1b 100644 --- a/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZonePreferenceFilter.java +++ b/microsphere-multiactive-commons/src/main/java/io/microsphere/multiple/active/zone/ZonePreferenceFilter.java @@ -44,13 +44,13 @@ public List filter(final List entities) { // Disabled case if (!zoneContext.isEnabled()) { - logger.debug("Zone Context feature is disabled! It could be enabled if the Spring property '{}' to be set 'true'", + logger.trace("Zone Context feature is disabled! It could be enabled if the Spring property '{}' to be set 'true'", ZONE_ENABLED_PROPERTY_NAME); return entities; } if (!zoneContext.isPreferenceEnabled()) { - logger.debug("Zone Preference feature is disabled as default! It could be enabled if the Spring property '{}' to be set 'true'", + logger.trace("Zone Preference feature is disabled as default! It could be enabled if the Spring property '{}' to be set 'true'", PREFERENCE_ENABLED_PROPERTY_NAME); return entities; } @@ -58,7 +58,7 @@ public List filter(final List entities) { // Ignored case final String zone = zoneContext.getZone(); if (isIgnored(zone)) { - logger.debug("Zone Preference feature will be ignored, caused by zone : '{}'", zone); + logger.trace("Zone Preference feature will be ignored, caused by zone : '{}'", zone); return entities; } @@ -72,7 +72,7 @@ public List filter(final List entities) { int currentSize = targetEntities.size(); if (currentSize <= 1) { // Not enough entity available - logger.debug("Not enough entity available after disabled zone['{}'] filter, " + "the entities' total size : {} -> actual size : {}", + logger.trace("Not enough entity available after disabled zone['{}'] filter, " + "the entities' total size : {} -> actual size : {}", disabledZone, totalSize, currentSize); return entities; } @@ -101,7 +101,7 @@ public List filter(final List entities) { // Upstream entities ready case int upstreamReadyPercentage = zoneContext.getPreferenceUpstreamZoneReadyPercentage(); if (isUpstreamZoneNotReady(zoneCount, totalSize, upstreamReadyPercentage)) { - logger.debug("The ready percentage of entities with zone is under the threshold [{}%], total entities size : {} , " + logger.trace("The ready percentage of entities with zone is under the threshold [{}%], total entities size : {} , " + "ready entities size : {}", upstreamReadyPercentage, totalSize, zoneCount); return targetEntities; } @@ -112,17 +112,17 @@ public List filter(final List entities) { // The min available in the same zone threshold case int sameZoneMinAvailable = zoneContext.getPreferenceUpstreamSameZoneMinAvailable(); if (isUnderSameZoneMinAvailableThreshold(sameZoneEntitiesSize, sameZoneMinAvailable)) { - logger.debug("The size of same zone ['{}'] entities is under the threshold : {}, actual size : {}", zone, sameZoneMinAvailable, + logger.trace("The size of same zone ['{}'] entities is under the threshold : {}, actual size : {}", zone, sameZoneMinAvailable, sameZoneEntitiesSize); return targetEntities; } - logger.debug("The same zone ['{}'] entities[size : {} , total : {}] are found!", zone, sameZoneEntitiesSize, totalSize); + logger.trace("The same zone ['{}'] entities[size : {} , total : {}] are found!", zone, sameZoneEntitiesSize, totalSize); return sameZoneEntities; } // No matched - logger.debug("No same zone ['{}'] entity was found, total entities size : {} , zone count : {}", zone, totalSize, zoneCount); + logger.trace("No same zone ['{}'] entity was found, total entities size : {} , zone count : {}", zone, totalSize, zoneCount); return targetEntities; } @@ -145,7 +145,7 @@ private List filterDisabledZone(List entities, String disabledZone, int to } } - logger.debug("After filtering the disabled zone['{}'] entities[size : {} -> {}] : {} -> {}", disabledZone, totalSize, targetEntities.size(), + logger.trace("After filtering the disabled zone['{}'] entities[size : {} -> {}] : {} -> {}", disabledZone, totalSize, targetEntities.size(), entities, targetEntities); return targetEntities; } diff --git a/microsphere-multiactive-commons/src/test/java/io/microsphere/multiple/active/zone/ZoneConstantsTest.java b/microsphere-multiactive-commons/src/test/java/io/microsphere/multiple/active/zone/ZoneConstantsTest.java new file mode 100644 index 0000000..7e24be5 --- /dev/null +++ b/microsphere-multiactive-commons/src/test/java/io/microsphere/multiple/active/zone/ZoneConstantsTest.java @@ -0,0 +1,117 @@ +/* + * 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.multiple.active.zone; + + +import org.junit.jupiter.api.Test; + +import static io.microsphere.multiple.active.zone.ZoneConstants.CURRENT_ZONE_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_LOCATOR_FAST_FAIL; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_LOCATOR_FAST_FAIL_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_ENABLED_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_UPSTREAM_DISABLED_ZONE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_TIMEOUT; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_TIMEOUT_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE_ENABLED; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE_ENABLED_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE_PREFERENCE_ENABLED; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE_PREFERENCE_FILTER_ORDER; +import static io.microsphere.multiple.active.zone.ZoneConstants.DEFAULT_ZONE_PREFERENCE_FILTER_ORDER_PROPERTY_VALUE; +import static io.microsphere.multiple.active.zone.ZoneConstants.ENABLED_PROPERTY_NAME_SUFFIX; +import static io.microsphere.multiple.active.zone.ZoneConstants.LOCATOR_FAST_FAIL_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.LOCATOR_PROPERTY_NAME_PREFIX; +import static io.microsphere.multiple.active.zone.ZoneConstants.LOCATOR_TIMEOUT_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.ORIGINAL_ZONE; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_ENABLED_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_FILER_PROPERTY_NAME_PREFIX; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_FILTER_ORDER_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_PROPERTY_NAME_PREFIX; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_UPSTREAM_DISABLED_ZONE_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.ZONE_ENABLED_PROPERTY_NAME; +import static io.microsphere.multiple.active.zone.ZoneConstants.ZONE_PROPERTY_NAME; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link ZoneConstants} Test + * + * @author Mercy + * @see ZoneConstants + * @since 1.0.0 + */ +class ZoneConstantsTest { + + @Test + void test() { + // Zone Properties + assertEquals(".enabled", ENABLED_PROPERTY_NAME_SUFFIX); + assertEquals("defaultZone", DEFAULT_ZONE); + assertEquals("originalZone", ORIGINAL_ZONE); + assertEquals("microsphere.availability.zone", ZONE_PROPERTY_NAME); + assertEquals("microsphere.current.availability.zone", CURRENT_ZONE_PROPERTY_NAME); + assertEquals("true", DEFAULT_ZONE_ENABLED_PROPERTY_VALUE); + assertTrue(DEFAULT_ZONE_ENABLED); + assertEquals("microsphere.availability.zone.enabled", ZONE_ENABLED_PROPERTY_NAME); + + // Zone Preference Properties + assertEquals("microsphere.availability.zone.preference.", PREFERENCE_PROPERTY_NAME_PREFIX); + assertEquals("false", DEFAULT_PREFERENCE_ENABLED_PROPERTY_VALUE); + assertFalse(DEFAULT_ZONE_PREFERENCE_ENABLED); + assertEquals("microsphere.availability.zone.preference.enabled", PREFERENCE_ENABLED_PROPERTY_NAME); + + // Zone Preference Filter Properties + assertEquals("microsphere.availability.zone.preference.filter.", PREFERENCE_FILER_PROPERTY_NAME_PREFIX); + assertEquals("10", DEFAULT_ZONE_PREFERENCE_FILTER_ORDER_PROPERTY_VALUE); + assertEquals(10, DEFAULT_ZONE_PREFERENCE_FILTER_ORDER); + assertEquals("microsphere.availability.zone.preference.filter.order", PREFERENCE_FILTER_ORDER_PROPERTY_NAME); + + // Zone Preference Upstream Properties + assertEquals("microsphere.availability.zone.preference.upstream.", PREFERENCE_UPSTREAM_PROPERTY_NAME_PREFIX); + assertEquals("100", DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_VALUE); + assertEquals(100, DEFAULT_PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE); + assertEquals("microsphere.availability.zone.preference.upstream.zone-ready-percentage", PREFERENCE_UPSTREAM_ZONE_READY_PERCENTAGE_PROPERTY_NAME); + + // Zone Preference Upstream Same Zone Properties + assertEquals("5", DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_VALUE); + assertEquals(5, DEFAULT_PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE); + assertEquals("microsphere.availability.zone.preference.upstream.same-zone-min-available", PREFERENCE_UPSTREAM_SAME_ZONE_MIN_AVAILABLE_PROPERTY_NAME); + + // Zone Preference Upstream Disabled Zone Properties + assertNull(DEFAULT_PREFERENCE_UPSTREAM_DISABLED_ZONE); + assertEquals("microsphere.availability.zone.preference.upstream.disabled-zone", PREFERENCE_UPSTREAM_DISABLED_ZONE_PROPERTY_NAME); + + // Zone Locator Properties + assertEquals("microsphere.availability.zone.locator.", LOCATOR_PROPERTY_NAME_PREFIX); + assertEquals("false", DEFAULT_LOCATOR_FAST_FAIL_PROPERTY_VALUE); + assertFalse(DEFAULT_LOCATOR_FAST_FAIL); + assertEquals("microsphere.availability.zone.locator.fast-fail", LOCATOR_FAST_FAIL_PROPERTY_NAME); + assertEquals("3000", DEFAULT_TIMEOUT_PROPERTY_VALUE); + assertEquals(3000, DEFAULT_TIMEOUT); + assertEquals("microsphere.availability.zone.locator.timeout", LOCATOR_TIMEOUT_PROPERTY_NAME); + } +} \ No newline at end of file diff --git a/microsphere-multiactive-netflix/pom.xml b/microsphere-multiactive-netflix/pom.xml index a87342f..51ce0af 100644 --- a/microsphere-multiactive-netflix/pom.xml +++ b/microsphere-multiactive-netflix/pom.xml @@ -24,7 +24,14 @@ - + + + io.github.microsphere-projects + microsphere-annotation-processor + true + + + io.github.microsphere-projects microsphere-multiactive-spring-cloud @@ -32,7 +39,7 @@ true - + org.springframework.boot spring-boot-starter @@ -41,13 +48,13 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-actuator true org.springframework.boot - spring-boot-starter-webflux + spring-boot-starter-web true @@ -59,11 +66,11 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-autoconfigure-processor true - + org.springframework.cloud spring-cloud-commons @@ -111,6 +118,34 @@ true + + + org.junit.jupiter + junit-jupiter + test + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + io.github.microsphere-projects + microsphere-spring-boot-test + test + + + + + ch.qos.logback + logback-classic + test + + \ No newline at end of file diff --git a/microsphere-multiactive-parent/pom.xml b/microsphere-multiactive-parent/pom.xml index f503ee3..d27fb2f 100644 --- a/microsphere-multiactive-parent/pom.xml +++ b/microsphere-multiactive-parent/pom.xml @@ -20,7 +20,7 @@ - 0.1.21 + 0.1.23 diff --git a/microsphere-multiactive-spring-boot/pom.xml b/microsphere-multiactive-spring-boot/pom.xml index c5a04ba..3889ed0 100644 --- a/microsphere-multiactive-spring-boot/pom.xml +++ b/microsphere-multiactive-spring-boot/pom.xml @@ -20,7 +20,14 @@ - + + + io.github.microsphere-projects + microsphere-annotation-processor + true + + + io.github.microsphere-projects microsphere-multiactive-spring @@ -31,6 +38,7 @@ io.github.microsphere-projects microsphere-spring-boot-core + true @@ -42,13 +50,13 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-actuator true org.springframework.boot - spring-boot-starter-webflux + spring-boot-starter-web true @@ -60,15 +68,36 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-autoconfigure-processor true - + - org.slf4j - slf4j-api - true + org.junit.jupiter + junit-jupiter + test + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + io.github.microsphere-projects + microsphere-spring-boot-test + test + + + + + ch.qos.logback + logback-classic + test diff --git a/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfiguration.java b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfiguration.java index 5713c8b..5ac965d 100644 --- a/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfiguration.java +++ b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfiguration.java @@ -3,8 +3,9 @@ import io.microsphere.multiple.active.zone.ZoneContext; import io.microsphere.multiple.active.zone.spring.CompositeZoneLocator; import io.microsphere.multiple.active.zone.spring.ZoneLocator; -import io.microsphere.multiple.active.zone.spring.boot.condition.ConditionalOnEnabledZone; +import io.microsphere.multiple.active.zone.spring.boot.condition.ConditionalOnAvailabilityZoneAvailable; import io.microsphere.multiple.active.zone.spring.event.ZoneContextChangedListener; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -15,6 +16,7 @@ import java.util.Collection; import java.util.List; +import static io.microsphere.multiple.active.zone.ZoneContext.get; import static io.microsphere.multiple.active.zone.spring.ZoneUtils.ZONE_CONTEXT_BEAN_NAME; import static io.microsphere.multiple.active.zone.spring.ZoneUtils.ZONE_LOCATOR_BEAN_NAME; import static io.microsphere.spring.core.io.support.SpringFactoriesLoaderUtils.loadFactories; @@ -26,18 +28,20 @@ * @author Mercy * @since 1.0.0 */ -@Configuration -@ConditionalOnEnabledZone +@Configuration(proxyBeanMethods = false) +@ConditionalOnAvailabilityZoneAvailable @Import(value = {ZoneContextChangedListener.class}) public class ZoneAutoConfiguration { @Bean(name = ZONE_CONTEXT_BEAN_NAME) + @ConditionalOnMissingBean public ZoneContext zoneContext() { - return ZoneContext.get(); + return get(); } - @Bean(name = ZONE_LOCATOR_BEAN_NAME) @Primary + @Bean(name = ZONE_LOCATOR_BEAN_NAME) + @ConditionalOnMissingBean public CompositeZoneLocator zoneLocator(Collection zoneLocatorBeans, ConfigurableApplicationContext context) { // Load from Spring Factories List zoneLocators = loadFactories(context, ZoneLocator.class); diff --git a/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnEnabledZone.java b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneAvailable.java similarity index 67% rename from microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnEnabledZone.java rename to microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneAvailable.java index 272630b..534f83f 100644 --- a/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnEnabledZone.java +++ b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneAvailable.java @@ -19,17 +19,15 @@ import io.microsphere.multiple.active.zone.ZoneContext; import io.microsphere.multiple.active.zone.spring.ZoneLocator; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Conditional; import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import static io.microsphere.multiple.active.zone.ZoneConstants.ENABLED_PROPERTY_NAME_SUFFIX; -import static io.microsphere.multiple.active.zone.ZoneConstants.ZONE_PROPERTY_NAME; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * {@link @Conditional} that checks if zone is enabled @@ -38,13 +36,13 @@ * @see Conditional * @since 1.0.0 */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RUNTIME) +@Target({TYPE, METHOD}) @Documented @ConditionalOnClass(value = { - ZoneContext.class, // from "microsphere-multiactive-commons" - ZoneLocator.class, // from microsphere-multiactive-spring + ZoneContext.class, // Microsphere Multi-Active Commons + ZoneLocator.class // Microsphere Multi-Active Spring }) -@ConditionalOnProperty(prefix = ZONE_PROPERTY_NAME, name = ENABLED_PROPERTY_NAME_SUFFIX) -public @interface ConditionalOnEnabledZone { +@ConditionalOnAvailabilityZoneEnabled +public @interface ConditionalOnAvailabilityZoneAvailable { } diff --git a/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneEnabled.java b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneEnabled.java new file mode 100644 index 0000000..51a571f --- /dev/null +++ b/microsphere-multiactive-spring-boot/src/main/java/io/microsphere/multiple/active/zone/spring/boot/condition/ConditionalOnAvailabilityZoneEnabled.java @@ -0,0 +1,43 @@ +/* + * 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.multiple.active.zone.spring.boot.condition; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Conditional; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static io.microsphere.multiple.active.zone.ZoneConstants.ZONE_ENABLED_PROPERTY_NAME; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * {@link @Conditional} that checks if zone is enabled + * + * @author Mercy + * @see Conditional + * @since 1.0.0 + */ +@Retention(RUNTIME) +@Target({TYPE, METHOD}) +@Documented +@ConditionalOnProperty(name = ZONE_ENABLED_PROPERTY_NAME, matchIfMissing = true) +public @interface ConditionalOnAvailabilityZoneEnabled { +} diff --git a/microsphere-multiactive-spring-boot/src/test/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfigurationTest.java b/microsphere-multiactive-spring-boot/src/test/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfigurationTest.java new file mode 100644 index 0000000..1a57980 --- /dev/null +++ b/microsphere-multiactive-spring-boot/src/test/java/io/microsphere/multiple/active/zone/spring/boot/autoconfigure/ZoneAutoConfigurationTest.java @@ -0,0 +1,62 @@ +/* + * 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.multiple.active.zone.spring.boot.autoconfigure; + + +import io.microsphere.multiple.active.zone.ZoneContext; +import io.microsphere.multiple.active.zone.spring.CompositeZoneLocator; +import io.microsphere.multiple.active.zone.spring.ZoneLocator; +import io.microsphere.spring.boot.test.AutoConfigurationTest; +import org.springframework.boot.test.context.SpringBootTest; + +import java.util.Set; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +/** + * {@link ZoneAutoConfiguration} Test + * + * @author Mercy + * @see ZoneAutoConfiguration + * @since 1.0.0 + */ +@SpringBootTest( + classes = { + ZoneAutoConfigurationTest.class + }, + webEnvironment = NONE +) +class ZoneAutoConfigurationTest extends AutoConfigurationTest { + + @Override + protected void configureAutoConfiguredClasses(Set> autoConfiguredClasses) { + autoConfiguredClasses.add(ZoneContext.class); + autoConfiguredClasses.add(CompositeZoneLocator.class); + } + + @Override + protected void configureGlobalDisabledPropertyValues(Set globalDisabledPropertyValues) { + globalDisabledPropertyValues.add("microsphere.availability.zone.enabled=false"); + } + + @Override + protected void configureGlobalMissingClasses(Set> globalMissingClasses) { + globalMissingClasses.add(ZoneContext.class); + globalMissingClasses.add(ZoneLocator.class); + } +} \ No newline at end of file diff --git a/microsphere-multiactive-spring-cloud/pom.xml b/microsphere-multiactive-spring-cloud/pom.xml index 7b1f392..d99be02 100644 --- a/microsphere-multiactive-spring-cloud/pom.xml +++ b/microsphere-multiactive-spring-cloud/pom.xml @@ -20,16 +20,25 @@ - + + + io.github.microsphere-projects + microsphere-annotation-processor + true + + + io.github.microsphere-projects microsphere-multiactive-spring-boot ${revision} + io.github.microsphere-projects microsphere-spring-cloud-commons + true @@ -41,13 +50,13 @@ org.springframework.boot - spring-boot-starter-web + spring-boot-starter-actuator true org.springframework.boot - spring-boot-starter-webflux + spring-boot-starter-web true @@ -59,7 +68,7 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-autoconfigure-processor true @@ -82,5 +91,33 @@ true + + + org.junit.jupiter + junit-jupiter + test + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + io.github.microsphere-projects + microsphere-spring-boot-test + test + + + + + ch.qos.logback + logback-classic + test + + \ No newline at end of file diff --git a/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneAutoConfiguration.java b/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneAutoConfiguration.java deleted file mode 100644 index 53ae095..0000000 --- a/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneAutoConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.microsphere.multiple.active.zone.spring.cloud.autoconfigure; - -import io.microsphere.multiple.active.zone.ZoneAttachmentHandler; -import io.microsphere.multiple.active.zone.spring.boot.condition.ConditionalOnEnabledZone; -import io.microsphere.multiple.active.zone.spring.cloud.event.ZoneAttachmentListener; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Zone Auto-Configuration for Spring Cloud - * - * @author Mercy - * @see io.microsphere.multiple.active.zone.spring.boot.autoconfigure.ZoneAutoConfiguration - * @since 1.0.0 - */ -@Configuration -@ConditionalOnEnabledZone -@Import(value = {ZoneAttachmentHandler.class}) -@AutoConfigureAfter(name = {"org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration"}) -public class ZoneAutoConfiguration { - - @Bean - @ConditionalOnClass(name = "org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent") - public ZoneAttachmentListener zoneAttachmentListener() { - return new ZoneAttachmentListener(); - } - -} diff --git a/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfiguration.java b/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfiguration.java new file mode 100644 index 0000000..2a3314b --- /dev/null +++ b/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfiguration.java @@ -0,0 +1,55 @@ +package io.microsphere.multiple.active.zone.spring.cloud.autoconfigure; + +import io.microsphere.multiple.active.zone.ZoneAttachmentHandler; +import io.microsphere.multiple.active.zone.ZoneContext; +import io.microsphere.multiple.active.zone.spring.boot.autoconfigure.ZoneAutoConfiguration; +import io.microsphere.multiple.active.zone.spring.boot.condition.ConditionalOnAvailabilityZoneAvailable; +import io.microsphere.multiple.active.zone.spring.cloud.event.ZoneAttachmentListener; +import io.microsphere.spring.cloud.client.service.registry.condition.ConditionalOnAutoServiceRegistrationEnabled; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +import static io.microsphere.spring.cloud.client.service.registry.constants.ServiceRegistryConstants.REGISTRATION_CLASS_NAME; + +/** + * Zone Auto-Configuration for Spring Cloud + * + * @author Mercy + * @see io.microsphere.multiple.active.zone.spring.boot.autoconfigure.ZoneAutoConfiguration + * @since 1.0.0 + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnAvailabilityZoneAvailable +@ConditionalOnAutoServiceRegistrationEnabled +@ConditionalOnClass(name = { + "org.aspectj.lang.annotation.Aspect", // AspectJ API + "io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreRegisteredEvent", // Microsphere Spring Cloud Commons API + REGISTRATION_CLASS_NAME +}) +@ConditionalOnBean(ZoneContext.class) +@AutoConfigureAfter( + value = { + ZoneAutoConfiguration.class + }, + name = { + "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration", // Spring Cloud Netflix Eureka API + "io.microsphere.spring.cloud.client.service.registry.autoconfigure.ServiceRegistryAutoConfiguration" // Microsphere Spring Cloud Commons API + }) +@Import(value = { + ZoneAttachmentHandler.class +}) +public class ZoneCloudAutoConfiguration { + + @Bean + @ConditionalOnBean(type = "io.microsphere.spring.cloud.client.service.registry.aspect.EventPublishingRegistrationAspect") + @ConditionalOnMissingBean + public ZoneAttachmentListener zoneAttachmentListener() { + return new ZoneAttachmentListener(); + } + +} \ No newline at end of file diff --git a/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/event/ZoneAttachmentListener.java b/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/event/ZoneAttachmentListener.java index 0d20fa8..7d6d72e 100644 --- a/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/event/ZoneAttachmentListener.java +++ b/microsphere-multiactive-spring-cloud/src/main/java/io/microsphere/multiple/active/zone/spring/cloud/event/ZoneAttachmentListener.java @@ -2,6 +2,7 @@ import io.microsphere.multiple.active.zone.ZoneAttachmentHandler; import io.microsphere.multiple.active.zone.ZoneContext; +import io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreRegisteredEvent; import org.springframework.beans.BeansException; import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; import org.springframework.cloud.client.serviceregistry.Registration; @@ -19,12 +20,12 @@ * @see ZoneContext * @since 1.0.0 */ -public class ZoneAttachmentListener implements ApplicationListener, ApplicationContextAware { +public class ZoneAttachmentListener implements ApplicationListener, ApplicationContextAware { private ApplicationContext applicationContext; @Override - public void onApplicationEvent(InstancePreRegisteredEvent event) { + public void onApplicationEvent(RegistrationPreRegisteredEvent event) { Registration registration = event.getRegistration(); Map metadata = registration.getMetadata(); ZoneAttachmentHandler zoneAttachmentHandler = applicationContext.getBean(ZoneAttachmentHandler.class); diff --git a/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring.factories b/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring.factories index e235938..49d36db 100644 --- a/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring.factories +++ b/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring.factories @@ -1,3 +1,3 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.microsphere.multiple.active.zone.spring.cloud.autoconfigure.ZoneAutoConfiguration,\ +io.microsphere.multiple.active.zone.spring.cloud.autoconfigure.ZoneCloudAutoConfiguration,\ io.microsphere.multiple.active.zone.spring.cloud.loadbalancer.CustomizedLoadBalancerAutoConfiguration \ No newline at end of file diff --git a/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index b76fd9e..556c7f3 100644 --- a/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/microsphere-multiactive-spring-cloud/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,2 @@ -io.microsphere.multiple.active.zone.spring.cloud.autoconfigure.ZoneAutoConfiguration +io.microsphere.multiple.active.zone.spring.cloud.autoconfigure.ZoneCloudAutoConfiguration io.microsphere.multiple.active.zone.spring.cloud.loadbalancer.CustomizedLoadBalancerAutoConfiguration \ No newline at end of file diff --git a/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationIntegrationTest.java b/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationIntegrationTest.java new file mode 100644 index 0000000..403b09e --- /dev/null +++ b/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationIntegrationTest.java @@ -0,0 +1,84 @@ +/* + * 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.multiple.active.zone.spring.cloud.autoconfigure; + +import io.microsphere.multiple.active.zone.ZoneAttachmentHandler; +import io.microsphere.multiple.active.zone.ZoneContext; +import io.microsphere.multiple.active.zone.spring.CompositeZoneLocator; +import io.microsphere.multiple.active.zone.spring.cloud.event.ZoneAttachmentListener; +import io.microsphere.spring.cloud.client.service.registry.InMemoryServiceRegistry; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.client.serviceregistry.Registration; +import org.springframework.cloud.client.serviceregistry.ServiceRegistry; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +/** + * {@link ZoneCloudAutoConfiguration} Integration Test + * + * @author Mercy + * @see ZoneCloudAutoConfiguration + * @since 1.0.0 + */ +@SpringBootTest( + classes = { + InMemoryServiceRegistry.class, + ZoneCloudAutoConfigurationIntegrationTest.class + }, + webEnvironment = NONE, + properties = { + "server.port=8080", + "spring.application.name=test-service", + "microsphere.spring.cloud.service-registry.auto-registration.simple.enabled=true" + } +) +@EnableAutoConfiguration +@EnableConfigurationProperties(value = { + ServerProperties.class +}) +public class ZoneCloudAutoConfigurationIntegrationTest { + + @Autowired + private Registration registration; + + @Autowired + private ServiceRegistry serviceRegistry; + + @Autowired + private ZoneContext zoneContext; + + @Autowired + private CompositeZoneLocator compositeZoneLocator; + + @Autowired + private ZoneAttachmentHandler zoneAttachmentHandler; + + @Autowired + private ZoneAttachmentListener zoneAttachmentListener; + + @Test + void test() { + assertNotNull(zoneContext); + } +} diff --git a/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationTest.java b/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationTest.java new file mode 100644 index 0000000..6f61c37 --- /dev/null +++ b/microsphere-multiactive-spring-cloud/src/test/java/io/microsphere/multiple/active/zone/spring/cloud/autoconfigure/ZoneCloudAutoConfigurationTest.java @@ -0,0 +1,72 @@ +/* + * 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.multiple.active.zone.spring.cloud.autoconfigure; + + +import io.microsphere.multiple.active.zone.ZoneAttachmentHandler; +import io.microsphere.multiple.active.zone.ZoneContext; +import io.microsphere.multiple.active.zone.spring.ZoneLocator; +import io.microsphere.multiple.active.zone.spring.cloud.event.ZoneAttachmentListener; +import io.microsphere.spring.boot.test.AutoConfigurationTest; +import io.microsphere.spring.cloud.client.service.registry.aspect.EventPublishingRegistrationAspect; +import io.microsphere.spring.cloud.client.service.registry.event.RegistrationPreRegisteredEvent; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.client.serviceregistry.Registration; + +import java.util.Set; + +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; + +/** + * {@link ZoneCloudAutoConfiguration} Test + * + * @author Mercy + * @see ZoneCloudAutoConfiguration + * @since 1.0.0 + */ +@SpringBootTest( + classes = { + ZoneContext.class, + EventPublishingRegistrationAspect.class, + ZoneCloudAutoConfigurationTest.class + }, + webEnvironment = NONE +) +class ZoneCloudAutoConfigurationTest extends AutoConfigurationTest { + + @Override + protected void configureAutoConfiguredClasses(Set> autoConfiguredClasses) { + autoConfiguredClasses.add(ZoneAttachmentHandler.class); + autoConfiguredClasses.add(ZoneAttachmentListener.class); + } + + @Override + protected void configureGlobalDisabledPropertyValues(Set globalDisabledPropertyValues) { + globalDisabledPropertyValues.add("microsphere.availability.zone.enabled=false"); + globalDisabledPropertyValues.add("spring.cloud.service-registry.auto-registration.enabled=false"); + } + + @Override + protected void configureGlobalMissingClasses(Set> globalMissingClasses) { + globalMissingClasses.add(ZoneLocator.class); + globalMissingClasses.add(Aspect.class); + globalMissingClasses.add(RegistrationPreRegisteredEvent.class); + globalMissingClasses.add(Registration.class); + } +} \ No newline at end of file diff --git a/microsphere-multiactive-spring/pom.xml b/microsphere-multiactive-spring/pom.xml index 7cbd7ec..4103665 100644 --- a/microsphere-multiactive-spring/pom.xml +++ b/microsphere-multiactive-spring/pom.xml @@ -20,7 +20,14 @@ - + + + io.github.microsphere-projects + microsphere-annotation-processor + true + + + io.github.microsphere-projects microsphere-multiactive-commons @@ -31,6 +38,7 @@ io.github.microsphere-projects microsphere-spring-context + true @@ -40,13 +48,6 @@ true - - - org.slf4j - slf4j-api - true - - org.junit.jupiter @@ -54,9 +55,24 @@ test + - org.junit.jupiter - junit-jupiter-engine + org.springframework + spring-test + test + + + + + io.github.microsphere-projects + microsphere-spring-test + test + + + + + ch.qos.logback + logback-classic test diff --git a/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/CompositeZoneLocator.java b/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/CompositeZoneLocator.java index 2cc9045..8c1a3d2 100644 --- a/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/CompositeZoneLocator.java +++ b/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/CompositeZoneLocator.java @@ -73,7 +73,7 @@ public String locate(Environment environment) { } } } else { - logger.debug("{} does not support to locate the zone", zoneLocator); + logger.trace("{} does not support to locate the zone", zoneLocator); } } catch (Throwable e) { logger.error("{} failed to locate the zone", zoneLocator, e); diff --git a/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/DefaultZoneLocator.java b/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/DefaultZoneLocator.java index 47449b8..5838468 100644 --- a/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/DefaultZoneLocator.java +++ b/microsphere-multiactive-spring/src/main/java/io/microsphere/multiple/active/zone/spring/DefaultZoneLocator.java @@ -31,7 +31,7 @@ public String locate(Environment environment) { if (StringUtils.hasText(zone)) { logger.info("The zone ['{}'] was located from the Spring Property [name: '{}']", zone, ZONE_PROPERTY_NAME); } else { - logger.debug("The property [name : '{}' ] of zone can't be found, the default value ['{}'] will be applied", ZONE_PROPERTY_NAME, + logger.trace("The property [name : '{}' ] of zone can't be found, the default value ['{}'] will be applied", ZONE_PROPERTY_NAME, DEFAULT_ZONE); zone = DEFAULT_ZONE; } diff --git a/microsphere-multiactive-spring/src/test/java/io/microsphere/multiple/active/zone/spring/event/ZoneContextChangedListenerTest.java b/microsphere-multiactive-spring/src/test/java/io/microsphere/multiple/active/zone/spring/event/ZoneContextChangedListenerTest.java index 9b8a2f9..13be6d7 100644 --- a/microsphere-multiactive-spring/src/test/java/io/microsphere/multiple/active/zone/spring/event/ZoneContextChangedListenerTest.java +++ b/microsphere-multiactive-spring/src/test/java/io/microsphere/multiple/active/zone/spring/event/ZoneContextChangedListenerTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import java.util.Collections; @@ -313,12 +314,12 @@ void testRevertOriginalZoneWhenLocatorDoesNotSupport() { // ZoneLocator that never supports ZoneLocator unsupportedLocator = new ZoneLocator() { @Override - public boolean supports(org.springframework.core.env.Environment environment) { + public boolean supports(Environment environment) { return false; } @Override - public String locate(org.springframework.core.env.Environment environment) { + public String locate(Environment environment) { return null; } }; diff --git a/pom.xml b/pom.xml index eeddc43..5a58dac 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.microsphere-projects microsphere-spring-cloud-parent - 0.1.21 + 0.1.23 io.github.microsphere-projects