Remove APIs deprecated for removal in 3.5

Closes gh-43788
This commit is contained in:
Andy Wilkinson
2025-01-14 12:34:43 +00:00
parent f301b2a123
commit 2f29a49a1d
61 changed files with 29 additions and 3522 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2024 the original author or authors.
* Copyright 2012-2025 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.
@@ -53,17 +53,6 @@ public class PrometheusScrapeEndpoint {
private volatile int nextMetricsScrapeSize = 16;
/**
* Creates a new {@link PrometheusScrapeEndpoint}.
* @param prometheusRegistry the Prometheus registry to use
* @deprecated since 3.3.1 for removal in 3.5.0 in favor of
* {@link #PrometheusScrapeEndpoint(PrometheusRegistry, Properties)}
*/
@Deprecated(since = "3.3.1", forRemoval = true)
public PrometheusScrapeEndpoint(PrometheusRegistry prometheusRegistry) {
this(prometheusRegistry, null);
}
/**
* Creates a new {@link PrometheusScrapeEndpoint}.
* @param prometheusRegistry the Prometheus registry to use

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2012-2024 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.export.prometheus;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Set;
import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.CollectorRegistry;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.lang.Nullable;
/**
* {@link Endpoint @Endpoint} that uses the Prometheus simpleclient to output metrics in a
* format that can be scraped by the Prometheus server.
*
* @author Jon Schneider
* @author Johnny Lim
* @since 2.0.0
* @deprecated since 3.3.0 for removal in 3.5.0 in favor of
* {@link PrometheusScrapeEndpoint}
*/
@Deprecated(since = "3.3.0", forRemoval = true)
@WebEndpoint(id = "prometheus")
public class PrometheusSimpleclientScrapeEndpoint {
private static final int METRICS_SCRAPE_CHARS_EXTRA = 1024;
private final CollectorRegistry collectorRegistry;
private volatile int nextMetricsScrapeSize = 16;
public PrometheusSimpleclientScrapeEndpoint(CollectorRegistry collectorRegistry) {
this.collectorRegistry = collectorRegistry;
}
@SuppressWarnings("removal")
@ReadOperation(producesFrom = TextOutputFormat.class)
public WebEndpointResponse<String> scrape(TextOutputFormat format, @Nullable Set<String> includedNames) {
try {
Writer writer = new StringWriter(this.nextMetricsScrapeSize);
Enumeration<MetricFamilySamples> samples = (includedNames != null)
? this.collectorRegistry.filteredMetricFamilySamples(includedNames)
: this.collectorRegistry.metricFamilySamples();
format.write(writer, samples);
String scrapePage = writer.toString();
this.nextMetricsScrapeSize = scrapePage.length() + METRICS_SCRAPE_CHARS_EXTRA;
return new WebEndpointResponse<>(scrapePage, format);
}
catch (IOException ex) {
// This actually never happens since StringWriter doesn't throw an IOException
throw new IllegalStateException("Writing metrics failed", ex);
}
}
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright 2012-2024 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.export.prometheus;
import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.exporter.common.TextFormat;
import org.springframework.boot.actuate.endpoint.Producible;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
/**
* A {@link Producible} enum for supported Prometheus {@link TextFormat}.
*
* @author Andy Wilkinson
* @since 2.5.0
* @deprecated since 3.3.0 for removal in 3.5.0 in favor of {@link PrometheusOutputFormat}
*/
@Deprecated(since = "3.3.0", forRemoval = true)
public enum TextOutputFormat implements Producible<TextOutputFormat> {
/**
* Prometheus text version 0.0.4.
*/
CONTENT_TYPE_004(TextFormat.CONTENT_TYPE_004) {
@Override
void write(Writer writer, Enumeration<MetricFamilySamples> samples) throws IOException {
TextFormat.write004(writer, samples);
}
@Override
public boolean isDefault() {
return true;
}
},
/**
* OpenMetrics text version 1.0.0.
*/
CONTENT_TYPE_OPENMETRICS_100(TextFormat.CONTENT_TYPE_OPENMETRICS_100) {
@Override
void write(Writer writer, Enumeration<MetricFamilySamples> samples) throws IOException {
TextFormat.writeOpenMetrics100(writer, samples);
}
};
private final MimeType mimeType;
TextOutputFormat(String mimeType) {
this.mimeType = MimeTypeUtils.parseMimeType(mimeType);
}
@Override
public MimeType getProducedMimeType() {
return this.mimeType;
}
abstract void write(Writer writer, Enumeration<MetricFamilySamples> samples) throws IOException;
}

View File

@@ -42,17 +42,6 @@ public class SessionsEndpoint {
private final FindByIndexNameSessionRepository<? extends Session> indexedSessionRepository;
/**
* Create a new {@link SessionsEndpoint} instance.
* @param sessionRepository the session repository
* @deprecated since 3.3.0 for removal in 3.5.0 in favor of
* {@link #SessionsEndpoint(SessionRepository, FindByIndexNameSessionRepository)}
*/
@Deprecated(since = "3.3.0", forRemoval = true)
public SessionsEndpoint(FindByIndexNameSessionRepository<? extends Session> sessionRepository) {
this(sessionRepository, sessionRepository);
}
/**
* Create a new {@link SessionsEndpoint} instance.
* @param sessionRepository the session repository

View File

@@ -1,150 +0,0 @@
/*
* Copyright 2012-2024 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.export.prometheus;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.common.TextFormat;
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link PrometheusSimpleclientScrapeEndpoint}.
*
* @author Jon Schneider
* @author Johnny Lim
*/
@SuppressWarnings({ "deprecation", "removal" })
class PrometheusSimpleclientScrapeEndpointIntegrationTests {
@WebEndpointTest
void scrapeHasContentTypeText004ByDefault(WebTestClient client) {
String expectedContentType = TextFormat.CONTENT_TYPE_004;
assertThat(TextFormat.chooseContentType(null)).isEqualTo(expectedContentType);
client.get()
.uri("/actuator/prometheus")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(expectedContentType))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapeHasContentTypeText004ByDefaultWhenClientAcceptsWildcardWithParameter(WebTestClient client) {
String expectedContentType = TextFormat.CONTENT_TYPE_004;
String accept = "*/*;q=0.8";
assertThat(TextFormat.chooseContentType(accept)).isEqualTo(expectedContentType);
client.get()
.uri("/actuator/prometheus")
.accept(MediaType.parseMediaType(accept))
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(expectedContentType))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapeCanProduceOpenMetrics100(WebTestClient client) {
MediaType openMetrics = MediaType.parseMediaType(TextFormat.CONTENT_TYPE_OPENMETRICS_100);
client.get()
.uri("/actuator/prometheus")
.accept(openMetrics)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(openMetrics)
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapePrefersToProduceOpenMetrics100(WebTestClient client) {
MediaType openMetrics = MediaType.parseMediaType(TextFormat.CONTENT_TYPE_OPENMETRICS_100);
MediaType textPlain = MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004);
client.get()
.uri("/actuator/prometheus")
.accept(openMetrics, textPlain)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(openMetrics);
}
@WebEndpointTest
void scrapeWithIncludedNames(WebTestClient client) {
client.get()
.uri("/actuator/prometheus?includedNames=counter1_total,counter2_total")
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.doesNotContain("counter3_total"));
}
@Configuration(proxyBeanMethods = false)
static class TestConfiguration {
@Bean
PrometheusSimpleclientScrapeEndpoint prometheusScrapeEndpoint(CollectorRegistry collectorRegistry) {
return new PrometheusSimpleclientScrapeEndpoint(collectorRegistry);
}
@Bean
CollectorRegistry collectorRegistry() {
return new CollectorRegistry(true);
}
@Bean
@SuppressWarnings("deprecation")
MeterRegistry registry(CollectorRegistry registry) {
io.micrometer.prometheus.PrometheusMeterRegistry meterRegistry = new io.micrometer.prometheus.PrometheusMeterRegistry(
(k) -> null, registry, Clock.SYSTEM);
Counter.builder("counter1").register(meterRegistry);
Counter.builder("counter2").register(meterRegistry);
Counter.builder("counter3").register(meterRegistry);
return meterRegistry;
}
}
}

View File

@@ -1,210 +0,0 @@
/*
* Copyright 2012-2024 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.export.prometheus;
import java.util.Properties;
import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for exposing a {@link PrometheusScrapeEndpoint} and
* {@link PrometheusSimpleclientScrapeEndpoint} with different IDs.
*
* @author Jon Schneider
* @author Johnny Lim
*/
class SecondCustomPrometheusScrapeEndpointIntegrationTests {
@WebEndpointTest
void scrapeHasContentTypeText004ByDefault(WebTestClient client) {
scrapeHasContentTypeText004ByDefault(client, "/actuator/prometheus");
scrapeHasContentTypeText004ByDefault(client, "/actuator/prometheussc");
}
private void scrapeHasContentTypeText004ByDefault(WebTestClient client, String uri) {
String expectedContentType = PrometheusTextFormatWriter.CONTENT_TYPE;
client.get()
.uri(uri)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(expectedContentType))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapeHasContentTypeText004ByDefaultWhenClientAcceptsWildcardWithParameter(WebTestClient client) {
scrapeHasContentTypeText004ByDefaultWhenClientAcceptsWildcardWithParameter(client, "/actuator/prometheus");
scrapeHasContentTypeText004ByDefaultWhenClientAcceptsWildcardWithParameter(client, "/actuator/prometheussc");
}
private void scrapeHasContentTypeText004ByDefaultWhenClientAcceptsWildcardWithParameter(WebTestClient client,
String uri) {
String expectedContentType = PrometheusTextFormatWriter.CONTENT_TYPE;
String accept = "*/*;q=0.8";
client.get()
.uri(uri)
.accept(MediaType.parseMediaType(accept))
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(expectedContentType))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapeCanProduceOpenMetrics100(WebTestClient client) {
scrapeCanProduceOpenMetrics100(client, "/actuator/prometheus");
scrapeCanProduceOpenMetrics100(client, "/actuator/prometheussc");
}
private void scrapeCanProduceOpenMetrics100(WebTestClient client, String uri) {
MediaType openMetrics = MediaType.parseMediaType(OpenMetricsTextFormatWriter.CONTENT_TYPE);
client.get()
.uri(uri)
.accept(openMetrics)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(openMetrics)
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.contains("counter3_total"));
}
@WebEndpointTest
void scrapePrefersToProduceOpenMetrics100(WebTestClient client) {
scrapePrefersToProduceOpenMetrics100(client, "/actuator/prometheus");
scrapePrefersToProduceOpenMetrics100(client, "/actuator/prometheussc");
}
private void scrapePrefersToProduceOpenMetrics100(WebTestClient client, String uri) {
MediaType openMetrics = MediaType.parseMediaType(OpenMetricsTextFormatWriter.CONTENT_TYPE);
MediaType textPlain = MediaType.parseMediaType(PrometheusTextFormatWriter.CONTENT_TYPE);
client.get()
.uri(uri)
.accept(openMetrics, textPlain)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(openMetrics);
}
@WebEndpointTest
void scrapeWithIncludedNames(WebTestClient client) {
scrapeWithIncludedNames(client, "/actuator/prometheus?includedNames=counter1,counter2");
scrapeWithIncludedNames(client, "/actuator/prometheussc?includedNames=counter1_total,counter2_total");
}
private void scrapeWithIncludedNames(WebTestClient client, String uri) {
client.get()
.uri(uri)
.exchange()
.expectStatus()
.isOk()
.expectHeader()
.contentType(MediaType.parseMediaType(PrometheusTextFormatWriter.CONTENT_TYPE))
.expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total")
.doesNotContain("counter3_total"));
}
@SuppressWarnings({ "deprecation", "removal" })
@Configuration(proxyBeanMethods = false)
static class TestConfiguration {
@Bean
PrometheusScrapeEndpoint prometheusScrapeEndpoint(PrometheusRegistry prometheusRegistry) {
return new PrometheusScrapeEndpoint(prometheusRegistry, new Properties());
}
@Bean
CustomPrometheusScrapeEndpoint customPrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) {
return new CustomPrometheusScrapeEndpoint(collectorRegistry);
}
@Bean
PrometheusRegistry prometheusRegistry() {
return new PrometheusRegistry();
}
@Bean
CollectorRegistry collectorRegistry() {
return new CollectorRegistry(true);
}
@Bean
PrometheusMeterRegistry registry(PrometheusRegistry prometheusRegistry) {
return new PrometheusMeterRegistry((k) -> null, prometheusRegistry, Clock.SYSTEM);
}
@Bean
io.micrometer.prometheus.PrometheusMeterRegistry oldRegistry(CollectorRegistry collectorRegistry) {
return new io.micrometer.prometheus.PrometheusMeterRegistry((k) -> null, collectorRegistry, Clock.SYSTEM);
}
@Bean
CompositeMeterRegistry compositeMeterRegistry(PrometheusMeterRegistry prometheusMeterRegistry,
io.micrometer.prometheus.PrometheusMeterRegistry prometheusSCMeterRegistry) {
CompositeMeterRegistry composite = new CompositeMeterRegistry();
composite.add(prometheusMeterRegistry).add(prometheusSCMeterRegistry);
Counter.builder("counter1").register(composite);
Counter.builder("counter2").register(composite);
Counter.builder("counter3").register(composite);
return composite;
}
@WebEndpoint(id = "prometheussc")
static class CustomPrometheusScrapeEndpoint extends PrometheusSimpleclientScrapeEndpoint {
CustomPrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) {
super(collectorRegistry);
}
}
}
}