diff --git a/pom.xml b/pom.xml index b09cca522..0c8609e6f 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ com.sonymobile.tools.gerrit gerrit-events - 2.22.0 + 2.23.0 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 51ae6e2de..8ab184387 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 @@ -24,6 +24,7 @@ package com.sonyericsson.hudson.plugins.gerrit.trigger; import com.sonyericsson.hudson.plugins.gerrit.trigger.utils.StringUtil; +import hudson.Functions; import com.sonymobile.tools.gerrit.gerritevents.ConnectionListener; import com.sonymobile.tools.gerrit.gerritevents.GerritEventListener; import com.sonymobile.tools.gerrit.gerritevents.dto.GerritEvent; @@ -34,14 +35,29 @@ import com.sonyericsson.hudson.plugins.gerrit.trigger.config.IGerritHudsonTriggerConfig; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.Reader; +import java.net.HttpURLConnection; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import net.sf.json.JSONObject; +import net.sf.json.JSONSerializer; + +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.HttpClients; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -264,20 +280,22 @@ private void tryLoadProjectList() { if (isConnected()) { logger.info("Trying to load project list."); IGerritHudsonTriggerConfig activeConfig = getConfig(); - SshConnection sshConnection = SshConnectionFactory.getConnection( - activeConfig.getGerritHostName(), - activeConfig.getGerritSshPort(), - activeConfig.getGerritProxy(), - activeConfig.getGerritAuthentication() - ); - List projects = readProjects(sshConnection.executeCommandReader(GERRIT_LS_PROJECTS)); + if (activeConfig == null) { + logger.error("Could not load project list: config is null for {}", serverName); + return; + } + List projects; + if (activeConfig.isUseHttpsPoller()) { + projects = loadProjectsViaRest(activeConfig); + } else { + projects = loadProjectsViaSsh(activeConfig); + } if (!projects.isEmpty()) { setGerritProjects(projects); logger.info("Project list from {} contains {} entries", serverName, projects.size()); } else { logger.warn("Project list from {} contains 0 projects", serverName); } - sshConnection.disconnect(); } else { logger.warn("Could not connect to Gerrit server when updating Gerrit project list: " + "Server is not connected (timeout)"); @@ -289,6 +307,95 @@ private void tryLoadProjectList() { } } + /** + * Loads the project list via the SSH {@code gerrit ls-projects} command. + * + * @param activeConfig the server configuration. + * @return the list of project names. + * @throws SshException if an SSH error occurs. + * @throws IOException if an I/O error occurs. + */ + private List loadProjectsViaSsh(IGerritHudsonTriggerConfig activeConfig) + throws SshException, IOException { + SshConnection sshConnection = SshConnectionFactory.getConnection( + activeConfig.getGerritHostName(), + activeConfig.getGerritSshPort(), + activeConfig.getGerritProxy(), + activeConfig.getGerritAuthentication() + ); + try { + return readProjects(sshConnection.executeCommandReader(GERRIT_LS_PROJECTS)); + } finally { + sshConnection.disconnect(); + } + } + + /** + * Loads the project list via the Gerrit REST API. + * + * @param activeConfig the server configuration. + * @return the list of project names. + * @throws IOException if an I/O error occurs. + */ + private List loadProjectsViaRest(IGerritHudsonTriggerConfig activeConfig) + throws IOException { + String frontEndUrl = activeConfig.getGerritFrontEndUrl(); + String url = Functions.joinPath(frontEndUrl, "a/projects/?d"); + + Credentials httpCredentials = activeConfig.getHttpCredentials(); + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(AuthScope.ANY, httpCredentials); + HttpClient httpClient = HttpClients.custom() + .setDefaultCredentialsProvider(credsProvider) + .build(); + HttpGet httpGet = new HttpGet(url); + HttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode != HttpURLConnection.HTTP_OK) { + throw new IOException("HTTP " + statusCode + " for project list query"); + } + + StringBuilder sb = new StringBuilder(); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(response.getEntity().getContent(), + StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } + String body = sb.toString(); + // Strip Gerrit JSON hijacking prevention prefix + if (body.startsWith(")]}'")) { + body = body.substring(")]}'".length()); + } + return readProjectsFromJson(body); + } + + /** + * Reads project names from a Gerrit REST API projects JSON response. + * The response format is a JSON object where each key is a project name. + * + * @param jsonBody the JSON response body. + * @return the list of project names. + * @throws IOException if JSON parsing fails. + */ + static List readProjectsFromJson(String jsonBody) throws IOException { + List projects = new ArrayList(); + try { + JSONObject json = (JSONObject)JSONSerializer.toJSON(jsonBody); + for (Iterator it = json.keys(); it.hasNext();) { + String key = (String)it.next(); + if (key != null && !key.isEmpty()) { + projects.add(key); + } + } + } catch (Exception ex) { + throw new IOException("Failed to parse projects JSON response", ex); + } + return projects; + } + /** * Get the the server config. * @return the server config or null if config not found. 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 31824e246..8c41df1be 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 @@ -100,6 +100,9 @@ import com.sonymobile.tools.gerrit.gerritevents.GerritHandler; import com.sonymobile.tools.gerrit.gerritevents.GerritQueryHandler; import com.sonymobile.tools.gerrit.gerritevents.GerritConnection; +import com.sonymobile.tools.gerrit.gerritevents.GerritEventSource; +import com.sonymobile.tools.gerrit.gerritevents.GerritRestPoller; +import com.sonymobile.tools.gerrit.gerritevents.GerritRestQueryHandler; import com.sonymobile.tools.gerrit.gerritevents.dto.GerritEvent; import com.sonymobile.tools.gerrit.gerritevents.dto.rest.Notify; import com.sonymobile.tools.gerrit.gerritevents.ssh.Authentication; @@ -152,7 +155,7 @@ public class GerritServer implements Describable, Action { private transient boolean timeoutWakeup = false; private transient String connectionResponse = ""; private transient GerritHandler gerritEventManager; - private transient GerritConnection gerritConnection; + private transient GerritEventSource gerritConnection; private transient GerritProjectListUpdater projectListUpdater; private IGerritHudsonTriggerConfig config; private transient GerritConnectionListener gerritConnectionListener; @@ -252,7 +255,7 @@ public IGerritHudsonTriggerConfig getConfig() { public void setConfig(IGerritHudsonTriggerConfig config) { checkPermission(); this.config = config; - gerritQueryHnadler = new GerritQueryHandler(config); + gerritQueryHnadler = null; } /** @@ -262,7 +265,11 @@ public void setConfig(IGerritHudsonTriggerConfig config) { */ public GerritQueryHandler getQueryHandler() { if (gerritQueryHnadler == null) { - gerritQueryHnadler = new GerritQueryHandler(config); + if (config.isUseHttpsPoller()) { + gerritQueryHnadler = new GerritRestQueryHandler(config); + } else { + gerritQueryHnadler = new GerritQueryHandler(config); + } } return gerritQueryHnadler; } @@ -581,9 +588,23 @@ public GerritConnectionListener getGerritConnectionListener() { public synchronized void startConnection() { checkPermission(); if (!config.hasDefaultValues()) { - if (gerritConnection == null) { + if (gerritConnection != null && gerritConnection.isConnected()) { + logger.warn("Already started!"); + } else { + // If there's an existing but dead connection, stop it first + if (gerritConnection != null) { + logger.info("{}: Stopping failed connection before restart.", name); + gerritConnection.shutdown(false); + gerritConnection.removeListener(gerritConnectionListener); + gerritConnection.removeListener(missedEventsPlaybackManager); + } logger.debug("Starting Gerrit connection..."); - gerritConnection = new GerritConnection(name, config); + if (config.isUseHttpsPoller()) { + logger.info("{}: Using HTTPS polling for Gerrit events.", name); + gerritConnection = new GerritRestPoller(name, config); + } else { + gerritConnection = new GerritConnection(name, config); + } if (config.isTriggerOnAllComments()) { logger.info("Will trigger on all comments, even from the configured user."); } else { @@ -598,8 +619,6 @@ public synchronized void startConnection() { gerritConnection.addListener(missedEventsPlaybackManager); gerritConnection.start(); - } else { - logger.warn("Already started!"); } // Initialize project list update after connection with Gerrit server projectListUpdater.initProjectListUpdater(); diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/PluginImpl.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/PluginImpl.java index ed6670dd0..954da4628 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/PluginImpl.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/PluginImpl.java @@ -335,6 +335,23 @@ public static GerritServer getFirstServer_() { return plugin.getFirstServer(); } + /** + * Get the server with the given name, falling back to the first server + * when the named server is not found. + * + * @param name the server name, or null. + * @return the server, or null if no server could be found. + */ + @CheckForNull + //CS IGNORE MethodName FOR NEXT 1 LINES. REASON: Static equivalent marker. + public static GerritServer getServerOrFirst_(String name) { + GerritServer server = getServer_(name); + if (server == null) { + server = getFirstServer_(); + } + return server; + } + /** * Set the list of Gerrit servers. * diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/Config.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/Config.java index c880aa14a..cf220ddcc 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/Config.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/Config.java @@ -162,6 +162,21 @@ public class Config implements IGerritHudsonTriggerConfig { * Global default for notification level. */ public static final Notify DEFAULT_NOTIFICATION_LEVEL = Notify.ALL; + /** + * Default value for {@link #isUseHttpsPoller()}. + */ + public static final boolean DEFAULT_USE_HTTPS_POLLER = + com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_USE_HTTPS_POLLER; + /** + * Default value for {@link #getHttpsPollInterval()}. + */ + public static final int DEFAULT_HTTPS_POLL_INTERVAL = + com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_HTTPS_POLL_INTERVAL; + /** + * Default value for {@link #getHttpsPollMaxChanges()}. + */ + public static final int DEFAULT_HTTPS_POLL_MAX_CHANGES = + com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues.DEFAULT_HTTPS_POLL_MAX_CHANGES; private String gerritHostName; private int gerritSshPort; @@ -175,29 +190,50 @@ public class Config implements IGerritHudsonTriggerConfig { private Secret gerritHttpPassword; private boolean restCodeReview; private boolean restVerified; + private boolean useHttpsPoller; + private int httpsPollInterval; + private int httpsPollMaxChanges; @Deprecated private transient boolean gerritBuildCurrentPatchesOnly; @Deprecated private transient int numberOfWorkerThreads; - private String gerritVerifiedCmdBuildSuccessful; - private String gerritVerifiedCmdBuildUnstable; - private String gerritVerifiedCmdBuildFailed; - private String gerritVerifiedCmdBuildStarted; - private String gerritVerifiedCmdBuildNotBuilt; - private String gerritVerifiedCmdBuildAborted; + @Deprecated + private transient String gerritVerifiedCmdBuildSuccessful; + @Deprecated + private transient String gerritVerifiedCmdBuildUnstable; + @Deprecated + private transient String gerritVerifiedCmdBuildFailed; + @Deprecated + private transient String gerritVerifiedCmdBuildStarted; + @Deprecated + private transient String gerritVerifiedCmdBuildNotBuilt; + @Deprecated + private transient String gerritVerifiedCmdBuildAborted; private String gerritFrontEndUrl; - private Integer gerritBuildStartedVerifiedValue = null; - private Integer gerritBuildSuccessfulVerifiedValue = null; - private Integer gerritBuildFailedVerifiedValue = null; - private Integer gerritBuildUnstableVerifiedValue = null; - private Integer gerritBuildNotBuiltVerifiedValue = null; - private Integer gerritBuildAbortedVerifiedValue = null; - private Integer gerritBuildStartedCodeReviewValue = null; - private Integer gerritBuildSuccessfulCodeReviewValue = null; - private Integer gerritBuildFailedCodeReviewValue = null; - private Integer gerritBuildUnstableCodeReviewValue = null; - private Integer gerritBuildNotBuiltCodeReviewValue = null; - private Integer gerritBuildAbortedCodeReviewValue = null; + @Deprecated + private transient Integer gerritBuildStartedVerifiedValue; + @Deprecated + private transient Integer gerritBuildSuccessfulVerifiedValue; + @Deprecated + private transient Integer gerritBuildFailedVerifiedValue; + @Deprecated + private transient Integer gerritBuildUnstableVerifiedValue; + @Deprecated + private transient Integer gerritBuildNotBuiltVerifiedValue; + @Deprecated + private transient Integer gerritBuildAbortedVerifiedValue; + @Deprecated + private transient Integer gerritBuildStartedCodeReviewValue; + @Deprecated + private transient Integer gerritBuildSuccessfulCodeReviewValue; + @Deprecated + private transient Integer gerritBuildFailedCodeReviewValue; + @Deprecated + private transient Integer gerritBuildUnstableCodeReviewValue; + @Deprecated + private transient Integer gerritBuildNotBuiltCodeReviewValue; + @Deprecated + private transient Integer gerritBuildAbortedCodeReviewValue; private boolean enableManualTrigger; private boolean enablePluginMessages; private boolean triggerOnAllComments; @@ -217,6 +253,8 @@ public class Config implements IGerritHudsonTriggerConfig { private Notify notificationLevel; private BuildCancellationPolicy buildCurrentPatchesOnly; private boolean voteSameTopic; + private GerritVoteValues voteValues; + private GerritCommandTemplates commandTemplates; /** * Constructor. @@ -246,27 +284,14 @@ public Config(IGerritHudsonTriggerConfig config) { gerritHttpPassword = Secret.fromString(config.getGerritHttpPassword()); restCodeReview = config.isRestCodeReview(); restVerified = config.isRestVerified(); + useHttpsPoller = config.isUseHttpsPoller(); + httpsPollInterval = config.getHttpsPollInterval(); + httpsPollMaxChanges = config.getHttpsPollMaxChanges(); gerritBuildCurrentPatchesOnly = config.isGerritBuildCurrentPatchesOnly(); numberOfWorkerThreads = config.getNumberOfReceivingWorkerThreads(); numberOfSendingWorkerThreads = config.getNumberOfSendingWorkerThreads(); - gerritBuildStartedVerifiedValue = config.getGerritBuildStartedVerifiedValue(); - gerritBuildStartedCodeReviewValue = config.getGerritBuildStartedCodeReviewValue(); - gerritBuildSuccessfulVerifiedValue = config.getGerritBuildSuccessfulVerifiedValue(); - gerritBuildSuccessfulCodeReviewValue = config.getGerritBuildSuccessfulCodeReviewValue(); - gerritBuildFailedVerifiedValue = config.getGerritBuildFailedVerifiedValue(); - gerritBuildFailedCodeReviewValue = config.getGerritBuildFailedCodeReviewValue(); - gerritBuildUnstableVerifiedValue = config.getGerritBuildUnstableVerifiedValue(); - gerritBuildUnstableCodeReviewValue = config.getGerritBuildUnstableCodeReviewValue(); - gerritBuildNotBuiltVerifiedValue = config.getGerritBuildNotBuiltVerifiedValue(); - gerritBuildNotBuiltCodeReviewValue = config.getGerritBuildNotBuiltCodeReviewValue(); - gerritBuildAbortedVerifiedValue = config.getGerritBuildAbortedVerifiedValue(); - gerritBuildAbortedCodeReviewValue = config.getGerritBuildAbortedCodeReviewValue(); - gerritVerifiedCmdBuildStarted = config.getGerritCmdBuildStarted(); - gerritVerifiedCmdBuildFailed = config.getGerritCmdBuildFailed(); - gerritVerifiedCmdBuildSuccessful = config.getGerritCmdBuildSuccessful(); - gerritVerifiedCmdBuildUnstable = config.getGerritCmdBuildUnstable(); - gerritVerifiedCmdBuildNotBuilt = config.getGerritCmdBuildNotBuilt(); - gerritVerifiedCmdBuildAborted = config.getGerritCmdBuildAborted(); + voteValues = GerritVoteValues.fromConfig(config); + commandTemplates = GerritCommandTemplates.fromConfig(config); gerritFrontEndUrl = config.getGerritFrontEndUrl(); enableManualTrigger = config.isEnableManualTrigger(); enablePluginMessages = config.isEnablePluginMessages(); @@ -330,38 +355,8 @@ public void setValues(JSONObject formData) { numberOfSendingWorkerThreads = DEFAULT_NR_OF_SENDING_WORKER_THREADS; } - setVoteValues(formData); - - gerritVerifiedCmdBuildStarted = formData.optString( - "gerritVerifiedCmdBuildStarted", - "gerrit review --project , " - + "--message 'Build Started ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); - gerritVerifiedCmdBuildFailed = formData.optString( - "gerritVerifiedCmdBuildFailed", - "gerrit review --project , " - + "--message 'Build Failed ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); - gerritVerifiedCmdBuildSuccessful = formData.optString( - "gerritVerifiedCmdBuildSuccessful", - "gerrit review --project , " - + "--message 'Build Successful ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); - gerritVerifiedCmdBuildUnstable = formData.optString( - "gerritVerifiedCmdBuildUnstable", - "gerrit review --project , " - + "--message 'Build Unstable ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); - gerritVerifiedCmdBuildNotBuilt = formData.optString( - "gerritVerifiedCmdBuildNotBuilt", - "gerrit review --project , " - + "--message 'No Builds Executed ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); - gerritVerifiedCmdBuildAborted = formData.optString( - "gerritVerifiedCmdBuildAborted", - "gerrit review --project , " - + "--message 'Build Aborted ' " - + "--verified --code-review --tag " + Constants.TAG_VALUE); + voteValues = new GerritVoteValues(formData); + commandTemplates = new GerritCommandTemplates(formData); gerritFrontEndUrl = formData.optString( "gerritFrontEndUrl", DEFAULT_GERRIT_HOSTNAME); @@ -420,64 +415,18 @@ public void setValues(JSONObject formData) { useRestApi = false; } - replicationConfig = ReplicationConfig.createReplicationConfigFromJSON(formData); - } - - /** - * Sets all config vote values from the provided JSONObject. - * @param formData the JSON object with form data. - */ - private void setVoteValues(JSONObject formData) { - if (formData.isEmpty()) { - gerritBuildStartedVerifiedValue = DEFAULT_GERRIT_BUILD_STARTED_VERIFIED_VALUE; - gerritBuildSuccessfulVerifiedValue = DEFAULT_GERRIT_BUILD_SUCCESSFUL_VERIFIED_VALUE; - gerritBuildFailedVerifiedValue = DEFAULT_GERRIT_BUILD_FAILURE_VERIFIED_VALUE; - gerritBuildUnstableVerifiedValue = DEFAULT_GERRIT_BUILD_UNSTABLE_VERIFIED_VALUE; - gerritBuildNotBuiltVerifiedValue = DEFAULT_GERRIT_BUILD_NOT_BUILT_VERIFIED_VALUE; - gerritBuildAbortedVerifiedValue = DEFAULT_GERRIT_BUILD_ABORTED_VERIFIED_VALUE; - gerritBuildStartedCodeReviewValue = DEFAULT_GERRIT_BUILD_STARTED_CODE_REVIEW_VALUE; - gerritBuildSuccessfulCodeReviewValue = DEFAULT_GERRIT_BUILD_SUCCESSFUL_CODE_REVIEW_VALUE; - gerritBuildFailedCodeReviewValue = DEFAULT_GERRIT_BUILD_FAILURE_CODE_REVIEW_VALUE; - gerritBuildUnstableCodeReviewValue = DEFAULT_GERRIT_BUILD_UNSTABLE_CODE_REVIEW_VALUE; - gerritBuildNotBuiltCodeReviewValue = DEFAULT_GERRIT_BUILD_NOT_BUILT_CODE_REVIEW_VALUE; - gerritBuildAbortedCodeReviewValue = DEFAULT_GERRIT_BUILD_ABORTED_CODE_REVIEW_VALUE; + if (formData.has("useHttpsPoller")) { + useHttpsPoller = true; + JSONObject httpsPoller = formData.getJSONObject("useHttpsPoller"); + httpsPollInterval = httpsPoller.optInt("httpsPollInterval", DEFAULT_HTTPS_POLL_INTERVAL); + httpsPollMaxChanges = httpsPoller.optInt("httpsPollMaxChanges", DEFAULT_HTTPS_POLL_MAX_CHANGES); } else { - gerritBuildStartedVerifiedValue = getValueFromFormData(formData, "gerritBuildStartedVerifiedValue"); - gerritBuildSuccessfulVerifiedValue = getValueFromFormData(formData, "gerritBuildSuccessfulVerifiedValue"); - gerritBuildFailedVerifiedValue = getValueFromFormData(formData, "gerritBuildFailedVerifiedValue"); - gerritBuildUnstableVerifiedValue = getValueFromFormData(formData, "gerritBuildUnstableVerifiedValue"); - gerritBuildNotBuiltVerifiedValue = getValueFromFormData(formData, "gerritBuildNotBuiltVerifiedValue"); - gerritBuildAbortedVerifiedValue = getValueFromFormData(formData, "gerritBuildAbortedVerifiedValue"); - gerritBuildStartedCodeReviewValue = getValueFromFormData(formData, "gerritBuildStartedCodeReviewValue"); - gerritBuildSuccessfulCodeReviewValue = getValueFromFormData(formData, - "gerritBuildSuccessfulCodeReviewValue"); - gerritBuildFailedCodeReviewValue = getValueFromFormData(formData, "gerritBuildFailedCodeReviewValue"); - gerritBuildUnstableCodeReviewValue = getValueFromFormData(formData, "gerritBuildUnstableCodeReviewValue"); - gerritBuildNotBuiltCodeReviewValue = getValueFromFormData(formData, "gerritBuildNotBuiltCodeReviewValue"); - gerritBuildAbortedCodeReviewValue = getValueFromFormData(formData, "gerritBuildAbortedCodeReviewValue"); + useHttpsPoller = false; + httpsPollInterval = DEFAULT_HTTPS_POLL_INTERVAL; + httpsPollMaxChanges = DEFAULT_HTTPS_POLL_MAX_CHANGES; } - } - /** - * Obtain value from a key in formdata. - * @param formData JSONObject. - * @param key key to extract value for. - * @return value. - */ - private Integer getValueFromFormData(JSONObject formData, String key) { - if (formData.has(key)) { - String testData = formData.optString(key); - if (testData == null || testData.isEmpty()) { - return null; - } else { - try { - return Integer.parseInt(testData); - } catch (NumberFormatException nfe) { - return null; - } - } - } - return null; + replicationConfig = ReplicationConfig.createReplicationConfigFromJSON(formData); } /** @@ -894,16 +843,23 @@ public String getVoteSameTopicDescription() { + " (see help for more)."; } + /** + * Get the command for successful builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildSuccessful()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildSuccessful() { - return gerritVerifiedCmdBuildSuccessful; + return getCommandTemplates().getCmdBuildSuccessful(); } /** * Set Gerrit Verified Cmd Build Successful. * * @param cmd the command - * @see #getGerritCmdBuildSuccessful() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildSuccessful(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildSuccessful(String cmd) { @@ -914,22 +870,28 @@ public void setGerritVerifiedCmdBuildSuccessful(String cmd) { * Set Gerrit Verified Cmd Build Successful. * * @param cmd the Gerrit command for successful verification - * @see #getGerritCmdBuildSuccessful() */ public void setGerritCmdBuildSuccessful(String cmd) { - gerritVerifiedCmdBuildSuccessful = cmd; + getCommandTemplates().setCmdBuildSuccessful(cmd); } + /** + * Get the command for unstable builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildUnstable()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildUnstable() { - return gerritVerifiedCmdBuildUnstable; + return getCommandTemplates().getCmdBuildUnstable(); } /** * Set Gerrit Verified Cmd Build Unstable. * * @param cmd the command - * @see #getGerritCmdBuildUnstable() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildUnstable(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildUnstable(String cmd) { @@ -940,22 +902,28 @@ public void setGerritVerifiedCmdBuildUnstable(String cmd) { * Set Gerrit Verified Cmd Build Unstable. * * @param cmd the command - * @see #getGerritCmdBuildUnstable() */ public void setGerritCmdBuildUnstable(String cmd) { - gerritVerifiedCmdBuildUnstable = cmd; + getCommandTemplates().setCmdBuildUnstable(cmd); } + /** + * Get the command for failed builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildFailed()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildFailed() { - return gerritVerifiedCmdBuildFailed; + return getCommandTemplates().getCmdBuildFailed(); } /** * Set Gerrit Verified Cmd Build Failed. * * @param cmd the command - * @see #getGerritCmdBuildFailed() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildFailed(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildFailed(String cmd) { @@ -966,22 +934,28 @@ public void setGerritVerifiedCmdBuildFailed(String cmd) { * Set Gerrit Verified Cmd Build Failed. * * @param cmd the command - * @see #getGerritCmdBuildFailed() */ public void setGerritCmdBuildFailed(String cmd) { - gerritVerifiedCmdBuildFailed = cmd; + getCommandTemplates().setCmdBuildFailed(cmd); } + /** + * Get the command for started builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildStarted()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildStarted() { - return gerritVerifiedCmdBuildStarted; + return getCommandTemplates().getCmdBuildStarted(); } /** * Set Gerrit Verified Cmd Build Started. * * @param cmd the command - * @see #getGerritCmdBuildStarted() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildStarted(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildStarted(String cmd) { @@ -992,22 +966,28 @@ public void setGerritVerifiedCmdBuildStarted(String cmd) { * Set Gerrit Verified Cmd Build Started. * * @param cmd the command - * @see #getGerritCmdBuildStarted() */ public void setGerritCmdBuildStarted(String cmd) { - gerritVerifiedCmdBuildStarted = cmd; + getCommandTemplates().setCmdBuildStarted(cmd); } + /** + * Get the command for not-built builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildNotBuilt()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildNotBuilt() { - return gerritVerifiedCmdBuildNotBuilt; + return getCommandTemplates().getCmdBuildNotBuilt(); } /** * Set Gerrit Verified Cmd Build NotBuilt. * * @param cmd the command - * @see #getGerritCmdBuildNotBuilt() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildNotBuilt(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildNotBuilt(String cmd) { @@ -1018,22 +998,28 @@ public void setGerritVerifiedCmdBuildNotBuilt(String cmd) { * Set Gerrit Verified Cmd Build NotBuilt. * * @param cmd the command - * @see #getGerritCmdBuildNotBuilt() */ public void setGerritCmdBuildNotBuilt(String cmd) { - gerritVerifiedCmdBuildNotBuilt = cmd; + getCommandTemplates().setCmdBuildNotBuilt(cmd); } + /** + * Get the command for aborted builds. + * + * @return the command string. + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#getCmdBuildAborted()} instead. + */ + @Deprecated @Override public String getGerritCmdBuildAborted() { - return gerritVerifiedCmdBuildAborted; + return getCommandTemplates().getCmdBuildAborted(); } /** * Set Gerrit Verified Cmd Build Aborted. * * @param cmd the command - * @see #getGerritCmdBuildAborted() + * @deprecated Use {@link #getCommandTemplates()}.{@link GerritCommandTemplates#setCmdBuildAborted(String)} instead. */ @Deprecated public void setGerritVerifiedCmdBuildAborted(String cmd) { @@ -1044,70 +1030,69 @@ public void setGerritVerifiedCmdBuildAborted(String cmd) { * Set Gerrit Verified Cmd Build Aborted. * * @param cmd the command - * @see #getGerritCmdBuildAborted() */ public void setGerritCmdBuildAborted(String cmd) { - gerritVerifiedCmdBuildAborted = cmd; + getCommandTemplates().setCmdBuildAborted(cmd); } @Override public Integer getGerritBuildStartedVerifiedValue() { - return gerritBuildStartedVerifiedValue; + return getVoteValues().getBuildStartedVerifiedValue(); } @Override public Integer getGerritBuildStartedCodeReviewValue() { - return gerritBuildStartedCodeReviewValue; + return getVoteValues().getBuildStartedCodeReviewValue(); } @Override public Integer getGerritBuildSuccessfulVerifiedValue() { - return gerritBuildSuccessfulVerifiedValue; + return getVoteValues().getBuildSuccessfulVerifiedValue(); } @Override public Integer getGerritBuildSuccessfulCodeReviewValue() { - return gerritBuildSuccessfulCodeReviewValue; + return getVoteValues().getBuildSuccessfulCodeReviewValue(); } @Override public Integer getGerritBuildFailedVerifiedValue() { - return gerritBuildFailedVerifiedValue; + return getVoteValues().getBuildFailedVerifiedValue(); } @Override public Integer getGerritBuildFailedCodeReviewValue() { - return gerritBuildFailedCodeReviewValue; + return getVoteValues().getBuildFailedCodeReviewValue(); } @Override public Integer getGerritBuildUnstableVerifiedValue() { - return gerritBuildUnstableVerifiedValue; + return getVoteValues().getBuildUnstableVerifiedValue(); } @Override public Integer getGerritBuildUnstableCodeReviewValue() { - return gerritBuildUnstableCodeReviewValue; + return getVoteValues().getBuildUnstableCodeReviewValue(); } @Override public Integer getGerritBuildNotBuiltVerifiedValue() { - return gerritBuildNotBuiltVerifiedValue; + return getVoteValues().getBuildNotBuiltVerifiedValue(); } @Override public Integer getGerritBuildNotBuiltCodeReviewValue() { - return gerritBuildNotBuiltCodeReviewValue; + return getVoteValues().getBuildNotBuiltCodeReviewValue(); } @Override public Integer getGerritBuildAbortedVerifiedValue() { - return gerritBuildAbortedVerifiedValue; + return getVoteValues().getBuildAbortedVerifiedValue(); } @Override public Integer getGerritBuildAbortedCodeReviewValue() { - return gerritBuildAbortedCodeReviewValue; + return getVoteValues().getBuildAbortedCodeReviewValue(); } /** @@ -1115,7 +1100,7 @@ public Integer getGerritBuildAbortedCodeReviewValue() { * @param gerritBuildStartedVerifiedValue value */ public void setGerritBuildStartedVerifiedValue(Integer gerritBuildStartedVerifiedValue) { - this.gerritBuildStartedVerifiedValue = gerritBuildStartedVerifiedValue; + getVoteValues().setBuildStartedVerifiedValue(gerritBuildStartedVerifiedValue); } /** @@ -1123,7 +1108,7 @@ public void setGerritBuildStartedVerifiedValue(Integer gerritBuildStartedVerifie * @param gerritBuildSuccessfulVerifiedValue value */ public void setGerritBuildSuccessfulVerifiedValue(Integer gerritBuildSuccessfulVerifiedValue) { - this.gerritBuildSuccessfulVerifiedValue = gerritBuildSuccessfulVerifiedValue; + getVoteValues().setBuildSuccessfulVerifiedValue(gerritBuildSuccessfulVerifiedValue); } /** @@ -1131,7 +1116,7 @@ public void setGerritBuildSuccessfulVerifiedValue(Integer gerritBuildSuccessfulV * @param gerritBuildFailedVerifiedValue value */ public void setGerritBuildFailedVerifiedValue(Integer gerritBuildFailedVerifiedValue) { - this.gerritBuildFailedVerifiedValue = gerritBuildFailedVerifiedValue; + getVoteValues().setBuildFailedVerifiedValue(gerritBuildFailedVerifiedValue); } /** @@ -1139,7 +1124,7 @@ public void setGerritBuildFailedVerifiedValue(Integer gerritBuildFailedVerifiedV * @param gerritBuildUnstableVerifiedValue value */ public void setGerritBuildUnstableVerifiedValue(Integer gerritBuildUnstableVerifiedValue) { - this.gerritBuildUnstableVerifiedValue = gerritBuildUnstableVerifiedValue; + getVoteValues().setBuildUnstableVerifiedValue(gerritBuildUnstableVerifiedValue); } /** @@ -1147,7 +1132,7 @@ public void setGerritBuildUnstableVerifiedValue(Integer gerritBuildUnstableVerif * @param gerritBuildNotBuiltVerifiedValue value */ public void setGerritBuildNotBuiltVerifiedValue(Integer gerritBuildNotBuiltVerifiedValue) { - this.gerritBuildNotBuiltVerifiedValue = gerritBuildNotBuiltVerifiedValue; + getVoteValues().setBuildNotBuiltVerifiedValue(gerritBuildNotBuiltVerifiedValue); } /** @@ -1155,7 +1140,7 @@ public void setGerritBuildNotBuiltVerifiedValue(Integer gerritBuildNotBuiltVerif * @param gerritBuildAbortedVerifiedValue value */ public void setGerritBuildAbortedVerifiedValue(Integer gerritBuildAbortedVerifiedValue) { - this.gerritBuildAbortedVerifiedValue = gerritBuildAbortedVerifiedValue; + getVoteValues().setBuildAbortedVerifiedValue(gerritBuildAbortedVerifiedValue); } /** @@ -1163,7 +1148,7 @@ public void setGerritBuildAbortedVerifiedValue(Integer gerritBuildAbortedVerifie * @param gerritBuildStartedCodeReviewValue value */ public void setGerritBuildStartedCodeReviewValue(Integer gerritBuildStartedCodeReviewValue) { - this.gerritBuildStartedCodeReviewValue = gerritBuildStartedCodeReviewValue; + getVoteValues().setBuildStartedCodeReviewValue(gerritBuildStartedCodeReviewValue); } /** @@ -1171,7 +1156,7 @@ public void setGerritBuildStartedCodeReviewValue(Integer gerritBuildStartedCodeR * @param gerritBuildSuccessfulCodeReviewValue value */ public void setGerritBuildSuccessfulCodeReviewValue(Integer gerritBuildSuccessfulCodeReviewValue) { - this.gerritBuildSuccessfulCodeReviewValue = gerritBuildSuccessfulCodeReviewValue; + getVoteValues().setBuildSuccessfulCodeReviewValue(gerritBuildSuccessfulCodeReviewValue); } /** @@ -1179,7 +1164,7 @@ public void setGerritBuildSuccessfulCodeReviewValue(Integer gerritBuildSuccessfu * @param gerritBuildFailedCodeReviewValue value */ public void setGerritBuildFailedCodeReviewValue(Integer gerritBuildFailedCodeReviewValue) { - this.gerritBuildFailedCodeReviewValue = gerritBuildFailedCodeReviewValue; + getVoteValues().setBuildFailedCodeReviewValue(gerritBuildFailedCodeReviewValue); } /** @@ -1187,7 +1172,7 @@ public void setGerritBuildFailedCodeReviewValue(Integer gerritBuildFailedCodeRev * @param gerritBuildUnstableCodeReviewValue value */ public void setGerritBuildUnstableCodeReviewValue(Integer gerritBuildUnstableCodeReviewValue) { - this.gerritBuildUnstableCodeReviewValue = gerritBuildUnstableCodeReviewValue; + getVoteValues().setBuildUnstableCodeReviewValue(gerritBuildUnstableCodeReviewValue); } /** @@ -1195,7 +1180,7 @@ public void setGerritBuildUnstableCodeReviewValue(Integer gerritBuildUnstableCod * @param gerritBuildNotBuiltCodeReviewValue value */ public void setGerritBuildNotBuiltCodeReviewValue(Integer gerritBuildNotBuiltCodeReviewValue) { - this.gerritBuildNotBuiltCodeReviewValue = gerritBuildNotBuiltCodeReviewValue; + getVoteValues().setBuildNotBuiltCodeReviewValue(gerritBuildNotBuiltCodeReviewValue); } /** @@ -1203,7 +1188,7 @@ public void setGerritBuildNotBuiltCodeReviewValue(Integer gerritBuildNotBuiltCod * @param gerritBuildAbortedCodeReviewValue value */ public void setGerritBuildAbortedCodeReviewValue(Integer gerritBuildAbortedCodeReviewValue) { - this.gerritBuildAbortedCodeReviewValue = gerritBuildAbortedCodeReviewValue; + getVoteValues().setBuildAbortedCodeReviewValue(gerritBuildAbortedCodeReviewValue); } @Override @@ -1434,6 +1419,82 @@ public void setRestVerified(boolean restVerified) { this.restVerified = restVerified; } + @Override + public boolean isUseHttpsPoller() { + return useHttpsPoller; + } + + /** + * Sets useHttpsPoller. + * @param useHttpsPoller true if HTTPS polling should be used for event ingestion. + * @see #isUseHttpsPoller() + */ + public void setUseHttpsPoller(boolean useHttpsPoller) { + this.useHttpsPoller = useHttpsPoller; + } + + @Override + public int getHttpsPollInterval() { + if (httpsPollInterval <= 0) { + httpsPollInterval = DEFAULT_HTTPS_POLL_INTERVAL; + } + return httpsPollInterval; + } + + /** + * Sets httpsPollInterval. + * @param httpsPollInterval the poll interval in seconds. + * @see #getHttpsPollInterval() + */ + public void setHttpsPollInterval(int httpsPollInterval) { + this.httpsPollInterval = httpsPollInterval; + } + + @Override + public int getHttpsPollMaxChanges() { + if (httpsPollMaxChanges <= 0) { + httpsPollMaxChanges = DEFAULT_HTTPS_POLL_MAX_CHANGES; + } + return httpsPollMaxChanges; + } + + /** + * Sets httpsPollMaxChanges. + * @param httpsPollMaxChanges the maximum changes per poll. + * @see #getHttpsPollMaxChanges() + */ + public void setHttpsPollMaxChanges(int httpsPollMaxChanges) { + this.httpsPollMaxChanges = httpsPollMaxChanges; + } + + /** + * Lazily-initialized accessor for the vote values sub-object. + * Ensures a non-null GerritVoteValues in the default constructor path + * where XStream has not performed readResolve(). + * + * @return the vote values sub-object, never null. + */ + public synchronized GerritVoteValues getVoteValues() { + if (voteValues == null) { + voteValues = new GerritVoteValues(); + } + return voteValues; + } + + /** + * Lazily-initialized accessor for the command templates sub-object. + * Ensures a non-null GerritCommandTemplates in the default constructor path + * where XStream has not performed readResolve(). + * + * @return the command templates sub-object, never null. + */ + public synchronized GerritCommandTemplates getCommandTemplates() { + if (commandTemplates == null) { + commandTemplates = new GerritCommandTemplates(); + } + return commandTemplates; + } + /** * When upgrading from an older version where buildCurrentPatchesOnly doesn't exist, * get the value from the now deprecated gerritBuildCurrentPatchesOnly. @@ -1455,7 +1516,7 @@ Object readResolve() { if (this.gerritVerifiedCmdBuildAborted == null) { this.gerritVerifiedCmdBuildAborted = this.gerritVerifiedCmdBuildFailed; - /* Only set these values when dealnig with an old configuration */ + /* Only set these values when dealing with an old configuration */ if (this.gerritBuildAbortedCodeReviewValue == null) { this.gerritBuildAbortedCodeReviewValue = this.gerritBuildFailedCodeReviewValue; } @@ -1465,6 +1526,38 @@ Object readResolve() { } } + // Migrate old flat vote-value fields into the sub-object + if (this.voteValues == null) { + this.voteValues = new GerritVoteValues(); + if (this.gerritBuildStartedVerifiedValue != null) { + this.voteValues.setBuildStartedVerifiedValue(gerritBuildStartedVerifiedValue); + this.voteValues.setBuildSuccessfulVerifiedValue(gerritBuildSuccessfulVerifiedValue); + this.voteValues.setBuildFailedVerifiedValue(gerritBuildFailedVerifiedValue); + this.voteValues.setBuildUnstableVerifiedValue(gerritBuildUnstableVerifiedValue); + this.voteValues.setBuildNotBuiltVerifiedValue(gerritBuildNotBuiltVerifiedValue); + this.voteValues.setBuildAbortedVerifiedValue(gerritBuildAbortedVerifiedValue); + this.voteValues.setBuildStartedCodeReviewValue(gerritBuildStartedCodeReviewValue); + this.voteValues.setBuildSuccessfulCodeReviewValue(gerritBuildSuccessfulCodeReviewValue); + this.voteValues.setBuildFailedCodeReviewValue(gerritBuildFailedCodeReviewValue); + this.voteValues.setBuildUnstableCodeReviewValue(gerritBuildUnstableCodeReviewValue); + this.voteValues.setBuildNotBuiltCodeReviewValue(gerritBuildNotBuiltCodeReviewValue); + this.voteValues.setBuildAbortedCodeReviewValue(gerritBuildAbortedCodeReviewValue); + } + } + + // Migrate old flat command-template fields into the sub-object + if (this.commandTemplates == null) { + this.commandTemplates = new GerritCommandTemplates(); + if (this.gerritVerifiedCmdBuildStarted != null) { + this.commandTemplates.setCmdBuildStarted(gerritVerifiedCmdBuildStarted); + this.commandTemplates.setCmdBuildSuccessful(gerritVerifiedCmdBuildSuccessful); + this.commandTemplates.setCmdBuildFailed(gerritVerifiedCmdBuildFailed); + this.commandTemplates.setCmdBuildUnstable(gerritVerifiedCmdBuildUnstable); + this.commandTemplates.setCmdBuildNotBuilt(gerritVerifiedCmdBuildNotBuilt); + this.commandTemplates.setCmdBuildAborted(gerritVerifiedCmdBuildAborted); + } + } + return this; } } diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritCommandTemplates.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritCommandTemplates.java new file mode 100644 index 000000000..4ded7eb2b --- /dev/null +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritCommandTemplates.java @@ -0,0 +1,277 @@ +/* + * The MIT License + * + * Copyright 2010 Sony Mobile Communications Inc. All rights reserved. + * Copyright 2026 Amarula Solutions. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.sonyericsson.hudson.plugins.gerrit.trigger.config; + +import net.sf.json.JSONObject; + +/** + * Holds the 6 Gerrit review command template strings for each build outcome. + * Extracted from {@link Config} to reduce class size and improve maintainability. + * + * @author Robert Sandell <robert.sandell@sonyericsson.com> + */ +public class GerritCommandTemplates { + + /** Default command for build started. */ + public static final String DEFAULT_CMD_BUILD_STARTED = + "gerrit review --project , " + + "--message 'Build Started ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + /** Default command for build successful. */ + public static final String DEFAULT_CMD_BUILD_SUCCESSFUL = + "gerrit review --project , " + + "--message 'Build Successful ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + /** Default command for build failed. */ + public static final String DEFAULT_CMD_BUILD_FAILED = + "gerrit review --project , " + + "--message 'Build Failed ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + /** Default command for build unstable. */ + public static final String DEFAULT_CMD_BUILD_UNSTABLE = + "gerrit review --project , " + + "--message 'Build Unstable ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + /** Default command for build not built. */ + public static final String DEFAULT_CMD_BUILD_NOT_BUILT = + "gerrit review --project , " + + "--message 'No Builds Executed ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + /** Default command for build aborted. */ + public static final String DEFAULT_CMD_BUILD_ABORTED = + "gerrit review --project , " + + "--message 'Build Aborted ' " + + "--verified --code-review --tag " + Constants.TAG_VALUE; + + private String buildStartedCommand; + private String buildSuccessfulCommand; + private String buildFailedCommand; + private String buildUnstableCommand; + private String buildNotBuiltCommand; + private String buildAbortedCommand; + + /** + * Default constructor. Sets all command templates to their defaults. + */ + public GerritCommandTemplates() { + setDefaults(); + } + + /** + * Constructs command templates from a JSON object. + * + * @param formData the JSON object with form data. + */ + public GerritCommandTemplates(JSONObject formData) { + setValues(formData); + } + + /** + * Copy constructor. + * + * @param source the GerritCommandTemplates to copy from. + */ + public GerritCommandTemplates(GerritCommandTemplates source) { + this.buildStartedCommand = source.buildStartedCommand; + this.buildSuccessfulCommand = source.buildSuccessfulCommand; + this.buildFailedCommand = source.buildFailedCommand; + this.buildUnstableCommand = source.buildUnstableCommand; + this.buildNotBuiltCommand = source.buildNotBuiltCommand; + this.buildAbortedCommand = source.buildAbortedCommand; + } + + /** + * Factory method to create a GerritCommandTemplates from an {@link IGerritHudsonTriggerConfig}. + * + * @param config the config to copy command templates from. + * @return a new GerritCommandTemplates instance. + */ + public static GerritCommandTemplates fromConfig(IGerritHudsonTriggerConfig config) { + GerritCommandTemplates c = new GerritCommandTemplates(); + c.buildStartedCommand = config.getGerritCmdBuildStarted(); + c.buildSuccessfulCommand = config.getGerritCmdBuildSuccessful(); + c.buildFailedCommand = config.getGerritCmdBuildFailed(); + c.buildUnstableCommand = config.getGerritCmdBuildUnstable(); + c.buildNotBuiltCommand = config.getGerritCmdBuildNotBuilt(); + c.buildAbortedCommand = config.getGerritCmdBuildAborted(); + return c; + } + + /** + * Sets all command templates from the provided JSONObject. + * + * @param formData the JSON object with form data. + */ + public void setValues(JSONObject formData) { + buildStartedCommand = formData.optString( + "gerritVerifiedCmdBuildStarted", + DEFAULT_CMD_BUILD_STARTED); + buildFailedCommand = formData.optString( + "gerritVerifiedCmdBuildFailed", + DEFAULT_CMD_BUILD_FAILED); + buildSuccessfulCommand = formData.optString( + "gerritVerifiedCmdBuildSuccessful", + DEFAULT_CMD_BUILD_SUCCESSFUL); + buildUnstableCommand = formData.optString( + "gerritVerifiedCmdBuildUnstable", + DEFAULT_CMD_BUILD_UNSTABLE); + buildNotBuiltCommand = formData.optString( + "gerritVerifiedCmdBuildNotBuilt", + DEFAULT_CMD_BUILD_NOT_BUILT); + buildAbortedCommand = formData.optString( + "gerritVerifiedCmdBuildAborted", + DEFAULT_CMD_BUILD_ABORTED); + } + + /** + * Sets all 6 command templates to their default values. + */ + private void setDefaults() { + buildStartedCommand = DEFAULT_CMD_BUILD_STARTED; + buildSuccessfulCommand = DEFAULT_CMD_BUILD_SUCCESSFUL; + buildFailedCommand = DEFAULT_CMD_BUILD_FAILED; + buildUnstableCommand = DEFAULT_CMD_BUILD_UNSTABLE; + buildNotBuiltCommand = DEFAULT_CMD_BUILD_NOT_BUILT; + buildAbortedCommand = DEFAULT_CMD_BUILD_ABORTED; + } + + /** + * Backward compatibility: when upgrading from an older version that didn't have + * the aborted build command, copy the failed build command as default. + * + * @return the resolved instance. + */ + Object readResolve() { + if (buildAbortedCommand == null && buildFailedCommand != null) { + buildAbortedCommand = buildFailedCommand; + } + return this; + } + + // ---- Getters ---- + + /** + * Get build started command template. + * @return the command template. + */ + public String getCmdBuildStarted() { + return buildStartedCommand; + } + + /** + * Get build successful command template. + * @return the command template. + */ + public String getCmdBuildSuccessful() { + return buildSuccessfulCommand; + } + + /** + * Get build failed command template. + * @return the command template. + */ + public String getCmdBuildFailed() { + return buildFailedCommand; + } + + /** + * Get build unstable command template. + * @return the command template. + */ + public String getCmdBuildUnstable() { + return buildUnstableCommand; + } + + /** + * Get build not built command template. + * @return the command template. + */ + public String getCmdBuildNotBuilt() { + return buildNotBuiltCommand; + } + + /** + * Get build aborted command template. + * @return the command template. + */ + public String getCmdBuildAborted() { + return buildAbortedCommand; + } + + // ---- Setters (needed for JCasC / configuration-as-code binding) ---- + + /** + * Set build started command template. + * @param value the command template. + */ + public void setCmdBuildStarted(String value) { + this.buildStartedCommand = value; + } + + /** + * Set build successful command template. + * @param value the command template. + */ + public void setCmdBuildSuccessful(String value) { + this.buildSuccessfulCommand = value; + } + + /** + * Set build failed command template. + * @param value the command template. + */ + public void setCmdBuildFailed(String value) { + this.buildFailedCommand = value; + } + + /** + * Set build unstable command template. + * @param value the command template. + */ + public void setCmdBuildUnstable(String value) { + this.buildUnstableCommand = value; + } + + /** + * Set build not built command template. + * @param value the command template. + */ + public void setCmdBuildNotBuilt(String value) { + this.buildNotBuiltCommand = value; + } + + /** + * Set build aborted command template. + * @param value the command template. + */ + public void setCmdBuildAborted(String value) { + this.buildAbortedCommand = value; + } +} diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritVoteValues.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritVoteValues.java new file mode 100644 index 000000000..9f3ae4047 --- /dev/null +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/config/GerritVoteValues.java @@ -0,0 +1,420 @@ +/* + * The MIT License + * + * Copyright 2010 Sony Mobile Communications Inc. All rights reserved. + * Copyright 2026 Amarula Solutions. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.sonyericsson.hudson.plugins.gerrit.trigger.config; + +import net.sf.json.JSONObject; + +/** + * Holds the 12 default vote values (verified and code-review) for each build outcome. + * Extracted from {@link Config} to reduce class size and improve maintainability. + * + * @author Robert Sandell <robert.sandell@sonyericsson.com> + */ +public class GerritVoteValues { + + /** + * Default verified vote to Gerrit when a build is started. + */ + public static final int DEFAULT_GERRIT_BUILD_STARTED_VERIFIED_VALUE = 0; + /** + * Default verified vote to Gerrit when a build is unstable. + */ + public static final int DEFAULT_GERRIT_BUILD_UNSTABLE_VERIFIED_VALUE = 0; + /** + * Default verified vote to Gerrit when a build is failed. + */ + public static final int DEFAULT_GERRIT_BUILD_FAILURE_VERIFIED_VALUE = -1; + /** + * Default verified vote to Gerrit when a build is successful. + */ + public static final int DEFAULT_GERRIT_BUILD_SUCCESSFUL_VERIFIED_VALUE = 1; + /** + * Default verified vote to Gerrit when a build is not built. + */ + public static final int DEFAULT_GERRIT_BUILD_NOT_BUILT_VERIFIED_VALUE = 0; + /** + * Default verified vote to Gerrit when a build is aborted. + */ + public static final int DEFAULT_GERRIT_BUILD_ABORTED_VERIFIED_VALUE = 0; + /** + * Default code review vote to Gerrit when a build is started. + */ + public static final int DEFAULT_GERRIT_BUILD_STARTED_CODE_REVIEW_VALUE = 0; + /** + * Default code review vote to Gerrit when a build is unstable. + */ + public static final int DEFAULT_GERRIT_BUILD_UNSTABLE_CODE_REVIEW_VALUE = -1; + /** + * Default code review vote to Gerrit when a build is failed. + */ + public static final int DEFAULT_GERRIT_BUILD_FAILURE_CODE_REVIEW_VALUE = 0; + /** + * Default code review vote to Gerrit when a build is successful. + */ + public static final int DEFAULT_GERRIT_BUILD_SUCCESSFUL_CODE_REVIEW_VALUE = 0; + /** + * Default code review vote to Gerrit when a build is not built. + */ + public static final int DEFAULT_GERRIT_BUILD_NOT_BUILT_CODE_REVIEW_VALUE = 0; + /** + * Default code review vote to Gerrit when a build is aborted. + */ + public static final int DEFAULT_GERRIT_BUILD_ABORTED_CODE_REVIEW_VALUE = 0; + + private Integer buildStartedVerifiedValue; + private Integer buildSuccessfulVerifiedValue; + private Integer buildFailedVerifiedValue; + private Integer buildUnstableVerifiedValue; + private Integer buildNotBuiltVerifiedValue; + private Integer buildAbortedVerifiedValue; + private Integer buildStartedCodeReviewValue; + private Integer buildSuccessfulCodeReviewValue; + private Integer buildFailedCodeReviewValue; + private Integer buildUnstableCodeReviewValue; + private Integer buildNotBuiltCodeReviewValue; + private Integer buildAbortedCodeReviewValue; + + /** + * Default constructor. Sets all vote values to their defaults. + */ + public GerritVoteValues() { + setDefaults(); + } + + /** + * Constructs vote values from a JSON object. + * + * @param formData the JSON object with form data. + */ + public GerritVoteValues(JSONObject formData) { + setValues(formData); + } + + /** + * Copy constructor. + * + * @param source the GerritVoteValues to copy from. + */ + public GerritVoteValues(GerritVoteValues source) { + this.buildStartedVerifiedValue = source.buildStartedVerifiedValue; + this.buildSuccessfulVerifiedValue = source.buildSuccessfulVerifiedValue; + this.buildFailedVerifiedValue = source.buildFailedVerifiedValue; + this.buildUnstableVerifiedValue = source.buildUnstableVerifiedValue; + this.buildNotBuiltVerifiedValue = source.buildNotBuiltVerifiedValue; + this.buildAbortedVerifiedValue = source.buildAbortedVerifiedValue; + this.buildStartedCodeReviewValue = source.buildStartedCodeReviewValue; + this.buildSuccessfulCodeReviewValue = source.buildSuccessfulCodeReviewValue; + this.buildFailedCodeReviewValue = source.buildFailedCodeReviewValue; + this.buildUnstableCodeReviewValue = source.buildUnstableCodeReviewValue; + this.buildNotBuiltCodeReviewValue = source.buildNotBuiltCodeReviewValue; + this.buildAbortedCodeReviewValue = source.buildAbortedCodeReviewValue; + } + + /** + * Factory method to create a GerritVoteValues from an {@link IGerritHudsonTriggerConfig}. + * + * @param config the config to copy vote values from. + * @return a new GerritVoteValues instance. + */ + public static GerritVoteValues fromConfig(IGerritHudsonTriggerConfig config) { + GerritVoteValues v = new GerritVoteValues(); + v.buildStartedVerifiedValue = config.getGerritBuildStartedVerifiedValue(); + v.buildStartedCodeReviewValue = config.getGerritBuildStartedCodeReviewValue(); + v.buildSuccessfulVerifiedValue = config.getGerritBuildSuccessfulVerifiedValue(); + v.buildSuccessfulCodeReviewValue = config.getGerritBuildSuccessfulCodeReviewValue(); + v.buildFailedVerifiedValue = config.getGerritBuildFailedVerifiedValue(); + v.buildFailedCodeReviewValue = config.getGerritBuildFailedCodeReviewValue(); + v.buildUnstableVerifiedValue = config.getGerritBuildUnstableVerifiedValue(); + v.buildUnstableCodeReviewValue = config.getGerritBuildUnstableCodeReviewValue(); + v.buildNotBuiltVerifiedValue = config.getGerritBuildNotBuiltVerifiedValue(); + v.buildNotBuiltCodeReviewValue = config.getGerritBuildNotBuiltCodeReviewValue(); + v.buildAbortedVerifiedValue = config.getGerritBuildAbortedVerifiedValue(); + v.buildAbortedCodeReviewValue = config.getGerritBuildAbortedCodeReviewValue(); + return v; + } + + /** + * Sets all vote values from the provided JSONObject. + * When formData is empty, all defaults are applied. + * + * @param formData the JSON object with form data. + */ + public void setValues(JSONObject formData) { + if (formData.isEmpty()) { + setDefaults(); + } else { + buildStartedVerifiedValue = getValueFromFormData(formData, "gerritBuildStartedVerifiedValue"); + buildSuccessfulVerifiedValue = getValueFromFormData(formData, "gerritBuildSuccessfulVerifiedValue"); + buildFailedVerifiedValue = getValueFromFormData(formData, "gerritBuildFailedVerifiedValue"); + buildUnstableVerifiedValue = getValueFromFormData(formData, "gerritBuildUnstableVerifiedValue"); + buildNotBuiltVerifiedValue = getValueFromFormData(formData, "gerritBuildNotBuiltVerifiedValue"); + buildAbortedVerifiedValue = getValueFromFormData(formData, "gerritBuildAbortedVerifiedValue"); + buildStartedCodeReviewValue = getValueFromFormData(formData, "gerritBuildStartedCodeReviewValue"); + buildSuccessfulCodeReviewValue = getValueFromFormData(formData, + "gerritBuildSuccessfulCodeReviewValue"); + buildFailedCodeReviewValue = getValueFromFormData(formData, "gerritBuildFailedCodeReviewValue"); + buildUnstableCodeReviewValue = getValueFromFormData(formData, "gerritBuildUnstableCodeReviewValue"); + buildNotBuiltCodeReviewValue = getValueFromFormData(formData, "gerritBuildNotBuiltCodeReviewValue"); + buildAbortedCodeReviewValue = getValueFromFormData(formData, "gerritBuildAbortedCodeReviewValue"); + } + } + + /** + * Obtain value from a key in formdata. + * + * @param formData JSONObject. + * @param key key to extract value for. + * @return value. + */ + private Integer getValueFromFormData(JSONObject formData, String key) { + if (formData.has(key)) { + String testData = formData.optString(key); + if (testData == null || testData.isEmpty()) { + return null; + } else { + try { + return Integer.parseInt(testData); + } catch (NumberFormatException nfe) { + return null; + } + } + } + return null; + } + + /** + * Sets all 12 vote values to their defaults. + */ + private void setDefaults() { + buildStartedVerifiedValue = DEFAULT_GERRIT_BUILD_STARTED_VERIFIED_VALUE; + buildSuccessfulVerifiedValue = DEFAULT_GERRIT_BUILD_SUCCESSFUL_VERIFIED_VALUE; + buildFailedVerifiedValue = DEFAULT_GERRIT_BUILD_FAILURE_VERIFIED_VALUE; + buildUnstableVerifiedValue = DEFAULT_GERRIT_BUILD_UNSTABLE_VERIFIED_VALUE; + buildNotBuiltVerifiedValue = DEFAULT_GERRIT_BUILD_NOT_BUILT_VERIFIED_VALUE; + buildAbortedVerifiedValue = DEFAULT_GERRIT_BUILD_ABORTED_VERIFIED_VALUE; + buildStartedCodeReviewValue = DEFAULT_GERRIT_BUILD_STARTED_CODE_REVIEW_VALUE; + buildSuccessfulCodeReviewValue = DEFAULT_GERRIT_BUILD_SUCCESSFUL_CODE_REVIEW_VALUE; + buildFailedCodeReviewValue = DEFAULT_GERRIT_BUILD_FAILURE_CODE_REVIEW_VALUE; + buildUnstableCodeReviewValue = DEFAULT_GERRIT_BUILD_UNSTABLE_CODE_REVIEW_VALUE; + buildNotBuiltCodeReviewValue = DEFAULT_GERRIT_BUILD_NOT_BUILT_CODE_REVIEW_VALUE; + buildAbortedCodeReviewValue = DEFAULT_GERRIT_BUILD_ABORTED_CODE_REVIEW_VALUE; + } + + // ---- Getters ---- + + /** + * Get build started verified value. + * @return the value. + */ + public Integer getBuildStartedVerifiedValue() { + return buildStartedVerifiedValue; + } + + /** + * Get build started code review value. + * @return the value. + */ + public Integer getBuildStartedCodeReviewValue() { + return buildStartedCodeReviewValue; + } + + /** + * Get build successful verified value. + * @return the value. + */ + public Integer getBuildSuccessfulVerifiedValue() { + return buildSuccessfulVerifiedValue; + } + + /** + * Get build successful code review value. + * @return the value. + */ + public Integer getBuildSuccessfulCodeReviewValue() { + return buildSuccessfulCodeReviewValue; + } + + /** + * Get build failed verified value. + * @return the value. + */ + public Integer getBuildFailedVerifiedValue() { + return buildFailedVerifiedValue; + } + + /** + * Get build failed code review value. + * @return the value. + */ + public Integer getBuildFailedCodeReviewValue() { + return buildFailedCodeReviewValue; + } + + /** + * Get build unstable verified value. + * @return the value. + */ + public Integer getBuildUnstableVerifiedValue() { + return buildUnstableVerifiedValue; + } + + /** + * Get build unstable code review value. + * @return the value. + */ + public Integer getBuildUnstableCodeReviewValue() { + return buildUnstableCodeReviewValue; + } + + /** + * Get build not built verified value. + * @return the value. + */ + public Integer getBuildNotBuiltVerifiedValue() { + return buildNotBuiltVerifiedValue; + } + + /** + * Get build not built code review value. + * @return the value. + */ + public Integer getBuildNotBuiltCodeReviewValue() { + return buildNotBuiltCodeReviewValue; + } + + /** + * Get build aborted verified value. + * @return the value. + */ + public Integer getBuildAbortedVerifiedValue() { + return buildAbortedVerifiedValue; + } + + /** + * Get build aborted code review value. + * @return the value. + */ + public Integer getBuildAbortedCodeReviewValue() { + return buildAbortedCodeReviewValue; + } + + // ---- Setters (needed for JCasC / configuration-as-code binding) ---- + + /** + * Set build started verified value. + * @param value the value. + */ + public void setBuildStartedVerifiedValue(Integer value) { + this.buildStartedVerifiedValue = value; + } + + /** + * Set build started code review value. + * @param value the value. + */ + public void setBuildStartedCodeReviewValue(Integer value) { + this.buildStartedCodeReviewValue = value; + } + + /** + * Set build successful verified value. + * @param value the value. + */ + public void setBuildSuccessfulVerifiedValue(Integer value) { + this.buildSuccessfulVerifiedValue = value; + } + + /** + * Set build successful code review value. + * @param value the value. + */ + public void setBuildSuccessfulCodeReviewValue(Integer value) { + this.buildSuccessfulCodeReviewValue = value; + } + + /** + * Set build failed verified value. + * @param value the value. + */ + public void setBuildFailedVerifiedValue(Integer value) { + this.buildFailedVerifiedValue = value; + } + + /** + * Set build failed code review value. + * @param value the value. + */ + public void setBuildFailedCodeReviewValue(Integer value) { + this.buildFailedCodeReviewValue = value; + } + + /** + * Set build unstable verified value. + * @param value the value. + */ + public void setBuildUnstableVerifiedValue(Integer value) { + this.buildUnstableVerifiedValue = value; + } + + /** + * Set build unstable code review value. + * @param value the value. + */ + public void setBuildUnstableCodeReviewValue(Integer value) { + this.buildUnstableCodeReviewValue = value; + } + + /** + * Set build not built verified value. + * @param value the value. + */ + public void setBuildNotBuiltVerifiedValue(Integer value) { + this.buildNotBuiltVerifiedValue = value; + } + + /** + * Set build not built code review value. + * @param value the value. + */ + public void setBuildNotBuiltCodeReviewValue(Integer value) { + this.buildNotBuiltCodeReviewValue = value; + } + + /** + * Set build aborted verified value. + * @param value the value. + */ + public void setBuildAbortedVerifiedValue(Integer value) { + this.buildAbortedVerifiedValue = value; + } + + /** + * Set build aborted code review value. + * @param value the value. + */ + public void setBuildAbortedCodeReviewValue(Integer value) { + this.buildAbortedCodeReviewValue = value; + } +} diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.java index 58a12a58f..cf2b32997 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerParameters.java @@ -266,6 +266,11 @@ public enum GerritTriggerParameters { * The version of the Gerrit instance. */ GERRIT_VERSION, + /** + * Parameter name for the git-over-HTTPS clone URL of the project. + * Format: {frontend_url}/a/{project}.git + */ + GERRIT_GIT_URL, /** * A hashcode of the Gerrit event object, to make sure every set of parameters * is unique (allowing jenkins to queue duplicate builds). @@ -557,6 +562,9 @@ private static void setOrCreateParametersForChangeBasedEvent(ChangeBasedEvent ev } GERRIT_CHANGE_URL.setOrCreateStringParameterValue( parameters, url, escapeQuotes); + String gitUrl = getGitURL(event, project); + GERRIT_GIT_URL.setOrCreateStringParameterValue( + parameters, gitUrl, escapeQuotes); if (event instanceof ChangeAbandoned) { nameAndEmailParameterMode.setOrCreateParameterValue(GERRIT_CHANGE_ABANDONER, parameters, getNameAndEmail(((ChangeAbandoned)event).getAbandoner()), @@ -680,6 +688,43 @@ private static String getURL(ChangeBasedEvent event, Job project) { return url; } + /** + * Get the git clone URL for the project from a ChangeBasedEvent. + * Format: {frontend_url}/a/{project}.git + * + * @param event the event + * @param project the project for which the parameters are being set + * @return the git clone URL + */ + private static String getGitURL(ChangeBasedEvent event, Job project) { + String url = ""; + String serverName = null; + //Figure out what serverName to use + if (event.getProvider() != null) { + serverName = event.getProvider().getName(); + } else if (project != null) { + GerritTrigger trigger = GerritTrigger.getTrigger(project); + if (trigger != null) { + String name = trigger.getServerName(); + if (!GerritServer.ANY_SERVER.equals(name)) { + serverName = name; + } + } + } + GerritServer server = PluginImpl.getServerOrFirst_(serverName); + if (server == null) { + return ""; + } + + IGerritHudsonTriggerConfig config = server.getConfig(); + if (config != null && event.getChange() != null) { + url = StringUtil.makeGerritGitUrl( + config.getGerritFrontEndUrl(), + event.getChange().getProject()); + } + return url; + } + /** * There are two uploader fields in the event, this method gets one of them if one is null. * diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/actions/manual/ManualTriggerAction.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/actions/manual/ManualTriggerAction.java index 5cceb1b6e..4c48deb5c 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/actions/manual/ManualTriggerAction.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/actions/manual/ManualTriggerAction.java @@ -153,6 +153,9 @@ private boolean isServerEnabled(String serverName) { * @return the config of the server or null if config not found. */ private IGerritHudsonTriggerConfig getServerConfig(String serverName) { + if (serverName == null) { + return null; + } GerritServer server = PluginImpl.getServer_(serverName); if (server != null) { IGerritHudsonTriggerConfig config = server.getConfig(); @@ -167,6 +170,24 @@ private IGerritHudsonTriggerConfig getServerConfig(String serverName) { return null; } + /** + * Get the server config for the given server name, falling back to + * the first enabled server when the named server is not found. + * + * @param serverName the name of the server, or null. + * @return the config, or null if no server could be found. + */ + private IGerritHudsonTriggerConfig getServerConfigOrFirst(String serverName) { + IGerritHudsonTriggerConfig config = getServerConfig(serverName); + if (config == null) { + ArrayList enabledServers = getEnabledServers(); + if (!enabledServers.isEmpty()) { + config = getServerConfig(enabledServers.get(0)); + } + } + return config; + } + /** * Return the front end url of selected server, or first enabled server if * selected doesn't exists (happens when serverName is null also). First @@ -177,14 +198,9 @@ private IGerritHudsonTriggerConfig getServerConfig(String serverName) { @SuppressWarnings("unused") //called from jelly public String getFrontEndUrl(String serverName) { - IGerritHudsonTriggerConfig serverConfig = getServerConfig(serverName); + IGerritHudsonTriggerConfig serverConfig = getServerConfigOrFirst(serverName); if (serverConfig != null) { return serverConfig.getGerritFrontEndUrl(); - } else { - ArrayList enabledServers = getEnabledServers(); - if (!enabledServers.isEmpty()) { - return getServerConfig(enabledServers.get(0)).getGerritFrontEndUrl(); - } } return null; } @@ -325,7 +341,13 @@ public void doGerritSearch(@QueryParameter("queryString") final String queryStri IGerritHudsonTriggerConfig config = getServerConfig(selectedServer); if (config != null) { - GerritQueryHandler handler = new GerritQueryHandler(config); + GerritServer server = PluginImpl.getServer_(selectedServer); + GerritQueryHandler handler = null; + if (server != null) { + handler = server.getQueryHandler(); + } else { + handler = new GerritQueryHandler(config); + } clearSessionData(session); session.setAttribute("queryString", queryString); @@ -592,8 +614,9 @@ public String getGerritUrl(JSONObject change, String serverName) { if (url != null && !url.isEmpty()) { return url; } else if (!change.optString("number", "").isEmpty()) { - if (getServerConfig(serverName) != null) { - return getServerConfig(serverName).getGerritFrontEndUrlFor( + IGerritHudsonTriggerConfig config = getServerConfigOrFirst(serverName); + if (config != null) { + return config.getGerritFrontEndUrlFor( change.getString("number"), "1"); } else { logger.error("Could not get config for the server: {}", serverName); diff --git a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/utils/StringUtil.java b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/utils/StringUtil.java index ea91315be..ceacf768d 100644 --- a/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/utils/StringUtil.java +++ b/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/utils/StringUtil.java @@ -29,6 +29,7 @@ import com.sonymobile.tools.gerrit.gerritevents.GerritEventListener; import com.sonymobile.tools.gerrit.gerritevents.dto.events.ChangeBasedEvent; import java.util.regex.Pattern; +import hudson.Functions; /** * Various string making utility methods. @@ -117,6 +118,18 @@ public static String getPluginJsUrl(String jsName) { return PLUGIN_JS_URL + jsName; } + /** + * Creates a Gerrit git clone URL from the frontend URL and project name. + * Gerrit exposes git repositories at {@code {frontend_url}/a/{project}.git}. + * + * @param frontEndUrl the Gerrit front-end URL (with or without trailing slash). + * @param project the Gerrit project name. + * @return the git clone URL. + */ + public static String makeGerritGitUrl(String frontEndUrl, String project) { + return Functions.joinPath(frontEndUrl, "a/" + project + ".git"); + } + /** * Escape quotes in String value. * @param value the name of String object having quotes. diff --git a/src/main/resources/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer/index.jelly b/src/main/resources/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer/index.jelly index 1219bde05..eb501e897 100644 --- a/src/main/resources/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer/index.jelly +++ b/src/main/resources/com/sonyericsson/hudson/plugins/gerrit/trigger/GerritServer/index.jelly @@ -5,6 +5,7 @@