Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
[![Codecov](https://codecov.io/gh/microsphere-projects/microsphere-spring-boot/branch/dev-1.x/graph/badge.svg)](https://app.codecov.io/gh/microsphere-projects/microsphere-spring-boot)
![Maven](https://img.shields.io/maven-central/v/io.github.microsphere-projects/microsphere-spring-boot.svg)
![License](https://img.shields.io/github/license/microsphere-projects/microsphere-spring-boot.svg)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/microsphere-projects/microsphere-spring-boot.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-boot "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/microsphere-projects/microsphere-spring-boot.svg)](http://isitmaintained.com/project/microsphere-projects/microsphere-spring-boot "Percentage of issues still open")


Microsphere Spring Boot is a collection of libraries that extends Spring Boot's capabilities with additional features
focused on configuration management, application diagnostics, and enhanced monitoring. The project is structured as a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.microsphere.annotation.ConfigurationProperty;
import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter;
import org.springframework.boot.autoconfigure.AutoConfigurationMetadata;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
Expand All @@ -12,13 +13,15 @@

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;

import static io.microsphere.annotation.ConfigurationProperty.APPLICATION_SOURCE;
import static io.microsphere.spring.core.env.EnvironmentUtils.asConfigurableEnvironment;
import static io.microsphere.util.ArrayUtils.EMPTY_STRING_ARRAY;
import static io.microsphere.util.ArrayUtils.combine;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;
import static org.springframework.boot.context.properties.bind.Binder.get;
import static org.springframework.util.Assert.isInstanceOf;
import static org.springframework.util.StringUtils.collectionToCommaDelimitedString;
import static org.springframework.util.StringUtils.commaDelimitedListToSet;
Expand All @@ -32,6 +35,11 @@
* <pre>{@code
* microsphere.autoconfigure.exclude=com.example.FooAutoConfiguration,com.example.BarAutoConfiguration
* }</pre>
* or
* <pre>{@code
* microsphere.autoconfigure.exclude[0]=com.example.FooAutoConfiguration
* microsphere.autoconfigure.exclude[1]=com.example.BarAutoConfiguration
* }</pre>
*
* <h4>Programmatically exclude classes</h4>
* <pre>{@code
Expand Down Expand Up @@ -70,18 +78,39 @@ public void setEnvironment(Environment environment) {
}

public static Set<String> getExcludedAutoConfigurationClasses(Environment environment) {
MutablePropertySources propertySources = getPropertySources(environment);
Set<String> allExcludedClasses = new TreeSet<>();
ConfigurableEnvironment configurableEnvironment = asConfigurableEnvironment(environment);
Set<String> allExcludedClasses = new LinkedHashSet<>();
addExcludedAutoConfigurationClasses(environment, getExcludedAutoConfigurationClasses(configurableEnvironment), allExcludedClasses);
addExcludedAutoConfigurationClasses(environment, getExcludedAutoConfigurationClassesFromBinder(configurableEnvironment), allExcludedClasses);
return allExcludedClasses.isEmpty() ? emptySet() : unmodifiableSet(allExcludedClasses);
}

private static void addExcludedAutoConfigurationClasses(Environment environment, String[] excludedClasses,
Set<String> allExcludedClasses) {
for (String excludedClass : excludedClasses) {
String resolvedExcludeClass = environment.resolvePlaceholders(excludedClass);
allExcludedClasses.addAll(commaDelimitedListToSet(resolvedExcludeClass));
}
}

private static String[] getExcludedAutoConfigurationClasses(ConfigurableEnvironment environment) {
Set<String> excludedClasses = new LinkedHashSet<>();
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource propertySource : propertySources) {
Object property = propertySource.getProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME);
if (property instanceof String) {
String exclude = (String) property;
String resolvedExclude = environment.resolvePlaceholders(exclude);
Set<String> excludedClasses = commaDelimitedListToSet(resolvedExclude);
allExcludedClasses.addAll(excludedClasses);
Set<String> classes = commaDelimitedListToSet(resolvedExclude);
excludedClasses.addAll(classes);
}
}
return allExcludedClasses.isEmpty() ? emptySet() : unmodifiableSet(allExcludedClasses);
return excludedClasses.isEmpty() ? EMPTY_STRING_ARRAY : excludedClasses.toArray(EMPTY_STRING_ARRAY);
}

private static String[] getExcludedAutoConfigurationClassesFromBinder(ConfigurableEnvironment environment) {
Binder binder = get(environment);
return binder.bind(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, String[].class).orElse(EMPTY_STRING_ARRAY);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.mock.env.MockEnvironment;

import java.util.Set;
import java.util.TreeSet;

import static io.microsphere.collection.Maps.ofMap;
import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME;
import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.addExcludedAutoConfigurationClass;
import static io.microsphere.spring.boot.autoconfigure.ConfigurableAutoConfigurationImportFilter.getExcludedAutoConfigurationClasses;
Expand Down Expand Up @@ -50,9 +53,15 @@ class ConfigurableAutoConfigurationImportFilterTest {

private MockEnvironment environment;

private String[] autoConfigurationClasses;

private ConfigurableAutoConfigurationImportFilter filter;

@BeforeEach
void setUp() {
environment = new MockEnvironment();
this.environment = new MockEnvironment();
this.autoConfigurationClasses = ofArray(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3);
this.filter = new ConfigurableAutoConfigurationImportFilter();
}

@Test
Expand All @@ -62,97 +71,123 @@ void testConstants() {

@Test
void testMatch() {
ConfigurableAutoConfigurationImportFilter filter = new ConfigurableAutoConfigurationImportFilter();
filter.setEnvironment(this.environment);

String[] autoConfigurationClasses = ofArray(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3);

boolean[] result = filter.match(autoConfigurationClasses, null);
this.filter.setEnvironment(this.environment);
boolean[] result = this.filter.match(this.autoConfigurationClasses, null);
assertTrue(result[0]);
assertTrue(result[1]);
assertTrue(result[2]);

this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
filter.setEnvironment(this.environment);
result = filter.match(autoConfigurationClasses, null);
this.filter.setEnvironment(this.environment);
result = this.filter.match(this.autoConfigurationClasses, null);
assertFalse(result[0]);
assertTrue(result[1]);
assertTrue(result[2]);

MutablePropertySources propertySources = this.environment.getPropertySources();
MapPropertySource mapPropertySource1 = new MapPropertySource("map-property-source-1",
ofMap(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2));
propertySources.addLast(mapPropertySource1);
this.filter.setEnvironment(this.environment);
result = this.filter.match(this.autoConfigurationClasses, null);
assertFalse(result[0]);
assertFalse(result[1]);
assertTrue(result[2]);

MapPropertySource mapPropertySource2 = new MapPropertySource("map-property-source-2",
ofMap(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_3));
propertySources.addLast(mapPropertySource2);
this.filter.setEnvironment(this.environment);
result = this.filter.match(this.autoConfigurationClasses, null);
assertFalse(result[0]);
assertFalse(result[1]);
assertFalse(result[2]);
}

@Test
void testMatchFromBinder() {
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[0]", TEST_CLASS_NAME_1);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[1]", TEST_CLASS_NAME_2);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME + "[2]", TEST_CLASS_NAME_3);
this.filter.setEnvironment(this.environment);
boolean[] result = this.filter.match(autoConfigurationClasses, null);
assertFalse(result[0]);
assertFalse(result[1]);
assertFalse(result[2]);
}

@Test
void testGetExcludedAutoConfigurationClasses() {
Set<String> classNames = getExcludedAutoConfigurationClasses(environment);
Set<String> classNames = getExcludedAutoConfigurationClasses(this.environment);
assertTrue(classNames.isEmpty());

environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(singleton(TEST_CLASS_NAME_1), classNames);

environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2);
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);

environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2 + "," + TEST_CLASS_NAME_3);
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_2 + "," + TEST_CLASS_NAME_3);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);

