diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java b/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java deleted file mode 100644 index 5d51634f9..000000000 --- a/src/main/java/org/jenkinsci/plugins/prometheus/context/Context.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.jenkinsci.plugins.prometheus.context; - -import com.google.inject.AbstractModule; -import hudson.Extension; -import org.jenkinsci.plugins.prometheus.service.DefaultPrometheusMetrics; -import org.jenkinsci.plugins.prometheus.service.PrometheusMetrics; - -@Extension -public class Context extends AbstractModule { - - @Override - public void configure() { - bind(PrometheusMetrics.class).to(DefaultPrometheusMetrics.class).in(com.google.inject.Singleton.class); - } - -} diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java index 5e8f38d10..35d164546 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/rest/PrometheusAction.java @@ -1,7 +1,7 @@ package org.jenkinsci.plugins.prometheus.rest; -import com.google.inject.Inject; import hudson.Extension; +import hudson.ExtensionList; import hudson.model.UnprotectedRootAction; import hudson.util.HttpResponses; import io.prometheus.client.exporter.common.TextFormat; @@ -15,14 +15,7 @@ @Extension public class PrometheusAction implements UnprotectedRootAction { - - private PrometheusMetrics prometheusMetrics; - - @Inject - public void setPrometheusMetrics(PrometheusMetrics prometheusMetrics) { - this.prometheusMetrics = prometheusMetrics; - } - + @Override public String getIconFileName() { return null; @@ -56,6 +49,7 @@ private boolean hasAccess() { } private HttpResponse prometheusResponse() { + PrometheusMetrics prometheusMetrics = ExtensionList.lookupSingleton(PrometheusMetrics.class); return (request, response, node) -> { response.setStatus(StaplerResponse.SC_OK); response.setContentType(TextFormat.CONTENT_TYPE_004); diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java index 71210e13a..e1f53fb23 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java @@ -1,5 +1,6 @@ package org.jenkinsci.plugins.prometheus.service; +import hudson.Extension; import hudson.ExtensionList; import hudson.init.InitMilestone; import hudson.init.Initializer; @@ -8,15 +9,8 @@ import io.prometheus.client.dropwizard.DropwizardExports; import io.prometheus.client.exporter.common.TextFormat; import io.prometheus.client.hotspot.DefaultExports; -import java.io.IOException; -import java.io.StringWriter; -import java.util.concurrent.atomic.AtomicReference; import jenkins.metrics.api.Metrics; -import org.jenkinsci.plugins.prometheus.CodeCoverageCollector; -import org.jenkinsci.plugins.prometheus.DiskUsageCollector; -import org.jenkinsci.plugins.prometheus.ExecutorCollector; -import org.jenkinsci.plugins.prometheus.JenkinsStatusCollector; -import org.jenkinsci.plugins.prometheus.JobCollector; +import org.jenkinsci.plugins.prometheus.*; import org.jenkinsci.plugins.prometheus.config.disabledmetrics.FilteredMetricEnumeration; import org.jenkinsci.plugins.prometheus.util.JenkinsNodeBuildsSampleBuilder; import org.kohsuke.accmod.Restricted; @@ -24,10 +18,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.StringWriter; +import java.util.concurrent.atomic.AtomicReference; + @Restricted(NoExternalUse.class) +@Extension public class DefaultPrometheusMetrics implements PrometheusMetrics { - private static final Logger logger = LoggerFactory.getLogger(DefaultPrometheusMetrics.class); + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPrometheusMetrics.class); private volatile boolean initialized = false; private volatile boolean initializing = false; @@ -40,10 +39,10 @@ public DefaultPrometheusMetrics() { } @Initializer(after = InitMilestone.JOB_LOADED) - public void init() { + public void registerCollectors() { if (!initialized && !initializing) { initializing = true; - logger.debug("Initializing..."); + LOGGER.debug("Initializing..."); collectorRegistry.register(new JobCollector()); collectorRegistry.register(new JenkinsStatusCollector()); collectorRegistry.register( @@ -67,14 +66,14 @@ public String getMetrics() { @Override public void collectMetrics() { if(!initialized) { - logger.debug("Not initialized"); + LOGGER.debug("Not initialized"); return; } try (StringWriter buffer = new StringWriter()) { TextFormat.write004(buffer, new FilteredMetricEnumeration(collectorRegistry.metricFamilySamples().asIterator())); cachedMetrics.set(buffer.toString()); } catch (IOException e) { - logger.debug("Unable to collect metrics"); + LOGGER.debug("Unable to collect metrics"); } } } diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java index 295517108..b0aa93de1 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorker.java @@ -1,7 +1,7 @@ package org.jenkinsci.plugins.prometheus.service; -import com.google.inject.Inject; import hudson.Extension; +import hudson.ExtensionList; import hudson.model.AsyncPeriodicWork; import hudson.model.TaskListener; import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration; @@ -16,16 +16,11 @@ public class PrometheusAsyncWorker extends AsyncPeriodicWork { private static final Logger logger = LoggerFactory.getLogger(PrometheusAsyncWorker.class); - private PrometheusMetrics prometheusMetrics; public PrometheusAsyncWorker() { super("prometheus_async_worker"); } - @Inject - public void setPrometheusMetrics(PrometheusMetrics prometheusMetrics) { - this.prometheusMetrics = prometheusMetrics; - } @Override public long getRecurrencePeriod() { @@ -38,6 +33,7 @@ public long getRecurrencePeriod() { @Override public void execute(TaskListener taskListener) { logger.debug("Collecting prometheus metrics"); + PrometheusMetrics prometheusMetrics = ExtensionList.lookupSingleton(PrometheusMetrics.class); prometheusMetrics.collectMetrics(); logger.debug("Prometheus metrics collected successfully"); } diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java index fd5103ecb..9dadc68e8 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/PrometheusMetrics.java @@ -1,6 +1,8 @@ package org.jenkinsci.plugins.prometheus.service; -public interface PrometheusMetrics { +import hudson.ExtensionPoint; + +public interface PrometheusMetrics extends ExtensionPoint { String getMetrics(); diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java deleted file mode 100644 index ea8d9358b..000000000 --- a/src/test/java/org/jenkinsci/plugins/prometheus/context/ContextTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.jenkinsci.plugins.prometheus.context; - -import com.codahale.metrics.MetricRegistry; -import com.google.inject.Guice; -import com.google.inject.Injector; -import jenkins.metrics.api.Metrics; -import jenkins.model.Jenkins; -import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration; -import org.jenkinsci.plugins.prometheus.service.DefaultPrometheusMetrics; -import org.jenkinsci.plugins.prometheus.service.PrometheusMetrics; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; - -import static org.mockito.Mockito.*; - -public class ContextTest { - - @Test - public void testCanInjectContext() { - try (MockedStatic jenkinsStatic = mockStatic(Jenkins.class); - MockedStatic prometheusConfigurationStatic = mockStatic(PrometheusConfiguration.class); - MockedStatic metricsStatic = mockStatic(Metrics.class)) { - Jenkins mockedJenkins = mock(Jenkins.class); - jenkinsStatic.when(Jenkins::get).thenReturn(mockedJenkins); - - MetricRegistry mockedMetrics = mock(MetricRegistry.class); - metricsStatic.when(Metrics::metricRegistry).thenReturn(mockedMetrics); - - PrometheusConfiguration mockedPrometheusConfiguration = mock(PrometheusConfiguration.class); - when(mockedPrometheusConfiguration.getLabeledBuildParameterNamesAsArray()).thenReturn(new String[]{}); - when(mockedPrometheusConfiguration.getDefaultNamespace()).thenReturn("default"); - prometheusConfigurationStatic.when(PrometheusConfiguration::get).thenReturn(mockedPrometheusConfiguration); - - Injector injector = Guice.createInjector(new Context()); - PrometheusMetrics prometheusMetrics = injector.getInstance(PrometheusMetrics.class); - - Assertions.assertNotNull(prometheusMetrics); - Assertions.assertEquals(DefaultPrometheusMetrics.class, prometheusMetrics.getClass()); - - PrometheusMetrics prometheusMetrics2 = injector.getInstance(PrometheusMetrics.class); - - Assertions.assertEquals(prometheusMetrics, prometheusMetrics2, "Should be the same as it's a singleton!"); - - - } - - } - -} \ No newline at end of file diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java index 58bc253e0..b750b6739 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/rest/PrometheusActionTest.java @@ -1,5 +1,6 @@ package org.jenkinsci.plugins.prometheus.rest; +import hudson.ExtensionList; import io.prometheus.client.exporter.common.TextFormat; import jenkins.metrics.api.Metrics; import jenkins.model.Jenkins; @@ -91,21 +92,24 @@ public void shouldReturnMetrics() throws IOException, ServletException { PrometheusMetrics prometheusMetrics = mock(PrometheusMetrics.class); String responseBody = "testMetric"; when(prometheusMetrics.getMetrics()).thenReturn(responseBody); - action.setPrometheusMetrics(prometheusMetrics); - StaplerRequest request = mock(StaplerRequest.class); - String url = "prometheus"; - when(request.getRestOfPath()).thenReturn(url); - - // when - HttpResponse actual = action.doDynamic(request); + try (MockedStatic extensionListMockedStatic = mockStatic(ExtensionList.class)) { + extensionListMockedStatic.when(() -> ExtensionList.lookupSingleton(PrometheusMetrics.class)).thenReturn(prometheusMetrics); + StaplerRequest request = mock(StaplerRequest.class); + String url = "prometheus"; + when(request.getRestOfPath()).thenReturn(url); + + // when + HttpResponse actual = action.doDynamic(request); + + // then + AssertStaplerResponse.from(actual) + .call() + .assertHttpStatus(HTTP_OK) + .assertContentType(TextFormat.CONTENT_TYPE_004) + .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store") + .assertBody(responseBody); + } - // then - AssertStaplerResponse.from(actual) - .call() - .assertHttpStatus(HTTP_OK) - .assertContentType(TextFormat.CONTENT_TYPE_004) - .assertHttpHeader("Cache-Control", "must-revalidate,no-cache,no-store") - .assertBody(responseBody); } private static class AssertStaplerResponse { diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java index 8ba367784..2d6e9116e 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/service/PrometheusAsyncWorkerTest.java @@ -1,5 +1,6 @@ package org.jenkinsci.plugins.prometheus.service; +import hudson.ExtensionList; import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration; import org.junit.jupiter.api.Test; import org.jvnet.hudson.test.Issue; @@ -20,15 +21,15 @@ public void shouldCollectMetrics() { // given PrometheusAsyncWorker asyncWorker = new PrometheusAsyncWorker(); PrometheusMetrics metrics = new TestPrometheusMetrics(); - asyncWorker.setPrometheusMetrics(metrics); - - // when - asyncWorker.execute(null); - - // then - String actual = metrics.getMetrics(); - assertEquals("1", actual); + try (MockedStatic extensionListMockedStatic = mockStatic(ExtensionList.class)) { + extensionListMockedStatic.when(() -> ExtensionList.lookupSingleton(PrometheusMetrics.class)).thenReturn(metrics); + // when + asyncWorker.execute(null); + // then + String actual = metrics.getMetrics(); + assertEquals("1", actual); + } } @Test public void testConvertSecondsToMillis() {