package org.jenkinsci.plugins.p4.trigger; import edu.umd.cs.findbugs.annotations.CheckForNull; import hudson.Extension; import hudson.model.Job; import hudson.model.UnprotectedRootAction; import hudson.triggers.Trigger; import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; import jenkins.scm.api.SCMEvent; import jenkins.scm.api.SCMHeadEvent; import net.sf.json.JSONObject; import org.apache.commons.io.IOUtils; import org.jenkinsci.plugins.p4.scm.events.P4BranchScmHeadEvent; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import javax.servlet.ServletException; import java.io.IOException; import java.net.URLDecoder; import java.nio.charset.Charset; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Logger; @Extension public class P4Hook implements UnprotectedRootAction { ExecutorService executorService = Executors.newSingleThreadExecutor(); public static final String URLNAME = "p4"; @Override public String getIconFileName() { return "/plugin/p4/icons/helix-24px.png"; } @Override public String getDisplayName() { return "P4 Trigger"; } @Override public String getUrlName() { return URLNAME; } public void doEvent(StaplerRequest req) throws ServletException, IOException { // exit early if no json String contentType = req.getContentType(); if (contentType == null || !contentType.startsWith("application/json")) { return; } String body = IOUtils.toString(req.getInputStream(), Charset.forName("UTF-8")); if (body.startsWith("payload=")) { body = body.substring(8); } JSONObject payload = JSONObject.fromObject(body); String typeString = payload.getString("type"); SCMEvent.Type eventType = SCMEvent.Type.valueOf(typeString); SCMHeadEvent.fireNow(new P4BranchScmHeadEvent(eventType, payload, SCMEvent.originOf(req))); } public void doChange(StaplerRequest req) throws IOException { String body = IOUtils.toString(req.getInputStream(), Charset.forName("UTF-8")); String contentType = req.getContentType(); if (contentType != null && contentType.startsWith("application/json")) { body = URLDecoder.decode(body, "UTF-8"); } if (body.startsWith("payload=")) { body = body.substring(8); JSONObject payload = JSONObject.fromObject(body); final String port = payload.getString("p4port"); //final String change = payload.getString("change"); final List<Job> jobs = getJobs(); LOGGER.info("Received trigger event for: " + port); if (port == null) { LOGGER.warning("p4port must be specified"); return; } // Use an executor to prevent blocking the trigger during polling executorService.submit(new Runnable() { @Override public void run() { try { probeJobs(port, jobs); } catch (IOException e) { LOGGER.severe("Error on Polling Thread."); e.printStackTrace(); } } }); } } public void doChangeSubmit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { JSONObject formData = req.getSubmittedForm(); if (!formData.isEmpty()) { String port = req.getParameter("_.p4port"); //String change = req.getParameter("_.change"); List<Job> jobs = getJobs(); LOGGER.info("Manual trigger event: "); if (port != null) { probeJobs(port, jobs); } else { LOGGER.warning("p4port must be specified"); } // send the user back. rsp.sendRedirect("../"); } } private void probeJobs(@CheckForNull String port, List<Job> jobs) throws IOException { for (Job<?, ?> job : jobs) { if (!job.isBuildable()) { continue; } LOGGER.fine("P4: trying: " + job.getName()); P4Trigger trigger = null; if (job instanceof ParameterizedJobMixIn.ParameterizedJob) { ParameterizedJobMixIn.ParameterizedJob pJob = (ParameterizedJobMixIn.ParameterizedJob) job; for (Trigger<?> t : pJob.getTriggers().values()) { if (t instanceof P4Trigger) { trigger = (P4Trigger) t; break; } } } if (trigger != null) { LOGGER.info("P4: probing: " + job.getName()); trigger.poke(job, port); } else { LOGGER.fine("P4: trigger not set: " + job.getName()); } } } private List<Job> getJobs() { Jenkins j = Jenkins.getInstance(); return j.getAllItems(Job.class); } final static Logger LOGGER = Logger.getLogger(P4Hook.class.getName()); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#19 | 26356 | matthew_smeeth |
Reverting job list to original pre 1.10.10 release. JENKINS-61156 |
||
#18 | 26352 | Paul Allen | [SECURITY-1765] | ||
#17 | 26294 | Paul Allen |
Merge pull request #116 from ajxb/ajb-trigger Get list of jobs immediately prior to probing |
||
#16 | 24622 | Paul Allen | Added 'command-launcher' for Jenkins 2.89.1 release and greater. | ||
#15 | 24529 | Paul Allen |
Swarm Commit Event support, refactoring and test. JENKINS-52605 (Fix doc in 'Includes' help bubble for MultiBranch) JENKINS-52066 (Improve Swarm Commit and Branch Event support) |
||
#14 | 24501 | Paul Allen | Refactor to use P4SCMXxx naming convention. | ||
#13 | 24492 | Paul Allen |
Initial work for MultiBranch Event trigger. JENKINS-52066 (Triggered Events and not Polling per change) |
||
#12 | 24488 | Paul Allen |
Min version Jenkins 2.60.3 Upgrade dependencies and move to Java 8. |
||
#11 | 24029 | Paul Allen |
Merge pull request #71 from AllegorithmicSAS/CrumbExclusion Add CrumbExclusion for /p4/change |
||
#10 | 23858 | Paul Allen |
Skip probing disabled Jobs. Includes minor updates to Polling tests. JENKINS-50634 |
||
#9 | 23258 | Paul Allen | Clean up a few minor warnings. | ||
#8 | 22823 | Paul Allen |
Update URLs in README. Minor find bug fix. |
||
#7 | 22822 | Paul Allen |
Pipeline trigger fixes for Graph. Fetch JobList outside ExecutorService. |
||
#6 | 22166 | Paul Allen | Brand update. | ||
#5 | 21272 | Paul Allen |
Use ExecutorService to prevent blocking during polling task. JENKINS-39278 JENKINS-39152 |
||
#4 | 19641 | Paul Allen |
Merge pull request #26 from Dohbedoh/hotfix/JENKINS-25249 [JENKINS-25249]: Fixed Null Pointer dereference |
||
#3 | 19593 | Paul Allen | More minor fixes to satisfy FindBugs Analysis. | ||
#2 | 19294 | Paul Allen |
Schedule build on trigger for subscribed Jobs. JENKINS-33858 |
||
#1 | 15403 | Paul Allen |
Perforce triggered polling BETA. Perforce triggers on a change-submit and sends a POST to the endpoint http://${JENKINS}/p4/change with the data: {"change":"12345","p4port":"localhost:1666"} Note: ‘change’ is not used (yet), but ‘p4port’ MUST match the credential in the Jenkins Job. JENKINS-25249 |