@Test public void saveJob_InternalError() throws Exception { when(requestHandler.createOrUpdateJob(kv, "megatron", "megatron", null, false)).thenThrow(new Exception("internal error")); Response response = resource.saveJob(kv, "megatron", "megatron", null, false); assertEquals(500, response.getStatus()); verifyZeroInteractions(spawn); }
@POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) public Response saveJob(@QueryParam("pairs") KVPairs kv, @QueryParam("user") String user, @QueryParam("token") String token, @QueryParam("sudo") String sudo, @DefaultValue("true") @QueryParam("defaults") boolean defaults) { String id = KVUtils.getValue(kv, "", "id", "job"); if (user == null) { return Response.status(Response.Status.BAD_REQUEST).entity("Missing required parameter 'user'").build(); } try { Job job = requestHandler.createOrUpdateJob(kv, user, token, sudo, defaults); log.info("[job/save][user={}][id={}] Job {}", user, job.getId(), jobUpdateAction(id)); return Response.ok("{\"id\":\"" + job.getId() + "\",\"updated\":\"true\"}").build(); } catch (IllegalArgumentException e) { log.warn("[job/save][user={}][id={}] Bad parameter: {}", user, id, e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (InsufficientPrivilegesException e) { return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); } catch (Exception e) { log.error("[job/save][user={}][id={}] Internal error: {}", user, id, e.getMessage(), e); return buildServerError(e); } }
JobsResource implements Closeable { @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) public Response saveJob(@QueryParam("pairs") KVPairs kv, @QueryParam("user") String user, @QueryParam("token") String token, @QueryParam("sudo") String sudo, @DefaultValue("true") @QueryParam("defaults") boolean defaults) { String id = KVUtils.getValue(kv, "", "id", "job"); if (user == null) { return Response.status(Response.Status.BAD_REQUEST).entity("Missing required parameter 'user'").build(); } try { Job job = requestHandler.createOrUpdateJob(kv, user, token, sudo, defaults); log.info("[job/save][user={}][id={}] Job {}", user, job.getId(), jobUpdateAction(id)); return Response.ok("{\"id\":\"" + job.getId() + "\",\"updated\":\"true\"}").build(); } catch (IllegalArgumentException e) { log.warn("[job/save][user={}][id={}] Bad parameter: {}", user, id, e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (InsufficientPrivilegesException e) { return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); } catch (Exception e) { log.error("[job/save][user={}][id={}] Internal error: {}", user, id, e.getMessage(), e); return buildServerError(e); } } }
JobsResource implements Closeable { @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) public Response saveJob(@QueryParam("pairs") KVPairs kv, @QueryParam("user") String user, @QueryParam("token") String token, @QueryParam("sudo") String sudo, @DefaultValue("true") @QueryParam("defaults") boolean defaults) { String id = KVUtils.getValue(kv, "", "id", "job"); if (user == null) { return Response.status(Response.Status.BAD_REQUEST).entity("Missing required parameter 'user'").build(); } try { Job job = requestHandler.createOrUpdateJob(kv, user, token, sudo, defaults); log.info("[job/save][user={}][id={}] Job {}", user, job.getId(), jobUpdateAction(id)); return Response.ok("{\"id\":\"" + job.getId() + "\",\"updated\":\"true\"}").build(); } catch (IllegalArgumentException e) { log.warn("[job/save][user={}][id={}] Bad parameter: {}", user, id, e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (InsufficientPrivilegesException e) { return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); } catch (Exception e) { log.error("[job/save][user={}][id={}] Internal error: {}", user, id, e.getMessage(), e); return buildServerError(e); } } JobsResource(Spawn spawn, SpawnServiceConfiguration configuration, JobRequestHandler requestHandler); }
JobsResource implements Closeable { @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) public Response saveJob(@QueryParam("pairs") KVPairs kv, @QueryParam("user") String user, @QueryParam("token") String token, @QueryParam("sudo") String sudo, @DefaultValue("true") @QueryParam("defaults") boolean defaults) { String id = KVUtils.getValue(kv, "", "id", "job"); if (user == null) { return Response.status(Response.Status.BAD_REQUEST).entity("Missing required parameter 'user'").build(); } try { Job job = requestHandler.createOrUpdateJob(kv, user, token, sudo, defaults); log.info("[job/save][user={}][id={}] Job {}", user, job.getId(), jobUpdateAction(id)); return Response.ok("{\"id\":\"" + job.getId() + "\",\"updated\":\"true\"}").build(); } catch (IllegalArgumentException e) { log.warn("[job/save][user={}][id={}] Bad parameter: {}", user, id, e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (InsufficientPrivilegesException e) { return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); } catch (Exception e) { log.error("[job/save][user={}][id={}] Internal error: {}", user, id, e.getMessage(), e); return buildServerError(e); } } JobsResource(Spawn spawn, SpawnServiceConfiguration configuration, JobRequestHandler requestHandler); @Override void close(); @GET @Path("/defaults") @Produces(MediaType.APPLICATION_JSON) JobDefaults defaults(); @POST @Path("/permissions") @Produces(MediaType.APPLICATION_JSON) Response changePermissions(@FormParam("jobs") String jobarg,
                                      @FormParam("creator") String creator,
                                      @FormParam("owner") String owner,
                                      @FormParam("group") String group,
                                      @FormParam("ownerWritable") String ownerWritable,
                                      @FormParam("groupWritable") String groupWritable,
                                      @FormParam("worldWritable") String worldWritable,
                                      @FormParam("ownerExecutable") String ownerExecutable,
                                      @FormParam("groupExecutable") String groupExecutable,
                                      @FormParam("worldExecutable") String worldExecutable,
                                      @FormParam("user") String user,
                                      @FormParam("token") String token,
                                      @FormParam("sudo") String sudo); @GET @Path("/enable") @Produces(MediaType.APPLICATION_JSON) Response enableJob(@QueryParam("jobs") String jobarg,
                              @QueryParam("enable") @DefaultValue("1") String enableParam,
                              @QueryParam("unsafe") @DefaultValue("false") boolean unsafe,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/rebalance") @Produces(MediaType.TEXT_PLAIN) Response rebalanceJob(@QueryParam("id") String id,
                                 @QueryParam("user") String user,
                                 @QueryParam("token") String token,
                                 @QueryParam("sudo") String sudo,
                                 @QueryParam("tasksToMove") @DefaultValue("-1") Integer tasksToMove); @GET @Path("/expand") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response expandJobGet(@QueryParam("id") @DefaultValue("") String id,
                                 @QueryParam("format") String format); @POST @Path("/expand") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response expandJobPost(@QueryParam("pairs") KVPairs kv); @GET @Path("/synchronize") @Produces(MediaType.APPLICATION_JSON) Response synchronizeJob(@QueryParam("id") @DefaultValue("") String id,
                                   @QueryParam("user") String user,
                                   @QueryParam("token") String token,
                                   @QueryParam("sudo") String sudo); @GET @Path("/delete") //TODO: should this be a @delete? @Produces(MediaType.APPLICATION_JSON) Response deleteJob(@QueryParam("id") @DefaultValue("") String id,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo,
                              @QueryParam("force") boolean force); @GET @Path("/test") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) Response test(@QueryParam("pairs") KVPairs params); @GET @Path("/list") @Produces(MediaType.APPLICATION_JSON) Response listJobs(); @GET @Path("/dependencies/sources") @Produces(MediaType.APPLICATION_JSON) Response getSourceDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/sinks") @Produces(MediaType.APPLICATION_JSON) Response getSinkDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/connected") @Produces(MediaType.APPLICATION_JSON) Response getConnectedDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/all") @Produces(MediaType.APPLICATION_JSON) Response getConnectedDependencies(); @GET @Path("/alerts.toggle") @Produces(MediaType.APPLICATION_JSON) Response toggleJobAlerts(@QueryParam("enable") @DefaultValue("true") Boolean enable,
                                    @QueryParam("user") String user,
                                    @QueryParam("token") String token,
                                    @QueryParam("sudo") String sudo); @GET @Path("/get") @Produces(MediaType.APPLICATION_JSON) Response getJob(@QueryParam("id") String id, @QueryParam("field") Optional<String> field); @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) Response saveJob(@QueryParam("pairs") KVPairs kv,
                            @QueryParam("user") String user,
                            @QueryParam("token") String token,
                            @QueryParam("sudo") String sudo,
                            @DefaultValue("true") @QueryParam("defaults") boolean defaults); @GET @Path("/updateMinionType") Response updateMinionType(@QueryParam("job") String jobId,
                                     @QueryParam("minionType") String minionType,
                                     @QueryParam("user") String user,
                                     @QueryParam("token") String token,
                                     @QueryParam("sudo") String sudo); @POST @Path("/submit") @Produces(MediaType.APPLICATION_JSON) Response submitJob(@QueryParam("pairs") KVPairs kv,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/revert") @Produces(MediaType.APPLICATION_JSON) Response revertJob(@QueryParam("id") String id,
                              @QueryParam("type") @DefaultValue("gold") String type,
                              @QueryParam("revision") @DefaultValue("-1") Integer revision,
                              @QueryParam("node") @DefaultValue("-1") Integer node,
                              @QueryParam("time") @DefaultValue("-1") Long time,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/backups.list") @Produces(MediaType.APPLICATION_JSON) Response getRevisions(@QueryParam("id") String id,
                                 @QueryParam("node") @DefaultValue("-1") int node,
                                 @QueryParam("user") String user,
                                 @QueryParam("token") String token); @GET @Path("/{jobID}/log") @Produces(MediaType.APPLICATION_JSON) Response getJobTaskLog(@PathParam("jobID") String jobID,
                                  @QueryParam("lines") @DefaultValue("50") int lines,
                                  @QueryParam("runsAgo") @DefaultValue("0") int runsAgo,
                                  @QueryParam("offset") @DefaultValue("-1") int offset,
                                  @QueryParam("out") @DefaultValue("1") int out,
                                  @QueryParam("minion") String minion,
                                  @QueryParam("port") String port,
                                  @QueryParam("node") String node); @GET @Path("/tasks.get") @Produces(MediaType.APPLICATION_JSON) Response getJobTasks(@QueryParam("id") String id); @GET @Path("/start") @Produces(MediaType.APPLICATION_JSON) Response startJob(@QueryParam("jobid") Optional<String> jobIds,
                             @QueryParam("select") @DefaultValue("-1") int select,
                             @QueryParam("id") Optional<String> id,
                             @QueryParam("task") @DefaultValue("-1") int task,
                             @QueryParam("priority") @DefaultValue("0") int priority,
                             @QueryParam("user") String user,
                             @QueryParam("token") String token,
                             @QueryParam("sudo") String sudo); @GET @Path("/checkJobDirs") @Produces(MediaType.APPLICATION_JSON) Response checkJobDirs(@QueryParam("id") String id, @QueryParam("node") @DefaultValue("-1") Integer node); @GET @Path("/fixJobDirs") @Produces(MediaType.APPLICATION_JSON) Response fixJobDirs(@QueryParam("id") String id,
                               @QueryParam("node") @DefaultValue("-1") int node,
                               @QueryParam("user") String user,
                               @QueryParam("token") String token,
                               @QueryParam("sudo") String sudo); @GET @Path("/history") @Produces(MediaType.APPLICATION_JSON) Response getJobHistory(@QueryParam("id") String id); @GET @Path("/config.view") @Produces(MediaType.TEXT_PLAIN) Response getJobHistoricalConfig(@QueryParam("id") String id, @QueryParam("commit") String commit); @GET @Path("/config.diff") @Produces(MediaType.TEXT_PLAIN) Response diffConfig(@QueryParam("id") String id, @QueryParam("commit") String commit); @GET @Path("/config.deleted") @Produces(MediaType.TEXT_PLAIN) Response getDeletedJobConfig(@QueryParam("id") String id); @GET @Path("/validate") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response validateJobGet(@QueryParam("id") @DefaultValue("") String id); @POST @Path("/validate") @Produces(MediaType.APPLICATION_JSON) Response validateJobPost(@QueryParam("pairs") KVPairs kv); @GET @Path("/stop") @Produces(MediaType.APPLICATION_JSON) Response stopJob(@QueryParam("jobid") Optional<String> jobIds,
                            @QueryParam("cancel") Optional<Boolean> cancelParam,
                            @QueryParam("force") Optional<Boolean> forceParam,
                            @QueryParam("node") @DefaultValue("-1") int nodeParam,
                            @QueryParam("id") Optional<String> id,
                            @QueryParam("task") @DefaultValue("-1") int task,
                            @QueryParam("user") String user,
                            @QueryParam("token") String token,
                            @QueryParam("sudo") String sudo); @GET @Path("/saveAllJobs") @Produces(MediaType.APPLICATION_JSON) Response saveAllJobs(@QueryParam("user") String user,  @QueryParam("token") String token,
                                @QueryParam("sudo") String sudo); }
