Skip to content

Commit 3665917

Browse files
committed
Merge branch '2.0.x'
2 parents 1e2d5a1 + c306e03 commit 3665917

File tree

2 files changed

+41
-14
lines changed
  • spring-boot-project/spring-boot-actuator/src

2 files changed

+41
-14
lines changed

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/EndpointId.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,44 @@
2323

2424
/**
2525
* An identifier for an actuator endpoint. Endpoint IDs may contain only letters, numbers
26-
* and {@code '.'}. They must begin with a lower-case letter. Case is ignored when
27-
* comparing endpoint IDs.
26+
* {@code '.'} and {@code '-'}. They must begin with a lower-case letter. Case and syntax
27+
* characters are ignored when comparing endpoint IDs.
2828
*
2929
* @author Phillip Webb
3030
* @since 2.0.6
3131
*/
3232
public final class EndpointId {
3333

34-
private static final Pattern VALID_CHARS = Pattern.compile("[a-zA-Z0-9\\.]+");
34+
private static final Pattern VALID_CHARS = Pattern.compile("[a-zA-Z0-9\\.\\-]+");
3535

3636
private final String value;
3737

3838
private final String lowerCaseValue;
3939

40+
private final String lowerCaseAlphaNumeric;
41+
4042
private EndpointId(String value) {
4143
Assert.hasText(value, "Value must not be empty");
4244
Assert.isTrue(VALID_CHARS.matcher(value).matches(),
43-
"Value must be alpha-numeric or '.'");
45+
"Value must only contain valid chars");
4446
Assert.isTrue(!Character.isDigit(value.charAt(0)),
4547
"Value must not start with a number");
4648
Assert.isTrue(!Character.isUpperCase(value.charAt(0)),
4749
"Value must not start with an uppercase letter");
4850
this.value = value;
4951
this.lowerCaseValue = value.toLowerCase(Locale.ENGLISH);
52+
this.lowerCaseAlphaNumeric = getAlphaNumerics(this.lowerCaseValue);
53+
}
54+
55+
private String getAlphaNumerics(String value) {
56+
StringBuilder result = new StringBuilder(value.length());
57+
for (int i = 0; i < value.length(); i++) {
58+
char ch = value.charAt(i);
59+
if (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
60+
result.append(ch);
61+
}
62+
}
63+
return result.toString();
5064
}
5165

5266
@Override
@@ -57,12 +71,13 @@ public boolean equals(Object obj) {
5771
if (obj == null || getClass() != obj.getClass()) {
5872
return false;
5973
}
60-
return toLowerCaseString().equals(((EndpointId) obj).toLowerCaseString());
74+
return this.lowerCaseAlphaNumeric
75+
.equals(((EndpointId) obj).lowerCaseAlphaNumeric);
6176
}
6277

6378
@Override
6479
public int hashCode() {
65-
return toLowerCaseString().hashCode();
80+
return this.lowerCaseAlphaNumeric.hashCode();
6681
}
6782

6883
/**

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/EndpointIdTests.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ public void ofWhenEmptyThrowsException() {
4141
}
4242

4343
@Test
44-
public void ofWhenContainsDashThrowsException() {
45-
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo-bar"))
46-
.withMessageContaining("Value must be alpha-numeric");
44+
public void ofWhenContainsInvalidCharThrowsException() {
45+
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo!bar"))
46+
.withMessage("Value must only contain valid chars");
4747
}
4848

4949
@Test
5050
public void ofWhenHasBadCharThrowsException() {
5151
assertThatIllegalArgumentException().isThrownBy(() -> EndpointId.of("foo!bar"))
52-
.withMessageContaining("Value must be alpha-numeric");
52+
.withMessage("Value must only contain valid chars");
5353
}
5454

5555
@Test
@@ -72,13 +72,25 @@ public void ofWhenContainsDotIsValid() {
7272
assertThat(endpointId.toString()).isEqualTo("foo.bar");
7373
}
7474

75+
@Test
76+
public void ofWhenContainsDashIsValid() {
77+
// Ideally we wouldn't support this but there are existing endpoints using the
78+
// pattern. See gh-14773
79+
EndpointId endpointId = EndpointId.of("foo-bar");
80+
assertThat(endpointId.toString()).isEqualTo("foo-bar");
81+
}
82+
7583
@Test
7684
public void equalsAndHashCode() {
77-
EndpointId one = EndpointId.of("foobar");
78-
EndpointId two = EndpointId.of("fooBar");
79-
EndpointId three = EndpointId.of("barfoo");
85+
EndpointId one = EndpointId.of("foobar1");
86+
EndpointId two = EndpointId.of("fooBar1");
87+
EndpointId three = EndpointId.of("foo-bar1");
88+
EndpointId four = EndpointId.of("foo.bar1");
89+
EndpointId five = EndpointId.of("barfoo1");
90+
EndpointId six = EndpointId.of("foobar2");
8091
assertThat(one.hashCode()).isEqualTo(two.hashCode());
81-
assertThat(one).isEqualTo(one).isEqualTo(two).isNotEqualTo(three);
92+
assertThat(one).isEqualTo(one).isEqualTo(two).isEqualTo(two).isEqualTo(three)
93+
.isEqualTo(four).isNotEqualTo(five).isNotEqualTo(six);
8294
}
8395

8496
@Test

0 commit comments

Comments
 (0)