new feature : abort an execution

This commit is contained in:
Vincent Behar 2011-07-06 17:29:48 +02:00
parent 59748a2481
commit d6b6ec3405
6 changed files with 239 additions and 0 deletions

View file

@ -22,10 +22,12 @@ import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.rundeck.api.RundeckApiException.RundeckApiLoginException;
import org.rundeck.api.domain.RundeckAbort;
import org.rundeck.api.domain.RundeckExecution;
import org.rundeck.api.domain.RundeckJob;
import org.rundeck.api.domain.RundeckProject;
import org.rundeck.api.domain.RundeckExecution.ExecutionStatus;
import org.rundeck.api.parser.AbortParser;
import org.rundeck.api.parser.ExecutionParser;
import org.rundeck.api.parser.ExecutionsParser;
import org.rundeck.api.parser.JobParser;
@ -655,6 +657,22 @@ public class RundeckClient implements Serializable {
new ExecutionParser("result/executions/execution"));
}
/**
* Abort an execution (identified by the given ID). The execution should be running...
*
* @param executionId identifier of the execution - mandatory
* @return a {@link RundeckAbort} instance - won't be null
* @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID)
* @throws RundeckApiLoginException if the login failed
* @throws IllegalArgumentException if the executionId is null
*/
public RundeckAbort abortExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException,
IllegalArgumentException {
AssertUtil.notNull(executionId, "executionId is mandatory to abort an execution !");
return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString(), "/abort"),
new AbortParser("result/abort"));
}
public String getUrl() {
return url;
}

View file

@ -0,0 +1,92 @@
/*
* Copyright 2011 Vincent Behar
*
* 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.
*/
package org.rundeck.api.domain;
import java.io.Serializable;
/**
* Represents an abort of a {@link RundeckExecution}
*
* @author Vincent Behar
*/
public class RundeckAbort implements Serializable {
private static final long serialVersionUID = 1L;
private AbortStatus status;
private RundeckExecution execution;
public AbortStatus getStatus() {
return status;
}
public void setStatus(AbortStatus status) {
this.status = status;
}
public RundeckExecution getExecution() {
return execution;
}
public void setExecution(RundeckExecution execution) {
this.execution = execution;
}
@Override
public String toString() {
return "RundeckAbort [status=" + status + ", execution=" + execution + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((execution == null) ? 0 : execution.hashCode());
result = prime * result + ((status == null) ? 0 : status.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RundeckAbort other = (RundeckAbort) obj;
if (execution == null) {
if (other.execution != null)
return false;
} else if (!execution.equals(other.execution))
return false;
if (status == null) {
if (other.status != null)
return false;
} else if (!status.equals(other.status))
return false;
return true;
}
/**
* The status of an abort
*/
public static enum AbortStatus {
PENDING, FAILED, ABORTED;
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright 2011 Vincent Behar
*
* 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.
*/
package org.rundeck.api.parser;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Node;
import org.rundeck.api.domain.RundeckAbort;
import org.rundeck.api.domain.RundeckExecution;
import org.rundeck.api.domain.RundeckAbort.AbortStatus;
/**
* Parser for a single {@link RundeckAbort}
*
* @author Vincent Behar
*/
public class AbortParser implements NodeParser<RundeckAbort> {
private String xpath;
public AbortParser() {
super();
}
/**
* @param xpath of the abort element if it is not the root node
*/
public AbortParser(String xpath) {
super();
this.xpath = xpath;
}
@Override
public RundeckAbort parseNode(Node node) {
Node abortNode = xpath != null ? node.selectSingleNode(xpath) : node;
RundeckAbort abort = new RundeckAbort();
try {
abort.setStatus(AbortStatus.valueOf(StringUtils.upperCase(abortNode.valueOf("@status"))));
} catch (IllegalArgumentException e) {
}
Node execNode = abortNode.selectSingleNode("execution");
if (execNode != null) {
RundeckExecution execution = new ExecutionParser().parseNode(execNode);
abort.setExecution(execution);
}
return abort;
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright 2011 Vincent Behar
*
* 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.
*/
package org.rundeck.api.parser;
import java.io.InputStream;
import org.dom4j.Document;
import org.junit.Assert;
import org.junit.Test;
import org.rundeck.api.domain.RundeckAbort;
import org.rundeck.api.domain.RundeckExecution;
import org.rundeck.api.domain.RundeckAbort.AbortStatus;
import org.rundeck.api.domain.RundeckExecution.ExecutionStatus;
/**
* Test the {@link AbortParser}
*
* @author Vincent Behar
*/
public class AbortParserTest {
@Test
public void parsePendingNode() throws Exception {
InputStream input = getClass().getResourceAsStream("abort-pending.xml");
Document document = ParserHelper.loadDocument(input);
RundeckAbort abort = new AbortParser("result/abort").parseNode(document);
RundeckExecution execution = abort.getExecution();
Assert.assertEquals(AbortStatus.PENDING, abort.getStatus());
Assert.assertEquals(new Long(1), execution.getId());
Assert.assertEquals(ExecutionStatus.RUNNING, execution.getStatus());
}
@Test
public void parseFailedNode() throws Exception {
InputStream input = getClass().getResourceAsStream("abort-failed.xml");
Document document = ParserHelper.loadDocument(input);
RundeckAbort abort = new AbortParser("result/abort").parseNode(document);
RundeckExecution execution = abort.getExecution();
Assert.assertEquals(AbortStatus.FAILED, abort.getStatus());
Assert.assertEquals(new Long(1), execution.getId());
Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus());
}
}

View file

@ -0,0 +1 @@
<result success='true' apiversion='1'><success><message>Execution status: previously succeeded</message></success><abort status='failed'><execution id='1' status='succeeded'/></abort></result>

View file

@ -0,0 +1 @@
<result success='true' apiversion='1'><success><message>Execution status: running</message></success><abort status='pending'><execution id='1' status='running'/></abort></result>