Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FIXED JENKINS-28632] Workflow step for awaiting for a deployment
- Loading branch information
Showing
7 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
src/main/java/org/jenkinsci/plugins/deployment/workflowsteps/AwaitDeploymentAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.jenkinsci.plugins.deployment.workflowsteps; | ||
|
||
import hudson.model.Run; | ||
import jenkins.model.RunAction2; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* AwaitDeployment action | ||
*/ | ||
public class AwaitDeploymentAction implements RunAction2 { | ||
|
||
private final String message; | ||
private final List<AwaitDeploymentStepExecution> executions = new ArrayList<AwaitDeploymentStepExecution>(); | ||
|
||
@DataBoundConstructor | ||
public AwaitDeploymentAction(String message) { | ||
this.message = message; | ||
} | ||
|
||
private transient Run<?,?> run; | ||
@Override | ||
public void onAttached(Run<?, ?> run) { | ||
this.run = run; | ||
} | ||
|
||
@Override | ||
public void onLoad(Run<?, ?> run) { | ||
this.run = run; | ||
assert executions != null && !executions.contains(null) : executions; | ||
for (AwaitDeploymentStepExecution step : executions) { | ||
step.run = run; | ||
} | ||
} | ||
|
||
@Override | ||
public String getIconFileName() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getUrlName() { | ||
return null; | ||
} | ||
|
||
/** | ||
* Called when {@link AwaitDeploymentAction} is completed to remove it from the active input list. | ||
*/ | ||
public synchronized void remove(AwaitDeploymentStepExecution exec) throws IOException { | ||
executions.remove(exec); | ||
run.save(); | ||
} | ||
|
||
public synchronized void add(@Nonnull AwaitDeploymentStepExecution step) throws IOException { | ||
this.executions.add(step); | ||
run.save(); | ||
} | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
src/main/java/org/jenkinsci/plugins/deployment/workflowsteps/AwaitDeploymentStep.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package org.jenkinsci.plugins.deployment.workflowsteps; | ||
|
||
import hudson.Extension; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
||
import java.io.Serializable; | ||
|
||
/** | ||
* Workflow Step for awaiting for a deployment | ||
*/ | ||
public class AwaitDeploymentStep extends AbstractStepImpl implements Serializable { | ||
|
||
private final int threshold; | ||
private final String env; | ||
|
||
@DataBoundConstructor | ||
public AwaitDeploymentStep(int threshold, String env) { | ||
this.threshold = threshold; | ||
this.env = env; | ||
} | ||
|
||
public int getThreshold() { | ||
return threshold; | ||
} | ||
|
||
public String getEnv() { | ||
return env; | ||
} | ||
|
||
@Override | ||
public DescriptorImpl getDescriptor() { | ||
return (DescriptorImpl)super.getDescriptor(); | ||
} | ||
|
||
@Extension | ||
public static class DescriptorImpl extends AbstractStepDescriptorImpl { | ||
|
||
public DescriptorImpl() { | ||
super(AwaitDeploymentStepExecution.class); | ||
} | ||
|
||
@Override | ||
public String getFunctionName() { | ||
return "awaitDeployment"; | ||
} | ||
|
||
@Override | ||
public String getDisplayName() { | ||
return "Awaiting for deployment"; | ||
} | ||
} | ||
|
||
} |
66 changes: 66 additions & 0 deletions
66
...ain/java/org/jenkinsci/plugins/deployment/workflowsteps/AwaitDeploymentStepExecution.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package org.jenkinsci.plugins.deployment.workflowsteps; | ||
|
||
import com.google.inject.Inject; | ||
import hudson.model.Fingerprint; | ||
import hudson.model.Job; | ||
import hudson.model.Run; | ||
import org.jenkinsci.plugins.deployment.DeploymentFacet; | ||
import org.jenkinsci.plugins.deployment.HostRecord; | ||
import org.jenkinsci.plugins.deployment.conditions.ThresholdCondition; | ||
import org.jenkinsci.plugins.workflow.graph.FlowNode; | ||
import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl; | ||
import org.jenkinsci.plugins.workflow.steps.StepContextParameter; | ||
|
||
import java.util.concurrent.ScheduledFuture; | ||
|
||
/** | ||
* The Execution for AwaitDeploymentStep | ||
*/ | ||
public class AwaitDeploymentStepExecution extends AbstractStepExecutionImpl { | ||
|
||
@Inject(optional=true) private transient AwaitDeploymentStep awaitDeploymentStep; | ||
@StepContextParameter | ||
private transient FlowNode node; | ||
@StepContextParameter | ||
transient Run run; | ||
private transient volatile ScheduledFuture<?> task; | ||
@StepContextParameter | ||
private transient Run build; | ||
@StepContextParameter | ||
private transient Job job; | ||
|
||
@Override | ||
public boolean start() throws Exception { | ||
node.addAction(new AwaitDeploymentAction("Await for deployment")); | ||
|
||
return false; | ||
} | ||
|
||
@Override public void stop(Throwable cause) throws Exception { | ||
if (task != null) { | ||
task.cancel(false); | ||
} | ||
getContext().onFailure(cause); | ||
} | ||
|
||
public void proceed(DeploymentFacet<?> facet, HostRecord newRecord) { | ||
ThresholdCondition thresholdCondition = new ThresholdCondition(awaitDeploymentStep.getEnv(), awaitDeploymentStep.getThreshold()); | ||
Fingerprint.RangeSet r = thresholdCondition.calcMatchingBuildNumberOf(null, facet.getFingerprint(), job); | ||
|
||
if (!r.isEmpty()) { | ||
for (Integer n : r.listNumbers()) { | ||
Run b = job.getBuildByNumber(n); | ||
if (b!=null) { | ||
if (b.getId().equals(build.getId())) { | ||
getContext().onSuccess(null); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override public void onResume() { | ||
super.onResume(); | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/org/jenkinsci/plugins/deployment/workflowsteps/WorkflowListenerImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package org.jenkinsci.plugins.deployment.workflowsteps; | ||
|
||
import com.google.common.base.Function; | ||
import hudson.Extension; | ||
import org.jenkinsci.plugins.deployment.DeploymentFacet; | ||
import org.jenkinsci.plugins.deployment.DeploymentFacetListener; | ||
import org.jenkinsci.plugins.deployment.DeploymentTrigger; | ||
import org.jenkinsci.plugins.deployment.HostRecord; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.LinkedBlockingQueue; | ||
import java.util.concurrent.ThreadPoolExecutor; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
/** | ||
* Deployment Listener for Workflow jobs | ||
*/ | ||
@Extension | ||
public class WorkflowListenerImpl extends DeploymentFacetListener { | ||
|
||
@Override | ||
public void onChange(final DeploymentFacet facet, final HostRecord newRecord) { | ||
LOGGER.log(Level.FINE, "Deployment triggered"); | ||
POOL.submit(new Runnable() { | ||
public void run() { | ||
AwaitDeploymentStepExecution.applyAll(AwaitDeploymentStepExecution.class, new Function<AwaitDeploymentStepExecution, Void>() { | ||
@Override public Void apply(@Nonnull AwaitDeploymentStepExecution awaitDeploymentStepExecution) { | ||
awaitDeploymentStepExecution.proceed(facet, newRecord); | ||
return null; | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Waits until all the pending deployment facets are processed. | ||
*/ | ||
public void sync() throws InterruptedException { | ||
try { | ||
POOL.submit(new Runnable() { | ||
public void run() { | ||
// no-op | ||
} | ||
}).get(); | ||
} catch (ExecutionException e) { | ||
throw (InterruptedException)new InterruptedException().initCause(e); | ||
} | ||
} | ||
|
||
public final ExecutorService POOL = new ThreadPoolExecutor(0, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); | ||
private static final Logger LOGGER = Logger.getLogger(DeploymentTrigger.class.getName()); | ||
|
||
} |