Support v5 executions query

This commit is contained in:
Greg Schueler 2012-09-13 17:27:18 -07:00
parent f582fd773b
commit 2960f59cc8
7 changed files with 915 additions and 14 deletions

View file

@ -25,13 +25,12 @@ import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.message.BasicNameValuePair;
import org.rundeck.api.util.ParametersUtil;
/**
* Builder for API paths
*
*
* @author Vincent Behar
*/
class ApiPathBuilder {
@ -49,7 +48,7 @@ class ApiPathBuilder {
/**
* Build a new instance, for the given "path" (the "path" is the part before the parameters. The path and the
* parameters are separated by a "?")
*
*
* @param paths elements of the path
*/
public ApiPathBuilder(String... paths) {
@ -64,11 +63,25 @@ class ApiPathBuilder {
}
}
/**
* Visit a {@link BuildsParameters} and add the parameters
*/
public ApiPathBuilder param(BuildsParameters params) {
params.buildParameters(this, false);
return this;
}
/**
* Visit a {@link BuildsParameters} and add the parameters
*/
public ApiPathBuilder field(BuildsParameters params) {
params.buildParameters(this, true);
return this;
}
/**
* Append the given parameter (key and value). This will only append the parameter if it is not blank (null, empty
* or whitespace), and make sure to add the right separator ("?" or "&") before. The key and value will be separated
* by the "=" character. Also, the value will be url-encoded.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null/empty/blank. Will be url-encoded.
* @return this, for method chaining
@ -142,7 +155,7 @@ class ApiPathBuilder {
* Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure
* to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. Also,
* the value will be converted to lower-case.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null
* @return this, for method chaining
@ -157,7 +170,7 @@ class ApiPathBuilder {
/**
* Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure
* to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null
* @return this, for method chaining
@ -172,7 +185,7 @@ class ApiPathBuilder {
/**
* Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure
* to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null
* @return this, for method chaining
@ -187,7 +200,7 @@ class ApiPathBuilder {
/**
* Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure
* to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null
* @return this, for method chaining
@ -202,7 +215,7 @@ class ApiPathBuilder {
/**
* Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure
* to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character.
*
*
* @param key of the parameter. Must not be null or empty
* @param value of the parameter. May be null
* @return this, for method chaining
@ -216,7 +229,7 @@ class ApiPathBuilder {
/**
* Append the given node filters, only if it is not null/empty
*
*
* @param nodeFilters may be null/empty
* @return this, for method chaining
* @see ParametersUtil#generateNodeFiltersString(Properties)
@ -233,7 +246,7 @@ class ApiPathBuilder {
/**
* When POSTing a request, add the given {@link InputStream} as an attachment to the content of the request. This
* will only add the stream if it is not null.
*
*
* @param name of the attachment. Must not be null or empty
* @param stream. May be null
* @return this, for method chaining
@ -259,7 +272,7 @@ class ApiPathBuilder {
/**
* Append the given string
*
*
* @param str to append
*/
private void append(String str) {
@ -291,4 +304,19 @@ class ApiPathBuilder {
public boolean hasPostContent() {
return getAttachments().size() > 0 || getForm().size() > 0;
}
/**
* BuildsParameters can add URL or POST parameters to an {@link ApiPathBuilder}
*
* @author Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
*/
public static interface BuildsParameters {
/**
* Add the parameters or form fields to the ApiPathBuilder
*
* @param builder the builder
* @param doPost if true, use form fields, otherwise use query parameters
*/
public boolean buildParameters(ApiPathBuilder builder, boolean doPost);
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright 2012 DTO Labs, Inc. (http://dtolabs.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* ExecutionQueryParameters.java
*
* User: Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
* Created: 9/13/12 3:54 PM
*
*/
package org.rundeck.api;
import org.rundeck.api.domain.RundeckExecution;
import org.rundeck.api.query.ExecutionQuery;
/**
* ExecutionQueryParameters adds parameters to a {@link ApiPathBuilder} from a {@link ExecutionQuery} object.
*
*
* @author Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
*/
class ExecutionQueryParameters extends QueryParameterBuilder {
ExecutionQuery query;
ExecutionQueryParameters(final ExecutionQuery query) {
this.query = query;
}
public boolean buildParameters(final ApiPathBuilder builder, final boolean doPost) {
boolean seen = false;
seen |= visit("jobFilter", query.getJob(), doPost, builder);
seen |= visit("jobExactFilter", query.getJobExact(), doPost, builder);
seen |= visit("project", query.getProject(), doPost, builder);
seen |= visit("groupPath", query.getGroupPath(), doPost, builder);
seen |= visit("groupPathExact", query.getGroupPathExact(), doPost, builder);
seen |= visit("descFilter", query.getDescription(), doPost, builder);
seen |= visit("userFilter", query.getUser(), doPost, builder);
if(null!=query.getAdhoc()){
seen |= visit("adhoc", query.getAdhoc(), doPost, builder);
}
seen |= visit("statusFilter", stringVal(query.getStatus()), doPost, builder);
seen |= visit("abortedbyFilter", query.getAbortedby(), doPost, builder);
seen |= visit("jobListFilter", query.getJobList(), doPost, builder);
seen |= visit("jobIdListFilter", query.getJobIdList(), doPost, builder);
seen |= visit("excludeJobIdListFilter", query.getExcludeJobIdList(), doPost, builder);
seen |= visit("excludeJobListFilter", query.getExcludeJobList(), doPost, builder);
seen |= visit("begin", query.getBegin(), doPost, builder);
seen |= visit("end", query.getEnd(), doPost, builder);
seen |= visit("recentFilter", query.getRecent(), doPost, builder);
return seen;
}
public static String stringVal(final RundeckExecution.ExecutionStatus status) {
return null != status ? status.toString().toLowerCase() : null;
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright 2012 DTO Labs, Inc. (http://dtolabs.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* QueryParameterBuilder.java
*
* User: Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
* Created: 9/13/12 4:21 PM
*
*/
package org.rundeck.api;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Abstract utility base class for building query parameters from a query object.
*
* @author Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
*/
abstract class QueryParameterBuilder implements ApiPathBuilder.BuildsParameters {
public static final String W3C_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
static final SimpleDateFormat format = new SimpleDateFormat(W3C_DATE_FORMAT);
/**
* Add a value to the builder for a given key
*
* @param key parameter name
* @param value value which can be a String, Boolean, Date or collection of Strings. Other types will be converted
* via {@link Object#toString()}
* @param doPost if true, add POST field instead of query parameters
* @param builder the builder
*
* @return true if the value was not null and was added to the builder
*/
protected boolean visit(String key, Object value, boolean doPost, ApiPathBuilder builder) {
if (null != value) {
if (doPost) {
if (value instanceof Collection) {
builder.field(key, (Collection<String>) value);
} else {
builder.field(key, stringVal(value));
}
return true;
} else {
if (value instanceof Collection) {
builder.param(key, (Collection<String>) value);
} else {
builder.param(key, stringVal(value));
}
return true;
}
}
return false;
}
private String stringVal(Object value) {
return value instanceof String ? (String) value :
value instanceof Boolean ? Boolean.toString((Boolean) value) :
value instanceof Date ? formatDate((Date) value)
: value.toString();
}
private String formatDate(Date value) {
return format.format(value);
}
}

View file

@ -52,6 +52,7 @@ import org.rundeck.api.parser.ProjectParser;
import org.rundeck.api.parser.StringParser;
import org.rundeck.api.parser.SystemInfoParser;
import org.rundeck.api.parser.OutputParser;
import org.rundeck.api.query.ExecutionQuery;
import org.rundeck.api.util.AssertUtil;
import org.rundeck.api.util.ParametersUtil;
@ -2008,8 +2009,34 @@ public class RundeckClient implements Serializable {
throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException {
AssertUtil.notBlank(jobId, "jobId is mandatory to get the executions of a job !");
return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId, "/executions").param("status", status)
.param("max", max)
.param("offset", offset),
.param("max", max)
.param("offset", offset),
new ListParser<RundeckExecution>(new ExecutionParser(),
"result/executions/execution"));
}
/**
* Get executions based on query parameters
*
* @param query query parameters for the request
* @param max number of results to return - optional (null for all)
* @param offset the 0-indexed offset for the first result to return - optional
* @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null
* @throws RundeckApiException in case of error when calling the API (non-existent job with this ID)
* @throws RundeckApiLoginException if the login fails (in case of login-based authentication)
* @throws RundeckApiTokenException if the token is invalid (in case of token-based authentication)
* @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace)
*/
public List<RundeckExecution> getExecutions(ExecutionQuery query, Long max, Long offset)
throws RundeckApiException, RundeckApiLoginException, RundeckApiTokenException, IllegalArgumentException {
if(!query.notBlank()){
throw new IllegalArgumentException("Some execution query parameter must be set");
}
AssertUtil.notBlank(query.getProject(),"project is required for execution query");
return new ApiCall(this).get(new ApiPathBuilder("/executions")
.param(new ExecutionQueryParameters(query))
.param("max", max)
.param("offset", offset),
new ListParser<RundeckExecution>(new ExecutionParser(),
"result/executions/execution"));
}

View file

@ -0,0 +1,335 @@
/*
* Copyright 2012 DTO Labs, Inc. (http://dtolabs.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* ExecutionQuery.java
*
* User: Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
* Created: 9/13/12 3:18 PM
*
*/
package org.rundeck.api.query;
import org.apache.commons.lang.StringUtils;
import org.rundeck.api.domain.RundeckExecution;
import java.util.*;
/**
* ExecutionQuery contains the query parameters for the /executions api, create one with the {@link Builder} class, e.g.
* using the {@link #builder()} method.
*
* @author Greg Schueler <a href="mailto:greg@dtosolutions.com">greg@dtosolutions.com</a>
*/
public class ExecutionQuery {
private RundeckExecution.ExecutionStatus status;
private String abortedby;
private List<String> jobList;
private List<String> jobIdList;
private List<String> excludeJobList;
private List<String> excludeJobIdList;
private Date begin;
private Date end;
private String recent;
private String job;
private String jobExact;
private String project;
private String groupPath;
private String groupPathExact;
private String user;
private String description;
private Boolean adhoc;
private ExecutionQuery() {
}
private ExecutionQuery(ExecutionQuery query) {
this.status = query.getStatus();
this.abortedby = query.getAbortedby();
this.jobList = query.getJobList();
this.jobIdList = query.getJobIdList();
this.excludeJobList = query.getExcludeJobList();
this.excludeJobIdList = query.getExcludeJobIdList();
this.begin = query.getBegin();
this.end = query.getEnd();
this.recent = query.getRecent();
this.job = query.getJob();
this.jobExact = query.getJobExact();
this.project = query.getProject();
this.groupPath = query.getGroupPath();
this.groupPathExact = query.getGroupPathExact();
this.description = query.getDescription();
this.user = query.getUser();
this.adhoc = query.getAdhoc();
}
/**
* Return true if some parameter is set
*/
public boolean notBlank() {
return null!=status ||
!StringUtils.isBlank(abortedby) ||
!StringUtils.isBlank(recent) ||
!StringUtils.isBlank(job) ||
!StringUtils.isBlank(jobExact) ||
!StringUtils.isBlank(groupPath) ||
!StringUtils.isBlank(groupPathExact) ||
!StringUtils.isBlank(description) ||
//boolean
(null!=adhoc) ||
//lists
(null != jobList && jobList.size() > 0) ||
(null != jobIdList && jobIdList.size() > 0) ||
(null != excludeJobList && excludeJobList.size() > 0) ||
(null != excludeJobIdList && excludeJobIdList.size() > 0) ||
//dates
(null != begin ) ||
(null != end )
;
}
public RundeckExecution.ExecutionStatus getStatus() {
return status;
}
public String getAbortedby() {
return abortedby;
}
public List<String> getJobList() {
return jobList;
}
public List<String> getExcludeJobList() {
return excludeJobList;
}
public List<String> getExcludeJobIdList() {
return excludeJobIdList;
}
public Date getBegin() {
return begin;
}
public Date getEnd() {
return end;
}
public String getRecent() {
return recent;
}
public String getJob() {
return job;
}
public String getJobExact() {
return jobExact;
}
public String getProject() {
return project;
}
public String getGroupPath() {
return groupPath;
}
public String getGroupPathExact() {
return groupPathExact;
}
public String getDescription() {
return description;
}
public List<String> getJobIdList() {
return jobIdList;
}
/**
* Create a Builder for an ExecutionQuery
*/
public static Builder builder() {
return new Builder();
}
public String getUser() {
return user;
}
public Boolean getAdhoc() {
return adhoc;
}
/**
* Builder for ExecutionQueries
*/
public static class Builder {
ExecutionQuery query;
public Builder() {
query = new ExecutionQuery();
}
/**
* Execution status to query
*/
public Builder status(RundeckExecution.ExecutionStatus status) {
query.status = status;
return this;
}
/**
* Username
*/
public Builder abortedby(String abortedby) {
query.abortedby = abortedby;
return this;
}
/**
* List of job "group/name" to query
*/
public Builder jobList(List<String> list) {
query.jobList = list;
return this;
}
/**
* List of job IDs to query
*/
public Builder jobIdList(List<String> list) {
query.jobIdList = list;
return this;
}
/**
* List of job "group/name" to exclude from query
*/
public Builder excludeJobList(List<String> list) {
query.excludeJobList = list;
return this;
}
/**
* List of job IDs to exclude from query
*/
public Builder excludeJobIdList(List<String> list) {
query.excludeJobIdList = list;
return this;
}
/**
* Start date/time for execution completion time
*/
public Builder begin(Date begin) {
query.begin = begin;
return this;
}
/**
* End date/time for execution completion time
*/
public Builder end(Date end) {
query.end = end;
return this;
}
/**
* Recent time filter, in the for "XY", where X is a number, and Y
* is one of: "h" (hour), "d" (day), "w" (week), "m" (month), "y" (year)
*/
public Builder recent(String recent) {
query.recent = recent;
return this;
}
/**
* Job name filter, which can match any part of the name
*/
public Builder job(String job) {
query.job = job;
return this;
}
/**
* Job exact name filter, much match exactly
*/
public Builder jobExact(String exact) {
query.jobExact = exact;
return this;
}
/**
* Project name
*/
public Builder project(String project) {
query.project = project;
return this;
}
/**
* Group path or super path, which will include any jobs within the subtree.
*/
public Builder groupPath(String path) {
query.groupPath = path;
return this;
}
/**
* Exact group path match
*/
public Builder groupPathExact(String exact) {
query.groupPathExact = exact;
return this;
}
/**
* Job description match
*/
public Builder description(String description) {
query.description = description;
return this;
}
/**
* Name of username that started the execution
*/
public Builder user(String user) {
query.user = user;
return this;
}
/**
* True to query only adhoc executions, false to query only Job executions, null for both
*/
public Builder adhoc(Boolean adhoc) {
query.adhoc = adhoc;
return this;
}
/**
* Build the query
*/
public ExecutionQuery build() {
return new ExecutionQuery(query);
}
}
}

View file

@ -17,6 +17,7 @@ package org.rundeck.api;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import betamax.MatchRule;
@ -26,10 +27,13 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.rundeck.api.domain.RundeckEvent;
import org.rundeck.api.domain.RundeckExecution;
import org.rundeck.api.domain.RundeckHistory;
import org.rundeck.api.domain.RundeckProject;
import betamax.Betamax;
import betamax.Recorder;
import org.rundeck.api.query.ExecutionQuery;
/**
* Test the {@link RundeckClient}. Uses betamax to unit-test HTTP requests without a live RunDeck instance.
@ -119,6 +123,106 @@ public class RundeckClientTest {
Assert.assertEquals(Arrays.asList("bob"), names);
}
@Test
@Betamax(tape = "get_executions",
mode = TapeMode.READ_ONLY,
match = {MatchRule.uri, MatchRule.headers, MatchRule.method, MatchRule.path, MatchRule.query})
public void getExecutions() throws Exception {
RundeckClient client = new RundeckClient("http://rundeck.local:4440", "0UUNkeRp4d58EDeCs7S6UdODp334DvK9");
final String projectName = "blah";
final List<RundeckExecution> jobTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.job("test job")
.build(),
2L,
0L);
Assert.assertEquals(2, jobTest.size());
final List<RundeckExecution> descriptionTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.description("a description")
.build(), 2L, 0L);
Assert.assertEquals(2, descriptionTest.size());
final List<RundeckExecution> abortedbyTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.abortedby("admin")
.build(),
2L,
0L);
Assert.assertEquals(1, abortedbyTest.size());
final List<RundeckExecution> beginTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.begin(new Date(1347581178168L))
.build(), 2L, 0L);
Assert.assertEquals(2, beginTest.size());
final List<RundeckExecution> endTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.end(new Date(1347581178168L))
.build(), 2L, 0L);
Assert.assertEquals(2, endTest.size());
final List<String> excludeJobIdList = Arrays.asList("123", "456");
final List<RundeckExecution> excludeJobIdListTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.excludeJobIdList(excludeJobIdList)
.build(), 2L, 0L);
Assert.assertEquals(2, excludeJobIdListTest.size());
final List<String> jobList = Arrays.asList("fruit/mango", "fruit/lemon");
final List<RundeckExecution> jobListTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.jobList(jobList)
.build(), 2L, 0L);
Assert.assertEquals(2, jobListTest.size());
final List<String> excludeJobList = Arrays.asList("a/path/job1", "path/to/job2");
final List<RundeckExecution> excludeJobListTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.excludeJobList(excludeJobList)
.build(), 2L, 0L);
Assert.assertEquals(2, excludeJobListTest.size());
final List<String> list = Arrays.asList("1f4415d7-3b52-4fc8-ba42-b6ac97508bff",
"d9fc5ee6-f1db-4d24-8808-feda18345bab");
final List<RundeckExecution> jobIdListTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.jobIdList(list)
.build(), 2L, 0L);
Assert.assertEquals(2, jobIdListTest.size());
final List<RundeckExecution> groupPathTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.groupPath("fruit")
.build(),
2L,
0L);
Assert.assertEquals(2, groupPathTest.size());
final List<RundeckExecution> groupPathExactTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.groupPathExact("fruit")
.build(), 2L, 0L);
Assert.assertEquals(2, groupPathExactTest.size());
final List<RundeckExecution> jobExactTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.jobExact("test job")
.build(),
2L,
0L);
Assert.assertEquals(2, jobExactTest.size());
final List<RundeckExecution> recentTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.recent("1h").build(), 2L, 0L);
Assert.assertEquals(2, recentTest.size());
final List<RundeckExecution> statusTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.status(RundeckExecution.ExecutionStatus.SUCCEEDED)
.build(), 2L, 0L);
Assert.assertEquals(2, statusTest.size());
final List<RundeckExecution> adhocTest = client.getExecutions(ExecutionQuery.builder()
.project(projectName)
.adhoc(true)
.build(), 2L, 0L);
Assert.assertEquals(2, adhocTest.size());
}
@Before
public void setUp() throws Exception {
// not that you can put whatever here, because we don't actually connect to the RunDeck instance

View file

@ -0,0 +1,249 @@
!tape
name: get_executions
interactions:
- recorded: 2012-09-14T22:04:13.134Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?jobFilter=test+job&project=blah&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(6.1.21)
Set-Cookie: JSESSIONID=zjp992wmk8is;Path=/
body: <result success='true' apiversion='5'><executions count='2'><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution><execution id='30' href='http://Venkman.local:4440/execution/follow/30' status='aborted'><user>admin</user><date-started unixtime='1347581285308'>2012-09-14T00:08:05Z</date-started><date-ended unixtime='1347581288381'>2012-09-14T00:08:08Z</date-ended><abortedby>admin</abortedby><job id='c545bdba-c823-4fa8-bbfd-3364e8cc8ba5'><name>test job2</name><group></group><project>blah</project><description>a description to test</description></job><description>echo this is a test [... 2 steps]</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.220Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&descFilter=a+description&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='30' href='http://Venkman.local:4440/execution/follow/30' status='aborted'><user>admin</user><date-started unixtime='1347581285308'>2012-09-14T00:08:05Z</date-started><date-ended unixtime='1347581288381'>2012-09-14T00:08:08Z</date-ended><abortedby>admin</abortedby><job id='c545bdba-c823-4fa8-bbfd-3364e8cc8ba5'><name>test job2</name><group></group><project>blah</project><description>a description to test</description></job><description>echo this is a test [... 2 steps]</description><argstring/></execution><execution id='29' href='http://Venkman.local:4440/execution/follow/29' status='succeeded'><user>admin</user><date-started unixtime='1347581230410'>2012-09-14T00:07:10Z</date-started><date-ended unixtime='1347581250696'>2012-09-14T00:07:30Z</date-ended><job id='c545bdba-c823-4fa8-bbfd-3364e8cc8ba5'><name>test job2</name><group></group><project>blah</project><description>a description to test</description></job><description>echo this is a test [... 2 steps]</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.342Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&begin=2012-09-13T17%3A06%3A18Z&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.404Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&end=2012-09-13T17%3A06%3A18Z&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='27' href='http://Venkman.local:4440/execution/follow/27' status='failed'><user>admin</user><date-started unixtime='1347040723674'>2012-09-07T17:58:43Z</date-started><date-ended unixtime='1347040726021'>2012-09-07T17:58:46Z</date-ended><job id='cf054831-6e1f-47c0-9382-5b1898aeaf2e'><name>local su test</name><group></group><project>blah</project><description></description></job><description>echo hi [... 2 steps]</description><argstring/></execution><execution id='26' href='http://Venkman.local:4440/execution/follow/26' status='failed'><user>admin</user><date-started unixtime='1347040599288'>2012-09-07T17:56:39Z</date-started><date-ended unixtime='1347040600629'>2012-09-07T17:56:40Z</date-ended><job id='cf054831-6e1f-47c0-9382-5b1898aeaf2e'><name>local su test</name><group></group><project>blah</project><description></description></job><description>echo hi [... 2 steps]</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.460Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&excludeJobIdListFilter=123&excludeJobIdListFilter=456&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.525Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&jobListFilter=fruit%2Fmango&jobListFilter=fruit%2Flemon&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='32' href='http://Venkman.local:4440/execution/follow/32' status='failed'><user>admin</user><date-started unixtime='1347644775513'>2012-09-14T17:46:15Z</date-started><date-ended unixtime='1347644775663'>2012-09-14T17:46:15Z</date-ended><job id='1f4415d7-3b52-4fc8-ba42-b6ac97508bff'><name>lemon</name><group>fruit</group><project>blah</project><description></description></job><description>echo lemon lemon [... 2 steps]</description><argstring/></execution><execution id='31' href='http://Venkman.local:4440/execution/follow/31' status='succeeded'><user>admin</user><date-started unixtime='1347644746884'>2012-09-14T17:45:46Z</date-started><date-ended unixtime='1347644747204'>2012-09-14T17:45:47Z</date-ended><job id='d9fc5ee6-f1db-4d24-8808-feda18345bab'><name>mango</name><group>fruit</group><project>blah</project><description></description></job><description>echo mango mango</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.575Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&excludeJobListFilter=a%2Fpath%2Fjob1&excludeJobListFilter=path%2Fto%2Fjob2&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.631Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&jobIdListFilter=1f4415d7-3b52-4fc8-ba42-b6ac97508bff&jobIdListFilter=d9fc5ee6-f1db-4d24-8808-feda18345bab&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='32' href='http://Venkman.local:4440/execution/follow/32' status='failed'><user>admin</user><date-started unixtime='1347644775513'>2012-09-14T17:46:15Z</date-started><date-ended unixtime='1347644775663'>2012-09-14T17:46:15Z</date-ended><job id='1f4415d7-3b52-4fc8-ba42-b6ac97508bff'><name>lemon</name><group>fruit</group><project>blah</project><description></description></job><description>echo lemon lemon [... 2 steps]</description><argstring/></execution><execution id='31' href='http://Venkman.local:4440/execution/follow/31' status='succeeded'><user>admin</user><date-started unixtime='1347644746884'>2012-09-14T17:45:46Z</date-started><date-ended unixtime='1347644747204'>2012-09-14T17:45:47Z</date-ended><job id='d9fc5ee6-f1db-4d24-8808-feda18345bab'><name>mango</name><group>fruit</group><project>blah</project><description></description></job><description>echo mango mango</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.682Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&groupPath=fruit&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='32' href='http://Venkman.local:4440/execution/follow/32' status='failed'><user>admin</user><date-started unixtime='1347644775513'>2012-09-14T17:46:15Z</date-started><date-ended unixtime='1347644775663'>2012-09-14T17:46:15Z</date-ended><job id='1f4415d7-3b52-4fc8-ba42-b6ac97508bff'><name>lemon</name><group>fruit</group><project>blah</project><description></description></job><description>echo lemon lemon [... 2 steps]</description><argstring/></execution><execution id='31' href='http://Venkman.local:4440/execution/follow/31' status='succeeded'><user>admin</user><date-started unixtime='1347644746884'>2012-09-14T17:45:46Z</date-started><date-ended unixtime='1347644747204'>2012-09-14T17:45:47Z</date-ended><job id='d9fc5ee6-f1db-4d24-8808-feda18345bab'><name>mango</name><group>fruit</group><project>blah</project><description></description></job><description>echo mango mango</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.735Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&groupPathExact=fruit&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='32' href='http://Venkman.local:4440/execution/follow/32' status='failed'><user>admin</user><date-started unixtime='1347644775513'>2012-09-14T17:46:15Z</date-started><date-ended unixtime='1347644775663'>2012-09-14T17:46:15Z</date-ended><job id='1f4415d7-3b52-4fc8-ba42-b6ac97508bff'><name>lemon</name><group>fruit</group><project>blah</project><description></description></job><description>echo lemon lemon [... 2 steps]</description><argstring/></execution><execution id='31' href='http://Venkman.local:4440/execution/follow/31' status='succeeded'><user>admin</user><date-started unixtime='1347644746884'>2012-09-14T17:45:46Z</date-started><date-ended unixtime='1347644747204'>2012-09-14T17:45:47Z</date-ended><job id='d9fc5ee6-f1db-4d24-8808-feda18345bab'><name>mango</name><group>fruit</group><project>blah</project><description></description></job><description>echo mango mango</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.785Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?jobExactFilter=test+job&project=blah&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution><execution id='28' href='http://Venkman.local:4440/execution/follow/28' status='succeeded'><user>admin</user><date-started unixtime='1347579864863'>2012-09-13T23:44:24Z</date-started><date-ended unixtime='1347579865110'>2012-09-13T23:44:25Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.836Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&loglevelFilter=INFO&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.883Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&recentFilter=1h&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-14T22:04:13.930Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&statusFilter=succeeded&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Server: Jetty(6.1.21)
body: <result success='true' apiversion='5'><executions count='2'><execution id='34' href='http://Venkman.local:4440/execution/follow/34' status='succeeded'><user>admin</user><date-started unixtime='1347660234844'>2012-09-14T22:03:54Z</date-started><date-ended unixtime='1347660234934'>2012-09-14T22:03:54Z</date-ended><job id='62a26001-b9fe-430a-8ba1-92cf04c10bba'><name>bonkers job</name><group></group><project>blah</project><description></description></job><description>echo why</description><argstring/></execution><execution id='33' href='http://Venkman.local:4440/execution/follow/33' status='succeeded'><user>admin</user><date-started unixtime='1347660078157'>2012-09-14T22:01:18Z</date-started><date-ended unixtime='1347660078425'>2012-09-14T22:01:18Z</date-ended><job id='4cfdfc23-be50-4a23-b291-b8a98897813b'><name>test job</name><group></group><project>blah</project><description></description></job><description>echo this is a test</description><argstring/></execution></executions></result>
- recorded: 2012-09-17T22:46:10.886Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&adhoc=true&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(6.1.21)
Set-Cookie: JSESSIONID=rqe6ggvlwr6p;Path=/
body: <result success='true' apiversion='5'><executions count='2'><execution id='20' href='http://Venkman.local:4440/execution/follow/20' status='failed'><user>admin</user><date-started unixtime='1347040226204'>2012-09-07T17:50:26Z</date-started><date-ended unixtime='1347040226462'>2012-09-07T17:50:26Z</date-ended><description>echo hi</description><argstring/></execution><execution id='19' href='http://Venkman.local:4440/execution/follow/19' status='failed'><user>admin</user><date-started unixtime='1347040211345'>2012-09-07T17:50:11Z</date-started><date-ended unixtime='1347040211602'>2012-09-07T17:50:11Z</date-ended><description>echo hi</description><argstring/></execution></executions></result>
- recorded: 2012-09-17T23:02:35.883Z
request:
method: GET
uri: http://rundeck.local:4440/api/5/executions?project=blah&abortedbyFilter=admin&max=2&offset=0
headers:
Host: rundeck.local:4440
Proxy-Connection: Keep-Alive
User-Agent: RunDeck API Java Client 5
X-RunDeck-Auth-Token: 0UUNkeRp4d58EDeCs7S6UdODp334DvK9
response:
status: 200
headers:
Content-Type: text/xml; charset=utf-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Jetty(6.1.21)
Set-Cookie: JSESSIONID=1ciy2jy8y2agx;Path=/
body: <result success='true' apiversion='5'><executions count='1'><execution id='30' href='http://Venkman.local:4440/execution/follow/30' status='aborted'><user>admin</user><date-started unixtime='1347581285308'>2012-09-14T00:08:05Z</date-started><date-ended unixtime='1347581288381'>2012-09-14T00:08:08Z</date-ended><abortedby>admin</abortedby><job id='c545bdba-c823-4fa8-bbfd-3364e8cc8ba5'><name>test job2</name><group></group><project>blah</project><description>a description to test</description></job><description>echo this is a test [... 2 steps]</description><argstring/></execution></executions></result>