// Test the placeholders
environment.setProperty("exclude", TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_3);
environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude}");
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty("exclude", TEST_CLASS_NAME_1 + "," + TEST_CLASS_NAME_3);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude}");
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_3)), classNames);

environment.setProperty("exclude1", TEST_CLASS_NAME_1);
environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2 + ",${exclude1}");
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty("exclude1", TEST_CLASS_NAME_1);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, TEST_CLASS_NAME_2 + ",${exclude1}");
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_2, TEST_CLASS_NAME_1)), classNames);

environment.setProperty("exclude1", TEST_CLASS_NAME_1);
environment.setProperty("exclude2", TEST_CLASS_NAME_2);
environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude1},${exclude2}");
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty("exclude1", TEST_CLASS_NAME_1);
this.environment.setProperty("exclude2", TEST_CLASS_NAME_2);
this.environment.setProperty(AUTO_CONFIGURE_EXCLUDE_PROPERTY_NAME, "${exclude1},${exclude2}");
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);
}

@Test
void testAddExcludedAutoConfigurationClass() {
Set<String> classNames = getExcludedAutoConfigurationClasses(environment);
Set<String> classNames = getExcludedAutoConfigurationClasses(this.environment);
assertTrue(classNames.isEmpty());

addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_1);
classNames = getExcludedAutoConfigurationClasses(environment);
addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_1);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(singleton(TEST_CLASS_NAME_1), classNames);

addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_2);
classNames = getExcludedAutoConfigurationClasses(environment);
addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_2);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2)), classNames);

// Test the placeholders
environment.setProperty("exclude3", TEST_CLASS_NAME_3);
addExcludedAutoConfigurationClass(environment, "${exclude3}");
classNames = getExcludedAutoConfigurationClasses(environment);
this.environment.setProperty("exclude3", TEST_CLASS_NAME_3);
addExcludedAutoConfigurationClass(this.environment, "${exclude3}");
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);

// Test the duplicated elements
addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_3);
classNames = getExcludedAutoConfigurationClasses(environment);
addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_3);
classNames = getExcludedAutoConfigurationClasses(this.environment);
assertEquals(new TreeSet(asList(TEST_CLASS_NAME_1, TEST_CLASS_NAME_2, TEST_CLASS_NAME_3)), classNames);
}

@Test
void testIsExcluded() {
ConfigurableAutoConfigurationImportFilter filter = new ConfigurableAutoConfigurationImportFilter();
filter.setEnvironment(this.environment);
this.filter.setEnvironment(this.environment);

assertFalse(filter.isExcluded(null));
assertFalse(filter.isExcluded(""));
assertFalse(filter.isExcluded(" "));
assertFalse(this.filter.isExcluded(null));
assertFalse(this.filter.isExcluded(""));
assertFalse(this.filter.isExcluded(" "));

assertFalse(filter.isExcluded(TEST_CLASS_NAME_1));
assertFalse(this.filter.isExcluded(TEST_CLASS_NAME_1));

addExcludedAutoConfigurationClass(environment, TEST_CLASS_NAME_1);
filter.setEnvironment(this.environment);
assertTrue(filter.isExcluded(TEST_CLASS_NAME_1));
addExcludedAutoConfigurationClass(this.environment, TEST_CLASS_NAME_1);
this.filter.setEnvironment(this.environment);
assertTrue(this.filter.isExcluded(TEST_CLASS_NAME_1));
}
}
2 changes: 1 addition & 1 deletion microsphere-spring-boot-parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<description>Microsphere Spring Boot Parent</description>

<properties>
<microsphere-spring.version>0.1.4</microsphere-spring.version>
<microsphere-spring.version>0.1.5</microsphere-spring.version>
<jolokia.version>1.7.2</jolokia.version>
</properties>

Expand Down
26 changes: 1 addition & 25 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
</scm>

<properties>
<revision>0.1.4-SNAPSHOT</revision>
<revision>0.1.5-SNAPSHOT</revision>
</properties>

<modules>
Expand All @@ -62,28 +62,4 @@
<module>microsphere-spring-boot-actuator</module>
</modules>

<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>

<repositories>
<repository>
<id>snapshot</id>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</repository>
</repositories>

</project>