UX-196# API for walking folder tree
- Folder contains other pipelines and folder and other buildable items - Nested folder or pipeline can be accessed using recursive REST path - Access p1 pipeline nested inside a folder: /organizations/jenkins/pipelines/folder1/pipelines/folder2/pipelines/p1 - Folder vs pipeline detection to happen with data extensibility/capability work
This commit is contained in:
parent
91e266ee0d
commit
603d36011d
|
@ -50,7 +50,7 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
throw new ServiceException.UnexpectedErrorException("no master branch to favorite");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(job, favoriteAction.isFavorite());
|
||||
FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,6 +63,11 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
return mbp.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return mbp.getFullName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTotalNumberOfBranches(){
|
||||
return countJobs(false);
|
||||
|
@ -95,7 +100,7 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public int getWeatherScore(){
|
||||
public Integer getWeatherScore(){
|
||||
/**
|
||||
* TODO: this code need cleanup once MultiBranchProject exposes default branch. At present
|
||||
*
|
||||
|
@ -229,5 +234,4 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
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.model.BluePipeline;
|
||||
|
@ -10,6 +12,7 @@ import jenkins.model.Jenkins;
|
|||
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -17,13 +20,37 @@ import java.util.List;
|
|||
* @author Vivek Pandey
|
||||
*/
|
||||
public class PipelineContainerImpl extends BluePipelineContainer {
|
||||
private final ItemGroup itemGroup;
|
||||
|
||||
public PipelineContainerImpl(ItemGroup itemGroup) {
|
||||
this.itemGroup = itemGroup;
|
||||
}
|
||||
|
||||
public PipelineContainerImpl() {
|
||||
this.itemGroup = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluePipeline get(String name) {
|
||||
Item item;
|
||||
if(itemGroup == null){
|
||||
item = Jenkins.getActiveInstance().getItem(name);
|
||||
}else{
|
||||
item = itemGroup.getItem(name);
|
||||
}
|
||||
|
||||
for (BluePipeline bluePipeline : this) {
|
||||
if (bluePipeline.getName().equals(name)) {
|
||||
return bluePipeline;
|
||||
if(item == null){
|
||||
throw new ServiceException.NotFoundException(String.format("Pipeline %s not found", name));
|
||||
}
|
||||
|
||||
if (item instanceof BuildableItem) {
|
||||
if (item instanceof MultiBranchProject) {
|
||||
return new MultiBranchPipelineImpl((MultiBranchProject) item);
|
||||
} else if (!isMultiBranchProjectJob((BuildableItem) item) && item instanceof Job) {
|
||||
return new PipelineImpl((Job) item);
|
||||
}
|
||||
} else if (item instanceof ItemGroup) {
|
||||
return new PipelineFolderImpl((ItemGroup) item);
|
||||
}
|
||||
|
||||
// TODO: I'm going to turn this into a decorator annotation
|
||||
|
@ -31,20 +58,31 @@ public class PipelineContainerImpl extends BluePipelineContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<BluePipeline> iterator() {
|
||||
List<BuildableItem> items = Jenkins.getActiveInstance().getAllItems(BuildableItem.class);
|
||||
if(itemGroup != null){
|
||||
return getPipelines(itemGroup.getItems());
|
||||
}else{
|
||||
return getPipelines(Jenkins.getActiveInstance().getAllItems(Item.class));
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean isMultiBranchProjectJob(BuildableItem item){
|
||||
return item instanceof WorkflowJob && item.getParent() instanceof MultiBranchProject;
|
||||
}
|
||||
|
||||
protected static Iterator<BluePipeline> getPipelines(Collection<Item> items){
|
||||
List<BluePipeline> pipelines = new ArrayList<>();
|
||||
for (BuildableItem item : items) {
|
||||
for (Item item : items) {
|
||||
if(item instanceof MultiBranchProject){
|
||||
pipelines.add(new MultiBranchPipelineImpl((MultiBranchProject) item));
|
||||
}else if(!isMultiBranchProjectJob(item) && item instanceof Job){
|
||||
}else if(item instanceof BuildableItem && !isMultiBranchProjectJob((BuildableItem) item)
|
||||
&& item instanceof Job){
|
||||
pipelines.add(new PipelineImpl((Job) item));
|
||||
}else if(item instanceof ItemGroup){
|
||||
pipelines.add(new PipelineFolderImpl((ItemGroup) item));
|
||||
}
|
||||
}
|
||||
return pipelines.iterator();
|
||||
}
|
||||
|
||||
private boolean isMultiBranchProjectJob(BuildableItem item){
|
||||
return item instanceof WorkflowJob && item.getParent() instanceof MultiBranchProject;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.model.ItemGroup;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFolder;
|
||||
import io.jenkins.blueocean.service.embedded.util.FavoriteUtil;
|
||||
import org.kohsuke.stapler.json.JsonBody;
|
||||
|
||||
/**
|
||||
* @author Vivek Pandey
|
||||
*/
|
||||
public class PipelineFolderImpl extends BluePipelineFolder {
|
||||
|
||||
private final ItemGroup folder;
|
||||
private final BluePipelineContainer container;
|
||||
|
||||
public PipelineFolderImpl(ItemGroup folder) {
|
||||
this.folder = folder;
|
||||
this.container = new PipelineContainerImpl(folder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrganization() {
|
||||
return OrganizationImpl.INSTANCE.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return folder.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return folder.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return folder.getFullName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluePipelineContainer getPipelines() {
|
||||
return new PipelineContainerImpl(folder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberOfFolders() {
|
||||
int count=0;
|
||||
for(BluePipeline p:getPipelines ()){
|
||||
if(p instanceof BluePipelineFolder){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberOfPipelines() {
|
||||
int count=0;
|
||||
for(BluePipeline p:getPipelines ()){
|
||||
if(!(p instanceof BluePipelineFolder)){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void favorite(@JsonBody FavoriteAction favoriteAction) {
|
||||
if(favoriteAction == null) {
|
||||
throw new ServiceException.BadRequestExpception("Must provide pipeline name");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(folder.getFullName(), favoriteAction.isFavorite());
|
||||
}
|
||||
}
|
|
@ -1,11 +1,15 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
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.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BlueRun;
|
||||
import io.jenkins.blueocean.rest.model.BlueRunContainer;
|
||||
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.json.JsonBody;
|
||||
|
@ -14,6 +18,7 @@ import org.kohsuke.stapler.verb.DELETE;
|
|||
import java.io.IOException;
|
||||
|
||||
import static io.jenkins.blueocean.rest.Utils.ensureTrailingSlash;
|
||||
import static io.jenkins.blueocean.service.embedded.rest.PipelineContainerImpl.isMultiBranchProjectJob;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
|
@ -21,10 +26,19 @@ import static io.jenkins.blueocean.rest.Utils.ensureTrailingSlash;
|
|||
public class PipelineImpl extends BluePipeline {
|
||||
/*package*/ final Job job;
|
||||
|
||||
protected PipelineImpl(Job job) {
|
||||
private final ItemGroup folder;
|
||||
protected PipelineImpl(ItemGroup folder, Job job) {
|
||||
this.job = job;
|
||||
this.folder = folder;
|
||||
}
|
||||
|
||||
public PipelineImpl(ItemGroup folder) {
|
||||
this(folder, null);
|
||||
}
|
||||
|
||||
public PipelineImpl(Job job) {
|
||||
this(null, job);
|
||||
}
|
||||
@Override
|
||||
public String getOrganization() {
|
||||
return OrganizationImpl.INSTANCE.getName();
|
||||
|
@ -41,7 +55,7 @@ public class PipelineImpl extends BluePipeline {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getWeatherScore() {
|
||||
public Integer getWeatherScore() {
|
||||
return job.getBuildHealth().getScore();
|
||||
}
|
||||
|
||||
|
@ -93,6 +107,30 @@ public class PipelineImpl extends BluePipeline {
|
|||
throw new ServiceException.BadRequestExpception("Must provide pipeline name");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(job, favoriteAction.isFavorite());
|
||||
FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullName(){
|
||||
return job.getFullName();
|
||||
}
|
||||
|
||||
public BluePipeline getPipelines(String name){
|
||||
assert folder != null;
|
||||
return getPipelines(folder, name);
|
||||
}
|
||||
|
||||
protected static BluePipeline getPipelines(ItemGroup itemGroup, String name){
|
||||
Item item = itemGroup.getItem(name);
|
||||
if(item instanceof BuildableItem){
|
||||
if(item instanceof MultiBranchProject){
|
||||
return new MultiBranchPipelineImpl((MultiBranchProject) item);
|
||||
}else if(!isMultiBranchProjectJob((BuildableItem) item) && item instanceof Job){
|
||||
return new PipelineImpl(itemGroup, (Job) item);
|
||||
}
|
||||
}else if(item instanceof ItemGroup){
|
||||
return new PipelineImpl((ItemGroup) item, null);
|
||||
}
|
||||
throw new ServiceException.NotFoundException(String.format("Pipeline %s not found", name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
package io.jenkins.blueocean.service.embedded.util;
|
||||
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.User;
|
||||
import hudson.plugins.favorite.FavoritePlugin;
|
||||
import hudson.plugins.favorite.user.FavoriteUserProperty;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import hudson.model.User;
|
||||
import hudson.plugins.favorite.FavoritePlugin;
|
||||
import hudson.plugins.favorite.user.FavoriteUserProperty;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import jenkins.model.Jenkins;
|
||||
|
||||
/**
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
public class FavoriteUtil {
|
||||
public static void favoriteJob(Job job, boolean favorite) {
|
||||
public static void favoriteJob(String fullName, boolean favorite) {
|
||||
User user = User.current();
|
||||
if(user == null) {
|
||||
throw new ServiceException.ForbiddenException("Must be logged in to use set favotites");
|
||||
|
@ -27,7 +25,7 @@ public class FavoriteUtil {
|
|||
boolean set = false;
|
||||
FavoriteUserProperty fup = user.getProperty(FavoriteUserProperty.class);
|
||||
if(fup != null) {
|
||||
set = fup.isJobFavorite(job.getFullName());
|
||||
set = fup.isJobFavorite(fullName);
|
||||
}
|
||||
//TODO: FavoritePlugin is null
|
||||
FavoritePlugin plugin = Jenkins.getInstance().getPlugin(FavoritePlugin.class);
|
||||
|
@ -36,7 +34,7 @@ public class FavoriteUtil {
|
|||
}
|
||||
if(favorite != set) {
|
||||
try {
|
||||
plugin.doToggleFavorite(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), job.getFullName(), Jenkins.getAuthentication().getName(), false);
|
||||
plugin.doToggleFavorite(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), fullName, Jenkins.getAuthentication().getName(), false);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException.UnexpectedErrorException("Something went wrong setting the favorite", e);
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ public abstract class BaseTest {
|
|||
Assert.assertEquals("jenkins", resp.get("organization"));
|
||||
Assert.assertEquals(p.getName(), resp.get("name"));
|
||||
Assert.assertEquals(p.getDisplayName(), resp.get("displayName"));
|
||||
Assert.assertEquals(p.getFullName(), resp.get("fullName"));
|
||||
Assert.assertEquals(p.getBuildHealth().getScore(), resp.get("weatherScore"));
|
||||
if(p.getLastSuccessfulBuild() != null){
|
||||
Run b = p.getLastSuccessfulBuild();
|
||||
|
|
|
@ -37,11 +37,41 @@ public class PipelineApiTest extends BaseTest {
|
|||
MockFolder folder = j.createFolder("folder1");
|
||||
Project p = folder.createProject(FreeStyleProject.class, "test1");
|
||||
|
||||
Map response = get("/organizations/jenkins/pipelines/test1");
|
||||
Map response = get("/organizations/jenkins/pipelines/folder1/test1");
|
||||
validatePipeline(p, response);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getNestedFolderPipelineTest() throws IOException {
|
||||
MockFolder folder1 = j.createFolder("folder1");
|
||||
Project p1 = folder1.createProject(FreeStyleProject.class, "test1");
|
||||
MockFolder folder2 = folder1.createProject(MockFolder.class, "folder2");
|
||||
MockFolder folder3 = folder1.createProject(MockFolder.class, "folder3");
|
||||
Project p2 = folder2.createProject(FreeStyleProject.class, "test2");
|
||||
|
||||
Map response = get("/organizations/jenkins/pipelines/folder1/pipelines/folder2/test2");
|
||||
validatePipeline(p2, response);
|
||||
|
||||
List<Map> pipelines = get("/organizations/jenkins/pipelines/folder1/pipelines/folder2/pipelines/", List.class);
|
||||
Assert.assertEquals(1, pipelines.size());
|
||||
validatePipeline(p2, pipelines.get(0));
|
||||
|
||||
pipelines = get("/organizations/jenkins/pipelines/folder1/pipelines/", List.class);
|
||||
Assert.assertEquals(3, pipelines.size());
|
||||
Assert.assertEquals("folder2", pipelines.get(0).get("name"));
|
||||
Assert.assertEquals("folder1/folder2", pipelines.get(0).get("fullName"));
|
||||
|
||||
response = get("/organizations/jenkins/pipelines/folder1");
|
||||
Assert.assertEquals("folder1", response.get("name"));
|
||||
Assert.assertEquals("folder1", response.get("displayName"));
|
||||
Assert.assertEquals(2, response.get("numberOfFolders"));
|
||||
Assert.assertEquals(1, response.get("numberOfPipelines"));
|
||||
Assert.assertEquals("folder1", response.get("fullName"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getPipelineTest() throws IOException {
|
||||
Project p = j.createFreeStyleProject("pipeline1");
|
||||
|
|
|
@ -63,6 +63,7 @@ $$
|
|||
"organization" : "jenkins",
|
||||
"name" : "pipeline1",
|
||||
"displayName": "pipeline1",
|
||||
"fullName": "pipeline1",
|
||||
"weatherScore": 100,
|
||||
"estimatedDurationInMillis": 20264,
|
||||
"lastSuccessfulRun": "http://localhost:64106/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/runs/1",
|
||||
|
@ -100,10 +101,68 @@ $$
|
|||
"organization" : "jenkins",
|
||||
"name" : "pipeline1",
|
||||
"displayName": "pipeline1",
|
||||
"fullName" : "pipeline1",
|
||||
"weatherScore": 100,
|
||||
"estimatedDurationInMillis": 280,
|
||||
}
|
||||
]
|
||||
|
||||
## Get a Folder
|
||||
|
||||
curl -v -X GET http://localhost:63934/jenkins/blue/rest/organizations/jenkins/pipelines/folder1/
|
||||
{
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineFolderImpl",
|
||||
"displayName" : "folder1",
|
||||
"fullName" : "folder1",
|
||||
"name" : "folder1",
|
||||
"organization" : "jenkins",
|
||||
"numberOfFolders" : 1,
|
||||
"numberOfPipelines" : 1
|
||||
}
|
||||
|
||||
|
||||
## Get Nested Pipeline Inside A Folder
|
||||
|
||||
curl -v -X GET http://localhost:62054/jenkins/blue/rest/organizations/jenkins/pipelines/folder1/pipelines/folder2/test2/
|
||||
|
||||
{
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineImpl",
|
||||
"displayName" : "test2",
|
||||
"estimatedDurationInMillis" : -1,
|
||||
"fullName" : "folder1/folder2/test2",
|
||||
"lastSuccessfulRun" : null,
|
||||
"latestRun" : null,
|
||||
"name" : "test2",
|
||||
"fullName" : "test2",
|
||||
"organization" : "jenkins",
|
||||
"weatherScore" : 100
|
||||
}
|
||||
|
||||
## Get nested Folder and Pipeline
|
||||
|
||||
Pipelines can be nested inside folder.
|
||||
|
||||
curl -v -X GET http://localhost:62054/jenkins/blue/rest/organizations/jenkins/pipelines/folder1/pipelines/
|
||||
|
||||
[ {
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineFolderImpl",
|
||||
"displayName" : "folder2",
|
||||
"fullName" : "folder1/folder2",
|
||||
"name" : "folder2",
|
||||
"organization" : "jenkins",
|
||||
"numberOfFolders" : 0,
|
||||
"numberOfPipelines" : 1
|
||||
}, {
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineImpl",
|
||||
"displayName" : "test1",
|
||||
"estimatedDurationInMillis" : -1,
|
||||
"fullName" : "folder1/test1",
|
||||
"lastSuccessfulRun" : null,
|
||||
"latestRun" : null,
|
||||
"name" : "test1",
|
||||
"organization" : "jenkins",
|
||||
"weatherScore" : 100
|
||||
} ]
|
||||
|
||||
## Get all runs in a pipeline
|
||||
|
||||
|
|
|
@ -3,11 +3,8 @@ package io.jenkins.blueocean.rest.model;
|
|||
import org.kohsuke.stapler.WebMethod;
|
||||
import org.kohsuke.stapler.export.Exported;
|
||||
import org.kohsuke.stapler.json.JsonBody;
|
||||
import org.kohsuke.stapler.json.JsonResponse;
|
||||
import org.kohsuke.stapler.verb.PUT;
|
||||
|
||||
import javax.xml.ws.WebFault;
|
||||
|
||||
/**
|
||||
* Defines pipeline state and its routing
|
||||
*
|
||||
|
@ -17,6 +14,7 @@ public abstract class BluePipeline extends Resource {
|
|||
public static final String ORGANIZATION="organization";
|
||||
public static final String NAME="name";
|
||||
public static final String DISPLAY_NAME="displayName";
|
||||
public static final String FULL_NAME="fullName";
|
||||
public static final String WEATHER_SCORE ="weatherScore";
|
||||
public static final String LATEST_RUN = "latestRun";
|
||||
public static final String ESTIMATED_DURATION = "estimatedDurationInMillis";
|
||||
|
@ -41,11 +39,17 @@ public abstract class BluePipeline extends Resource {
|
|||
@Exported(name = DISPLAY_NAME)
|
||||
public abstract String getDisplayName();
|
||||
|
||||
/**
|
||||
* @return Includes parent folders if any. For example folder1/folder2/p1
|
||||
*/
|
||||
@Exported(name = FULL_NAME)
|
||||
public abstract String getFullName();
|
||||
|
||||
/**
|
||||
* @return weather health score percentile
|
||||
*/
|
||||
@Exported(name = WEATHER_SCORE)
|
||||
public abstract int getWeatherScore();
|
||||
public abstract Integer getWeatherScore();
|
||||
|
||||
/**
|
||||
* @return The Latest Run for the branch
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package io.jenkins.blueocean.rest.model;
|
||||
|
||||
import org.kohsuke.stapler.export.Exported;
|
||||
|
||||
/**
|
||||
* Folder has pipelines, could also hold another BluePipelineFolders.
|
||||
*
|
||||
* BluePipelineFolder subclasses BluePipeline in order to handle recursive pipelines path:
|
||||
*
|
||||
* /pipelines/f1/pipelines/f2/pipelines/p1
|
||||
*
|
||||
*
|
||||
* @author Vivek Pandey
|
||||
*
|
||||
* @see BluePipelineContainer
|
||||
*/
|
||||
public abstract class BluePipelineFolder extends BluePipeline {
|
||||
|
||||
private static final String NUMBER_OF_PIPELINES = "numberOfPipelines";
|
||||
|
||||
private static final String NUMBER_OF_FOLDERS = "numberOfFolders";
|
||||
|
||||
/**
|
||||
* @return Gives pipeline container
|
||||
*/
|
||||
public abstract BluePipelineContainer getPipelines();
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets nested BluePipeline inside the BluePipelineFolder
|
||||
*
|
||||
* For example for: /pipelines/folder1/pipelines/folder2/pipelines/p1, call sequnce will be:
|
||||
*
|
||||
* <ul>
|
||||
* <li>getPipelines().get("folder1")</li>
|
||||
* <li>getPipelines().get(folder2)</li>
|
||||
* <li>getDynamics(p1)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param name name of pipeline
|
||||
*
|
||||
* @return a {@link BluePipeline}
|
||||
*/
|
||||
public BluePipeline getDynamic(String name){
|
||||
return getPipelines().get(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Number of folders in this folder
|
||||
*/
|
||||
@Exported(name = NUMBER_OF_FOLDERS)
|
||||
public abstract Integer getNumberOfFolders();
|
||||
|
||||
|
||||
/**
|
||||
* @return Number of pipelines in this folder. Pipeline is any buildable type.
|
||||
*/
|
||||
@Exported(name = NUMBER_OF_PIPELINES)
|
||||
public abstract Integer getNumberOfPipelines();
|
||||
|
||||
|
||||
@Override
|
||||
@Exported(skipNull = true)
|
||||
public Integer getWeatherScore() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Exported(skipNull = true)
|
||||
public BlueRun getLatestRun() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Exported(skipNull = true)
|
||||
public String getLastSuccessfulRun() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Exported(skipNull = true)
|
||||
public Long getEstimatedDurationInMillis() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Exported(skipNull = true)
|
||||
public BlueRunContainer getRuns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue