Introduce `PluginDataHandlerProvider` Transition from `PluginDataHandler` to `PluginDataHandlerProvider` to broaden the application of persistent plugin data across different scopes. Initially, only a Global scope is supported, but the addition of Project and Change Set scopes is planned in future commits to support ongoing developments and issue resolutions. Change-Id: I1ed78760a6a86b5df89c27a1823b1940acd27b89 Signed-off-by: Patrizio <patrizio.gelosi@amarulasolutions.com>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandler.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandler.java index 09cfba1..c3f92dc 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandler.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandler.java
@@ -14,8 +14,8 @@ private final Properties configProperties = new Properties(); @Inject - public PluginDataHandler(@com.google.gerrit.extensions.annotations.PluginData Path pluginDataDir) { - this.configFile = pluginDataDir.resolve("plugin.config"); + public PluginDataHandler(Path configFilePath) { + this.configFile = configFilePath; try { loadOrCreateProperties(); } catch (IOException e) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandlerProvider.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandlerProvider.java new file mode 100644 index 0000000..f7366ca --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/data/PluginDataHandlerProvider.java
@@ -0,0 +1,26 @@ +package com.googlesource.gerrit.plugins.chatgpt.data; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; + +import java.nio.file.Path; + +@Singleton +public class PluginDataHandlerProvider implements Provider<PluginDataHandler> { + private final Path defaultPluginDataPath; + + @Inject + public PluginDataHandlerProvider(@com.google.gerrit.extensions.annotations.PluginData Path defaultPluginDataPath) { + this.defaultPluginDataPath = defaultPluginDataPath; + } + + public PluginDataHandler get(Path configPath) { + return new PluginDataHandler(configPath); + } + + @Override + public PluginDataHandler get() { + return get(defaultPluginDataPath.resolve("plugin.config")); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/GerritEventContextModule.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/GerritEventContextModule.java index 0d76a17..4384b40 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/GerritEventContextModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/listener/GerritEventContextModule.java
@@ -2,8 +2,11 @@ import com.google.gerrit.extensions.config.FactoryModule; import com.google.gerrit.server.events.Event; +import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; import com.googlesource.gerrit.plugins.chatgpt.data.ChangeSetDataProvider; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange; import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.data.ChangeSetData; import com.googlesource.gerrit.plugins.chatgpt.mode.interfaces.client.api.chatgpt.IChatGptClient; @@ -32,6 +35,7 @@ bind(Configuration.class).toInstance(config); bind(GerritChange.class).toInstance(new GerritChange(event)); bind(ChangeSetData.class).toProvider(ChangeSetDataProvider.class).in(SINGLETON); + bind(PluginDataHandler.class).toProvider(PluginDataHandlerProvider.class).in(Singleton.class); } private Class<? extends IChatGptClient> getChatGptMode() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptAssistant.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptAssistant.java index 2fd2771..7fc146c 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptAssistant.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptAssistant.java
@@ -2,6 +2,7 @@ import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.ClientBase; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptParameters; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptTools; @@ -30,12 +31,16 @@ private final GitRepoFiles gitRepoFiles; private final PluginDataHandler pluginDataHandler; - public ChatGptAssistant(Configuration config, GerritChange change, GitRepoFiles gitRepoFiles, - PluginDataHandler pluginDataHandler) { + public ChatGptAssistant( + Configuration config, + GerritChange change, + GitRepoFiles gitRepoFiles, + PluginDataHandlerProvider pluginDataHandlerProvider + ) { super(config); this.change = change; this.gitRepoFiles = gitRepoFiles; - this.pluginDataHandler = pluginDataHandler; + this.pluginDataHandler = pluginDataHandlerProvider.get(); } public void setupAssistant() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptClientStateful.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptClientStateful.java index 6e5944d..5d652bb 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptClientStateful.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptClientStateful.java
@@ -4,7 +4,7 @@ import com.google.inject.Inject; import com.google.inject.Singleton; import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; -import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.chatgpt.ChatGptClient; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange; import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.api.chatgpt.ChatGptResponseContent; @@ -15,13 +15,13 @@ @Slf4j @Singleton public class ChatGptClientStateful extends ChatGptClient implements IChatGptClient { - private final PluginDataHandler pluginDataHandler; + private final PluginDataHandlerProvider pluginDataHandlerProvider; @VisibleForTesting @Inject - public ChatGptClientStateful(PluginDataHandler pluginDataHandler) { + public ChatGptClientStateful(PluginDataHandlerProvider pluginDataHandlerProvider) { super(); - this.pluginDataHandler = pluginDataHandler; + this.pluginDataHandlerProvider = pluginDataHandlerProvider; } public ChatGptResponseContent ask(Configuration config, ChangeSetData changeSetData, GerritChange change, String patchSet) { @@ -33,7 +33,7 @@ String threadId = chatGptThread.createThread(); chatGptThread.addMessage(); - ChatGptRun chatGptRun = new ChatGptRun(threadId, config, pluginDataHandler); + ChatGptRun chatGptRun = new ChatGptRun(threadId, config, pluginDataHandlerProvider); chatGptRun.createRun(); chatGptRun.pollRun(); // Attribute `requestBody` is valued for testing purposes
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptRun.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptRun.java index 9be6680..466afa1 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptRun.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/chatgpt/ChatGptRun.java
@@ -2,6 +2,7 @@ import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.ClientBase; import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.api.chatgpt.ChatGptToolCall; import com.googlesource.gerrit.plugins.chatgpt.mode.stateful.client.api.UriResourceLocatorStateful; @@ -32,10 +33,10 @@ private ChatGptResponse runResponse; private ChatGptListResponse stepResponse; - public ChatGptRun(String threadId, Configuration config, PluginDataHandler pluginDataHandler) { + public ChatGptRun(String threadId, Configuration config, PluginDataHandlerProvider pluginDataHandlerProvider) { super(config); this.threadId = threadId; - this.pluginDataHandler = pluginDataHandler; + this.pluginDataHandler = pluginDataHandlerProvider.get(); } public void createRun() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/gerrit/GerritClientPatchSetStateful.java b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/gerrit/GerritClientPatchSetStateful.java index 502bac0..7c66e56 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/gerrit/GerritClientPatchSetStateful.java +++ b/src/main/java/com/googlesource/gerrit/plugins/chatgpt/mode/stateful/client/api/gerrit/GerritClientPatchSetStateful.java
@@ -5,7 +5,7 @@ import com.google.gerrit.server.util.ManualRequestContext; import com.google.inject.Inject; import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; -import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.data.ChangeSetData; import com.googlesource.gerrit.plugins.chatgpt.mode.stateful.client.api.chatgpt.ChatGptAssistant; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange; @@ -28,7 +28,7 @@ Pattern.MULTILINE); private final GitRepoFiles gitRepoFiles; - private final PluginDataHandler pluginDataHandler; + private final PluginDataHandlerProvider pluginDataHandlerProvider; private GerritChange change; @@ -38,15 +38,15 @@ Configuration config, AccountCache accountCache, GitRepoFiles gitRepoFiles, - PluginDataHandler pluginDataHandler) { + PluginDataHandlerProvider pluginDataHandlerProvider) { super(config, accountCache); this.gitRepoFiles = gitRepoFiles; - this.pluginDataHandler = pluginDataHandler; + this.pluginDataHandlerProvider = pluginDataHandlerProvider; } public String getPatchSet(ChangeSetData changeSetData, GerritChange change) throws Exception { this.change = change; - ChatGptAssistant chatGptAssistant = new ChatGptAssistant(config, change, gitRepoFiles, pluginDataHandler); + ChatGptAssistant chatGptAssistant = new ChatGptAssistant(config, change, gitRepoFiles, pluginDataHandlerProvider); chatGptAssistant.setupAssistant(); String formattedPatch = getPatchFromGerrit();
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewStatefulTest.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewStatefulTest.java index 3be3d8f..02f16c5 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewStatefulTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewStatefulTest.java
@@ -8,6 +8,7 @@ import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gson.JsonObject; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; import com.googlesource.gerrit.plugins.chatgpt.mode.common.model.api.chatgpt.ChatGptResponseContent; import com.googlesource.gerrit.plugins.chatgpt.mode.stateful.client.api.UriResourceLocatorStateful; import com.googlesource.gerrit.plugins.chatgpt.mode.stateful.client.prompt.ChatGptPromptStateful; @@ -19,6 +20,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnitRunner; @@ -49,6 +51,9 @@ private ChatGptPromptStateful chatGptPromptStateful; private JsonObject threadMessage; + @Mock + protected PluginDataHandler pluginDataHandler; + public ChatGptReviewStatefulTest() { MockitoAnnotations.openMocks(this); } @@ -59,6 +64,9 @@ // Mock the Global Config values that differ from the ones provided by Default when(globalConfig.getString(Mockito.eq("gptMode"), Mockito.anyString())) .thenReturn(MODES.stateful.name()); + + // Mock the pluginDataHandlerProvider to return the mocked pluginDataHandler + when(pluginDataHandlerProvider.get()).thenReturn(pluginDataHandler); } protected void initConfig() {
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTestBase.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTestBase.java index fd316e0..393a87f 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTestBase.java +++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/ChatGptReviewTestBase.java
@@ -29,13 +29,12 @@ import com.google.gson.JsonObject; import com.google.inject.AbstractModule; import com.google.inject.Guice; -import com.googlesource.gerrit.plugins.chatgpt.config.ConfigCreator; -import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; -import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; -import com.googlesource.gerrit.plugins.chatgpt.listener.EventHandlerTask; -import com.googlesource.gerrit.plugins.chatgpt.listener.GerritEventContextModule; import com.google.inject.TypeLiteral; import com.google.inject.util.Providers; +import com.googlesource.gerrit.plugins.chatgpt.config.ConfigCreator; +import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; +import com.googlesource.gerrit.plugins.chatgpt.listener.EventHandlerTask; import com.googlesource.gerrit.plugins.chatgpt.localization.Localizer; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritChange; import com.googlesource.gerrit.plugins.chatgpt.mode.common.client.api.gerrit.GerritClient; @@ -102,7 +101,7 @@ protected GitRepoFiles gitRepoFiles; @Mock - protected PluginDataHandler pluginDataHandler; + protected PluginDataHandlerProvider pluginDataHandlerProvider; @Mock protected OneOffRequestContext context; @@ -278,13 +277,13 @@ EventHandlerTask task = Guice.createInjector(new AbstractModule() { @Override protected void configure() { - install(new GerritEventContextModule(config, event)); + install(new TestGerritEventContextModule(config, event)); bind(GerritClient.class).toInstance(gerritClient); bind(GitRepoFiles.class).toInstance(gitRepoFiles); bind(ConfigCreator.class).toInstance(mockConfigCreator); bind(PatchSetReviewer.class).toInstance(patchSetReviewer); - bind(PluginDataHandler.class).toInstance(pluginDataHandler); + bind(PluginDataHandlerProvider.class).toInstance(pluginDataHandlerProvider); bind(AccountCache.class).toInstance(mockAccountCache()); } }).getInstance(EventHandlerTask.class); @@ -378,14 +377,14 @@ private IChatGptClient getChatGptClient() { return switch (config.getGptMode()) { - case stateful -> new ChatGptClientStateful(pluginDataHandler); + case stateful -> new ChatGptClientStateful(pluginDataHandlerProvider); case stateless -> new ChatGptClientStateless(); }; } private IGerritClientPatchSet getGerritClientPatchSet() { return switch (config.getGptMode()) { - case stateful -> new GerritClientPatchSetStateful(config, accountCacheMock, gitRepoFiles, pluginDataHandler); + case stateful -> new GerritClientPatchSetStateful(config, accountCacheMock, gitRepoFiles, pluginDataHandlerProvider); case stateless -> new GerritClientPatchSetStateless(config, accountCacheMock); }; }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PluginDataTest.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PluginDataTest.java index 0823fec..5bdc08f 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PluginDataTest.java +++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/PluginDataTest.java
@@ -7,6 +7,7 @@ import java.nio.file.Path; import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandler; +import com.googlesource.gerrit.plugins.chatgpt.data.PluginDataHandlerProvider; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -36,7 +37,8 @@ @Test public void testValueSetAndGet() { - PluginDataHandler handler = new PluginDataHandler(mockPluginDataPath); + PluginDataHandlerProvider provider = new PluginDataHandlerProvider(mockPluginDataPath); + PluginDataHandler handler = provider.get(); String key = "testKey"; String value = "testValue"; @@ -50,7 +52,8 @@ @Test public void testRemoveValue() { - PluginDataHandler handler = new PluginDataHandler(mockPluginDataPath); + PluginDataHandlerProvider provider = new PluginDataHandlerProvider(mockPluginDataPath); + PluginDataHandler handler = provider.get(); String key = "testKey"; String value = "testValue"; @@ -69,7 +72,8 @@ // Ensure the file doesn't exist before creating the handler Files.deleteIfExists(realPluginDataPath); - new PluginDataHandler(mockPluginDataPath); + PluginDataHandlerProvider provider = new PluginDataHandlerProvider(mockPluginDataPath); + provider.get(); // The constructor should create the file if it doesn't exist assertTrue("The config file should exist after initializing the handler.", Files.exists(realPluginDataPath));
diff --git a/src/test/java/com/googlesource/gerrit/plugins/chatgpt/TestGerritEventContextModule.java b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/TestGerritEventContextModule.java new file mode 100644 index 0000000..7506e9a --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/chatgpt/TestGerritEventContextModule.java
@@ -0,0 +1,23 @@ +package com.googlesource.gerrit.plugins.chatgpt; + +import com.google.gerrit.extensions.annotations.PluginData; +import com.google.gerrit.server.events.Event; +import com.google.inject.Provides; +import com.googlesource.gerrit.plugins.chatgpt.config.Configuration; +import com.googlesource.gerrit.plugins.chatgpt.listener.GerritEventContextModule; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class TestGerritEventContextModule extends GerritEventContextModule { + + public TestGerritEventContextModule(Configuration config, Event event) { + super(config, event); + } + + @Provides + @PluginData + Path providePluginDataPath() { + return Paths.get(System.getProperty("pluginDataPath", "test-plugin-data")); + } +}