From 5293e45825d98ef90ab98b9fe92be9b9ac34674a Mon Sep 17 00:00:00 2001 From: Maria Helena Braga Barnabe Date: Tue, 11 May 2021 09:44:17 -0300 Subject: [PATCH 1/4] Fix Gerrit Trigger not updating the list of gerrit projects automatically. --- .../trigger/GerritProjectListUpdater.java | 2 +- .../plugins/gerrit/trigger/GerritServer.java | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java index f82019eea..01df9a5cb 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java @@ -220,7 +220,7 @@ private void waitFor(long delay) { /** * Try to load entire project list from Gerrit server. */ - private void tryLoadProjectList() { + public void tryLoadProjectList() { int interval = 1; while (!isConnected() && !shutdown) { logger.info("Not connected to {}, waiting for {} second(s)", serverName, interval); diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java index 62c4a6533..8931bc0af 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java @@ -40,6 +40,7 @@ import hudson.model.Descriptor; import hudson.model.Hudson; import hudson.security.Permission; +import hudson.triggers.SafeTimerTask; import hudson.util.FormValidation; import hudson.util.ListBoxModel; import hudson.util.Secret; @@ -136,6 +137,14 @@ public class GerritServer implements Describable, Action { private static final String START_FAILURE = "Error establising conection"; private static final String STOP_SUCCESS = "Connection stopped"; private static final String STOP_FAILURE = "Error terminating connection"; + /** + * Holds the timer initial delay, in minutes, to wait before update the gerrit project list. + */ + private static final int INITIAL_DELAY = 2; + /** + * Holds the frequency period of the timer, in minutes. + */ + private static final int TIMER_PERIOD = 5; /** * Key that is used to select to trigger a build on events from any server. */ @@ -482,6 +491,7 @@ public void start() { projectListUpdater = new GerritProjectListUpdater(name); projectListUpdater.start(); + scheduleProjectListUpdate(projectListUpdater); missedEventsPlaybackManager.checkIfEventsLogPluginSupported(); addListener((GerritEventListener)missedEventsPlaybackManager); @@ -490,6 +500,20 @@ public void start() { started = true; } + /** + * This method creates a timer that schedule the update of gerrit project list. + * + * @param projectListUpdater the project list updater object + */ + public static void scheduleProjectListUpdate(GerritProjectListUpdater projectListUpdater) { + jenkins.util.Timer.get().scheduleAtFixedRate(new SafeTimerTask() { + @Override + protected void doRun() throws Exception { + projectListUpdater.tryLoadProjectList(); + } + }, INITIAL_DELAY, TIMER_PERIOD, TimeUnit.MINUTES); + } + /** * Initializes the Gerrit connection listener for this server. */ From b82142fa3af5bf18320e1d71f748474542390ce2 Mon Sep 17 00:00:00 2001 From: Maria Helena Braga Barnabe Date: Tue, 11 May 2021 09:44:17 -0300 Subject: [PATCH 2/4] Fix Gerrit Trigger not updating the list of gerrit projects automatically. --- .../trigger/GerritProjectListUpdater.java | 97 ++++++++++--------- .../plugins/gerrit/trigger/GerritServer.java | 60 +++--------- ...erritProjectListUpdaterFunctionalTest.java | 5 +- 3 files changed, 72 insertions(+), 90 deletions(-) diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java index 01df9a5cb..c9bc5e5e0 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java @@ -37,6 +37,8 @@ import java.io.Reader; import java.util.ArrayList; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -50,13 +52,20 @@ * * @author Gustaf Lundh <Gustaf.Lundh@sonyericsson.com> */ -public class GerritProjectListUpdater extends Thread implements ConnectionListener, NamedGerritEventListener { +public class GerritProjectListUpdater implements ConnectionListener, NamedGerritEventListener { /** * The command for fetching projects. */ public static final String GERRIT_LS_PROJECTS = "gerrit ls-projects"; private static final int MAX_WAIT_TIME = 64; + /** + * Holds the frequency period of the timer, in minutes. + */ + private static final int TIMER_PERIOD = 5; + + private Timer timer; + private AtomicBoolean connected = new AtomicBoolean(false); private boolean shutdown = false; private static final Logger logger = LoggerFactory.getLogger(GerritProjectListUpdater.class); @@ -68,8 +77,6 @@ public class GerritProjectListUpdater extends Thread implements ConnectionListen * @param serverName the name of the Gerrit server. */ public GerritProjectListUpdater(String serverName) { - this.setName(this.getClass().getName() + " for " + serverName + " Thread"); - this.setDaemon(true); this.serverName = serverName; addThisAsListener(); } @@ -141,58 +148,58 @@ public void gerritEvent(ProjectCreated gerritEvent) { } /** - * Shutdown the thread. + * Initialize project list updater. */ - public synchronized void shutdown() { - shutdown = true; - notify(); - } - - @Override - public void run() { - // Never query this Gerrit-server for project list. - if (!getConfig().isEnableProjectAutoCompletion()) { - return; + public void initProjectListUpdater() { + logger.info("Init project list updater"); + if(timer == null){ + // Never query this Gerrit-server for project list. + if (!getConfig().isEnableProjectAutoCompletion()) { + return; + } + timer = new Timer(serverName); + scheduleProjectListUpdate(getConfig().getProjectListFetchDelay()); } - if (getConfig().getProjectListFetchDelay() == 0) { - tryLoadProjectList(); - } else { - waitFor(getConfig().getProjectListFetchDelay()); - tryLoadProjectList(); + else{ + logger.error("Can't create two timers for the same Gerrit instance: " + serverName); } + } - if (listenToProjectCreatedEvents()) { - logger.info("ProjectCreated events supported by Gerrit Server {}. " - + "Will now listen for new projects...", serverName); - } else { - while (!shutdown) { - waitFor(getConfig().getProjectListRefreshInterval()); - tryLoadProjectList(); + /** + * Cancel project list update timer. + */ + public void cancelProjectListUpdater() { + try { + if (timer != null) { + timer.cancel(); + shutdown = true; + timer = null; + } else { + logger.error("Unable to cancel project list update task because timer is null"); } + } catch (Exception e) { + logger.error("Error canceling project list updater: ", e); } } /** - * Add this as GerritEventListener if project events supported. - * @return true is project created events are supported and listener is added. + * This method creates a timer that schedule the update of the gerrit project list. + * + * @param initDelay the initial delay, in seconds. */ - private boolean listenToProjectCreatedEvents() { - // Listen to project-created events. - PluginImpl plugin = PluginImpl.getInstance(); - if (plugin != null) { - GerritServer server = plugin.getServer(serverName); - if (server != null) { - if (server.isProjectCreatedEventsSupported()) { - // If run was called before. - server.removeListener(this.gerritEventListener()); - server.addListener(this.gerritEventListener()); - return true; + public void scheduleProjectListUpdate(int initDelay) { + logger.info("Start timer to update project list"); + if (timer != null) { + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + tryLoadProjectList(); } - } else { - logger.error("Could not find the server {} to add GerritEventListener.", serverName); - } + }, TimeUnit.SECONDS.toMillis(initDelay), TimeUnit.MINUTES.toMillis(TIMER_PERIOD)); + } + else { + logger.error("Unable to schedule project list update task because timer is null"); } - return false; } /** @@ -220,7 +227,7 @@ private void waitFor(long delay) { /** * Try to load entire project list from Gerrit server. */ - public void tryLoadProjectList() { + private void tryLoadProjectList() { int interval = 1; while (!isConnected() && !shutdown) { logger.info("Not connected to {}, waiting for {} second(s)", serverName, interval); @@ -249,7 +256,7 @@ public void tryLoadProjectList() { sshConnection.disconnect(); } else { logger.warn("Could not connect to Gerrit server when updating Gerrit project list: " - + "Server is not connected (timeout)"); + + "Server is not connected (timeout)"); } } catch (SshException ex) { logger.warn("Could not connect to Gerrit server when updating Gerrit project list: ", ex); diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java index 8931bc0af..8c566f7a1 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer.java @@ -40,7 +40,6 @@ import hudson.model.Descriptor; import hudson.model.Hudson; import hudson.security.Permission; -import hudson.triggers.SafeTimerTask; import hudson.util.FormValidation; import hudson.util.ListBoxModel; import hudson.util.Secret; @@ -137,14 +136,6 @@ public class GerritServer implements Describable, Action { private static final String START_FAILURE = "Error establising conection"; private static final String STOP_SUCCESS = "Connection stopped"; private static final String STOP_FAILURE = "Error terminating connection"; - /** - * Holds the timer initial delay, in minutes, to wait before update the gerrit project list. - */ - private static final int INITIAL_DELAY = 2; - /** - * Holds the frequency period of the timer, in minutes. - */ - private static final int TIMER_PERIOD = 5; /** * Key that is used to select to trigger a build on events from any server. */ @@ -182,7 +173,7 @@ public GerritMissedEventsPlaybackManager getMissedEventsPlaybackManager() { return missedEventsPlaybackManager; } - /** + /** * Convenience method for jelly to get url of the server list's page relative to root. * * @see GerritManagement#getUrlName() @@ -490,8 +481,6 @@ public void start() { projectListUpdater = new GerritProjectListUpdater(name); - projectListUpdater.start(); - scheduleProjectListUpdate(projectListUpdater); missedEventsPlaybackManager.checkIfEventsLogPluginSupported(); addListener((GerritEventListener)missedEventsPlaybackManager); @@ -500,20 +489,6 @@ public void start() { started = true; } - /** - * This method creates a timer that schedule the update of gerrit project list. - * - * @param projectListUpdater the project list updater object - */ - public static void scheduleProjectListUpdate(GerritProjectListUpdater projectListUpdater) { - jenkins.util.Timer.get().scheduleAtFixedRate(new SafeTimerTask() { - @Override - protected void doRun() throws Exception { - projectListUpdater.tryLoadProjectList(); - } - }, INITIAL_DELAY, TIMER_PERIOD, TimeUnit.MINUTES); - } - /** * Initializes the Gerrit connection listener for this server. */ @@ -533,12 +508,7 @@ public void stop() { logger.info("Stopping GerritServer " + name); if (projectListUpdater != null) { - projectListUpdater.shutdown(); - try { - projectListUpdater.join(); - } catch (InterruptedException ie) { - logger.error("project list updater of " + name + "interrupted", ie); - } + projectListUpdater.cancelProjectListUpdater(); projectListUpdater = null; } @@ -628,6 +598,8 @@ public synchronized void startConnection() { } else { logger.warn("Already started!"); } + // Initialize project list update after connection with Gerrit server + projectListUpdater.initProjectListUpdater(); } } @@ -851,11 +823,11 @@ public FormValidation doTestRestConnection( } CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(new AuthScope(null, -1), - new UsernamePasswordCredentials(gerritHttpUserName, - password)); + new UsernamePasswordCredentials(gerritHttpUserName, + password)); HttpClient httpclient = HttpClients.custom() - .setDefaultCredentialsProvider(credsProvider) - .build(); + .setDefaultCredentialsProvider(credsProvider) + .build(); HttpGet httpGet = new HttpGet(restUrl + "a/projects/?d"); HttpResponse execute; try { @@ -884,7 +856,7 @@ public FormValidation doTestRestConnection( * @return list of slaves. */ public ListBoxModel doFillDefaultSlaveIdItems( - @QueryParameter("name") @RelativePath("../..") final String serverName) { + @QueryParameter("name") @RelativePath("../..") final String serverName) { ListBoxModel items = new ListBoxModel(); logger.trace("filling default gerrit slave drop down for sever {}", serverName); GerritServer server = PluginImpl.getServer_(serverName); @@ -895,7 +867,7 @@ public ListBoxModel doFillDefaultSlaveIdItems( } ReplicationConfig replicationConfig = server.getConfig().getReplicationConfig(); if (replicationConfig == null || !replicationConfig.isEnableReplication() - || replicationConfig.getGerritSlaves().size() == 0) { + || replicationConfig.getGerritSlaves().size() == 0) { logger.trace(Messages.GerritSlaveNotDefined()); items.add(Messages.GerritSlaveNotDefined(), ""); return items; @@ -941,7 +913,7 @@ public static Map notificationLevelTextsById() { return textsById; } - /** + /** * Saves the form to the configuration and disk. * @param req StaplerRequest * @param rsp StaplerResponse @@ -949,10 +921,10 @@ public static Map notificationLevelTextsById() { * @throws IOException if something unfortunate happens. * @throws InterruptedException if something unfortunate happens. */ - @RequirePOST + @RequirePOST public void doConfigSubmit(StaplerRequest req, StaplerResponse rsp) throws ServletException, - IOException, - InterruptedException { + IOException, + InterruptedException { checkPermission(); if (logger.isDebugEnabled()) { logger.debug("submit {}", req.toString()); @@ -1297,8 +1269,8 @@ private void setConnectionResponse(String response) { */ @RequirePOST public void doRemoveConfirm(StaplerRequest req, StaplerResponse rsp) throws ServletException, - IOException, - InterruptedException { + IOException, + InterruptedException { checkPermission(); stopConnection(); diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java index 69743806b..ef3331846 100644 --- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java +++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java @@ -37,6 +37,7 @@ import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.recipes.WithTimeout; import static com.sonymobile.tools.gerrit.gerritevents.mock.SshdServerMock.GERRIT_STREAM_EVENTS; //CS IGNORE AvoidStarImport FOR NEXT 1 LINES. REASON: UnitTest. @@ -55,7 +56,8 @@ public class GerritProjectListUpdaterFunctionalTest { public final JenkinsRule j = new JenkinsRule(); private static final int SLEEPTIME = 1; - private static final int LONGSLEEPTIME = 10; + private static final int LONGSLEEPTIME = 310; + private static final int TIMEOUT = 350; private static final long MAXSLEEPTIME = 10; @@ -100,6 +102,7 @@ public void tearDown() throws Exception { * connection startup. * @throws Exception if occurs. */ + @WithTimeout(TIMEOUT) @Test public void testProjectListUpdateActiveOnStartup() throws Exception { GerritServer gerritServer = new GerritServer("ABCDEF"); From 361b7b52161e82e792103789fea4858d4ee7e86d Mon Sep 17 00:00:00 2001 From: Maria Helena Braga Barnabe Date: Tue, 11 May 2021 09:44:17 -0300 Subject: [PATCH 3/4] Fix Gerrit Trigger not updating the list of gerrit projects automatically. --- .../trigger/GerritProjectListUpdaterFunctionalTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java index ef3331846..9c055c865 100644 --- a/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java +++ b/src/test/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdaterFunctionalTest.java @@ -56,8 +56,8 @@ public class GerritProjectListUpdaterFunctionalTest { public final JenkinsRule j = new JenkinsRule(); private static final int SLEEPTIME = 1; - private static final int LONGSLEEPTIME = 310; - private static final int TIMEOUT = 350; + private static final int LONGSLEEPTIME = 320; + private static final int TIMEOUT = 370; private static final long MAXSLEEPTIME = 10; From 1f9b4eb72a6c3308e89283432153976d1b12884c Mon Sep 17 00:00:00 2001 From: Maria Helena Braga Barnabe Date: Tue, 11 May 2021 09:44:17 -0300 Subject: [PATCH 4/4] Fix Gerrit Trigger not updating the list of gerrit projects automatically. --- .../plugins/gerrit/trigger/GerritProjectListUpdater.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java index c9bc5e5e0..e5bea25aa 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritProjectListUpdater.java @@ -152,15 +152,14 @@ public void gerritEvent(ProjectCreated gerritEvent) { */ public void initProjectListUpdater() { logger.info("Init project list updater"); - if(timer == null){ + if (timer == null) { // Never query this Gerrit-server for project list. if (!getConfig().isEnableProjectAutoCompletion()) { return; } timer = new Timer(serverName); scheduleProjectListUpdate(getConfig().getProjectListFetchDelay()); - } - else{ + } else { logger.error("Can't create two timers for the same Gerrit instance: " + serverName); } } @@ -196,8 +195,7 @@ public void run() { tryLoadProjectList(); } }, TimeUnit.SECONDS.toMillis(initDelay), TimeUnit.MINUTES.toMillis(TIMER_PERIOD)); - } - else { + } else { logger.error("Unable to schedule project list update task because timer is null"); } }