Merge pull request #293 from jenkinsci/bug/JENKINS-36207
JENKINS-36207# Make BluePipeline extensible
This commit is contained in:
commit
4fc6519c53
|
@ -16,9 +16,7 @@ import io.jenkins.blueocean.rest.model.GenericResource;
|
|||
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.export.Exported;
|
||||
import org.kohsuke.stapler.export.ExportedBean;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -176,15 +174,8 @@ public class AbstractRunImpl<T extends Run> extends BlueRun {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Collection<?> getActions() {
|
||||
List<BlueActionProxy> actionProxies = new ArrayList<>();
|
||||
for(Action action:run.getAllActions()){
|
||||
if(action == null || !action.getClass().isAnnotationPresent(ExportedBean.class)){
|
||||
continue;
|
||||
}
|
||||
actionProxies.add(new ActionProxiesImpl(action, this));
|
||||
}
|
||||
return actionProxies;
|
||||
public Collection<BlueActionProxy> getActions() {
|
||||
return PipelineImpl.getActionProxies(run.getAllActions(), this);
|
||||
}
|
||||
|
||||
protected static BlueRun getBlueRun(Run r, Link parent){
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.Job;
|
||||
import hudson.model.Result;
|
||||
import hudson.model.Run;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.Navigable;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BlueActionProxy;
|
||||
import io.jenkins.blueocean.rest.model.BlueMultiBranchPipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import io.jenkins.blueocean.rest.model.BlueQueueItem;
|
||||
import io.jenkins.blueocean.rest.model.BlueRun;
|
||||
import io.jenkins.blueocean.rest.model.BlueRunContainer;
|
||||
|
@ -252,8 +257,25 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BlueActionProxy> getActions() {
|
||||
return PipelineImpl.getActionProxies(mbp.getAllActions(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Link getLink() {
|
||||
return self;
|
||||
}
|
||||
|
||||
@Extension(ordinal = 2)
|
||||
public static class PipelineFactoryImpl extends BluePipelineFactory{
|
||||
|
||||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if (item instanceof MultiBranchProject) {
|
||||
return new MultiBranchPipelineImpl((MultiBranchProject) item, parent.getLink());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.jenkins.blueocean.commons.ServiceException;
|
|||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import jenkins.branch.MultiBranchProject;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||
|
@ -49,16 +50,12 @@ public class PipelineContainerImpl extends BluePipelineContainer {
|
|||
}
|
||||
|
||||
public BluePipeline get(Item item){
|
||||
if (item instanceof BuildableItem) {
|
||||
if (item instanceof MultiBranchProject) {
|
||||
return new MultiBranchPipelineImpl((MultiBranchProject) item, getLink());
|
||||
} else if (item instanceof Job) {
|
||||
return new PipelineImpl((Job) item, getLink());
|
||||
for(BluePipelineFactory factory:BluePipelineFactory.all()){
|
||||
BluePipeline pipeline = factory.getPipeline(item, this);
|
||||
if( pipeline!= null){
|
||||
return pipeline;
|
||||
}
|
||||
} else if (item instanceof ItemGroup) {
|
||||
return new PipelineFolderImpl((ItemGroup) item, getLink());
|
||||
}
|
||||
|
||||
// TODO: I'm going to turn this into a decorator annotation
|
||||
throw new ServiceException.NotFoundException(String.format("Pipeline %s not found", item.getName()));
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BlueActionProxy;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFolder;
|
||||
import io.jenkins.blueocean.service.embedded.util.FavoriteUtil;
|
||||
import org.kohsuke.stapler.json.JsonBody;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.jenkins.blueocean.service.embedded.rest.PipelineImpl.getRecursivePathFromFullName;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +52,11 @@ public class PipelineFolderImpl extends BluePipelineFolder {
|
|||
return folder.getFullName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BlueActionProxy> getActions() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluePipelineContainer getPipelines() {
|
||||
return new PipelineContainerImpl(folder);
|
||||
|
@ -86,4 +99,15 @@ public class PipelineFolderImpl extends BluePipelineFolder {
|
|||
return OrganizationImpl.INSTANCE.getLink().rel("pipelines").rel(getRecursivePathFromFullName(this));
|
||||
}
|
||||
|
||||
@Extension(ordinal = 0)
|
||||
public static class PipelineFactoryImpl extends BluePipelineFactory{
|
||||
|
||||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if (item instanceof ItemGroup) {
|
||||
return new PipelineFolderImpl((ItemGroup) item, parent.getLink());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.Extension;
|
||||
import hudson.model.Action;
|
||||
import hudson.model.BuildableItem;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.Navigable;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BlueActionProxy;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import io.jenkins.blueocean.rest.model.BlueQueueContainer;
|
||||
import io.jenkins.blueocean.rest.model.BlueRun;
|
||||
import io.jenkins.blueocean.rest.model.BlueRunContainer;
|
||||
|
@ -15,16 +20,21 @@ import io.jenkins.blueocean.service.embedded.util.FavoriteUtil;
|
|||
import jenkins.branch.MultiBranchProject;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.WebMethod;
|
||||
import org.kohsuke.stapler.export.ExportedBean;
|
||||
import org.kohsuke.stapler.json.JsonBody;
|
||||
import org.kohsuke.stapler.verb.DELETE;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static io.jenkins.blueocean.service.embedded.rest.PipelineContainerImpl.isMultiBranchProjectJob;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
|
||||
public class PipelineImpl extends BluePipeline {
|
||||
/*package*/ final Job job;
|
||||
|
||||
|
@ -93,6 +103,11 @@ public class PipelineImpl extends BluePipeline {
|
|||
return new RunContainerImpl(this, job);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BlueActionProxy> getActions() {
|
||||
return getActionProxies(job.getAllActions(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Navigable
|
||||
public BlueQueueContainer getQueue() {
|
||||
|
@ -140,8 +155,6 @@ public class PipelineImpl extends BluePipeline {
|
|||
|
||||
@Override
|
||||
public Link getLink() {
|
||||
// Link parentLink = (parent == null) ? OrganizationImpl.INSTANCE.getLink().rel("pipelines") : parent;
|
||||
|
||||
return OrganizationImpl.INSTANCE.getLink().rel("pipelines").rel(getRecursivePathFromFullName(this));
|
||||
}
|
||||
|
||||
|
@ -164,4 +177,28 @@ public class PipelineImpl extends BluePipeline {
|
|||
return pipelinePath.toString();
|
||||
}
|
||||
|
||||
@Extension(ordinal = 1)
|
||||
public static class PipelineFactoryImpl extends BluePipelineFactory {
|
||||
|
||||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if (item instanceof Job) {
|
||||
return new PipelineImpl((Job) item, parent.getLink());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<BlueActionProxy> getActionProxies(List<? extends Action> actions, Reachable parent){
|
||||
List<BlueActionProxy> actionProxies = new ArrayList<>();
|
||||
for(Action action:actions){
|
||||
if(action == null || !action.getClass().isAnnotationPresent(ExportedBean.class)){
|
||||
continue;
|
||||
}
|
||||
actionProxies.add(new ActionProxiesImpl(action, parent));
|
||||
}
|
||||
return actionProxies;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.jenkins.blueocean.service.embedded;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mashape.unirest.http.HttpResponse;
|
||||
import hudson.Extension;
|
||||
import hudson.FilePath;
|
||||
import hudson.Launcher;
|
||||
import hudson.model.AbstractBuild;
|
||||
|
@ -10,6 +11,9 @@ import hudson.model.Cause;
|
|||
import hudson.model.CauseAction;
|
||||
import hudson.model.FreeStyleBuild;
|
||||
import hudson.model.FreeStyleProject;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import hudson.model.ParametersAction;
|
||||
import hudson.model.ParametersDefinitionProperty;
|
||||
import hudson.model.Project;
|
||||
|
@ -21,6 +25,11 @@ import hudson.tasks.ArtifactArchiver;
|
|||
import hudson.tasks.Shell;
|
||||
import hudson.tasks.junit.JUnitResultArchiver;
|
||||
import hudson.tasks.junit.TestResultAction;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import io.jenkins.blueocean.service.embedded.rest.PipelineImpl;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
|
||||
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||
|
@ -30,6 +39,7 @@ import org.junit.Test;
|
|||
import org.jvnet.hudson.test.MockFolder;
|
||||
import org.jvnet.hudson.test.TestBuilder;
|
||||
import org.kohsuke.stapler.AcceptHeader;
|
||||
import org.kohsuke.stapler.export.Exported;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -532,4 +542,40 @@ public class PipelineApiTest extends BaseTest {
|
|||
Assert.assertNotNull(p3.getQueueItem());
|
||||
Assert.assertEquals(Long.toString(p3.getQueueItem().getId()), r.get("id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPipelinesExtensionTest() throws Exception {
|
||||
|
||||
Project p = j.createFreeStyleProject("pipeline1");
|
||||
|
||||
Map<String,Object> response = get("/organizations/jenkins/pipelines/pipeline1");
|
||||
validatePipeline(p, response);
|
||||
|
||||
Assert.assertEquals("hello world!", response.get("hello"));
|
||||
}
|
||||
|
||||
@Extension(ordinal = 3)
|
||||
public static class PipelineFactoryTestImpl extends BluePipelineFactory {
|
||||
|
||||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if(item instanceof Job){
|
||||
return new TestPipelineImpl(null, (Job)item, parent.getLink());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestPipelineImpl extends PipelineImpl {
|
||||
|
||||
public TestPipelineImpl(ItemGroup folder, Job job, Link parent) {
|
||||
super(folder, job, parent);
|
||||
}
|
||||
|
||||
@Exported(name = "hello")
|
||||
public String getHello(){
|
||||
return "hello world!";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import org.kohsuke.stapler.export.Exported;
|
|||
import org.kohsuke.stapler.json.JsonBody;
|
||||
import org.kohsuke.stapler.verb.PUT;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Defines pipeline state and its routing
|
||||
*
|
||||
|
@ -20,6 +22,7 @@ public abstract class BluePipeline extends Resource {
|
|||
public static final String LATEST_RUN = "latestRun";
|
||||
public static final String ESTIMATED_DURATION = "estimatedDurationInMillis";
|
||||
public static final String LAST_SUCCESSFUL_RUN = "lastSuccessfulRun";
|
||||
public static final String ACTIONS = "actions";
|
||||
|
||||
/**
|
||||
* @return name of the organization
|
||||
|
@ -74,6 +77,15 @@ public abstract class BluePipeline extends Resource {
|
|||
@Navigable
|
||||
public abstract BlueRunContainer getRuns();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Gives Actions associated with this Run
|
||||
*/
|
||||
@Navigable
|
||||
@Exported(name = ACTIONS, inline = true)
|
||||
public abstract Collection<BlueActionProxy> getActions();
|
||||
|
||||
/**
|
||||
* @return Gives {@link BlueQueueContainer}
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.jenkins.blueocean.rest.model;
|
||||
|
||||
import hudson.ExtensionList;
|
||||
import hudson.ExtensionPoint;
|
||||
import hudson.model.Item;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
|
||||
/**
|
||||
* Factory that gives instance of {@link BluePipeline}
|
||||
*
|
||||
* It's useful for example in cases where a plugin that has custom project and they want to serve
|
||||
* extra meta-data thru BluePipeline, would provide implementation of their BluePipeline and and implementation
|
||||
* of BluePipelineFactory.
|
||||
*
|
||||
* @author Vivek Pandey
|
||||
*/
|
||||
public abstract class BluePipelineFactory implements ExtensionPoint {
|
||||
public abstract BluePipeline getPipeline(Item item, Reachable parent);
|
||||
|
||||
public static ExtensionList<BluePipelineFactory> all(){
|
||||
return ExtensionList.lookup(BluePipelineFactory.class);
|
||||
}
|
||||
}
|
|
@ -162,13 +162,19 @@ public abstract class BlueRun extends Resource {
|
|||
@Navigable
|
||||
public abstract BluePipelineNodeContainer getNodes();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Gives Actions associated with this Run
|
||||
*/
|
||||
@Navigable
|
||||
@Exported(name = ACTIONS, inline = true)
|
||||
public abstract Collection<?> getActions();
|
||||
public abstract Collection<BlueActionProxy> getActions();
|
||||
|
||||
/**
|
||||
* @return Gives steps from pipeline. The list of steps must not include stages, this is because stage could be
|
||||
* interpreted as step as its StepAtomNode and implementation of this API must ensure not to include it.
|
||||
*/
|
||||
@Navigable
|
||||
@Exported(name = STEPS)
|
||||
public abstract BluePipelineStepContainer getSteps();
|
||||
|
||||
|
@ -182,6 +188,7 @@ public abstract class BlueRun extends Resource {
|
|||
* X-TEXT-SIZE header value with *start* query parameter.</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Navigable
|
||||
public abstract Object getLog();
|
||||
|
||||
public enum BlueRunState {
|
||||
|
|
Loading…
Reference in New Issue