Switch to Spring Framework SNAPSHOTs

See gh-30624
This commit is contained in:
Brian Clozel
2022-04-12 17:02:03 +02:00
parent 44211564a4
commit 77b7f2f1ce
17 changed files with 70 additions and 90 deletions

View File

@@ -26,6 +26,8 @@ import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
@@ -62,12 +64,16 @@ public class ElasticsearchReactiveHealthIndicator extends AbstractReactiveHealth
}
private Mono<Health> doHealthCheck(Health.Builder builder, ClientResponse response) {
if (response.statusCode().is2xxSuccessful()) {
HttpStatusCode httpStatusCode = response.statusCode();
HttpStatus httpStatus = HttpStatus.resolve(httpStatusCode.value());
if (httpStatusCode.is2xxSuccessful()) {
return response.bodyToMono(STRING_OBJECT_MAP).map((body) -> getHealth(builder, body));
}
builder.down();
builder.withDetail("statusCode", response.rawStatusCode());
builder.withDetail("reasonPhrase", response.statusCode().getReasonPhrase());
builder.withDetail("statusCode", httpStatusCode.value());
if (httpStatus != null) {
builder.withDetail("reasonPhrase", httpStatus.getReasonPhrase());
}
return response.releaseBody().thenReturn(builder.build());
}

View File

@@ -97,7 +97,7 @@ public final class RestTemplateExchangeTags {
if (response == null) {
return "CLIENT_ERROR";
}
return String.valueOf(response.getRawStatusCode());
return String.valueOf(response.getStatusCode().value());
}
catch (IOException ex) {
return "IO_ERROR";
@@ -128,7 +128,7 @@ public final class RestTemplateExchangeTags {
public static Tag outcome(ClientHttpResponse response) {
try {
if (response != null) {
return Outcome.forStatus(response.getRawStatusCode()).asTag();
return Outcome.forStatus(response.getStatusCode().value()).asTag();
}
}
catch (IOException ex) {

View File

@@ -86,7 +86,7 @@ public final class WebClientExchangeTags {
*/
public static Tag status(ClientResponse response, Throwable throwable) {
if (response != null) {
return Tag.of("status", String.valueOf(response.rawStatusCode()));
return Tag.of("status", String.valueOf(response.statusCode().value()));
}
if (throwable != null) {
return (throwable instanceof IOException) ? IO_ERROR : CLIENT_ERROR;
@@ -117,7 +117,7 @@ public final class WebClientExchangeTags {
* @since 2.2.0
*/
public static Tag outcome(ClientResponse response) {
Outcome outcome = (response != null) ? Outcome.forStatus(response.rawStatusCode()) : Outcome.UNKNOWN;
Outcome outcome = (response != null) ? Outcome.forStatus(response.statusCode().value()) : Outcome.UNKNOWN;
return outcome.asTag();
}

View File

@@ -25,7 +25,7 @@ import io.micrometer.core.instrument.Tag;
import org.springframework.boot.actuate.metrics.http.Outcome;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.HttpStatusCode;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.HandlerMapping;
import org.springframework.web.server.ServerWebExchange;
@@ -80,7 +80,7 @@ public final class WebFluxTags {
* @return the status tag derived from the response status
*/
public static Tag status(ServerWebExchange exchange) {
HttpStatus status = exchange.getResponse().getStatusCode();
HttpStatusCode status = exchange.getResponse().getStatusCode();
if (status == null) {
status = HttpStatus.OK;
}
@@ -122,7 +122,7 @@ public final class WebFluxTags {
}
return Tag.of("uri", patternString);
}
HttpStatus status = exchange.getResponse().getStatusCode();
HttpStatusCode status = exchange.getResponse().getStatusCode();
if (status != null) {
if (status.is3xxRedirection()) {
return URI_REDIRECTION;
@@ -181,19 +181,9 @@ public final class WebFluxTags {
return Outcome.UNKNOWN.asTag();
}
}
Integer statusCode = extractStatusCode(exchange);
Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode) : Outcome.SUCCESS;
HttpStatusCode statusCode = exchange.getResponse().getStatusCode();
Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode.value()) : Outcome.SUCCESS;
return outcome.asTag();
}
private static Integer extractStatusCode(ServerWebExchange exchange) {
ServerHttpResponse response = exchange.getResponse();
Integer statusCode = response.getRawStatusCode();
if (statusCode != null) {
return statusCode;
}
HttpStatus status = response.getStatusCode();
return (status != null) ? status.value() : null;
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.boot.actuate.elasticsearch;
import java.time.Duration;
import java.util.Map;
import okhttp3.mockwebserver.MockResponse;
@@ -44,6 +45,8 @@ import static org.assertj.core.api.Assertions.entry;
*/
class ElasticsearchReactiveHealthIndicatorTests {
private static final Duration TIMEOUT = Duration.ofSeconds(5);
private MockWebServer server;
private ElasticsearchReactiveHealthIndicator healthIndicator;
@@ -65,7 +68,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
@Test
void elasticsearchIsUp() {
setupMockResponse(200, "green");
Health health = this.healthIndicator.health().block();
Health health = this.healthIndicator.health().block(TIMEOUT);
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertHealthDetailsWithStatus(health.getDetails(), "green");
}
@@ -73,7 +76,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
@Test
void elasticsearchWithYellowStatusIsUp() {
setupMockResponse(200, "yellow");
Health health = this.healthIndicator.health().block();
Health health = this.healthIndicator.health().block(TIMEOUT);
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertHealthDetailsWithStatus(health.getDetails(), "yellow");
}
@@ -81,7 +84,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
@Test
void elasticsearchIsDown() throws Exception {
this.server.shutdown();
Health health = this.healthIndicator.health().block();
Health health = this.healthIndicator.health().block(TIMEOUT);
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("error")).asString()
.contains("org.springframework.data.elasticsearch.client.NoReachableHostException");
@@ -93,7 +96,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
// to "/"
this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.OK.value()));
this.server.enqueue(new MockResponse().setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value()));
Health health = this.healthIndicator.health().block();
Health health = this.healthIndicator.health().block(TIMEOUT);
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("statusCode")).asString().isEqualTo("500");
assertThat(health.getDetails().get("reasonPhrase")).asString().isEqualTo("Internal Server Error");
@@ -102,7 +105,7 @@ class ElasticsearchReactiveHealthIndicatorTests {
@Test
void elasticsearchIsOutOfServiceByStatus() {
setupMockResponse(200, "red");
Health health = this.healthIndicator.health().block();
Health health = this.healthIndicator.health().block(TIMEOUT);
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
assertHealthDetailsWithStatus(health.getDetails(), "red");
}

View File

@@ -23,6 +23,7 @@ import io.micrometer.core.instrument.Tag;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.mock.http.client.MockClientHttpResponse;
@@ -83,7 +84,7 @@ class RestTemplateExchangeTagsTests {
@Test
void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception {
ClientHttpResponse response = mock(ClientHttpResponse.class);
given(response.getRawStatusCode()).willThrow(IOException.class);
given(response.getStatusCode()).willThrow(IOException.class);
Tag tag = RestTemplateExchangeTags.outcome(response);
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
}
@@ -91,7 +92,7 @@ class RestTemplateExchangeTagsTests {
@Test
void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOException {
ClientHttpResponse response = mock(ClientHttpResponse.class);
given(response.getRawStatusCode()).willReturn(490);
given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(490));
Tag tag = RestTemplateExchangeTags.outcome(response);
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
}
@@ -99,7 +100,7 @@ class RestTemplateExchangeTagsTests {
@Test
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() throws IOException {
ClientHttpResponse response = mock(ClientHttpResponse.class);
given(response.getRawStatusCode()).willReturn(701);
given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(701));
Tag tag = RestTemplateExchangeTags.outcome(response);
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
}

View File

@@ -54,7 +54,7 @@ class DefaultWebClientExchangeTagsProviderTests {
this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
.attribute(URI_TEMPLATE_ATTRIBUTE, "https://example.org/projects/{project}").build();
this.response = mock(ClientResponse.class);
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ class MetricsWebClientFilterFunctionTests {
void filterShouldRecordTimer() {
ClientRequest request = ClientRequest
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests")
.tags("method", "GET", "uri", "/projects/spring-boot", "status", "200").timer().count()).isEqualTo(1);
@@ -86,7 +86,7 @@ class MetricsWebClientFilterFunctionTests {
ClientRequest request = ClientRequest
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot"))
.attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}").build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
this.filterFunction.filter(request, this.exchange).block(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests")
.tags("method", "GET", "uri", "/projects/{project}", "status", "200").timer().count()).isEqualTo(1);
@@ -120,7 +120,7 @@ class MetricsWebClientFilterFunctionTests {
void filterWhenCancelThrownShouldRecordTimer() {
ClientRequest request = ClientRequest
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
Mono<ClientResponse> filter = this.filterFunction.filter(request, this.exchange);
StepVerifier.create(filter).thenCancel().verify(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests")
@@ -135,7 +135,7 @@ class MetricsWebClientFilterFunctionTests {
void filterWhenCancelAfterResponseThrownShouldNotRecordTimer() {
ClientRequest request = ClientRequest
.create(HttpMethod.GET, URI.create("https://example.com/projects/spring-boot")).build();
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
Mono<ClientResponse> filter = this.filterFunction.filter(request, this.exchange);
StepVerifier.create(filter).expectNextCount(1).thenCancel().verify(Duration.ofSeconds(5));
assertThat(this.registry.get("http.client.requests")

View File

@@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
@@ -93,7 +94,7 @@ class WebClientExchangeTagsTests {
@Test
void status() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "200"));
}
@@ -110,7 +111,7 @@ class WebClientExchangeTagsTests {
@Test
void statusWhenNonStandard() {
given(this.response.rawStatusCode()).willReturn(490);
given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490));
assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "490"));
}
@@ -127,49 +128,49 @@ class WebClientExchangeTagsTests {
@Test
void outcomeTagIsInformationalWhenResponseIs1xx() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.CONTINUE.value());
given(this.response.statusCode()).willReturn(HttpStatus.CONTINUE);
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
}
@Test
void outcomeTagIsSuccessWhenResponseIs2xx() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.OK.value());
given(this.response.statusCode()).willReturn(HttpStatus.OK);
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("SUCCESS");
}
@Test
void outcomeTagIsRedirectionWhenResponseIs3xx() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY.value());
given(this.response.statusCode()).willReturn(HttpStatus.MOVED_PERMANENTLY);
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
}
@Test
void outcomeTagIsClientErrorWhenResponseIs4xx() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_REQUEST.value());
given(this.response.statusCode()).willReturn(HttpStatus.BAD_REQUEST);
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
}
@Test
void outcomeTagIsServerErrorWhenResponseIs5xx() {
given(this.response.rawStatusCode()).willReturn(HttpStatus.BAD_GATEWAY.value());
given(this.response.statusCode()).willReturn(HttpStatus.BAD_GATEWAY);
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
}
@Test
void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() {
given(this.response.rawStatusCode()).willReturn(490);
given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490));
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
}
@Test
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() {
given(this.response.rawStatusCode()).willReturn(701);
given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(701));
Tag tag = WebClientExchangeTags.outcome(this.response);
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -153,7 +153,7 @@ class WebFluxTagsTests {
ServerHttpRequest request = mock(ServerHttpRequest.class);
ServerHttpResponse response = mock(ServerHttpResponse.class);
given(response.getStatusCode()).willReturn(HttpStatus.OK);
given(response.getRawStatusCode()).willReturn(null);
given(response.getStatusCode().value()).willReturn(null);
given(exchange.getRequest()).willReturn(request);
given(exchange.getResponse()).willReturn(response);
Tag tag = WebFluxTags.outcome(exchange, null);