Support mixed case endpoint includes/excludes

Update `ExposeExcludePropertyEndpointFilter` so that mixed case
endpoint IDs are supported. Prior to this commit it was not easy for
an endpoint to be missed by the filter due to the formatting of the
property value.

See gh-14773
pull/14914/head
Phillip Webb 6 years ago
parent 674a909bab
commit df5dfbf4be

@ -21,11 +21,13 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.EndpointFilter;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint; import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder; import org.springframework.boot.context.properties.bind.Binder;
@ -74,10 +76,19 @@ public class ExposeExcludePropertyEndpointFilter<E extends ExposableEndpoint<?>>
} }
private Set<String> bind(Binder binder, String name) { private Set<String> bind(Binder binder, String name) {
return asSet(binder.bind(name, Bindable.listOf(String.class)) return asSet(binder.bind(name, Bindable.listOf(String.class)).map(this::cleanup)
.orElseGet(ArrayList::new)); .orElseGet(ArrayList::new));
} }
private List<String> cleanup(List<String> values) {
return values.stream().map(this::cleanup).collect(Collectors.toList());
}
private String cleanup(String value) {
return "*".equals(value) ? "*"
: EndpointId.fromPropertyValue(value).toLowerCaseString();
}
private Set<String> asSet(Collection<String> items) { private Set<String> asSet(Collection<String> items) {
if (items == null) { if (items == null) {
return Collections.emptySet(); return Collections.emptySet();

@ -147,6 +147,12 @@ public class ExposeExcludePropertyEndpointFilterTests {
assertThat(match(EndpointId.of("buz"))).isFalse(); assertThat(match(EndpointId.of("buz"))).isFalse();
} }
@Test
public void matchWhenMixedCaseShouldMatch() {
setupFilter("foo-bar", "");
assertThat(match(EndpointId.of("fooBar"))).isTrue();
}
private void setupFilter(String include, String exclude) { private void setupFilter(String include, String exclude) {
MockEnvironment environment = new MockEnvironment(); MockEnvironment environment = new MockEnvironment();
environment.setProperty("foo.include", include); environment.setProperty("foo.include", include);

@ -87,4 +87,14 @@ public final class EndpointId {
return new EndpointId(value); return new EndpointId(value);
} }
/**
* Factory method to create a new {@link EndpointId} from a property value. Is more
* lenient that {@link #of(String)} to allow for common "relaxed" property variants.
* @param value the property value to convert
* @return an {@link EndpointId} instance
*/
public static EndpointId fromPropertyValue(String value) {
return new EndpointId(value.replace("-", ""));
}
} }

@ -93,4 +93,10 @@ public class EndpointIdTests {
assertThat(EndpointId.of("fooBar").toString()).isEqualTo("fooBar"); assertThat(EndpointId.of("fooBar").toString()).isEqualTo("fooBar");
} }
@Test
public void fromPropertyValueStripsDashes() {
EndpointId fromPropertyValue = EndpointId.fromPropertyValue("foo-bar");
assertThat(fromPropertyValue).isEqualTo(EndpointId.of("fooBar"));
}
} }

Loading…
Cancel
Save