From 643212e2d297dd1cfaa4697ef65905a01fd4d2f8 Mon Sep 17 00:00:00 2001 From: Ben Donnelly Date: Fri, 15 Dec 2023 18:04:36 +0000 Subject: [PATCH 1/2] feat(plugin): add new api for plugin registration in api - needed for scenarios where SPI is not an option --- .../com/intergral/deep/agent/api/IDeep.java | 9 ++++++ .../com/intergral/deep/agent/DeepAgent.java | 7 ++++ .../deep/agent/settings/Settings.java | 32 +++++++++++++++++-- .../intergral/deep/agent/DeepAgentTest.java | 14 ++++++++ .../deep/agent/settings/SettingsTest.java | 32 +++++++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) diff --git a/agent-api/src/main/java/com/intergral/deep/agent/api/IDeep.java b/agent-api/src/main/java/com/intergral/deep/agent/api/IDeep.java index b185178..5be9a99 100644 --- a/agent-api/src/main/java/com/intergral/deep/agent/api/IDeep.java +++ b/agent-api/src/main/java/com/intergral/deep/agent/api/IDeep.java @@ -18,6 +18,7 @@ package com.intergral.deep.agent.api; import com.intergral.deep.agent.api.plugin.MetricDefinition; +import com.intergral.deep.agent.api.spi.IDeepPlugin; import com.intergral.deep.agent.api.tracepoint.ITracepoint.ITracepointRegistration; import java.util.Collection; import java.util.Map; @@ -55,6 +56,14 @@ public interface IDeep { */ String getVersion(); + /** + * This allows the registration of custom plugins. + * + * @param plugin the plugin that can be used to decorate snapshots + * @return a {@link IRegistration} that can be used to unregister the plugin + */ + IRegistration registerPlugin(final IDeepPlugin plugin); + /** * Create a tracepoint that will only exist on this instance. * diff --git a/agent/src/main/java/com/intergral/deep/agent/DeepAgent.java b/agent/src/main/java/com/intergral/deep/agent/DeepAgent.java index 304ef04..4425501 100644 --- a/agent/src/main/java/com/intergral/deep/agent/DeepAgent.java +++ b/agent/src/main/java/com/intergral/deep/agent/DeepAgent.java @@ -19,6 +19,7 @@ import com.intergral.deep.agent.api.DeepVersion; import com.intergral.deep.agent.api.IDeep; +import com.intergral.deep.agent.api.IRegistration; import com.intergral.deep.agent.api.plugin.MetricDefinition; import com.intergral.deep.agent.api.resource.Resource; import com.intergral.deep.agent.api.spi.IDeepPlugin; @@ -84,6 +85,12 @@ public String getVersion() { return DeepVersion.VERSION; } + @Override + public IRegistration registerPlugin(final IDeepPlugin plugin) { + plugin.configure(this.settings, Reflection.getInstance()); + return this.settings.addPlugin(plugin); + } + @Override public ITracepointRegistration registerTracepoint(final String path, final int line) { return registerTracepoint(path, line, Collections.emptyMap(), Collections.emptyList(), Collections.emptyList()); diff --git a/agent/src/main/java/com/intergral/deep/agent/settings/Settings.java b/agent/src/main/java/com/intergral/deep/agent/settings/Settings.java index c026dfa..8a6c97d 100644 --- a/agent/src/main/java/com/intergral/deep/agent/settings/Settings.java +++ b/agent/src/main/java/com/intergral/deep/agent/settings/Settings.java @@ -17,6 +17,7 @@ package com.intergral.deep.agent.settings; +import com.intergral.deep.agent.api.IRegistration; import com.intergral.deep.agent.api.logger.ITracepointLogger; import com.intergral.deep.agent.api.logger.TracepointLogger; import com.intergral.deep.agent.api.resource.Resource; @@ -51,7 +52,7 @@ public class Settings implements ISettings { private static final AtomicBoolean IS_ACTIVE = new AtomicBoolean(true); private final Properties properties; private Resource resource; - private Collection plugins = Collections.emptyList(); + private final Collection plugins = new ArrayList<>(); private ITracepointLogger tracepointLogger = new TracepointLogger(); private Settings(Properties properties) { @@ -321,7 +322,7 @@ public List getAsList(final String key) { * @return the discovered plugin with the given name, or {@code null} if a plugin with the provided name and type cannot be found. */ public T getPluginByName(final Class clazz, final String name) { - final Collection plugins = getPlugins(clazz, t -> t.getClass().getName().endsWith(name)); + final Collection plugins = getPlugins(clazz, t -> t.getClass().getName().equals(name)); if (plugins.isEmpty()) { return null; } @@ -364,7 +365,8 @@ private Collection getPlugins(final Class target, final Predicate p * @param plugins the plugins to use */ public void setPlugins(Collection plugins) { - this.plugins = plugins; + this.plugins.clear(); + this.plugins.addAll(plugins); } /** @@ -419,6 +421,30 @@ public void setTracepointLogger(final ITracepointLogger tracepointLogger) { this.tracepointLogger = tracepointLogger; } + /** + * Add a plugin to the current config. + * + * @param plugin the new plugin + * @return the plugin registration + */ + public IRegistration addPlugin(final IDeepPlugin plugin) { + this.plugins.add(plugin); + return new IRegistration() { + @Override + public void unregister() { + final boolean removeIf = Settings.this.plugins.removeIf(existing -> existing == plugin); + if (!removeIf) { + throw new IllegalStateException(String.format("cannot remove plugin: %s", plugin)); + } + } + + @Override + public IDeepPlugin get() { + return plugin; + } + }; + } + /** * Used to indicate an invalid config value. */ diff --git a/agent/src/test/java/com/intergral/deep/agent/DeepAgentTest.java b/agent/src/test/java/com/intergral/deep/agent/DeepAgentTest.java index f49406c..9bb2c84 100644 --- a/agent/src/test/java/com/intergral/deep/agent/DeepAgentTest.java +++ b/agent/src/test/java/com/intergral/deep/agent/DeepAgentTest.java @@ -24,6 +24,8 @@ import static org.mockito.Mockito.times; import com.intergral.deep.agent.api.DeepVersion; +import com.intergral.deep.agent.api.IRegistration; +import com.intergral.deep.agent.api.spi.IDeepPlugin; import com.intergral.deep.agent.api.tracepoint.ITracepoint; import com.intergral.deep.agent.api.tracepoint.ITracepoint.ITracepointRegistration; import com.intergral.deep.agent.settings.Settings; @@ -79,7 +81,19 @@ void start_shouldSetPluginsAndResource() throws IOException { Mockito.verify(settings).setPlugins(Mockito.anyCollection()); Mockito.verify(settings).setResource(Mockito.any()); + } + + @Test + void registerPlugin() { + //noinspection unchecked + final IRegistration iRegistration = Mockito.mock(IRegistration.class); + Mockito.when(settings.addPlugin(Mockito.any())).thenReturn(iRegistration); + + final IDeepPlugin deepPlugin = Mockito.mock(IDeepPlugin.class); + deepAgent.registerPlugin(deepPlugin); + Mockito.verify(settings, times(1)).addPlugin(Mockito.any()); + Mockito.verify(deepPlugin, times(1)).configure(settings, Reflection.getInstance()); } @Test diff --git a/agent/src/test/java/com/intergral/deep/agent/settings/SettingsTest.java b/agent/src/test/java/com/intergral/deep/agent/settings/SettingsTest.java index 7a92cc8..02b2a1f 100644 --- a/agent/src/test/java/com/intergral/deep/agent/settings/SettingsTest.java +++ b/agent/src/test/java/com/intergral/deep/agent/settings/SettingsTest.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import com.intergral.deep.agent.api.IRegistration; import com.intergral.deep.agent.api.logger.ITracepointLogger; import com.intergral.deep.agent.api.plugin.IMetricProcessor; import com.intergral.deep.agent.api.spi.IDeepPlugin; @@ -177,6 +178,32 @@ void plugins() { assertNull(notFound); } + @Test + void addPlugin() { + final Settings settings = Settings.build(new HashMap<>()); + + final TestPlugin plugin = new TestPlugin(); + final IRegistration iDeepPluginIRegistration = settings.addPlugin(plugin); + + assertNotNull(iDeepPluginIRegistration.get()); + + assertSame(plugin, iDeepPluginIRegistration.get()); + + assertEquals(1, settings.getPlugins().size()); + + assertNotNull(settings.getPluginByName(TestPlugin.class, TestPlugin.class.getName())); + + iDeepPluginIRegistration.unregister(); + + assertEquals(0, settings.getPlugins().size()); + + assertNull(settings.getPluginByName(TestPlugin.class, TestPlugin.class.getName())); + + final IllegalStateException illegalStateException = assertThrows(IllegalStateException.class, iDeepPluginIRegistration::unregister); + assertEquals("cannot remove plugin: TestPlugin{}", illegalStateException.getMessage()); + + } + private static class TestPlugin implements IDeepPlugin, IMetricProcessor, ITracepointLogger { @Override @@ -207,5 +234,10 @@ public void summary(final String name, final Map labels, final S public void logTracepoint(final String logMsg, final String tracepointId, final String snapshotId) { } + + @Override + public String toString() { + return "TestPlugin{}"; + } } } \ No newline at end of file From 573d322bd90097981d97156a040e8b76bd4563ef Mon Sep 17 00:00:00 2001 From: Ben Donnelly Date: Fri, 15 Dec 2023 19:35:38 +0000 Subject: [PATCH 2/2] feat(plugin): add new api for plugin registration in api - needed for scenarios where SPI is not an option --- .github/workflows/update_docs.yml | 2 +- CHANGELOG.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update_docs.yml b/.github/workflows/update_docs.yml index 768d3b0..8c3909b 100644 --- a/.github/workflows/update_docs.yml +++ b/.github/workflows/update_docs.yml @@ -50,7 +50,7 @@ jobs: uses: robinraju/release-downloader@v1.8 with: latest: true - fileName: Maven Site + fileName: Maven.Site - name: Unpack run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 06e7014..76ea738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # main - Unreleased - +- **[CHANGE]**: plugin: Add new API for registering plugins [#84](https://github.com/intergral/deep/pull/84) [@Umaaz](https://github.com/Umaaz) # 1.1.3 (15/12/2023) -- **[CHANGE]**: update: Update deep proto to 1.0.3 [#74](https://github.com/intergral/deep/pull/74) [@Umaaz](https://github.com/Umaaz) +- **[CHANGE]**: update: Update deep proto to 1.0.3 [#74](https://github.com/intergral/deep/pull/74) [@Umaaz](https://github.com/Umaaz) - **[CHANGE]**: plugin: Change the plugins to use SPI to load [#77](https://github.com/intergral/deep/pull/77) [@Umaaz](https://github.com/Umaaz) - **[FEATURE]**: metrics: Add support for metrics from tracepoints [#74](https://github.com/intergral/deep/pull/74) [@Umaaz](https://github.com/Umaaz)