Skip to content

Commit b54ff7c

Browse files
committed
Merge branch '2.1.x'
Closes gh-17950
2 parents ba6fe60 + 608228d commit b54ff7c

File tree

4 files changed

+46
-29
lines changed

4 files changed

+46
-29
lines changed

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTags.java

+22-18
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
package org.springframework.boot.actuate.metrics.web.reactive.client;
1818

1919
import java.io.IOException;
20+
import java.util.Collections;
21+
import java.util.HashMap;
22+
import java.util.Map;
2023
import java.util.regex.Pattern;
2124

2225
import io.micrometer.core.instrument.Tag;
2326

2427
import org.springframework.http.HttpStatus;
28+
import org.springframework.http.HttpStatus.Series;
2529
import org.springframework.http.client.reactive.ClientHttpRequest;
2630
import org.springframework.web.reactive.function.client.ClientRequest;
2731
import org.springframework.web.reactive.function.client.ClientResponse;
@@ -59,6 +63,18 @@ public final class WebClientExchangeTags {
5963

6064
private static final Tag OUTCOME_SERVER_ERROR = Tag.of("outcome", "SERVER_ERROR");
6165

66+
private static final Map<Series, Tag> SERIES_OUTCOMES;
67+
68+
static {
69+
Map<Series, Tag> seriesOutcomes = new HashMap<>();
70+
seriesOutcomes.put(Series.INFORMATIONAL, OUTCOME_INFORMATIONAL);
71+
seriesOutcomes.put(Series.SUCCESSFUL, OUTCOME_SUCCESS);
72+
seriesOutcomes.put(Series.REDIRECTION, OUTCOME_REDIRECTION);
73+
seriesOutcomes.put(Series.CLIENT_ERROR, OUTCOME_CLIENT_ERROR);
74+
seriesOutcomes.put(Series.SERVER_ERROR, OUTCOME_SERVER_ERROR);
75+
SERIES_OUTCOMES = Collections.unmodifiableMap(seriesOutcomes);
76+
}
77+
6278
private WebClientExchangeTags() {
6379
}
6480

@@ -94,7 +110,7 @@ private static String extractPath(String url) {
94110
* @return the status tag
95111
*/
96112
public static Tag status(ClientResponse response) {
97-
return Tag.of("status", String.valueOf(response.statusCode().value()));
113+
return Tag.of("status", String.valueOf(response.rawStatusCode()));
98114
}
99115

100116
/**
@@ -132,28 +148,16 @@ public static Tag clientName(ClientRequest request) {
132148
public static Tag outcome(ClientResponse response) {
133149
try {
134150
if (response != null) {
135-
HttpStatus status = response.statusCode();
136-
if (status.is1xxInformational()) {
137-
return OUTCOME_INFORMATIONAL;
138-
}
139-
if (status.is2xxSuccessful()) {
140-
return OUTCOME_SUCCESS;
141-
}
142-
if (status.is3xxRedirection()) {
143-
return OUTCOME_REDIRECTION;
144-
}
145-
if (status.is4xxClientError()) {
146-
return OUTCOME_CLIENT_ERROR;
147-
}
148-
if (status.is5xxServerError()) {
149-
return OUTCOME_SERVER_ERROR;
151+
Series series = HttpStatus.Series.resolve(response.rawStatusCode());
152+
if (series != null) {
153+
return SERIES_OUTCOMES.getOrDefault(series, OUTCOME_UNKNOWN);
150154
}
151155
}
152-
return OUTCOME_UNKNOWN;
153156
}
154157
catch (IllegalArgumentException exc) {
155-
return OUTCOME_UNKNOWN;
158+
// Continue
156159
}
160+
return OUTCOME_UNKNOWN;
157161
}
158162

159163
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/DefaultWebClientExchangeTagsProviderTests.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void setup() {
5454
this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
5555
.attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}").build();
5656
this.response = mock(ClientResponse.class);
57-
given(this.response.statusCode()).willReturn(HttpStatus.OK);
57+
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
5858
}
5959

6060
@Test

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/MetricsWebClientFilterFunctionTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void setup() {
7272
void filterShouldRecordTimer() {
7373
ClientRequest request = ClientRequest
7474
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
75-
given(this.response.statusCode()).willReturn(HttpStatus.OK);
75+
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
7676
this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(30));
7777
assertThat(this.registry.get("http.client.requests")
7878
.tags("method", "GET", "uri", "/projects/spring-boot", "status", "200").timer().count()).isEqualTo(1);
@@ -83,7 +83,7 @@ void filterWhenUriTemplatePresentShouldRecordTimer() {
8383
ClientRequest request = ClientRequest
8484
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot"))
8585
.attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}").build();
86-
given(this.response.statusCode()).willReturn(HttpStatus.OK);
86+
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
8787
this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(30));
8888
assertThat(this.registry.get("http.client.requests")
8989
.tags("method", "GET", "uri", "/projects/{project}", "status", "200").timer().count()).isEqualTo(1);

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/web/reactive/client/WebClientExchangeTagsTests.java

+21-8
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ void setup() {
5252
this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
5353
.attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}").build();
5454
this.response = mock(ClientResponse.class);
55-
given(this.response.statusCode()).willReturn(HttpStatus.OK);
5655
}
5756

5857
@Test
@@ -86,6 +85,7 @@ void clientName() {
8685

8786
@Test
8887
void status() {
88+
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
8989
assertThat(WebClientExchangeTags.status(this.response)).isEqualTo(Tag.of("status", "200"));
9090
}
9191

@@ -100,6 +100,12 @@ void statusWhenClientException() {
100100
.isEqualTo(Tag.of("status", "CLIENT_ERROR"));
101101
}
102102

103+
@Test
104+
void statusWhenNonStandard() {
105+
given(this.response.rawStatusCode()).willReturn(490);
106+
assertThat(WebClientExchangeTags.status(this.response)).isEqualTo(Tag.of("status", "490"));
107+
}
108+
103109
@Test
104110
void outcomeTagIsUnknownWhenResponseIsNull() {
105111
Tag tag = WebClientExchangeTags.outcome(null);
@@ -108,42 +114,49 @@ void outcomeTagIsUnknownWhenResponseIsNull() {
108114

109115
@Test
110116
void outcomeTagIsInformationalWhenResponseIs1xx() {
111-
given(this.response.statusCode()).willReturn(HttpStatus.CONTINUE);
117+
given(this.response.rawStatusCode()).willReturn(HttpStatus.CONTINUE.value());
112118
Tag tag = WebClientExchangeTags.outcome(this.response);
113119
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
114120
}
115121

116122
@Test
117123
void outcomeTagIsSuccessWhenResponseIs2xx() {
118-
given(this.response.statusCode()).willReturn(HttpStatus.OK);
124+
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
119125
Tag tag = WebClientExchangeTags.outcome(this.response);
120126
assertThat(tag.getValue()).isEqualTo("SUCCESS");
121127
}
122128

123129
@Test
124130
void outcomeTagIsRedirectionWhenResponseIs3xx() {
125-
given(this.response.statusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY);
131+
given(this.response.rawStatusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY.value());
126132
Tag tag = WebClientExchangeTags.outcome(this.response);
127133
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
128134
}
129135

130136
@Test
131137
void outcomeTagIsClientErrorWhenResponseIs4xx() {
132-
given(this.response.statusCode()).willReturn(HttpStatus.BAD_REQUEST);
138+
given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_REQUEST.value());
133139
Tag tag = WebClientExchangeTags.outcome(this.response);
134140
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
135141
}
136142

137143
@Test
138144
void outcomeTagIsServerErrorWhenResponseIs5xx() {
139-
given(this.response.statusCode()).willReturn(HttpStatus.BAD_GATEWAY);
145+
given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_GATEWAY.value());
140146
Tag tag = WebClientExchangeTags.outcome(this.response);
141147
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
142148
}
143149

144150
@Test
145-
void outcomeTagIsUnknownWhenResponseStatusIsUnknown() {
146-
given(this.response.statusCode()).willThrow(IllegalArgumentException.class);
151+
void outcomeTagIsServerErrorWhenResponseIsNonStandardInKnownSeries() {
152+
given(this.response.rawStatusCode()).willReturn(490);
153+
Tag tag = WebClientExchangeTags.outcome(this.response);
154+
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
155+
}
156+
157+
@Test
158+
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() {
159+
given(this.response.rawStatusCode()).willReturn(701);
147160
Tag tag = WebClientExchangeTags.outcome(this.response);
148161
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
149162
}

0 commit comments

Comments
 (0)