JobsResource implements Closeable { @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) public Response saveJob(@QueryParam("pairs") KVPairs kv, @QueryParam("user") String user, @QueryParam("token") String token, @QueryParam("sudo") String sudo, @DefaultValue("true") @QueryParam("defaults") boolean defaults) { String id = KVUtils.getValue(kv, "", "id", "job"); if (user == null) { return Response.status(Response.Status.BAD_REQUEST).entity("Missing required parameter 'user'").build(); } try { Job job = requestHandler.createOrUpdateJob(kv, user, token, sudo, defaults); log.info("[job/save][user={}][id={}] Job {}", user, job.getId(), jobUpdateAction(id)); return Response.ok("{\"id\":\"" + job.getId() + "\",\"updated\":\"true\"}").build(); } catch (IllegalArgumentException e) { log.warn("[job/save][user={}][id={}] Bad parameter: {}", user, id, e.getMessage(), e); return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build(); } catch (InsufficientPrivilegesException e) { return Response.status(Response.Status.UNAUTHORIZED).entity(e.getMessage()).build(); } catch (Exception e) { log.error("[job/save][user={}][id={}] Internal error: {}", user, id, e.getMessage(), e); return buildServerError(e); } } JobsResource(Spawn spawn, SpawnServiceConfiguration configuration, JobRequestHandler requestHandler); @Override void close(); @GET @Path("/defaults") @Produces(MediaType.APPLICATION_JSON) JobDefaults defaults(); @POST @Path("/permissions") @Produces(MediaType.APPLICATION_JSON) Response changePermissions(@FormParam("jobs") String jobarg,
                                      @FormParam("creator") String creator,
                                      @FormParam("owner") String owner,
                                      @FormParam("group") String group,
                                      @FormParam("ownerWritable") String ownerWritable,
                                      @FormParam("groupWritable") String groupWritable,
                                      @FormParam("worldWritable") String worldWritable,
                                      @FormParam("ownerExecutable") String ownerExecutable,
                                      @FormParam("groupExecutable") String groupExecutable,
                                      @FormParam("worldExecutable") String worldExecutable,
                                      @FormParam("user") String user,
                                      @FormParam("token") String token,
                                      @FormParam("sudo") String sudo); @GET @Path("/enable") @Produces(MediaType.APPLICATION_JSON) Response enableJob(@QueryParam("jobs") String jobarg,
                              @QueryParam("enable") @DefaultValue("1") String enableParam,
                              @QueryParam("unsafe") @DefaultValue("false") boolean unsafe,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/rebalance") @Produces(MediaType.TEXT_PLAIN) Response rebalanceJob(@QueryParam("id") String id,
                                 @QueryParam("user") String user,
                                 @QueryParam("token") String token,
                                 @QueryParam("sudo") String sudo,
                                 @QueryParam("tasksToMove") @DefaultValue("-1") Integer tasksToMove); @GET @Path("/expand") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response expandJobGet(@QueryParam("id") @DefaultValue("") String id,
                                 @QueryParam("format") String format); @POST @Path("/expand") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response expandJobPost(@QueryParam("pairs") KVPairs kv); @GET @Path("/synchronize") @Produces(MediaType.APPLICATION_JSON) Response synchronizeJob(@QueryParam("id") @DefaultValue("") String id,
                                   @QueryParam("user") String user,
                                   @QueryParam("token") String token,
                                   @QueryParam("sudo") String sudo); @GET @Path("/delete") //TODO: should this be a @delete? @Produces(MediaType.APPLICATION_JSON) Response deleteJob(@QueryParam("id") @DefaultValue("") String id,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo,
                              @QueryParam("force") boolean force); @GET @Path("/test") @Consumes(MediaType.APPLICATION_FORM_URLENCODED) Response test(@QueryParam("pairs") KVPairs params); @GET @Path("/list") @Produces(MediaType.APPLICATION_JSON) Response listJobs(); @GET @Path("/dependencies/sources") @Produces(MediaType.APPLICATION_JSON) Response getSourceDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/sinks") @Produces(MediaType.APPLICATION_JSON) Response getSinkDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/connected") @Produces(MediaType.APPLICATION_JSON) Response getConnectedDependencies(@QueryParam("id") @DefaultValue("") String id); @GET @Path("/dependencies/all") @Produces(MediaType.APPLICATION_JSON) Response getConnectedDependencies(); @GET @Path("/alerts.toggle") @Produces(MediaType.APPLICATION_JSON) Response toggleJobAlerts(@QueryParam("enable") @DefaultValue("true") Boolean enable,
                                    @QueryParam("user") String user,
                                    @QueryParam("token") String token,
                                    @QueryParam("sudo") String sudo); @GET @Path("/get") @Produces(MediaType.APPLICATION_JSON) Response getJob(@QueryParam("id") String id, @QueryParam("field") Optional<String> field); @POST @Path("/save") @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED, MediaType.WILDCARD}) @Produces(MediaType.APPLICATION_JSON) Response saveJob(@QueryParam("pairs") KVPairs kv,
                            @QueryParam("user") String user,
                            @QueryParam("token") String token,
                            @QueryParam("sudo") String sudo,
                            @DefaultValue("true") @QueryParam("defaults") boolean defaults); @GET @Path("/updateMinionType") Response updateMinionType(@QueryParam("job") String jobId,
                                     @QueryParam("minionType") String minionType,
                                     @QueryParam("user") String user,
                                     @QueryParam("token") String token,
                                     @QueryParam("sudo") String sudo); @POST @Path("/submit") @Produces(MediaType.APPLICATION_JSON) Response submitJob(@QueryParam("pairs") KVPairs kv,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/revert") @Produces(MediaType.APPLICATION_JSON) Response revertJob(@QueryParam("id") String id,
                              @QueryParam("type") @DefaultValue("gold") String type,
                              @QueryParam("revision") @DefaultValue("-1") Integer revision,
                              @QueryParam("node") @DefaultValue("-1") Integer node,
                              @QueryParam("time") @DefaultValue("-1") Long time,
                              @QueryParam("user") String user,
                              @QueryParam("token") String token,
                              @QueryParam("sudo") String sudo); @GET @Path("/backups.list") @Produces(MediaType.APPLICATION_JSON) Response getRevisions(@QueryParam("id") String id,
                                 @QueryParam("node") @DefaultValue("-1") int node,
                                 @QueryParam("user") String user,
                                 @QueryParam("token") String token); @GET @Path("/{jobID}/log") @Produces(MediaType.APPLICATION_JSON) Response getJobTaskLog(@PathParam("jobID") String jobID,
                                  @QueryParam("lines") @DefaultValue("50") int lines,
                                  @QueryParam("runsAgo") @DefaultValue("0") int runsAgo,
                                  @QueryParam("offset") @DefaultValue("-1") int offset,
                                  @QueryParam("out") @DefaultValue("1") int out,
                                  @QueryParam("minion") String minion,
                                  @QueryParam("port") String port,
                                  @QueryParam("node") String node); @GET @Path("/tasks.get") @Produces(MediaType.APPLICATION_JSON) Response getJobTasks(@QueryParam("id") String id); @GET @Path("/start") @Produces(MediaType.APPLICATION_JSON) Response startJob(@QueryParam("jobid") Optional<String> jobIds,
                             @QueryParam("select") @DefaultValue("-1") int select,
                             @QueryParam("id") Optional<String> id,
                             @QueryParam("task") @DefaultValue("-1") int task,
                             @QueryParam("priority") @DefaultValue("0") int priority,
                             @QueryParam("user") String user,
                             @QueryParam("token") String token,
                             @QueryParam("sudo") String sudo); @GET @Path("/checkJobDirs") @Produces(MediaType.APPLICATION_JSON) Response checkJobDirs(@QueryParam("id") String id, @QueryParam("node") @DefaultValue("-1") Integer node); @GET @Path("/fixJobDirs") @Produces(MediaType.APPLICATION_JSON) Response fixJobDirs(@QueryParam("id") String id,
                               @QueryParam("node") @DefaultValue("-1") int node,
                               @QueryParam("user") String user,
                               @QueryParam("token") String token,
                               @QueryParam("sudo") String sudo); @GET @Path("/history") @Produces(MediaType.APPLICATION_JSON) Response getJobHistory(@QueryParam("id") String id); @GET @Path("/config.view") @Produces(MediaType.TEXT_PLAIN) Response getJobHistoricalConfig(@QueryParam("id") String id, @QueryParam("commit") String commit); @GET @Path("/config.diff") @Produces(MediaType.TEXT_PLAIN) Response diffConfig(@QueryParam("id") String id, @QueryParam("commit") String commit); @GET @Path("/config.deleted") @Produces(MediaType.TEXT_PLAIN) Response getDeletedJobConfig(@QueryParam("id") String id); @GET @Path("/validate") @Produces(MediaType.APPLICATION_OCTET_STREAM) Response validateJobGet(@QueryParam("id") @DefaultValue("") String id); @POST @Path("/validate") @Produces(MediaType.APPLICATION_JSON) Response validateJobPost(@QueryParam("pairs") KVPairs kv); @GET @Path("/stop") @Produces(MediaType.APPLICATION_JSON) Response stopJob(@QueryParam("jobid") Optional<String> jobIds,
                            @QueryParam("cancel") Optional<Boolean> cancelParam,
                            @QueryParam("force") Optional<Boolean> forceParam,
                            @QueryParam("node") @DefaultValue("-1") int nodeParam,
                            @QueryParam("id") Optional<String> id,
                            @QueryParam("task") @DefaultValue("-1") int task,
                            @QueryParam("user") String user,
                            @QueryParam("token") String token,
                            @QueryParam("sudo") String sudo); @GET @Path("/saveAllJobs") @Produces(MediaType.APPLICATION_JSON) Response saveAllJobs(@QueryParam("user") String user,  @QueryParam("token") String token,
                                @QueryParam("sudo") String sudo);  }