diff --git a/src/main/java/org/rundeck/api/ApiPathBuilder.java b/src/main/java/org/rundeck/api/ApiPathBuilder.java
index 3e78c93..0fe823c 100644
--- a/src/main/java/org/rundeck/api/ApiPathBuilder.java
+++ b/src/main/java/org/rundeck/api/ApiPathBuilder.java
@@ -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 greg@dtosolutions.com
+ */
+ 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);
+ }
}
diff --git a/src/main/java/org/rundeck/api/ExecutionQueryParameters.java b/src/main/java/org/rundeck/api/ExecutionQueryParameters.java
new file mode 100644
index 0000000..dd8753d
--- /dev/null
+++ b/src/main/java/org/rundeck/api/ExecutionQueryParameters.java
@@ -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 greg@dtosolutions.com
+* 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 greg@dtosolutions.com
+ */
+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;
+ }
+
+}
diff --git a/src/main/java/org/rundeck/api/QueryParameterBuilder.java b/src/main/java/org/rundeck/api/QueryParameterBuilder.java
new file mode 100644
index 0000000..6fd0126
--- /dev/null
+++ b/src/main/java/org/rundeck/api/QueryParameterBuilder.java
@@ -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 greg@dtosolutions.com
+* 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 greg@dtosolutions.com
+ */
+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) value);
+ } else {
+ builder.field(key, stringVal(value));
+ }
+ return true;
+ } else {
+ if (value instanceof Collection) {
+ builder.param(key, (Collection) 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);
+ }
+}
diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java
index 331cb6f..8147ac1 100644
--- a/src/main/java/org/rundeck/api/RundeckClient.java
+++ b/src/main/java/org/rundeck/api/RundeckClient.java
@@ -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(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 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(new ExecutionParser(),
"result/executions/execution"));
}
diff --git a/src/main/java/org/rundeck/api/query/ExecutionQuery.java b/src/main/java/org/rundeck/api/query/ExecutionQuery.java
new file mode 100644
index 0000000..b78c39f
--- /dev/null
+++ b/src/main/java/org/rundeck/api/query/ExecutionQuery.java
@@ -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 greg@dtosolutions.com
+* 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 greg@dtosolutions.com
+ */
+public class ExecutionQuery {
+ private RundeckExecution.ExecutionStatus status;
+ private String abortedby;
+ private List jobList;
+ private List jobIdList;
+ private List excludeJobList;
+ private List 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 getJobList() {
+ return jobList;
+ }
+
+ public List getExcludeJobList() {
+ return excludeJobList;
+ }
+
+ public List 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 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 list) {
+ query.jobList = list;
+ return this;
+ }
+ /**
+ * List of job IDs to query
+ */
+ public Builder jobIdList(List list) {
+ query.jobIdList = list;
+ return this;
+ }
+
+ /**
+ * List of job "group/name" to exclude from query
+ */
+ public Builder excludeJobList(List list) {
+ query.excludeJobList = list;
+ return this;
+ }
+
+ /**
+ * List of job IDs to exclude from query
+ */
+ public Builder excludeJobIdList(List 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);
+ }
+ }
+}
diff --git a/src/test/java/org/rundeck/api/RundeckClientTest.java b/src/test/java/org/rundeck/api/RundeckClientTest.java
index 2a821d2..eaee9c4 100644
--- a/src/test/java/org/rundeck/api/RundeckClientTest.java
+++ b/src/test/java/org/rundeck/api/RundeckClientTest.java
@@ -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 jobTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .job("test job")
+ .build(),
+ 2L,
+ 0L);
+ Assert.assertEquals(2, jobTest.size());
+ final List descriptionTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .description("a description")
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, descriptionTest.size());
+ final List abortedbyTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .abortedby("admin")
+ .build(),
+ 2L,
+ 0L);
+ Assert.assertEquals(1, abortedbyTest.size());
+ final List beginTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .begin(new Date(1347581178168L))
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, beginTest.size());
+ final List endTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .end(new Date(1347581178168L))
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, endTest.size());
+ final List excludeJobIdList = Arrays.asList("123", "456");
+ final List excludeJobIdListTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .excludeJobIdList(excludeJobIdList)
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, excludeJobIdListTest.size());
+ final List jobList = Arrays.asList("fruit/mango", "fruit/lemon");
+ final List jobListTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .jobList(jobList)
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, jobListTest.size());
+ final List excludeJobList = Arrays.asList("a/path/job1", "path/to/job2");
+ final List excludeJobListTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .excludeJobList(excludeJobList)
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, excludeJobListTest.size());
+ final List list = Arrays.asList("1f4415d7-3b52-4fc8-ba42-b6ac97508bff",
+ "d9fc5ee6-f1db-4d24-8808-feda18345bab");
+ final List jobIdListTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .jobIdList(list)
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, jobIdListTest.size());
+ final List groupPathTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .groupPath("fruit")
+ .build(),
+ 2L,
+ 0L);
+ Assert.assertEquals(2, groupPathTest.size());
+ final List groupPathExactTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .groupPathExact("fruit")
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, groupPathExactTest.size());
+ final List jobExactTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .jobExact("test job")
+ .build(),
+ 2L,
+ 0L);
+ Assert.assertEquals(2, jobExactTest.size());
+
+ final List recentTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .recent("1h").build(), 2L, 0L);
+ Assert.assertEquals(2, recentTest.size());
+ final List statusTest = client.getExecutions(ExecutionQuery.builder()
+ .project(projectName)
+ .status(RundeckExecution.ExecutionStatus.SUCCEEDED)
+ .build(), 2L, 0L);
+ Assert.assertEquals(2, statusTest.size());
+ final List 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
diff --git a/src/test/resources/betamax/tapes/get_executions.yaml b/src/test/resources/betamax/tapes/get_executions.yaml
new file mode 100644
index 0000000..cfc1b20
--- /dev/null
+++ b/src/test/resources/betamax/tapes/get_executions.yaml
@@ -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: admin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a testadmin2012-09-14T00:08:05Z2012-09-14T00:08:08Zadmintest job2blaha description to testecho this is a test [... 2 steps]
+- 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: admin2012-09-14T00:08:05Z2012-09-14T00:08:08Zadmintest job2blaha description to testecho this is a test [... 2 steps]admin2012-09-14T00:07:10Z2012-09-14T00:07:30Ztest job2blaha description to testecho this is a test [... 2 steps]
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-07T17:58:43Z2012-09-07T17:58:46Zlocal su testblahecho hi [... 2 steps]admin2012-09-07T17:56:39Z2012-09-07T17:56:40Zlocal su testblahecho hi [... 2 steps]
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-14T17:46:15Z2012-09-14T17:46:15Zlemonfruitblahecho lemon lemon [... 2 steps]admin2012-09-14T17:45:46Z2012-09-14T17:45:47Zmangofruitblahecho mango mango
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-14T17:46:15Z2012-09-14T17:46:15Zlemonfruitblahecho lemon lemon [... 2 steps]admin2012-09-14T17:45:46Z2012-09-14T17:45:47Zmangofruitblahecho mango mango
+- 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: admin2012-09-14T17:46:15Z2012-09-14T17:46:15Zlemonfruitblahecho lemon lemon [... 2 steps]admin2012-09-14T17:45:46Z2012-09-14T17:45:47Zmangofruitblahecho mango mango
+- 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: admin2012-09-14T17:46:15Z2012-09-14T17:46:15Zlemonfruitblahecho lemon lemon [... 2 steps]admin2012-09-14T17:45:46Z2012-09-14T17:45:47Zmangofruitblahecho mango mango
+- 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: admin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a testadmin2012-09-13T23:44:24Z2012-09-13T23:44:25Ztest jobblahecho this is a test
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-14T22:03:54Z2012-09-14T22:03:54Zbonkers jobblahecho whyadmin2012-09-14T22:01:18Z2012-09-14T22:01:18Ztest jobblahecho this is a test
+- 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: admin2012-09-07T17:50:26Z2012-09-07T17:50:26Zecho hiadmin2012-09-07T17:50:11Z2012-09-07T17:50:11Zecho hi
+- 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: admin2012-09-14T00:08:05Z2012-09-14T00:08:08Zadmintest job2blaha description to testecho this is a test [... 2 steps]