Remove deprecated code that was to be removed in 3.2
Closes gh-36034
This commit is contained in:
@@ -141,7 +141,7 @@ public class PrometheusPushGatewayManager {
|
||||
}
|
||||
this.scheduled.cancel(false);
|
||||
switch (shutdownOperation) {
|
||||
case PUSH, POST -> post();
|
||||
case POST -> post();
|
||||
case PUT -> put();
|
||||
case DELETE -> delete();
|
||||
}
|
||||
@@ -162,13 +162,6 @@ public class PrometheusPushGatewayManager {
|
||||
*/
|
||||
POST,
|
||||
|
||||
/**
|
||||
* Perform a POST before shutdown.
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of {@link #POST}.
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
PUSH,
|
||||
|
||||
/**
|
||||
* Perform a PUT before shutdown.
|
||||
*/
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link RestTemplateExchangeTagsProvider}.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Nishant Raut
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.client.observation.DefaultClientRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public class DefaultRestTemplateExchangeTagsProvider implements RestTemplateExchangeTagsProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getTags(String urlTemplate, HttpRequest request, ClientHttpResponse response) {
|
||||
Tag uriTag = (StringUtils.hasText(urlTemplate) ? RestTemplateExchangeTags.uri(urlTemplate)
|
||||
: RestTemplateExchangeTags.uri(request));
|
||||
return Arrays.asList(RestTemplateExchangeTags.method(request), uriTag,
|
||||
RestTemplateExchangeTags.status(response), RestTemplateExchangeTags.clientName(request),
|
||||
RestTemplateExchangeTags.outcome(response));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.http.Outcome;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.observation.DefaultClientRequestObservationConvention;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Factory methods for creating {@link Tag Tags} related to a request-response exchange
|
||||
* performed by a {@link RestTemplate}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Jon Schneider
|
||||
* @author Nishant Raut
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link DefaultClientRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public final class RestTemplateExchangeTags {
|
||||
|
||||
private static final Pattern STRIP_URI_PATTERN = Pattern.compile("^https?://[^/]+/");
|
||||
|
||||
private RestTemplateExchangeTags() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code method} {@code Tag} for the {@link HttpRequest#getMethod() method}
|
||||
* of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the method tag
|
||||
*/
|
||||
public static Tag method(HttpRequest request) {
|
||||
return Tag.of("method", request.getMethod().name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} {@code Tag} for the URI of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the uri tag
|
||||
*/
|
||||
public static Tag uri(HttpRequest request) {
|
||||
return Tag.of("uri", ensureLeadingSlash(stripUri(request.getURI().toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} {@code Tag} from the given {@code uriTemplate}.
|
||||
* @param uriTemplate the template
|
||||
* @return the uri tag
|
||||
*/
|
||||
public static Tag uri(String uriTemplate) {
|
||||
String uri = (StringUtils.hasText(uriTemplate) ? uriTemplate : "none");
|
||||
return Tag.of("uri", ensureLeadingSlash(stripUri(uri)));
|
||||
}
|
||||
|
||||
private static String stripUri(String uri) {
|
||||
return STRIP_URI_PATTERN.matcher(uri).replaceAll("");
|
||||
}
|
||||
|
||||
private static String ensureLeadingSlash(String url) {
|
||||
return (url == null || url.startsWith("/")) ? url : "/" + url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code status} {@code Tag} derived from the
|
||||
* {@link ClientHttpResponse#getStatusCode() status} of the given {@code response}.
|
||||
* @param response the response
|
||||
* @return the status tag
|
||||
*/
|
||||
public static Tag status(ClientHttpResponse response) {
|
||||
return Tag.of("status", getStatusMessage(response));
|
||||
}
|
||||
|
||||
private static String getStatusMessage(ClientHttpResponse response) {
|
||||
try {
|
||||
if (response == null) {
|
||||
return "CLIENT_ERROR";
|
||||
}
|
||||
return String.valueOf(response.getStatusCode().value());
|
||||
}
|
||||
catch (IOException ex) {
|
||||
return "IO_ERROR";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code client.name} {@code Tag} derived from the {@link URI#getHost host}
|
||||
* of the {@link HttpRequest#getURI() URI} of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the client.name tag
|
||||
*/
|
||||
public static Tag clientName(HttpRequest request) {
|
||||
String host = request.getURI().getHost();
|
||||
if (host == null) {
|
||||
host = "none";
|
||||
}
|
||||
return Tag.of("client.name", host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code outcome} {@code Tag} derived from the
|
||||
* {@link ClientHttpResponse#getStatusCode() status} of the given {@code response}.
|
||||
* @param response the response
|
||||
* @return the outcome tag
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public static Tag outcome(ClientHttpResponse response) {
|
||||
try {
|
||||
if (response != null) {
|
||||
return Outcome.forStatus(response.getStatusCode().value()).asTag();
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Continue
|
||||
}
|
||||
return Outcome.UNKNOWN.asTag();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.client;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.observation.ClientRequestObservationConvention;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Provides {@link Tag Tags} for an exchange performed by a {@link RestTemplate}.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link ClientRequestObservationConvention}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface RestTemplateExchangeTagsProvider {
|
||||
|
||||
/**
|
||||
* Provides the tags to be associated with metrics that are recorded for the given
|
||||
* {@code request} and {@code response} exchange.
|
||||
* @param urlTemplate the source URl template, if available
|
||||
* @param request the request
|
||||
* @param response the response (may be {@code null} if the exchange failed)
|
||||
* @return the tags
|
||||
*/
|
||||
Iterable<Tag> getTags(String urlTemplate, HttpRequest request, ClientHttpResponse response);
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.client;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link WebClientExchangeTagsProvider}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Nishant Raut
|
||||
* @since 2.1.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.web.reactive.function.client.ClientRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public class DefaultWebClientExchangeTagsProvider implements WebClientExchangeTagsProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> tags(ClientRequest request, ClientResponse response, Throwable throwable) {
|
||||
Tag method = WebClientExchangeTags.method(request);
|
||||
Tag uri = WebClientExchangeTags.uri(request);
|
||||
Tag clientName = WebClientExchangeTags.clientName(request);
|
||||
Tag status = WebClientExchangeTags.status(response, throwable);
|
||||
Tag outcome = WebClientExchangeTags.outcome(response);
|
||||
return Arrays.asList(method, uri, clientName, status, outcome);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.http.Outcome;
|
||||
import org.springframework.http.client.reactive.ClientHttpRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* Factory methods for creating {@link Tag Tags} related to a request-response exchange
|
||||
* performed by a {@link WebClient}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Nishant Raut
|
||||
* @since 2.1.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public final class WebClientExchangeTags {
|
||||
|
||||
private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
|
||||
|
||||
private static final Tag IO_ERROR = Tag.of("status", "IO_ERROR");
|
||||
|
||||
private static final Tag CLIENT_ERROR = Tag.of("status", "CLIENT_ERROR");
|
||||
|
||||
private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/");
|
||||
|
||||
private static final Tag CLIENT_NAME_NONE = Tag.of("client.name", "none");
|
||||
|
||||
private WebClientExchangeTags() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code method} {@code Tag} for the {@link ClientHttpRequest#getMethod()
|
||||
* method} of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the method tag
|
||||
*/
|
||||
public static Tag method(ClientRequest request) {
|
||||
return Tag.of("method", request.method().name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} {@code Tag} for the URI path of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the uri tag
|
||||
*/
|
||||
public static Tag uri(ClientRequest request) {
|
||||
String uri = (String) request.attribute(URI_TEMPLATE_ATTRIBUTE).orElseGet(() -> request.url().toString());
|
||||
return Tag.of("uri", extractPath(uri));
|
||||
}
|
||||
|
||||
private static String extractPath(String url) {
|
||||
String path = PATTERN_BEFORE_PATH.matcher(url).replaceFirst("");
|
||||
return (path.startsWith("/") ? path : "/" + path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code status} {@code Tag} derived from the
|
||||
* {@link ClientResponse#statusCode()} of the given {@code response} if available, the
|
||||
* thrown exception otherwise, or considers the request as Cancelled as a last resort.
|
||||
* @param response the response
|
||||
* @param throwable the exception
|
||||
* @return the status tag
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public static Tag status(ClientResponse response, Throwable throwable) {
|
||||
if (response != null) {
|
||||
return Tag.of("status", String.valueOf(response.statusCode().value()));
|
||||
}
|
||||
if (throwable != null) {
|
||||
return (throwable instanceof IOException) ? IO_ERROR : CLIENT_ERROR;
|
||||
}
|
||||
return CLIENT_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code client.name} {@code Tag} derived from the
|
||||
* {@link java.net.URI#getHost host} of the {@link ClientRequest#url() URL} of the
|
||||
* given {@code request}.
|
||||
* @param request the request
|
||||
* @return the client.name tag
|
||||
*/
|
||||
public static Tag clientName(ClientRequest request) {
|
||||
String host = request.url().getHost();
|
||||
if (host == null) {
|
||||
return CLIENT_NAME_NONE;
|
||||
}
|
||||
return Tag.of("client.name", host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code outcome} {@code Tag} derived from the
|
||||
* {@link ClientResponse#statusCode() status} of the given {@code response}.
|
||||
* @param response the response
|
||||
* @return the outcome tag
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public static Tag outcome(ClientResponse response) {
|
||||
Outcome outcome = (response != null) ? Outcome.forStatus(response.statusCode().value()) : Outcome.UNKNOWN;
|
||||
return outcome.asTag();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.client;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
|
||||
/**
|
||||
* {@link Tag Tags} provider for an exchange performed by a
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.1.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.web.reactive.function.client.ClientRequestObservationConvention}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface WebClientExchangeTagsProvider {
|
||||
|
||||
/**
|
||||
* Provide tags to be associated with metrics for the client exchange.
|
||||
* @param request the client request
|
||||
* @param response the server response (may be {@code null})
|
||||
* @param throwable the exception (may be {@code null})
|
||||
* @return tags to associate with metrics for the request and response exchange
|
||||
*/
|
||||
Iterable<Tag> tags(ClientRequest request, ClientResponse response, Throwable throwable);
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link WebFluxTagsProvider}.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.reactive.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public class DefaultWebFluxTagsProvider implements WebFluxTagsProvider {
|
||||
|
||||
private final boolean ignoreTrailingSlash;
|
||||
|
||||
private final List<WebFluxTagsContributor> contributors;
|
||||
|
||||
public DefaultWebFluxTagsProvider() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultWebFluxTagsProvider} that will provide tags from the
|
||||
* given {@code contributors} in addition to its own.
|
||||
* @param contributors the contributors that will provide additional tags
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public DefaultWebFluxTagsProvider(List<WebFluxTagsContributor> contributors) {
|
||||
this(false, contributors);
|
||||
}
|
||||
|
||||
public DefaultWebFluxTagsProvider(boolean ignoreTrailingSlash) {
|
||||
this(ignoreTrailingSlash, Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultWebFluxTagsProvider} that will provide tags from the
|
||||
* given {@code contributors} in addition to its own.
|
||||
* @param ignoreTrailingSlash whether trailing slashes should be ignored when
|
||||
* determining the {@code uri} tag.
|
||||
* @param contributors the contributors that will provide additional tags
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public DefaultWebFluxTagsProvider(boolean ignoreTrailingSlash, List<WebFluxTagsContributor> contributors) {
|
||||
this.ignoreTrailingSlash = ignoreTrailingSlash;
|
||||
this.contributors = contributors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> httpRequestTags(ServerWebExchange exchange, Throwable exception) {
|
||||
Tags tags = Tags.empty();
|
||||
tags = tags.and(WebFluxTags.method(exchange));
|
||||
tags = tags.and(WebFluxTags.uri(exchange, this.ignoreTrailingSlash));
|
||||
tags = tags.and(WebFluxTags.exception(exception));
|
||||
tags = tags.and(WebFluxTags.status(exchange));
|
||||
tags = tags.and(WebFluxTags.outcome(exchange, exception));
|
||||
for (WebFluxTagsContributor contributor : this.contributors) {
|
||||
tags = tags.and(contributor.httpRequestTags(exchange, exception));
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.http.Outcome;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.reactive.HandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
/**
|
||||
* Factory methods for {@link Tag Tags} associated with a request-response exchange that
|
||||
* is handled by WebFlux.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @author Michael McFadyen
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.reactive.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public final class WebFluxTags {
|
||||
|
||||
private static final Tag URI_NOT_FOUND = Tag.of("uri", "NOT_FOUND");
|
||||
|
||||
private static final Tag URI_REDIRECTION = Tag.of("uri", "REDIRECTION");
|
||||
|
||||
private static final Tag URI_ROOT = Tag.of("uri", "root");
|
||||
|
||||
private static final Tag URI_UNKNOWN = Tag.of("uri", "UNKNOWN");
|
||||
|
||||
private static final Tag EXCEPTION_NONE = Tag.of("exception", "None");
|
||||
|
||||
private static final Pattern FORWARD_SLASHES_PATTERN = Pattern.compile("//+");
|
||||
|
||||
private static final Set<String> DISCONNECTED_CLIENT_EXCEPTIONS = new HashSet<>(
|
||||
Arrays.asList("AbortedException", "ClientAbortException", "EOFException", "EofException"));
|
||||
|
||||
private WebFluxTags() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code method} tag based on the
|
||||
* {@link org.springframework.http.server.reactive.ServerHttpRequest#getMethod()
|
||||
* method} of the {@link ServerWebExchange#getRequest()} request of the given
|
||||
* {@code exchange}.
|
||||
* @param exchange the exchange
|
||||
* @return the method tag whose value is a capitalized method (e.g. GET).
|
||||
*/
|
||||
public static Tag method(ServerWebExchange exchange) {
|
||||
return Tag.of("method", exchange.getRequest().getMethod().name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code status} tag based on the response status of the given
|
||||
* {@code exchange}.
|
||||
* @param exchange the exchange
|
||||
* @return the status tag derived from the response status
|
||||
*/
|
||||
public static Tag status(ServerWebExchange exchange) {
|
||||
HttpStatusCode status = exchange.getResponse().getStatusCode();
|
||||
if (status == null) {
|
||||
status = HttpStatus.OK;
|
||||
}
|
||||
return Tag.of("status", String.valueOf(status.value()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} tag based on the URI of the given {@code exchange}. Uses the
|
||||
* {@link HandlerMapping#BEST_MATCHING_PATTERN_ATTRIBUTE} best matching pattern if
|
||||
* available. Falling back to {@code REDIRECTION} for 3xx responses, {@code NOT_FOUND}
|
||||
* for 404 responses, {@code root} for requests with no path info, and {@code UNKNOWN}
|
||||
* for all other requests.
|
||||
* @param exchange the exchange
|
||||
* @return the uri tag derived from the exchange
|
||||
*/
|
||||
public static Tag uri(ServerWebExchange exchange) {
|
||||
return uri(exchange, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} tag based on the URI of the given {@code exchange}. Uses the
|
||||
* {@link HandlerMapping#BEST_MATCHING_PATTERN_ATTRIBUTE} best matching pattern if
|
||||
* available. Falling back to {@code REDIRECTION} for 3xx responses, {@code NOT_FOUND}
|
||||
* for 404 responses, {@code root} for requests with no path info, and {@code UNKNOWN}
|
||||
* for all other requests.
|
||||
* @param exchange the exchange
|
||||
* @param ignoreTrailingSlash whether to ignore the trailing slash
|
||||
* @return the uri tag derived from the exchange
|
||||
*/
|
||||
public static Tag uri(ServerWebExchange exchange, boolean ignoreTrailingSlash) {
|
||||
PathPattern pathPattern = exchange.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
if (pathPattern != null) {
|
||||
String patternString = pathPattern.getPatternString();
|
||||
if (ignoreTrailingSlash && patternString.length() > 1) {
|
||||
patternString = removeTrailingSlash(patternString);
|
||||
}
|
||||
if (patternString.isEmpty()) {
|
||||
return URI_ROOT;
|
||||
}
|
||||
return Tag.of("uri", patternString);
|
||||
}
|
||||
HttpStatusCode status = exchange.getResponse().getStatusCode();
|
||||
if (status != null) {
|
||||
if (status.is3xxRedirection()) {
|
||||
return URI_REDIRECTION;
|
||||
}
|
||||
if (status == HttpStatus.NOT_FOUND) {
|
||||
return URI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
String path = getPathInfo(exchange);
|
||||
if (path.isEmpty()) {
|
||||
return URI_ROOT;
|
||||
}
|
||||
return URI_UNKNOWN;
|
||||
}
|
||||
|
||||
private static String getPathInfo(ServerWebExchange exchange) {
|
||||
String path = exchange.getRequest().getPath().value();
|
||||
String uri = StringUtils.hasText(path) ? path : "/";
|
||||
String singleSlashes = FORWARD_SLASHES_PATTERN.matcher(uri).replaceAll("/");
|
||||
return removeTrailingSlash(singleSlashes);
|
||||
}
|
||||
|
||||
private static String removeTrailingSlash(String text) {
|
||||
if (!StringUtils.hasLength(text)) {
|
||||
return text;
|
||||
}
|
||||
return text.endsWith("/") ? text.substring(0, text.length() - 1) : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code exception} tag based on the {@link Class#getSimpleName() simple
|
||||
* name} of the class of the given {@code exception}.
|
||||
* @param exception the exception, may be {@code null}
|
||||
* @return the exception tag derived from the exception
|
||||
*/
|
||||
public static Tag exception(Throwable exception) {
|
||||
if (exception != null) {
|
||||
String simpleName = exception.getClass().getSimpleName();
|
||||
return Tag.of("exception", StringUtils.hasText(simpleName) ? simpleName : exception.getClass().getName());
|
||||
}
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code outcome} tag based on the response status of the given
|
||||
* {@code exchange} and the exception thrown during request processing.
|
||||
* @param exchange the exchange
|
||||
* @param exception the termination signal sent by the publisher
|
||||
* @return the outcome tag derived from the response status
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public static Tag outcome(ServerWebExchange exchange, Throwable exception) {
|
||||
if (exception != null) {
|
||||
if (DISCONNECTED_CLIENT_EXCEPTIONS.contains(exception.getClass().getSimpleName())) {
|
||||
return Outcome.UNKNOWN.asTag();
|
||||
}
|
||||
}
|
||||
HttpStatusCode statusCode = exchange.getResponse().getStatusCode();
|
||||
Outcome outcome = (statusCode != null) ? Outcome.forStatus(statusCode.value()) : Outcome.SUCCESS;
|
||||
return outcome.asTag();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* A contributor of {@link Tag Tags} for WebFlux-based request handling. Typically used by
|
||||
* a {@link WebFluxTagsProvider} to provide tags in addition to its defaults.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.3.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.reactive.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface WebFluxTagsContributor {
|
||||
|
||||
/**
|
||||
* Provides tags to be associated with metrics for the given {@code exchange}.
|
||||
* @param exchange the exchange
|
||||
* @param ex the current exception (may be {@code null})
|
||||
* @return tags to associate with metrics for the request and response exchange
|
||||
*/
|
||||
Iterable<Tag> httpRequestTags(ServerWebExchange exchange, Throwable ex);
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
* Provides {@link Tag Tags} for WebFlux-based request handling.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.reactive.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface WebFluxTagsProvider {
|
||||
|
||||
/**
|
||||
* Provides tags to be associated with metrics for the given {@code exchange}.
|
||||
* @param exchange the exchange
|
||||
* @param ex the current exception (may be {@code null})
|
||||
* @return tags to associate with metrics for the request and response exchange
|
||||
*/
|
||||
Iterable<Tag> httpRequestTags(ServerWebExchange exchange, Throwable ex);
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Actuator support for WebFlux metrics.
|
||||
*/
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.servlet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link WebMvcTagsProvider}.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
@SuppressWarnings("removal")
|
||||
public class DefaultWebMvcTagsProvider implements WebMvcTagsProvider {
|
||||
|
||||
private final boolean ignoreTrailingSlash;
|
||||
|
||||
private final List<WebMvcTagsContributor> contributors;
|
||||
|
||||
public DefaultWebMvcTagsProvider() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultWebMvcTagsProvider} that will provide tags from the
|
||||
* given {@code contributors} in addition to its own.
|
||||
* @param contributors the contributors that will provide additional tags
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public DefaultWebMvcTagsProvider(List<WebMvcTagsContributor> contributors) {
|
||||
this(false, contributors);
|
||||
}
|
||||
|
||||
public DefaultWebMvcTagsProvider(boolean ignoreTrailingSlash) {
|
||||
this(ignoreTrailingSlash, Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultWebMvcTagsProvider} that will provide tags from the
|
||||
* given {@code contributors} in addition to its own.
|
||||
* @param ignoreTrailingSlash whether trailing slashes should be ignored when
|
||||
* determining the {@code uri} tag.
|
||||
* @param contributors the contributors that will provide additional tags
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public DefaultWebMvcTagsProvider(boolean ignoreTrailingSlash, List<WebMvcTagsContributor> contributors) {
|
||||
this.ignoreTrailingSlash = ignoreTrailingSlash;
|
||||
this.contributors = contributors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
Throwable exception) {
|
||||
Tags tags = Tags.of(WebMvcTags.method(request), WebMvcTags.uri(request, response, this.ignoreTrailingSlash),
|
||||
WebMvcTags.exception(exception), WebMvcTags.status(response), WebMvcTags.outcome(response));
|
||||
for (WebMvcTagsContributor contributor : this.contributors) {
|
||||
tags = tags.and(contributor.getTags(request, response, handler, exception));
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
|
||||
Tags tags = Tags.of(WebMvcTags.method(request), WebMvcTags.uri(request, null, this.ignoreTrailingSlash));
|
||||
for (WebMvcTagsContributor contributor : this.contributors) {
|
||||
tags = tags.and(contributor.getLongRequestTags(request, handler));
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.servlet;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.http.Outcome;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
/**
|
||||
* Factory methods for {@link Tag Tags} associated with a request-response exchange that
|
||||
* is handled by Spring MVC.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public final class WebMvcTags {
|
||||
|
||||
private static final String DATA_REST_PATH_PATTERN_ATTRIBUTE = "org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH";
|
||||
|
||||
private static final Tag URI_NOT_FOUND = Tag.of("uri", "NOT_FOUND");
|
||||
|
||||
private static final Tag URI_REDIRECTION = Tag.of("uri", "REDIRECTION");
|
||||
|
||||
private static final Tag URI_ROOT = Tag.of("uri", "root");
|
||||
|
||||
private static final Tag URI_UNKNOWN = Tag.of("uri", "UNKNOWN");
|
||||
|
||||
private static final Tag EXCEPTION_NONE = Tag.of("exception", "None");
|
||||
|
||||
private static final Tag STATUS_UNKNOWN = Tag.of("status", "UNKNOWN");
|
||||
|
||||
private static final Tag METHOD_UNKNOWN = Tag.of("method", "UNKNOWN");
|
||||
|
||||
private static final Pattern TRAILING_SLASH_PATTERN = Pattern.compile("/$");
|
||||
|
||||
private static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("//+");
|
||||
|
||||
private WebMvcTags() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code method} tag based on the {@link HttpServletRequest#getMethod()
|
||||
* method} of the given {@code request}.
|
||||
* @param request the request
|
||||
* @return the method tag whose value is a capitalized method (e.g. GET).
|
||||
*/
|
||||
public static Tag method(HttpServletRequest request) {
|
||||
return (request != null) ? Tag.of("method", request.getMethod()) : METHOD_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code status} tag based on the status of the given {@code response}.
|
||||
* @param response the HTTP response
|
||||
* @return the status tag derived from the status of the response
|
||||
*/
|
||||
public static Tag status(HttpServletResponse response) {
|
||||
return (response != null) ? Tag.of("status", Integer.toString(response.getStatus())) : STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} tag based on the URI of the given {@code request}. Uses the
|
||||
* {@link HandlerMapping#BEST_MATCHING_PATTERN_ATTRIBUTE} best matching pattern if
|
||||
* available. Falling back to {@code REDIRECTION} for 3xx responses, {@code NOT_FOUND}
|
||||
* for 404 responses, {@code root} for requests with no path info, and {@code UNKNOWN}
|
||||
* for all other requests.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @return the uri tag derived from the request
|
||||
*/
|
||||
public static Tag uri(HttpServletRequest request, HttpServletResponse response) {
|
||||
return uri(request, response, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code uri} tag based on the URI of the given {@code request}. Uses the
|
||||
* {@link HandlerMapping#BEST_MATCHING_PATTERN_ATTRIBUTE} best matching pattern if
|
||||
* available. Falling back to {@code REDIRECTION} for 3xx responses, {@code NOT_FOUND}
|
||||
* for 404 responses, {@code root} for requests with no path info, and {@code UNKNOWN}
|
||||
* for all other requests.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param ignoreTrailingSlash whether to ignore the trailing slash
|
||||
* @return the uri tag derived from the request
|
||||
*/
|
||||
public static Tag uri(HttpServletRequest request, HttpServletResponse response, boolean ignoreTrailingSlash) {
|
||||
if (request != null) {
|
||||
String pattern = getMatchingPattern(request);
|
||||
if (pattern != null) {
|
||||
if (ignoreTrailingSlash && pattern.length() > 1) {
|
||||
pattern = TRAILING_SLASH_PATTERN.matcher(pattern).replaceAll("");
|
||||
}
|
||||
if (pattern.isEmpty()) {
|
||||
return URI_ROOT;
|
||||
}
|
||||
return Tag.of("uri", pattern);
|
||||
}
|
||||
if (response != null) {
|
||||
HttpStatus status = extractStatus(response);
|
||||
if (status != null) {
|
||||
if (status.is3xxRedirection()) {
|
||||
return URI_REDIRECTION;
|
||||
}
|
||||
if (status == HttpStatus.NOT_FOUND) {
|
||||
return URI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
String pathInfo = getPathInfo(request);
|
||||
if (pathInfo.isEmpty()) {
|
||||
return URI_ROOT;
|
||||
}
|
||||
}
|
||||
return URI_UNKNOWN;
|
||||
}
|
||||
|
||||
private static HttpStatus extractStatus(HttpServletResponse response) {
|
||||
try {
|
||||
return HttpStatus.valueOf(response.getStatus());
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMatchingPattern(HttpServletRequest request) {
|
||||
PathPattern dataRestPathPattern = (PathPattern) request.getAttribute(DATA_REST_PATH_PATTERN_ATTRIBUTE);
|
||||
if (dataRestPathPattern != null) {
|
||||
return dataRestPathPattern.getPatternString();
|
||||
}
|
||||
return (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
|
||||
}
|
||||
|
||||
private static String getPathInfo(HttpServletRequest request) {
|
||||
String pathInfo = request.getPathInfo();
|
||||
String uri = StringUtils.hasText(pathInfo) ? pathInfo : "/";
|
||||
uri = MULTIPLE_SLASH_PATTERN.matcher(uri).replaceAll("/");
|
||||
return TRAILING_SLASH_PATTERN.matcher(uri).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code exception} tag based on the {@link Class#getSimpleName() simple
|
||||
* name} of the class of the given {@code exception}.
|
||||
* @param exception the exception, may be {@code null}
|
||||
* @return the exception tag derived from the exception
|
||||
*/
|
||||
public static Tag exception(Throwable exception) {
|
||||
if (exception != null) {
|
||||
String simpleName = exception.getClass().getSimpleName();
|
||||
return Tag.of("exception", StringUtils.hasText(simpleName) ? simpleName : exception.getClass().getName());
|
||||
}
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code outcome} tag based on the status of the given {@code response}.
|
||||
* @param response the HTTP response
|
||||
* @return the outcome tag derived from the status of the response
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public static Tag outcome(HttpServletResponse response) {
|
||||
Outcome outcome = (response != null) ? Outcome.forStatus(response.getStatus()) : Outcome.UNKNOWN;
|
||||
return outcome.asTag();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.servlet;
|
||||
|
||||
import io.micrometer.core.instrument.LongTaskTimer;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* A contributor of {@link Tag Tags} for Spring MVC-based request handling. Typically used
|
||||
* by a {@link WebMvcTagsProvider} to provide tags in addition to its defaults.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.3.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface WebMvcTagsContributor {
|
||||
|
||||
/**
|
||||
* Provides tags to be associated with metrics for the given {@code request} and
|
||||
* {@code response} exchange.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param handler the handler for the request or {@code null} if the handler is
|
||||
* unknown
|
||||
* @param exception the current exception, if any
|
||||
* @return tags to associate with metrics for the request and response exchange
|
||||
*/
|
||||
Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
Throwable exception);
|
||||
|
||||
/**
|
||||
* Provides tags to be used by {@link LongTaskTimer long task timers}.
|
||||
* @param request the HTTP request
|
||||
* @param handler the handler for the request or {@code null} if the handler is
|
||||
* unknown
|
||||
* @return tags to associate with metrics recorded for the request
|
||||
*/
|
||||
Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler);
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.servlet;
|
||||
|
||||
import io.micrometer.core.instrument.LongTaskTimer;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Provides {@link Tag Tags} for Spring MVC-based request handling.
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @deprecated since 3.0.0 for removal in 3.2.0 in favor of
|
||||
* {@link org.springframework.http.server.observation.ServerRequestObservationConvention}
|
||||
*/
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
public interface WebMvcTagsProvider {
|
||||
|
||||
/**
|
||||
* Provides tags to be associated with metrics for the given {@code request} and
|
||||
* {@code response} exchange.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param handler the handler for the request or {@code null} if the handler is
|
||||
* unknown
|
||||
* @param exception the current exception, if any
|
||||
* @return tags to associate with metrics for the request and response exchange
|
||||
*/
|
||||
Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
Throwable exception);
|
||||
|
||||
/**
|
||||
* Provides tags to be used by {@link LongTaskTimer long task timers}.
|
||||
* @param request the HTTP request
|
||||
* @param handler the handler for the request or {@code null} if the handler is
|
||||
* unknown
|
||||
* @return tags to associate with metrics recorded for the request
|
||||
*/
|
||||
Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler);
|
||||
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Actuator support for Spring MVC metrics.
|
||||
*/
|
||||
package org.springframework.boot.actuate.metrics.web.servlet;
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.web.servlet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.web.servlet.DefaultWebMvcTagsProvider;
|
||||
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTagsContributor;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultWebMvcTagsProvider}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
class DefaultWebMvcTagsProviderTests {
|
||||
|
||||
@Test
|
||||
void whenTagsAreProvidedThenDefaultTagsArePresent() {
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider().getTags(null, null, null, null));
|
||||
assertThat(tags).containsOnlyKeys("exception", "method", "outcome", "status", "uri");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSomeContributorsWhenTagsAreProvidedThenDefaultTagsAndContributedTagsArePresent() {
|
||||
Map<String, Tag> tags = asMap(
|
||||
new DefaultWebMvcTagsProvider(Arrays.asList(new TestWebMvcTagsContributor("alpha"),
|
||||
new TestWebMvcTagsContributor("bravo", "charlie")))
|
||||
.getTags(null, null, null, null));
|
||||
assertThat(tags).containsOnlyKeys("exception", "method", "outcome", "status", "uri", "alpha", "bravo",
|
||||
"charlie");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenLongRequestTagsAreProvidedThenDefaultTagsArePresent() {
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider().getLongRequestTags(null, null));
|
||||
assertThat(tags).containsOnlyKeys("method", "uri");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSomeContributorsWhenLongRequestTagsAreProvidedThenDefaultTagsAndContributedTagsArePresent() {
|
||||
Map<String, Tag> tags = asMap(
|
||||
new DefaultWebMvcTagsProvider(Arrays.asList(new TestWebMvcTagsContributor("alpha"),
|
||||
new TestWebMvcTagsContributor("bravo", "charlie")))
|
||||
.getLongRequestTags(null, null));
|
||||
assertThat(tags).containsOnlyKeys("method", "uri", "alpha", "bravo", "charlie");
|
||||
}
|
||||
|
||||
@Test
|
||||
void trailingSlashIsIncludedByDefault() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/the/uri/");
|
||||
request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "{one}/{two}/");
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider().getTags(request, null, null, null));
|
||||
assertThat(tags.get("uri").getValue()).isEqualTo("{one}/{two}/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void trailingSlashCanBeIgnored() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/the/uri/");
|
||||
request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "{one}/{two}/");
|
||||
Map<String, Tag> tags = asMap(new DefaultWebMvcTagsProvider(true).getTags(request, null, null, null));
|
||||
assertThat(tags.get("uri").getValue()).isEqualTo("{one}/{two}");
|
||||
}
|
||||
|
||||
private Map<String, Tag> asMap(Iterable<Tag> tags) {
|
||||
return StreamSupport.stream(tags.spliterator(), false)
|
||||
.collect(Collectors.toMap(Tag::getKey, Function.identity()));
|
||||
}
|
||||
|
||||
private static final class TestWebMvcTagsContributor implements WebMvcTagsContributor {
|
||||
|
||||
private final List<String> tagNames;
|
||||
|
||||
private TestWebMvcTagsContributor(String... tagNames) {
|
||||
this.tagNames = Arrays.asList(tagNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getTags(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||
Throwable exception) {
|
||||
return this.tagNames.stream().map((name) -> Tag.of(name, "value")).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> getLongRequestTags(HttpServletRequest request, Object handler) {
|
||||
return this.tagNames.stream().map((name) -> Tag.of(name, "value")).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.endpoint.web.servlet;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.metrics.web.servlet.WebMvcTags;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebMvcTags}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
class WebMvcTagsTests {
|
||||
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@Test
|
||||
void uriTagIsDataRestsEffectiveRepositoryLookupPathWhenAvailable() {
|
||||
this.request.setAttribute(
|
||||
"org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping.EFFECTIVE_REPOSITORY_RESOURCE_LOOKUP_PATH",
|
||||
new PathPatternParser().parse("/api/cities"));
|
||||
this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "/api/{repository}");
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("/api/cities");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsBestMatchingPatternWhenAvailable() {
|
||||
this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "/spring/");
|
||||
this.response.setStatus(301);
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("/spring/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenBestMatchingPatternIsEmpty() {
|
||||
this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "");
|
||||
this.response.setStatus(301);
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueWithBestMatchingPatternAndIgnoreTrailingSlashRemoveTrailingSlash() {
|
||||
this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "/spring/");
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response, true);
|
||||
assertThat(tag.getValue()).isEqualTo("/spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueWithBestMatchingPatternAndIgnoreTrailingSlashKeepSingleSlash() {
|
||||
this.request.setAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, "/");
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response, true);
|
||||
assertThat(tag.getValue()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenRequestHasNoPatternOrPathInfo() {
|
||||
assertThat(WebMvcTags.uri(this.request, null).getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenRequestHasNoPatternAndSlashPathInfo() {
|
||||
this.request.setPathInfo("/");
|
||||
assertThat(WebMvcTags.uri(this.request, null).getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsUnknownWhenRequestHasNoPatternAndNonRootPathInfo() {
|
||||
this.request.setPathInfo("/example");
|
||||
assertThat(WebMvcTags.uri(this.request, null).getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRedirectionWhenResponseStatusIs3xx() {
|
||||
this.response.setStatus(301);
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsNotFoundWhenResponseStatusIs404() {
|
||||
this.response.setStatus(404);
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("NOT_FOUND");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagToleratesCustomResponseStatus() {
|
||||
this.response.setStatus(601);
|
||||
Tag tag = WebMvcTags.uri(this.request, this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagIsUnknownWhenRequestIsNull() {
|
||||
Tag tag = WebMvcTags.uri(null, null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseIsNull() {
|
||||
Tag tag = WebMvcTags.outcome(null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsInformationalWhenResponseIs1xx() {
|
||||
this.response.setStatus(100);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseIs2xx() {
|
||||
this.response.setStatus(200);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsRedirectionWhenResponseIs3xx() {
|
||||
this.response.setStatus(301);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIs4xx() {
|
||||
this.response.setStatus(400);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() {
|
||||
this.response.setStatus(490);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsServerErrorWhenResponseIs5xx() {
|
||||
this.response.setStatus(500);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() {
|
||||
this.response.setStatus(701);
|
||||
Tag tag = WebMvcTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -140,18 +140,6 @@ class PrometheusPushGatewayManagerTests {
|
||||
then(otherScheduler).should(never()).shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
void shutdownWhenShutdownOperationIsPushPerformsPushAddOnShutdown() throws Exception {
|
||||
givenScheduleAtFixedRateWithReturnFuture();
|
||||
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(this.pushGateway, this.registry,
|
||||
this.scheduler, this.pushRate, "job", this.groupingKey, ShutdownOperation.PUSH);
|
||||
manager.shutdown();
|
||||
then(this.future).should().cancel(false);
|
||||
then(this.pushGateway).should().pushAdd(this.registry, "job", this.groupingKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shutdownWhenShutdownOperationIsPostPerformsPushAddOnShutdown() throws Exception {
|
||||
givenScheduleAtFixedRateWithReturnFuture();
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
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;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link RestTemplateExchangeTags}.
|
||||
*
|
||||
* @author Nishant Raut
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@SuppressWarnings({ "removal" })
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
class RestTemplateExchangeTagsTests {
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseIsNull() {
|
||||
Tag tag = RestTemplateExchangeTags.outcome(null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsInformationalWhenResponseIs1xx() {
|
||||
ClientHttpResponse response = new MockClientHttpResponse("foo".getBytes(), HttpStatus.CONTINUE);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseIs2xx() {
|
||||
ClientHttpResponse response = new MockClientHttpResponse("foo".getBytes(), HttpStatus.OK);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsRedirectionWhenResponseIs3xx() {
|
||||
ClientHttpResponse response = new MockClientHttpResponse("foo".getBytes(), HttpStatus.MOVED_PERMANENTLY);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIs4xx() {
|
||||
ClientHttpResponse response = new MockClientHttpResponse("foo".getBytes(), HttpStatus.BAD_REQUEST);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsServerErrorWhenResponseIs5xx() {
|
||||
ClientHttpResponse response = new MockClientHttpResponse("foo".getBytes(), HttpStatus.BAD_GATEWAY);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseThrowsIOException() throws Exception {
|
||||
ClientHttpResponse response = mock(ClientHttpResponse.class);
|
||||
given(response.getStatusCode()).willThrow(IOException.class);
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() throws IOException {
|
||||
ClientHttpResponse response = mock(ClientHttpResponse.class);
|
||||
given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(490));
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() throws IOException {
|
||||
ClientHttpResponse response = mock(ClientHttpResponse.class);
|
||||
given(response.getStatusCode()).willReturn(HttpStatusCode.valueOf(701));
|
||||
Tag tag = RestTemplateExchangeTags.outcome(response);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void clientNameTagIsHostOfRequestUri() {
|
||||
ClientHttpRequest request = mock(ClientHttpRequest.class);
|
||||
given(request.getURI()).willReturn(URI.create("https://example.org"));
|
||||
Tag tag = RestTemplateExchangeTags.clientName(request);
|
||||
assertThat(tag).isEqualTo(Tag.of("client.name", "example.org"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultWebClientExchangeTagsProvider}
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Nishant Raut
|
||||
*/
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
class DefaultWebClientExchangeTagsProviderTests {
|
||||
|
||||
private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
|
||||
|
||||
private final WebClientExchangeTagsProvider tagsProvider = new DefaultWebClientExchangeTagsProvider();
|
||||
|
||||
private ClientRequest request;
|
||||
|
||||
private ClientResponse response;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
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.statusCode()).willReturn(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagsShouldBePopulated() {
|
||||
Iterable<Tag> tags = this.tagsProvider.tags(this.request, this.response, null);
|
||||
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"),
|
||||
Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagsWhenNoUriTemplateShouldProvideUriPath() {
|
||||
ClientRequest request = ClientRequest
|
||||
.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
|
||||
.build();
|
||||
Iterable<Tag> tags = this.tagsProvider.tags(request, this.response, null);
|
||||
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/spring-boot"),
|
||||
Tag.of("client.name", "example.org"), Tag.of("status", "200"), Tag.of("outcome", "SUCCESS"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagsWhenIoExceptionShouldReturnIoErrorStatus() {
|
||||
Iterable<Tag> tags = this.tagsProvider.tags(this.request, null, new IOException());
|
||||
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"),
|
||||
Tag.of("client.name", "example.org"), Tag.of("status", "IO_ERROR"), Tag.of("outcome", "UNKNOWN"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagsWhenExceptionShouldReturnClientErrorStatus() {
|
||||
Iterable<Tag> tags = this.tagsProvider.tags(this.request, null, new IllegalArgumentException());
|
||||
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"),
|
||||
Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void tagsWhenCancelledRequestShouldReturnClientErrorStatus() {
|
||||
Iterable<Tag> tags = this.tagsProvider.tags(this.request, null, null);
|
||||
assertThat(tags).containsExactlyInAnyOrder(Tag.of("method", "GET"), Tag.of("uri", "/projects/{project}"),
|
||||
Tag.of("client.name", "example.org"), Tag.of("status", "CLIENT_ERROR"), Tag.of("outcome", "UNKNOWN"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
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;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebClientExchangeTags}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Nishant Raut
|
||||
*/
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
class WebClientExchangeTagsTests {
|
||||
|
||||
private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
|
||||
|
||||
private ClientRequest request;
|
||||
|
||||
private ClientResponse response;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
void method() {
|
||||
assertThat(WebClientExchangeTags.method(this.request)).isEqualTo(Tag.of("method", "GET"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriWhenAbsoluteTemplateIsAvailableShouldReturnTemplate() {
|
||||
assertThat(WebClientExchangeTags.uri(this.request)).isEqualTo(Tag.of("uri", "/projects/{project}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriWhenRelativeTemplateIsAvailableShouldReturnTemplate() {
|
||||
this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
|
||||
.attribute(URI_TEMPLATE_ATTRIBUTE, "/projects/{project}")
|
||||
.build();
|
||||
assertThat(WebClientExchangeTags.uri(this.request)).isEqualTo(Tag.of("uri", "/projects/{project}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriWhenTemplateIsMissingShouldReturnPath() {
|
||||
this.request = ClientRequest.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot"))
|
||||
.build();
|
||||
assertThat(WebClientExchangeTags.uri(this.request)).isEqualTo(Tag.of("uri", "/projects/spring-boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriWhenTemplateIsMissingShouldReturnPathWithQueryParams() {
|
||||
this.request = ClientRequest
|
||||
.create(HttpMethod.GET, URI.create("https://example.org/projects/spring-boot?section=docs"))
|
||||
.build();
|
||||
assertThat(WebClientExchangeTags.uri(this.request))
|
||||
.isEqualTo(Tag.of("uri", "/projects/spring-boot?section=docs"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void clientName() {
|
||||
assertThat(WebClientExchangeTags.clientName(this.request)).isEqualTo(Tag.of("client.name", "example.org"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void status() {
|
||||
given(this.response.statusCode()).willReturn(HttpStatus.OK);
|
||||
assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "200"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusWhenIOException() {
|
||||
assertThat(WebClientExchangeTags.status(null, new IOException())).isEqualTo(Tag.of("status", "IO_ERROR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusWhenClientException() {
|
||||
assertThat(WebClientExchangeTags.status(null, new IllegalArgumentException()))
|
||||
.isEqualTo(Tag.of("status", "CLIENT_ERROR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusWhenNonStandard() {
|
||||
given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(490));
|
||||
assertThat(WebClientExchangeTags.status(this.response, null)).isEqualTo(Tag.of("status", "490"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void statusWhenCancelled() {
|
||||
assertThat(WebClientExchangeTags.status(null, null)).isEqualTo(Tag.of("status", "CLIENT_ERROR"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseIsNull() {
|
||||
Tag tag = WebClientExchangeTags.outcome(null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsInformationalWhenResponseIs1xx() {
|
||||
given(this.response.statusCode()).willReturn(HttpStatus.CONTINUE);
|
||||
Tag tag = WebClientExchangeTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseIs2xx() {
|
||||
given(this.response.statusCode()).willReturn(HttpStatus.OK);
|
||||
Tag tag = WebClientExchangeTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsRedirectionWhenResponseIs3xx() {
|
||||
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.statusCode()).willReturn(HttpStatus.BAD_REQUEST);
|
||||
Tag tag = WebClientExchangeTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsServerErrorWhenResponseIs5xx() {
|
||||
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.statusCode()).willReturn(HttpStatusCode.valueOf(490));
|
||||
Tag tag = WebClientExchangeTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() {
|
||||
given(this.response.statusCode()).willReturn(HttpStatusCode.valueOf(701));
|
||||
Tag tag = WebClientExchangeTags.outcome(this.response);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultWebFluxTagsProvider}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
class DefaultWebFluxTagsProviderTests {
|
||||
|
||||
@Test
|
||||
void whenTagsAreProvidedThenDefaultTagsArePresent() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test"));
|
||||
Map<String, Tag> tags = asMap(new DefaultWebFluxTagsProvider().httpRequestTags(exchange, null));
|
||||
assertThat(tags).containsOnlyKeys("exception", "method", "outcome", "status", "uri");
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenSomeContributorsWhenTagsAreProvidedThenDefaultTagsAndContributedTagsArePresent() {
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/test"));
|
||||
Map<String, Tag> tags = asMap(
|
||||
new DefaultWebFluxTagsProvider(Arrays.asList(new TestWebFluxTagsContributor("alpha"),
|
||||
new TestWebFluxTagsContributor("bravo", "charlie")))
|
||||
.httpRequestTags(exchange, null));
|
||||
assertThat(tags).containsOnlyKeys("exception", "method", "outcome", "status", "uri", "alpha", "bravo",
|
||||
"charlie");
|
||||
}
|
||||
|
||||
private Map<String, Tag> asMap(Iterable<Tag> tags) {
|
||||
return StreamSupport.stream(tags.spliterator(), false)
|
||||
.collect(Collectors.toMap(Tag::getKey, Function.identity()));
|
||||
}
|
||||
|
||||
private static final class TestWebFluxTagsContributor implements WebFluxTagsContributor {
|
||||
|
||||
private final List<String> tagNames;
|
||||
|
||||
private TestWebFluxTagsContributor(String... tagNames) {
|
||||
this.tagNames = Arrays.asList(tagNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Tag> httpRequestTags(ServerWebExchange exchange, Throwable ex) {
|
||||
return this.tagNames.stream().map((name) -> Tag.of(name, "value")).toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.metrics.web.reactive.server;
|
||||
|
||||
import java.io.EOFException;
|
||||
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.web.reactive.HandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.pattern.PathPatternParser;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebFluxTags}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Michael McFadyen
|
||||
* @author Madhura Bhave
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
@Deprecated(since = "3.0.0", forRemoval = true)
|
||||
class WebFluxTagsTests {
|
||||
|
||||
private MockServerWebExchange exchange;
|
||||
|
||||
private final PathPatternParser parser = new PathPatternParser();
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
this.exchange = MockServerWebExchange.from(MockServerHttpRequest.get(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsBestMatchingPatternWhenAvailable() {
|
||||
this.exchange.getAttributes()
|
||||
.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, this.parser.parse("/spring/"));
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("/spring/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenBestMatchingPatternIsEmpty() {
|
||||
this.exchange.getAttributes().put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, this.parser.parse(""));
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueWithBestMatchingPatternAndIgnoreTrailingSlashRemoveTrailingSlash() {
|
||||
this.exchange.getAttributes()
|
||||
.put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, this.parser.parse("/spring/"));
|
||||
Tag tag = WebFluxTags.uri(this.exchange, true);
|
||||
assertThat(tag.getValue()).isEqualTo("/spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueWithBestMatchingPatternAndIgnoreTrailingSlashKeepSingleSlash() {
|
||||
this.exchange.getAttributes().put(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, this.parser.parse("/"));
|
||||
Tag tag = WebFluxTags.uri(this.exchange, true);
|
||||
assertThat(tag.getValue()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRedirectionWhenResponseStatusIs3xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsNotFoundWhenResponseStatusIs404() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("NOT_FOUND");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagToleratesCustomResponseStatus() {
|
||||
this.exchange.getResponse().setRawStatusCode(601);
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenRequestHasNoPatternOrPathInfo() {
|
||||
Tag tag = WebFluxTags.uri(this.exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsRootWhenRequestHasNoPatternAndSlashPathInfo() {
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/").build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
Tag tag = WebFluxTags.uri(exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("root");
|
||||
}
|
||||
|
||||
@Test
|
||||
void uriTagValueIsUnknownWhenRequestHasNoPatternAndNonRootPathInfo() {
|
||||
MockServerHttpRequest request = MockServerHttpRequest.get("/example").build();
|
||||
ServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
Tag tag = WebFluxTags.uri(exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void methodTagToleratesNonStandardHttpMethods() {
|
||||
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||
ServerHttpRequest request = mock(ServerHttpRequest.class);
|
||||
given(exchange.getRequest()).willReturn(request);
|
||||
given(request.getMethod()).willReturn(HttpMethod.valueOf("CUSTOM"));
|
||||
Tag tag = WebFluxTags.method(exchange);
|
||||
assertThat(tag.getValue()).isEqualTo("CUSTOM");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseStatusIsNull() {
|
||||
this.exchange.getResponse().setStatusCode(null);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseStatusIsAvailableFromUnderlyingServer() {
|
||||
ServerWebExchange exchange = mock(ServerWebExchange.class);
|
||||
ServerHttpRequest request = mock(ServerHttpRequest.class);
|
||||
ServerHttpResponse response = mock(ServerHttpResponse.class);
|
||||
given(response.getStatusCode()).willReturn(HttpStatus.OK);
|
||||
given(response.getStatusCode().value()).willReturn(null);
|
||||
given(exchange.getRequest()).willReturn(request);
|
||||
given(exchange.getResponse()).willReturn(response);
|
||||
Tag tag = WebFluxTags.outcome(exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsInformationalWhenResponseIs1xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.CONTINUE);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("INFORMATIONAL");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsSuccessWhenResponseIs2xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.OK);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("SUCCESS");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsRedirectionWhenResponseIs3xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.MOVED_PERMANENTLY);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("REDIRECTION");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIs4xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsServerErrorWhenResponseIs5xx() {
|
||||
this.exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("SERVER_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsClientErrorWhenResponseIsNonStandardInClientSeries() {
|
||||
this.exchange.getResponse().setRawStatusCode(490);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("CLIENT_ERROR");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenResponseStatusIsInUnknownSeries() {
|
||||
this.exchange.getResponse().setRawStatusCode(701);
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, null);
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void outcomeTagIsUnknownWhenExceptionIsDisconnectedClient() {
|
||||
Tag tag = WebFluxTags.outcome(this.exchange, new EOFException("broken pipe"));
|
||||
assertThat(tag.getValue()).isEqualTo("UNKNOWN");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user