diff --git a/src/main/java/org/rundeck/api/RundeckClient.java b/src/main/java/org/rundeck/api/RundeckClient.java index 7c3f1ed..d549ab0 100644 --- a/src/main/java/org/rundeck/api/RundeckClient.java +++ b/src/main/java/org/rundeck/api/RundeckClient.java @@ -30,6 +30,7 @@ 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.RundeckHistory; import org.rundeck.api.domain.RundeckJob; import org.rundeck.api.domain.RundeckJobsImportMethod; import org.rundeck.api.domain.RundeckJobsImportResult; @@ -39,6 +40,7 @@ import org.rundeck.api.domain.RundeckSystemInfo; import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; import org.rundeck.api.parser.AbortParser; import org.rundeck.api.parser.ExecutionParser; +import org.rundeck.api.parser.HistoryParser; import org.rundeck.api.parser.JobParser; import org.rundeck.api.parser.JobsImportResultParser; import org.rundeck.api.parser.ListParser; @@ -1895,6 +1897,26 @@ public class RundeckClient implements Serializable { new AbortParser("result/abort")); } + /* + * History + */ + + /** + * Get the (events) history for the given project + * + * @param project name of the project - mandatory + * @return a {@link RundeckHistory} instance - won't be null + * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) + * @throws RundeckApiLoginException if the login failed + * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) + */ + public RundeckHistory getHistory(String project) throws RundeckApiException, RundeckApiLoginException, + IllegalArgumentException { + AssertUtil.notBlank(project, "project is mandatory to get the history !"); + return new ApiCall(this).get(new ApiPathBuilder("/history").param("project", project), + new HistoryParser("result/events")); + } + /* * Nodes */ diff --git a/src/main/java/org/rundeck/api/domain/RundeckEvent.java b/src/main/java/org/rundeck/api/domain/RundeckEvent.java new file mode 100644 index 0000000..5b9dfbd --- /dev/null +++ b/src/main/java/org/rundeck/api/domain/RundeckEvent.java @@ -0,0 +1,372 @@ +/* + * 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; +import java.util.Date; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang.time.DurationFormatUtils; + +/** + * Represents a RunDeck event + * + * @author Vincent Behar + */ +public class RundeckEvent implements Serializable { + + private static final long serialVersionUID = 1L; + + private String title; + + private EventStatus status; + + private String summary; + + private NodeSummary nodeSummary; + + private String user; + + private String project; + + private Date startedAt; + + private Date endedAt; + + /** only if the execution was aborted */ + private String abortedBy; + + /** only if associated with an execution */ + private Long executionId; + + /** only if associated with a job */ + private String jobId; + + /** + * @return the duration of the event in milliseconds (or null if the dates are invalid) + */ + public Long getDurationInMillis() { + if (startedAt == null || endedAt == null) { + return null; + } + return endedAt.getTime() - startedAt.getTime(); + } + + /** + * @return the duration of the event in seconds (or null if the dates are invalid) + */ + public Long getDurationInSeconds() { + Long durationInMillis = getDurationInMillis(); + return durationInMillis != null ? TimeUnit.MILLISECONDS.toSeconds(durationInMillis) : null; + } + + /** + * @return the duration of the event, as a human-readable string : "3 minutes 34 seconds" (or null if the dates are + * invalid) + */ + public String getDuration() { + Long durationInMillis = getDurationInMillis(); + return durationInMillis != null ? DurationFormatUtils.formatDurationWords(durationInMillis, true, true) : null; + } + + /** + * @return the duration of the event, as a "short" human-readable string : "0:03:34.187" (or null if the dates are + * invalid) + */ + public String getShortDuration() { + Long durationInMillis = getDurationInMillis(); + return durationInMillis != null ? DurationFormatUtils.formatDurationHMS(durationInMillis) : null; + } + + /** + * @return true if this event is for an ad-hoc command or script, false otherwise (for a job) + */ + public boolean isAdhoc() { + return "adhoc".equals(title); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the status of the event - see {@link EventStatus} + */ + public EventStatus getStatus() { + return status; + } + + public void setStatus(EventStatus status) { + this.status = status; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + /** + * @return the node summary - see {@link NodeSummary} + */ + public NodeSummary getNodeSummary() { + return nodeSummary; + } + + public void setNodeSummary(NodeSummary nodeSummary) { + this.nodeSummary = nodeSummary; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getProject() { + return project; + } + + public void setProject(String project) { + this.project = project; + } + + public Date getStartedAt() { + return (startedAt != null) ? new Date(startedAt.getTime()) : null; + } + + public void setStartedAt(Date startedAt) { + this.startedAt = ((startedAt != null) ? new Date(startedAt.getTime()) : null); + } + + public Date getEndedAt() { + return (endedAt != null) ? new Date(endedAt.getTime()) : null; + } + + public void setEndedAt(Date endedAt) { + this.endedAt = ((endedAt != null) ? new Date(endedAt.getTime()) : null); + } + + public String getAbortedBy() { + return abortedBy; + } + + public void setAbortedBy(String abortedBy) { + this.abortedBy = abortedBy; + } + + /** + * @return the ID of the execution associated with this event, or null if there is not + */ + public Long getExecutionId() { + return executionId; + } + + public void setExecutionId(Long executionId) { + this.executionId = executionId; + } + + /** + * @return the ID of the job associated with this event, or null in the case of an ad-hoc command or script + */ + public String getJobId() { + return jobId; + } + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + @Override + public String toString() { + return "RundeckEvent [abortedBy=" + abortedBy + ", endedAt=" + endedAt + ", executionId=" + executionId + + ", jobId=" + jobId + ", nodeSummary=" + nodeSummary + ", project=" + project + ", startedAt=" + + startedAt + ", status=" + status + ", summary=" + summary + ", title=" + title + ", user=" + user + + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((abortedBy == null) ? 0 : abortedBy.hashCode()); + result = prime * result + ((endedAt == null) ? 0 : endedAt.hashCode()); + result = prime * result + ((executionId == null) ? 0 : executionId.hashCode()); + result = prime * result + ((jobId == null) ? 0 : jobId.hashCode()); + result = prime * result + ((nodeSummary == null) ? 0 : nodeSummary.hashCode()); + result = prime * result + ((project == null) ? 0 : project.hashCode()); + result = prime * result + ((startedAt == null) ? 0 : startedAt.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((summary == null) ? 0 : summary.hashCode()); + result = prime * result + ((title == null) ? 0 : title.hashCode()); + result = prime * result + ((user == null) ? 0 : user.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; + RundeckEvent other = (RundeckEvent) obj; + if (abortedBy == null) { + if (other.abortedBy != null) + return false; + } else if (!abortedBy.equals(other.abortedBy)) + return false; + if (endedAt == null) { + if (other.endedAt != null) + return false; + } else if (!endedAt.equals(other.endedAt)) + return false; + if (executionId == null) { + if (other.executionId != null) + return false; + } else if (!executionId.equals(other.executionId)) + return false; + if (jobId == null) { + if (other.jobId != null) + return false; + } else if (!jobId.equals(other.jobId)) + return false; + if (nodeSummary == null) { + if (other.nodeSummary != null) + return false; + } else if (!nodeSummary.equals(other.nodeSummary)) + return false; + if (project == null) { + if (other.project != null) + return false; + } else if (!project.equals(other.project)) + return false; + if (startedAt == null) { + if (other.startedAt != null) + return false; + } else if (!startedAt.equals(other.startedAt)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (summary == null) { + if (other.summary != null) + return false; + } else if (!summary.equals(other.summary)) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + return true; + } + + /** + * Summary for nodes + */ + public static class NodeSummary implements Serializable { + + private static final long serialVersionUID = 1L; + + private int succeeded; + + private int failed; + + private int total; + + public int getSucceeded() { + return succeeded; + } + + public void setSucceeded(int succeeded) { + this.succeeded = succeeded; + } + + public int getFailed() { + return failed; + } + + public void setFailed(int failed) { + this.failed = failed; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + @Override + public String toString() { + return "NodeSummary [succeeded=" + succeeded + ", failed=" + failed + ", total=" + total + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + failed; + result = prime * result + succeeded; + result = prime * result + total; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + NodeSummary other = (NodeSummary) obj; + if (failed != other.failed) + return false; + if (succeeded != other.succeeded) + return false; + if (total != other.total) + return false; + return true; + } + + } + + /** + * The status of an event + */ + public static enum EventStatus { + SUCCEEDED, FAILED, ABORTED; + } + +} diff --git a/src/main/java/org/rundeck/api/domain/RundeckHistory.java b/src/main/java/org/rundeck/api/domain/RundeckHistory.java new file mode 100644 index 0000000..b7db93f --- /dev/null +++ b/src/main/java/org/rundeck/api/domain/RundeckHistory.java @@ -0,0 +1,130 @@ +/* + * 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; +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a portion of the RunDeck (events) history + * + * @author Vincent Behar + */ +public class RundeckHistory implements Serializable { + + private static final long serialVersionUID = 1L; + + private List events; + + private int count; + + private int total; + + private int max; + + private int offset; + + public void addEvent(RundeckEvent event) { + if (events == null) { + events = new ArrayList(); + } + events.add(event); + } + + public List getEvents() { + return events; + } + + public void setEvents(List events) { + this.events = events; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getMax() { + return max; + } + + public void setMax(int max) { + this.max = max; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + @Override + public String toString() { + return "RundeckHistory [count=" + count + ", max=" + max + ", offset=" + offset + ", total=" + total + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + count; + result = prime * result + ((events == null) ? 0 : events.hashCode()); + result = prime * result + max; + result = prime * result + offset; + result = prime * result + total; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RundeckHistory other = (RundeckHistory) obj; + if (count != other.count) + return false; + if (events == null) { + if (other.events != null) + return false; + } else if (!events.equals(other.events)) + return false; + if (max != other.max) + return false; + if (offset != other.offset) + return false; + if (total != other.total) + return false; + return true; + } + +} diff --git a/src/main/java/org/rundeck/api/parser/EventParser.java b/src/main/java/org/rundeck/api/parser/EventParser.java new file mode 100644 index 0000000..c9c67b4 --- /dev/null +++ b/src/main/java/org/rundeck/api/parser/EventParser.java @@ -0,0 +1,87 @@ +/* + * 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.util.Date; +import org.apache.commons.lang.StringUtils; +import org.dom4j.Node; +import org.rundeck.api.domain.RundeckEvent; +import org.rundeck.api.domain.RundeckEvent.EventStatus; +import org.rundeck.api.domain.RundeckEvent.NodeSummary; + +/** + * Parser for a single {@link RundeckEvent} + * + * @author Vincent Behar + */ +public class EventParser implements XmlNodeParser { + + private String xpath; + + public EventParser() { + super(); + } + + /** + * @param xpath of the event element if it is not the root node + */ + public EventParser(String xpath) { + super(); + this.xpath = xpath; + } + + @Override + public RundeckEvent parseXmlNode(Node node) { + Node eventNode = xpath != null ? node.selectSingleNode(xpath) : node; + + RundeckEvent event = new RundeckEvent(); + + event.setTitle(StringUtils.trimToNull(eventNode.valueOf("title"))); + try { + event.setStatus(EventStatus.valueOf(StringUtils.upperCase(eventNode.valueOf("status")))); + } catch (IllegalArgumentException e) { + event.setStatus(null); + } + event.setSummary(StringUtils.trimToNull(eventNode.valueOf("summary"))); + + NodeSummary nodeSummary = new NodeSummary(); + nodeSummary.setSucceeded(Integer.valueOf(eventNode.valueOf("node-summary/@succeeded"))); + nodeSummary.setFailed(Integer.valueOf(eventNode.valueOf("node-summary/@failed"))); + nodeSummary.setTotal(Integer.valueOf(eventNode.valueOf("node-summary/@total"))); + event.setNodeSummary(nodeSummary); + + event.setUser(StringUtils.trimToNull(eventNode.valueOf("user"))); + event.setProject(StringUtils.trimToNull(eventNode.valueOf("project"))); + String startedAt = StringUtils.trimToNull(eventNode.valueOf("@starttime")); + if (startedAt != null) { + event.setStartedAt(new Date(Long.valueOf(startedAt))); + } + String endedAt = StringUtils.trimToNull(eventNode.valueOf("@endtime")); + if (endedAt != null) { + event.setEndedAt(new Date(Long.valueOf(endedAt))); + } + event.setAbortedBy(StringUtils.trimToNull(eventNode.valueOf("abortedby"))); + try { + event.setExecutionId(Long.valueOf(eventNode.valueOf("execution/@id"))); + } catch (NumberFormatException e) { + event.setExecutionId(null); + } + event.setJobId(StringUtils.trimToNull(eventNode.valueOf("job/@id"))); + + return event; + } + +} diff --git a/src/main/java/org/rundeck/api/parser/HistoryParser.java b/src/main/java/org/rundeck/api/parser/HistoryParser.java new file mode 100644 index 0000000..b80b500 --- /dev/null +++ b/src/main/java/org/rundeck/api/parser/HistoryParser.java @@ -0,0 +1,67 @@ +/* + * 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.util.List; +import org.dom4j.Node; +import org.rundeck.api.domain.RundeckEvent; +import org.rundeck.api.domain.RundeckHistory; + +/** + * Parser for a single {@link RundeckHistory} + * + * @author Vincent Behar + */ +public class HistoryParser implements XmlNodeParser { + + private String xpath; + + public HistoryParser() { + super(); + } + + /** + * @param xpath of the history element if it is not the root node + */ + public HistoryParser(String xpath) { + super(); + this.xpath = xpath; + } + + @Override + public RundeckHistory parseXmlNode(Node node) { + Node eventsNode = xpath != null ? node.selectSingleNode(xpath) : node; + + RundeckHistory history = new RundeckHistory(); + + history.setCount(Integer.valueOf(eventsNode.valueOf("@count"))); + history.setTotal(Integer.valueOf(eventsNode.valueOf("@total"))); + history.setMax(Integer.valueOf(eventsNode.valueOf("@max"))); + history.setOffset(Integer.valueOf(eventsNode.valueOf("@offset"))); + + @SuppressWarnings("unchecked") + List eventNodes = eventsNode.selectNodes("event"); + EventParser eventParser = new EventParser(); + + for (Node eventNode : eventNodes) { + RundeckEvent event = eventParser.parseXmlNode(eventNode); + history.addEvent(event); + } + + return history; + } + +} diff --git a/src/test/java/org/rundeck/api/parser/EventParserTest.java b/src/test/java/org/rundeck/api/parser/EventParserTest.java new file mode 100644 index 0000000..2c30ab2 --- /dev/null +++ b/src/test/java/org/rundeck/api/parser/EventParserTest.java @@ -0,0 +1,77 @@ +/* + * 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 java.util.Date; +import org.dom4j.Document; +import org.junit.Assert; +import org.junit.Test; +import org.rundeck.api.domain.RundeckEvent; +import org.rundeck.api.domain.RundeckEvent.EventStatus; + +/** + * Test the {@link EventParser} + * + * @author Vincent Behar + */ +public class EventParserTest { + + @Test + public void parseSucceededEvent() throws Exception { + InputStream input = getClass().getResourceAsStream("event-succeeded.xml"); + Document document = ParserHelper.loadDocument(input); + + RundeckEvent event = new EventParser("event").parseXmlNode(document); + + Assert.assertFalse(event.isAdhoc()); + Assert.assertEquals("job-name", event.getTitle()); + Assert.assertEquals(EventStatus.SUCCEEDED, event.getStatus()); + Assert.assertEquals("ps", event.getSummary()); + Assert.assertEquals(2, event.getNodeSummary().getSucceeded()); + Assert.assertEquals(0, event.getNodeSummary().getFailed()); + Assert.assertEquals(2, event.getNodeSummary().getTotal()); + Assert.assertEquals("admin", event.getUser()); + Assert.assertEquals("test", event.getProject()); + Assert.assertEquals(new Date(1311946495646L), event.getStartedAt()); + Assert.assertEquals(new Date(1311946557618L), event.getEndedAt()); + Assert.assertEquals("1", event.getJobId()); + Assert.assertEquals(new Long(2), event.getExecutionId()); + } + + @Test + public void parseAdhocEvent() throws Exception { + InputStream input = getClass().getResourceAsStream("event-adhoc.xml"); + Document document = ParserHelper.loadDocument(input); + + RundeckEvent event = new EventParser("event").parseXmlNode(document); + + Assert.assertTrue(event.isAdhoc()); + Assert.assertEquals("adhoc", event.getTitle()); + Assert.assertEquals(EventStatus.FAILED, event.getStatus()); + Assert.assertEquals("ls $HOME", event.getSummary()); + Assert.assertEquals(1, event.getNodeSummary().getSucceeded()); + Assert.assertEquals(1, event.getNodeSummary().getFailed()); + Assert.assertEquals(2, event.getNodeSummary().getTotal()); + Assert.assertEquals("admin", event.getUser()); + Assert.assertEquals("test", event.getProject()); + Assert.assertEquals(new Date(1311945953547L), event.getStartedAt()); + Assert.assertEquals(new Date(1311945963467L), event.getEndedAt()); + Assert.assertEquals(null, event.getJobId()); + Assert.assertEquals(new Long(1), event.getExecutionId()); + } + +} diff --git a/src/test/java/org/rundeck/api/parser/HistoryParserTest.java b/src/test/java/org/rundeck/api/parser/HistoryParserTest.java new file mode 100644 index 0000000..d4f4229 --- /dev/null +++ b/src/test/java/org/rundeck/api/parser/HistoryParserTest.java @@ -0,0 +1,78 @@ +/* + * 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 java.util.Date; +import org.dom4j.Document; +import org.junit.Assert; +import org.junit.Test; +import org.rundeck.api.domain.RundeckEvent; +import org.rundeck.api.domain.RundeckHistory; +import org.rundeck.api.domain.RundeckEvent.EventStatus; + +/** + * Test the {@link HistoryParser} + * + * @author Vincent Behar + */ +public class HistoryParserTest { + + @Test + public void parseHistory() throws Exception { + InputStream input = getClass().getResourceAsStream("history.xml"); + Document document = ParserHelper.loadDocument(input); + + RundeckHistory history = new HistoryParser("result/events").parseXmlNode(document); + + Assert.assertEquals(2, history.getCount()); + Assert.assertEquals(4, history.getTotal()); + Assert.assertEquals(2, history.getMax()); + Assert.assertEquals(0, history.getOffset()); + Assert.assertEquals(2, history.getEvents().size()); + + RundeckEvent event1 = history.getEvents().get(0); + Assert.assertFalse(event1.isAdhoc()); + Assert.assertEquals("job-name", event1.getTitle()); + Assert.assertEquals(EventStatus.SUCCEEDED, event1.getStatus()); + Assert.assertEquals("ps", event1.getSummary()); + Assert.assertEquals(2, event1.getNodeSummary().getSucceeded()); + Assert.assertEquals(0, event1.getNodeSummary().getFailed()); + Assert.assertEquals(2, event1.getNodeSummary().getTotal()); + Assert.assertEquals("admin", event1.getUser()); + Assert.assertEquals("test", event1.getProject()); + Assert.assertEquals(new Date(1311946495646L), event1.getStartedAt()); + Assert.assertEquals(new Date(1311946557618L), event1.getEndedAt()); + Assert.assertEquals("1", event1.getJobId()); + Assert.assertEquals(new Long(2), event1.getExecutionId()); + + RundeckEvent event2 = history.getEvents().get(1); + Assert.assertTrue(event2.isAdhoc()); + Assert.assertEquals("adhoc", event2.getTitle()); + Assert.assertEquals(EventStatus.FAILED, event2.getStatus()); + Assert.assertEquals("ls $HOME", event2.getSummary()); + Assert.assertEquals(1, event2.getNodeSummary().getSucceeded()); + Assert.assertEquals(1, event2.getNodeSummary().getFailed()); + Assert.assertEquals(2, event2.getNodeSummary().getTotal()); + Assert.assertEquals("admin", event2.getUser()); + Assert.assertEquals("test", event2.getProject()); + Assert.assertEquals(new Date(1311945953547L), event2.getStartedAt()); + Assert.assertEquals(new Date(1311945963467L), event2.getEndedAt()); + Assert.assertEquals(null, event2.getJobId()); + Assert.assertEquals(new Long(1), event2.getExecutionId()); + } + +} diff --git a/src/test/resources/org/rundeck/api/parser/event-adhoc.xml b/src/test/resources/org/rundeck/api/parser/event-adhoc.xml new file mode 100644 index 0000000..1aa6275 --- /dev/null +++ b/src/test/resources/org/rundeck/api/parser/event-adhoc.xml @@ -0,0 +1 @@ +adhocfailedls $HOMEadmintest2011-07-29T13:25:53Z2011-07-29T13:26:03Z \ No newline at end of file diff --git a/src/test/resources/org/rundeck/api/parser/event-succeeded.xml b/src/test/resources/org/rundeck/api/parser/event-succeeded.xml new file mode 100644 index 0000000..7557e66 --- /dev/null +++ b/src/test/resources/org/rundeck/api/parser/event-succeeded.xml @@ -0,0 +1 @@ +job-namesucceededpsadmintest2011-07-29T13:34:55Z2011-07-29T13:35:57Z \ No newline at end of file diff --git a/src/test/resources/org/rundeck/api/parser/history.xml b/src/test/resources/org/rundeck/api/parser/history.xml new file mode 100644 index 0000000..3aa0b8c --- /dev/null +++ b/src/test/resources/org/rundeck/api/parser/history.xml @@ -0,0 +1 @@ +job-namesucceededpsadmintest2011-07-29T13:34:55Z2011-07-29T13:35:57Zadhocfailedls $HOMEadmintest2011-07-29T13:25:53Z2011-07-29T13:26:03Z \ No newline at end of file