Skip to content

Commit

Permalink
Merge pull request #437 from mariahbb1/fix-update-project-list
Browse files Browse the repository at this point in the history
Fix Gerrit Trigger not updating the list of gerrit projects automatically
  • Loading branch information
rsandell committed Sep 9, 2021
2 parents 52d9e72 + 1f9b4eb commit e07fd5a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 65 deletions.
Expand Up @@ -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;

Expand All @@ -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);
Expand All @@ -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();
}
Expand Down Expand Up @@ -141,58 +148,56 @@ 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;
}
if (getConfig().getProjectListFetchDelay() == 0) {
tryLoadProjectList();
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());
} else {
waitFor(getConfig().getProjectListFetchDelay());
tryLoadProjectList();
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;
}

/**
Expand Down Expand Up @@ -249,7 +254,7 @@ private 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);
Expand Down
Expand Up @@ -174,7 +174,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()
Expand Down Expand Up @@ -482,7 +482,6 @@ public void start() {

projectListUpdater =
new GerritProjectListUpdater(name);
projectListUpdater.start();

missedEventsPlaybackManager.checkIfEventsLogPluginSupported();
addListener((GerritEventListener)missedEventsPlaybackManager);
Expand Down Expand Up @@ -510,12 +509,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;
}

Expand Down Expand Up @@ -605,6 +599,8 @@ public synchronized void startConnection() {
} else {
logger.warn("Already started!");
}
// Initialize project list update after connection with Gerrit server
projectListUpdater.initProjectListUpdater();
}
}

Expand Down Expand Up @@ -828,11 +824,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 {
Expand Down Expand Up @@ -861,7 +857,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);
Expand All @@ -872,7 +868,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;
Expand Down Expand Up @@ -918,18 +914,18 @@ public static Map<Notify, String> notificationLevelTextsById() {
return textsById;
}

/**
/**
* Saves the form to the configuration and disk.
* @param req StaplerRequest
* @param rsp StaplerResponse
* @throws ServletException if something unfortunate happens.
* @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());
Expand Down Expand Up @@ -1274,8 +1270,8 @@ private void setConnectionResponse(String response) {
*/
@RequirePOST
public void doRemoveConfirm(StaplerRequest req, StaplerResponse rsp) throws ServletException,
IOException,
InterruptedException {
IOException,
InterruptedException {

checkPermission();
stopConnection();
Expand Down
Expand Up @@ -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.
Expand All @@ -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 = 320;
private static final int TIMEOUT = 370;

private static final long MAXSLEEPTIME = 10;

Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit e07fd5a

Please sign in to comment.