Merge pull request #328 from jenkinsci/improvement/JENKINS-36580
JENKINS-36580# PUT .../pipelines/:id/favorite/ enhancements
This commit is contained in:
commit
5b1cf811bd
|
@ -26,7 +26,8 @@ public class FavoriteContainerImpl extends BlueFavoriteContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BlueFavorite get(final String name) {
|
||||
public BlueFavorite get(String name) {
|
||||
name = FavoriteUtil.decodeFullName(name);
|
||||
if(user.isFavorite(name)){
|
||||
Item item = Jenkins.getInstance().getItemByFullName(name);
|
||||
if(FavoriteUtil.isFavorableItem(item)) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.Util;
|
||||
import hudson.model.Item;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.hal.LinkResolver;
|
||||
import io.jenkins.blueocean.rest.model.BlueFavorite;
|
||||
import jenkins.model.Jenkins;
|
||||
import io.jenkins.blueocean.service.embedded.util.FavoriteUtil;
|
||||
|
||||
/**
|
||||
* @author Vivek Pandey
|
||||
|
@ -15,11 +15,15 @@ public class FavoriteImpl extends BlueFavorite {
|
|||
|
||||
private final Object item;
|
||||
private final Link self;
|
||||
private final LinkResolver linkResolver;
|
||||
|
||||
public FavoriteImpl(Object item, Link self) {
|
||||
this.self = self;
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public FavoriteImpl(Item item, Reachable parent) {
|
||||
this.self = parent.getLink().rel(Util.rawEncode(item.getFullName()));
|
||||
this.linkResolver = Jenkins.getInstance().getInjector().getInstance(LinkResolver.class);
|
||||
this.self = parent.getLink().rel(FavoriteUtil.encodeFullName(item.getFullName()));
|
||||
LinkResolver linkResolver = Jenkins.getInstance().getInjector().getInstance(LinkResolver.class);
|
||||
|
||||
final Link link = linkResolver.resolve(item);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ 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.BlueFavorite;
|
||||
import io.jenkins.blueocean.rest.model.BlueFavoriteAction;
|
||||
import io.jenkins.blueocean.rest.model.BlueMultiBranchPipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
|
@ -52,7 +53,7 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
|
||||
|
||||
@Override
|
||||
public void favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
public BlueFavorite favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
if(favoriteAction == null) {
|
||||
throw new ServiceException.BadRequestExpception("Must provide pipeline name");
|
||||
}
|
||||
|
@ -62,7 +63,8 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
throw new ServiceException.BadRequestExpception("no master branch to favorite");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
Link link = FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
return new FavoriteImpl(new BranchImpl(job, getLink().rel("branches")), link);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@ 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.BlueFavorite;
|
||||
import io.jenkins.blueocean.rest.model.BlueFavoriteAction;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
|
@ -87,12 +88,13 @@ public class PipelineFolderImpl extends BluePipelineFolder {
|
|||
|
||||
|
||||
@Override
|
||||
public void favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
public BlueFavorite favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
if(favoriteAction == null) {
|
||||
throw new ServiceException.BadRequestExpception("Must provide pipeline name");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(folder.getFullName(), favoriteAction.isFavorite());
|
||||
Link link = FavoriteUtil.favoriteJob(folder.getFullName(), favoriteAction.isFavorite());
|
||||
return new FavoriteImpl(this, link);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,6 +9,7 @@ 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.BlueFavorite;
|
||||
import io.jenkins.blueocean.rest.model.BlueFavoriteAction;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BlueQueueContainer;
|
||||
|
@ -103,12 +104,13 @@ public class PipelineImpl extends BluePipeline {
|
|||
|
||||
|
||||
@Override
|
||||
public void favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
public BlueFavorite favorite(@JsonBody BlueFavoriteAction favoriteAction) {
|
||||
if(favoriteAction == null) {
|
||||
throw new ServiceException.BadRequestExpception("Must provide pipeline name");
|
||||
}
|
||||
|
||||
FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
Link link = FavoriteUtil.favoriteJob(job.getFullName(), favoriteAction.isFavorite());
|
||||
return new FavoriteImpl(this, link);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.jenkins.blueocean.service.embedded.util;
|
||||
|
||||
import hudson.Util;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
|
@ -7,21 +8,23 @@ import hudson.model.User;
|
|||
import hudson.plugins.favorite.FavoritePlugin;
|
||||
import hudson.plugins.favorite.user.FavoriteUserProperty;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.service.embedded.rest.UserImpl;
|
||||
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 java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
/**
|
||||
* @author Ivan Meredith
|
||||
*/
|
||||
public class FavoriteUtil {
|
||||
public static void favoriteJob(String fullName, boolean favorite) {
|
||||
public static Link favoriteJob(String fullName, boolean favorite) {
|
||||
User user = User.current();
|
||||
if(user == null) {
|
||||
throw new ServiceException.ForbiddenException("Must be logged in to use set favotites");
|
||||
throw new ServiceException.ForbiddenException("Must be logged in to use set favorites");
|
||||
}
|
||||
boolean set = false;
|
||||
FavoriteUserProperty fup = user.getProperty(FavoriteUserProperty.class);
|
||||
|
@ -31,7 +34,7 @@ public class FavoriteUtil {
|
|||
//TODO: FavoritePlugin is null
|
||||
FavoritePlugin plugin = Jenkins.getInstance().getPlugin(FavoritePlugin.class);
|
||||
if(plugin == null) {
|
||||
throw new ServiceException.UnexpectedErrorException("Can not find instance of favorites plugin");
|
||||
throw new ServiceException.UnexpectedErrorException("Can not find instance of Favorite Plugin");
|
||||
}
|
||||
if(favorite != set) {
|
||||
try {
|
||||
|
@ -40,25 +43,23 @@ public class FavoriteUtil {
|
|||
throw new ServiceException.UnexpectedErrorException("Something went wrong setting the favorite", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String generateBlueUrl(String org, Item i) {
|
||||
String url = "/organizations/" + org + "/pipelines/";
|
||||
if(i instanceof WorkflowJob) {
|
||||
WorkflowJob job = (WorkflowJob)i;
|
||||
ItemGroup it = job.getParent();
|
||||
if(it instanceof WorkflowMultiBranchProject) {
|
||||
url += ((WorkflowMultiBranchProject) it).getName() + "/branches/" + job.getName();
|
||||
} else {
|
||||
url += job.getName();
|
||||
}
|
||||
} else {
|
||||
url += i.getName();
|
||||
}
|
||||
return url;
|
||||
return new UserImpl(user).getLink().rel("favorites/"+ Util.rawEncode(FavoriteUtil.encodeFullName(fullName)));
|
||||
}
|
||||
|
||||
public static boolean isFavorableItem(Item i){
|
||||
return i!= null && (i instanceof Job || i instanceof ItemGroup);
|
||||
}
|
||||
|
||||
public static String encodeFullName(String name){
|
||||
return Util.rawEncode(Util.rawEncode(name));
|
||||
}
|
||||
|
||||
public static String decodeFullName(String name){
|
||||
try {
|
||||
return URLDecoder.decode(URLDecoder.decode(name, "UTF-8"), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ServiceException.UnexpectedErrorException("Something went wrong URL decoding fullName: "+name, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -428,11 +428,13 @@ public class MultiBranchTest extends BaseTest{
|
|||
WorkflowJob p = scheduleAndFindBranchProject(mp, "master");
|
||||
j.waitUntilNoActivity();
|
||||
|
||||
new RequestBuilder(baseUrl)
|
||||
Map m = new RequestBuilder(baseUrl)
|
||||
.put("/organizations/jenkins/pipelines/p/favorite")
|
||||
.auth("alice", "alice")
|
||||
.data(ImmutableMap.of("favorite", true))
|
||||
.build(String.class);
|
||||
.build(Map.class);
|
||||
|
||||
validatePipeline(p, (Map) m.get("item"));
|
||||
|
||||
List l = new RequestBuilder(baseUrl)
|
||||
.get("/users/"+user.getId()+"/favorites/")
|
||||
|
@ -467,11 +469,16 @@ public class MultiBranchTest extends BaseTest{
|
|||
WorkflowJob p = scheduleAndFindBranchProject(mp, "master");
|
||||
j.waitUntilNoActivity();
|
||||
|
||||
new RequestBuilder(baseUrl)
|
||||
WorkflowJob p1 = scheduleAndFindBranchProject(mp, "feature2");
|
||||
|
||||
Map map = new RequestBuilder(baseUrl)
|
||||
.put("/organizations/jenkins/pipelines/p/branches/feature2/favorite")
|
||||
.auth("alice", "alice")
|
||||
.data(ImmutableMap.of("favorite", true))
|
||||
.build(String.class);
|
||||
.build(Map.class);
|
||||
|
||||
|
||||
validatePipeline(p1, (Map) map.get("item"));
|
||||
|
||||
List l = new RequestBuilder(baseUrl)
|
||||
.get("/users/"+user.getId()+"/favorites/")
|
||||
|
@ -480,7 +487,6 @@ public class MultiBranchTest extends BaseTest{
|
|||
|
||||
Assert.assertEquals(l.size(), 1);
|
||||
|
||||
WorkflowJob p1 = scheduleAndFindBranchProject(mp, "feature2");
|
||||
Map branch = (Map)((Map)l.get(0)).get("item");
|
||||
|
||||
validatePipeline(p1, branch);
|
||||
|
|
|
@ -92,12 +92,13 @@ public class ProfileApiTest extends BaseTest{
|
|||
user.setFullName("Alice Cooper");
|
||||
Project p = j.createFreeStyleProject("pipeline1");
|
||||
|
||||
new RequestBuilder(baseUrl)
|
||||
Map map = new RequestBuilder(baseUrl)
|
||||
.put("/organizations/jenkins/pipelines/pipeline1/favorite")
|
||||
.auth("alice", "alice")
|
||||
.data(ImmutableMap.of("favorite", true))
|
||||
.build(String.class);
|
||||
.build(Map.class);
|
||||
|
||||
validatePipeline(p, (Map) map.get("item"));
|
||||
List l = new RequestBuilder(baseUrl)
|
||||
.get("/users/"+user.getId()+"/favorites/")
|
||||
.auth("alice","alice")
|
||||
|
|
|
@ -1119,19 +1119,68 @@ This will show up as a download in the browser.
|
|||
Unit testing...
|
||||
|
||||
|
||||
## Favorite API
|
||||
|
||||
Favorite API can be used to favorite a pipeline (Multi-branch, branch, pipeline or even folder) for a logged in user.
|
||||
If favorite request is successful then the repsonse is favorited item.
|
||||
|
||||
curl -u alice:xxx -H"Content-Type:application/json" -XPUT -d '{"favorite":true} ttp://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite
|
||||
|
||||
{
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.FavoriteImpl",
|
||||
"_links" : {
|
||||
"self" : {
|
||||
"_class" : "io.jenkins.blueocean.rest.hal.Link",
|
||||
"href" : "/blue/rest/users/alice/favorites/pipeline1/"
|
||||
}
|
||||
},
|
||||
"item" : {
|
||||
"displayName" : "pipeline1",
|
||||
"_links" : {
|
||||
"runs" : {
|
||||
"href" : "/blue/rest/organizations/jenkins/pipelines/pipeline1/runs/",
|
||||
"_class" : "io.jenkins.blueocean.rest.hal.Link"
|
||||
},
|
||||
"self" : {
|
||||
"href" : "/blue/rest/organizations/jenkins/pipelines/pipeline1/",
|
||||
"_class" : "io.jenkins.blueocean.rest.hal.Link"
|
||||
},
|
||||
"queue" : {
|
||||
"href" : "/blue/rest/organizations/jenkins/pipelines/pipeline1/queue/",
|
||||
"_class" : "io.jenkins.blueocean.rest.hal.Link"
|
||||
},
|
||||
"actions" : {
|
||||
"_class" : "io.jenkins.blueocean.rest.hal.Link",
|
||||
"href" : "/blue/rest/organizations/jenkins/pipelines/pipeline1/actions/"
|
||||
}
|
||||
},
|
||||
"organization" : "jenkins",
|
||||
"latestRun" : null,
|
||||
"name" : "pipeline1",
|
||||
"actions" : [],
|
||||
"weatherScore" : 100,
|
||||
"_class" : "io.jenkins.blueocean.service.embedded.rest.PipelineImpl",
|
||||
"fullName" : "pipeline1",
|
||||
"lastSuccessfulRun" : null,
|
||||
"estimatedDurationInMillis" : -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
## Favorite a pipeline
|
||||
Returns 200 on success. Must be authenticated.
|
||||
|
||||
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} ttp://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite
|
||||
|
||||
## Favorite a multibranch pipeline
|
||||
## Favorite a multi branch pipeline
|
||||
Must be authenticated.
|
||||
|
||||
This favorites the master branch. Returns 200 on success. 500 if master does not exist
|
||||
|
||||
curl -u bob:bob -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/favorite
|
||||
|
||||
## Favorite a multibranch pipeline branch
|
||||
## Favorite a multi branch pipeline branch
|
||||
Returns 200 on success. Must be authenticated.
|
||||
|
||||
curl -H"Content-Type:application/json" -XPUT -d '{"favorite":true} http://localhost:56748/jenkins/blue/rest/organizations/jenkins/pipelines/pipeline1/branches/master/favorite
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.jenkins.blueocean.rest.model;
|
||||
|
||||
import io.jenkins.blueocean.commons.stapler.TreeResponse;
|
||||
import io.jenkins.blueocean.rest.Navigable;
|
||||
import io.jenkins.blueocean.rest.annotation.Capability;
|
||||
import org.kohsuke.stapler.WebMethod;
|
||||
|
@ -96,5 +97,6 @@ public abstract class BluePipeline extends Resource {
|
|||
|
||||
@PUT
|
||||
@WebMethod(name="favorite")
|
||||
public abstract void favorite(@JsonBody BlueFavoriteAction favoriteAction);
|
||||
@TreeResponse
|
||||
public abstract BlueFavorite favorite(@JsonBody BlueFavoriteAction favoriteAction);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue