diff --git a/apidocs/allclasses-frame.html b/apidocs/allclasses-frame.html index d8117f0..6061b89 100644 --- a/apidocs/allclasses-frame.html +++ b/apidocs/allclasses-frame.html @@ -2,13 +2,13 @@
- +AssertUtil + | AbortParser
+ +AssertUtil ExecutionParser @@ -32,11 +34,13 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) JobsParser -NodeFiltersBuilder +NodeFiltersBuilder -NodeParser +NodeParser -OptionsBuilder +NodesParser + +OptionsBuilder ParametersUtil @@ -46,6 +50,10 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) ProjectsParser +RundeckAbort + +RundeckAbort.AbortStatus + RundeckApiException RundeckApiException.RundeckApiLoginException @@ -58,8 +66,12 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) RundeckJob +RundeckNode + RundeckProject +XmlNodeParser + |
AssertUtil + | AbortParser
+ +AssertUtil ExecutionParser @@ -32,11 +34,13 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) JobsParser -NodeFiltersBuilder +NodeFiltersBuilder -NodeParser +NodeParser -OptionsBuilder +NodesParser + +OptionsBuilder ParametersUtil @@ -46,6 +50,10 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) ProjectsParser +RundeckAbort + +RundeckAbort.AbortStatus + RundeckApiException RundeckApiException.RundeckApiLoginException @@ -58,8 +66,12 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT API) RundeckJob +RundeckNode + RundeckProject +XmlNodeParser + |
RundeckAbort
RundeckExecution
Node
sRundeckNode
List
of RundeckNode
String
is blank (null, empty or only whitespace)
Node
-Node
RundeckExecution
RundeckClient
for the RunDeck instance at the given url
Node
s
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.NodeFiltersBuilder +
public class NodeFiltersBuilder
+Builder for node filters +
+ +
+
+Constructor Summary | +|
---|---|
NodeFiltersBuilder()
+
++ Build a new instance. |
+
+Method Summary | +|
---|---|
+ NodeFiltersBuilder |
+excludeHostname(String hostname)
+
++ Exclude nodes matching the given hostname |
+
+ NodeFiltersBuilder |
+excludeName(String name)
+
++ Exclude nodes matching the given name |
+
+ NodeFiltersBuilder |
+excludeOsArch(String osArch)
+
++ Exclude nodes matching the given OS-arch |
+
+ NodeFiltersBuilder |
+excludeOsFamily(String osFamily)
+
++ Exclude nodes matching the given OS-family |
+
+ NodeFiltersBuilder |
+excludeOsName(String osName)
+
++ Exclude nodes matching the given OS-name |
+
+ NodeFiltersBuilder |
+excludeOsVersion(String osVersion)
+
++ Exclude nodes matching the given OS-version |
+
+ NodeFiltersBuilder |
+excludePrecedence(boolean excludePrecedence)
+
++ Whether exclusion filters take precedence (default to yes). |
+
+ NodeFiltersBuilder |
+excludeTags(String tags)
+
++ Exclude nodes matching the given tags |
+
+ NodeFiltersBuilder |
+excludeType(String type)
+
++ Exclude nodes matching the given type |
+
+ NodeFiltersBuilder |
+hostname(String hostname)
+
++ Include nodes matching the given hostname |
+
+ NodeFiltersBuilder |
+name(String name)
+
++ Include nodes matching the given name |
+
+ NodeFiltersBuilder |
+osArch(String osArch)
+
++ Include nodes matching the given OS-arch |
+
+ NodeFiltersBuilder |
+osFamily(String osFamily)
+
++ Include nodes matching the given OS-family |
+
+ NodeFiltersBuilder |
+osName(String osName)
+
++ Include nodes matching the given OS-name |
+
+ NodeFiltersBuilder |
+osVersion(String osVersion)
+
++ Include nodes matching the given OS-version |
+
+ NodeFiltersBuilder |
+tags(String tags)
+
++ Include nodes matching the given tags |
+
+ Properties |
+toProperties()
+
++ |
+
+ NodeFiltersBuilder |
+type(String type)
+
++ Include nodes matching the given type |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public NodeFiltersBuilder()+
toProperties()
.
++
+Method Detail | +
---|
+public NodeFiltersBuilder hostname(String hostname)+
+
hostname
-
+excludeHostname(String)
+public NodeFiltersBuilder type(String type)+
+
type
-
+excludeType(String)
+public NodeFiltersBuilder tags(String tags)+
+
tags
-
+excludeTags(String)
+public NodeFiltersBuilder name(String name)+
+
name
-
+excludeName(String)
+public NodeFiltersBuilder osName(String osName)+
+
osName
-
+excludeOsName(String)
+public NodeFiltersBuilder osFamily(String osFamily)+
+
osFamily
-
+excludeOsFamily(String)
+public NodeFiltersBuilder osArch(String osArch)+
+
osArch
-
+excludeOsArch(String)
+public NodeFiltersBuilder osVersion(String osVersion)+
+
osVersion
-
+excludeOsVersion(String)
+public NodeFiltersBuilder excludeHostname(String hostname)+
+
hostname
-
+hostname(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeType(String type)+
+
type
-
+type(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeTags(String tags)+
+
tags
-
+tags(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeName(String name)+
+
name
-
+name(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeOsName(String osName)+
+
osName
-
+osName(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeOsFamily(String osFamily)+
+
osFamily
-
+osFamily(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeOsArch(String osArch)+
+
osArch
-
+osArch(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludeOsVersion(String osVersion)+
+
osVersion
-
+osVersion(String)
,
+excludePrecedence(boolean)
+public NodeFiltersBuilder excludePrecedence(boolean excludePrecedence)+
+
excludePrecedence
-
++public Properties toProperties()+
Properties
instance
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.OptionsBuilder +
public class OptionsBuilder
+Builder for job options +
+ +
+
+Constructor Summary | +|
---|---|
OptionsBuilder()
+
++ Build a new instance. |
+
+Method Summary | +|
---|---|
+ OptionsBuilder |
+addOption(Object key,
+ Object value)
+
++ Add an option |
+
+ Properties |
+toProperties()
+
++ |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public OptionsBuilder()+
addOption(Object, Object)
to add some options, and then
+ toProperties()
when you're done !
++
+Method Detail | +
---|
+public OptionsBuilder addOption(Object key, + Object value)+
+
key
- of the optionvalue
- of the option
++public Properties toProperties()+
Properties
instance
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
-Main entry point to talk to a RunDeck instance
+Main entry point to talk to a RunDeck instance.
+ Usage :
+
+
+ RundeckClient rundeck = new RundeckClient("http://localhost:4440", "admin", "admin");
+ List<RundeckJob> jobs = rundeck.getJobs();
+
+ RundeckJob job = rundeck.findJob("my-project", "main-group/sub-group", "job-name");
+ RundeckExecution execution = rundeck.triggerJob(job.getId(),
+ new OptionsBuilder().addOption("version", "1.2.0").toProperties());
+
+ List<RundeckExecution> runningExecutions = rundeck.getRunningExecutions("my-project");
+
+
@@ -170,6 +183,14 @@ Main entry point to talk to a RunDeck instance
RundeckAbort
abortExecution(Long executionId)
+
+ boolean
equals(Object obj)
@@ -207,6 +228,26 @@ Main entry point to talk to a RunDeck instance
List<RundeckExecution>
getJobExecutions(String jobId)
+ List<RundeckExecution>
getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status)
+
+ List<RundeckExecution>
getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status,
+ Long max,
+ Long offset)
+
RundeckNode
getNode(String name,
+ String project)
+
+ List<RundeckNode>
getNodes()
+
+ List<RundeckNode>
getNodes(String project)
+
+ List<RundeckNode>
getNodes(String project,
+ Properties nodeFilters)
+
+ String
getPassword()
@@ -272,6 +347,14 @@ Main entry point to talk to a RunDeck instance
List<RundeckExecution>
getRunningExecutions()
+
+ List<RundeckExecution>
getRunningExecutions(String project)
OptionsBuilder
.
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.
RundeckExecution
instance for the newly created (and running) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -814,8 +897,8 @@ public OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
- NodeFiltersBuilder
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
+ NodeFiltersBuilder
RundeckExecution
instance for the newly created (and running) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -870,7 +953,7 @@ public OptionsBuilder
.
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -899,8 +982,8 @@ public OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
- NodeFiltersBuilder
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
+ NodeFiltersBuilder
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -930,7 +1013,7 @@ public OptionsBuilder
.poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -961,8 +1044,8 @@ public OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
- NodeFiltersBuilder
poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
+jobId
- identifier of the job - mandatoryoptions
- of the job - optional. See OptionsBuilder
.nodeFilters
- for overriding the nodes on which the job will be executed - optional. See
+ NodeFiltersBuilder
poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
@@ -1017,7 +1100,7 @@ public NodeFiltersBuilder
+project
- name of the project - mandatorycommand
- to be executed - mandatorynodeFilters
- for selecting nodes on which the command will be executed. See NodeFiltersBuilder
RundeckExecution
instance for the newly created (and running) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent project with this name)
@@ -1105,7 +1188,7 @@ public NodeFiltersBuilder
+project
- name of the project - mandatorycommand
- to be executed - mandatorynodeFilters
- for selecting nodes on which the command will be executed. See NodeFiltersBuilder
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent project with this name)
@@ -1137,7 +1220,7 @@ public NodeFiltersBuilder
poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
+project
- name of the project - mandatorycommand
- to be executed - mandatorynodeFilters
- for selecting nodes on which the command will be executed. See NodeFiltersBuilder
poolingInterval
- for checking the status of the execution. Must be > 0.poolingUnit
- unit (seconds, milli-seconds, ...) of the interval. Default to seconds.
RundeckExecution
instance for the (finished/aborted) execution - won't be null
RundeckApiException
- in case of error when calling the API (non-existent project with this name)
@@ -1147,6 +1230,28 @@ public +public List<RundeckExecution> getRunningExecutions() + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException+
+
List
of RundeckExecution
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API
+RundeckApiException.RundeckApiLoginException
- if the login failed@@ -1195,6 +1300,58 @@ public+getJobExecutions
++public List<RundeckExecution> getJobExecutions(String jobId, + RundeckExecution.ExecutionStatus status) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
jobId
- identifier of the job - mandatorystatus
- of the executions - optional (null for all)
+List
of RundeckExecution
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the jobId is blank (null, empty or whitespace)+public List<RundeckExecution> getJobExecutions(String jobId, + RundeckExecution.ExecutionStatus status, + Long max, + Long offset) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
jobId
- identifier of the job - mandatorystatus
- of the executions - optional (null for all)max
- number of results to return - optional (null for all)offset
- the 0-indexed offset for the first result to return - optional
+List
of RundeckExecution
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API (non-existent job with this ID)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the jobId is blank (null, empty or whitespace)@@ -1219,6 +1376,126 @@ public+abortExecution
++public RundeckAbort abortExecution(Long executionId) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
executionId
- identifier of the execution - mandatory
+RundeckAbort
instance - won't be null
+RundeckApiException
- in case of error when calling the API (non-existent execution with this ID)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the executionId is null+public List<RundeckNode> getNodes() + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException+
+
List
of RundeckNode
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API
+RundeckApiException.RundeckApiLoginException
- if the login failed+public List<RundeckNode> getNodes(String project) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
project
- name of the project - mandatory
+List
of RundeckNode
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API (non-existent project with this name)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the project is blank (null, empty or whitespace)getNodes(String, Properties)
+public List<RundeckNode> getNodes(String project, + Properties nodeFilters) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
project
- name of the project - mandatorynodeFilters
- for filtering the nodes - optional. See NodeFiltersBuilder
+List
of RundeckNode
: might be empty, but won't be null
+RundeckApiException
- in case of error when calling the API (non-existent project with this name)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the project is blank (null, empty or whitespace)+public RundeckNode getNode(String name, + String project) + throws RundeckApiException, + RundeckApiException.RundeckApiLoginException, + IllegalArgumentException+
+
name
- of the node - mandatoryproject
- name of the project - mandatory
+RundeckNode
instance - won't be null
+RundeckApiException
- in case of error when calling the API (non-existent name or project with this name)
+RundeckApiException.RundeckApiLoginException
- if the login failed
+IllegalArgumentException
- if the name or project is blank (null, empty or whitespace)diff --git a/apidocs/org/rundeck/api/class-use/NodeFiltersBuilder.html b/apidocs/org/rundeck/api/class-use/NodeFiltersBuilder.html new file mode 100644 index 0000000..366a9b3 --- /dev/null +++ b/apidocs/org/rundeck/api/class-use/NodeFiltersBuilder.html @@ -0,0 +1,309 @@ + + + + + + ++Uses of Class org.rundeck.api.NodeFiltersBuilder (RunDeck API - Java Client 1.0-SNAPSHOT API) + + + + + + + + + + + + +
+ + + + + +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use NodeFiltersBuilder | +|
---|---|
org.rundeck.api | +Java client for the RunDeck API. | +
+Uses of NodeFiltersBuilder in org.rundeck.api | +
---|
+ +
Methods in org.rundeck.api that return NodeFiltersBuilder | +|
---|---|
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeHostname(String hostname)
+
++ Exclude nodes matching the given hostname |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeName(String name)
+
++ Exclude nodes matching the given name |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeOsArch(String osArch)
+
++ Exclude nodes matching the given OS-arch |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeOsFamily(String osFamily)
+
++ Exclude nodes matching the given OS-family |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeOsName(String osName)
+
++ Exclude nodes matching the given OS-name |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeOsVersion(String osVersion)
+
++ Exclude nodes matching the given OS-version |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludePrecedence(boolean excludePrecedence)
+
++ Whether exclusion filters take precedence (default to yes). |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeTags(String tags)
+
++ Exclude nodes matching the given tags |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.excludeType(String type)
+
++ Exclude nodes matching the given type |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.hostname(String hostname)
+
++ Include nodes matching the given hostname |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.name(String name)
+
++ Include nodes matching the given name |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.osArch(String osArch)
+
++ Include nodes matching the given OS-arch |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.osFamily(String osFamily)
+
++ Include nodes matching the given OS-family |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.osName(String osName)
+
++ Include nodes matching the given OS-name |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.osVersion(String osVersion)
+
++ Include nodes matching the given OS-version |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.tags(String tags)
+
++ Include nodes matching the given tags |
+
+ NodeFiltersBuilder |
+NodeFiltersBuilder.type(String type)
+
++ Include nodes matching the given type |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use OptionsBuilder | +|
---|---|
org.rundeck.api | +Java client for the RunDeck API. | +
+Uses of OptionsBuilder in org.rundeck.api | +
---|
+ +
Methods in org.rundeck.api that return OptionsBuilder | +|
---|---|
+ OptionsBuilder |
+OptionsBuilder.addOption(Object key,
+ Object value)
+
++ Add an option |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
RundeckAbort
RundeckClient.abortExecution(Long executionId)
+
+ RundeckJob
RundeckClient.findJob(String project,
String groupPath,
@@ -142,6 +150,26 @@ Uses of List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId)
+ List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status)
+
+ List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status,
+ Long max,
+ Long offset)
+
RundeckNode
RundeckClient.getNode(String name,
+ String project)
+
+ List<RundeckNode>
RundeckClient.getNodes()
+
+ List<RundeckNode>
RundeckClient.getNodes(String project)
+
+ List<RundeckNode>
RundeckClient.getNodes(String project,
+ Properties nodeFilters)
+
+ RundeckProject
RundeckClient.getProject(String projectName)
@@ -191,6 +253,14 @@ Uses of
List<RundeckExecution>
RundeckClient.getRunningExecutions()
+
+ List<RundeckExecution>
RundeckClient.getRunningExecutions(String project)
RundeckAbort
RundeckClient.abortExecution(Long executionId)
+
+ RundeckJob
RundeckClient.findJob(String project,
String groupPath,
@@ -162,6 +170,26 @@ Uses of List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId)
+ List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status)
+
+ List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status,
+ Long max,
+ Long offset)
+
RundeckNode
RundeckClient.getNode(String name,
+ String project)
+
+ List<RundeckNode>
RundeckClient.getNodes()
+
+ List<RundeckNode>
RundeckClient.getNodes(String project)
+
+ List<RundeckNode>
RundeckClient.getNodes(String project,
+ Properties nodeFilters)
+
+ RundeckProject
RundeckClient.getProject(String projectName)
@@ -211,6 +273,14 @@ Uses of
List<RundeckExecution>
RundeckClient.getRunningExecutions()
+
+ List<RundeckExecution>
RundeckClient.getRunningExecutions(String project)
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | ENUM CONSTANTS | FIELD | METHOD | ++DETAIL: ENUM CONSTANTS | FIELD | METHOD | +
+java.lang.Object ++java.lang.Enum<RundeckAbort.AbortStatus> +
org.rundeck.api.domain.RundeckAbort.AbortStatus +
public static enum RundeckAbort.AbortStatus
+The status of an abort +
+ +
+
+Enum Constant Summary | +|
---|---|
ABORTED
+
++ |
+|
FAILED
+
++ |
+|
PENDING
+
++ |
+
+Method Summary | +|
---|---|
+static RundeckAbort.AbortStatus |
+valueOf(String name)
+
++ Returns the enum constant of this type with the specified name. |
+
+static RundeckAbort.AbortStatus[] |
+values()
+
++ Returns an array containing the constants of this enum type, in +the order they are declared. |
+
Methods inherited from class java.lang.Enum | +
---|
clone, compareTo, equals, finalize, getDeclaringClass, hashCode, name, ordinal, toString, valueOf |
+
Methods inherited from class java.lang.Object | +
---|
getClass, notify, notifyAll, wait, wait, wait |
+
+Enum Constant Detail | +
---|
+public static final RundeckAbort.AbortStatus PENDING+
+public static final RundeckAbort.AbortStatus FAILED+
+public static final RundeckAbort.AbortStatus ABORTED+
+Method Detail | +
---|
+public static RundeckAbort.AbortStatus[] values()+
+for (RundeckAbort.AbortStatus c : RundeckAbort.AbortStatus.values()) + System.out.println(c); ++
+
+public static RundeckAbort.AbortStatus valueOf(String name)+
+
name
- the name of the enum constant to be returned.
+IllegalArgumentException
- if this enum type has no constant
+with the specified name
+NullPointerException
- if the argument is null
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | ENUM CONSTANTS | FIELD | METHOD | ++DETAIL: ENUM CONSTANTS | FIELD | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.domain.RundeckAbort +
public class RundeckAbort
+Represents an abort of a RundeckExecution
+
+ +
+
+Nested Class Summary | +|
---|---|
+static class |
+RundeckAbort.AbortStatus
+
++ The status of an abort |
+
+Constructor Summary | +|
---|---|
RundeckAbort()
+
++ |
+
+Method Summary | +|
---|---|
+ boolean |
+equals(Object obj)
+
++ |
+
+ RundeckExecution |
+getExecution()
+
++ |
+
+ RundeckAbort.AbortStatus |
+getStatus()
+
++ |
+
+ int |
+hashCode()
+
++ |
+
+ void |
+setExecution(RundeckExecution execution)
+
++ |
+
+ void |
+setStatus(RundeckAbort.AbortStatus status)
+
++ |
+
+ String |
+toString()
+
++ |
+
Methods inherited from class java.lang.Object | +
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
+
+Constructor Detail | +
---|
+public RundeckAbort()+
+Method Detail | +
---|
+public RundeckAbort.AbortStatus getStatus()+
+public void setStatus(RundeckAbort.AbortStatus status)+
+public RundeckExecution getExecution()+
+public void setExecution(RundeckExecution execution)+
+public String toString()+
toString
in class Object
+public int hashCode()+
hashCode
in class Object
+public boolean equals(Object obj)+
equals
in class Object
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.domain.RundeckNode +
public class RundeckNode
+Represents a RunDeck node (server on which RunDeck can execute jobs and commands) +
+ +
+
+Constructor Summary | +|
---|---|
RundeckNode()
+
++ |
+
+Method Summary | +|
---|---|
+ boolean |
+equals(Object obj)
+
++ |
+
+ String |
+getDescription()
+
++ |
+
+ String |
+getEditUrl()
+
++ |
+
+ String |
+getHostname()
+
++ |
+
+ String |
+getName()
+
++ |
+
+ String |
+getOsArch()
+
++ |
+
+ String |
+getOsFamily()
+
++ |
+
+ String |
+getOsName()
+
++ |
+
+ String |
+getOsVersion()
+
++ |
+
+ String |
+getRemoteUrl()
+
++ |
+
+ List<String> |
+getTags()
+
++ |
+
+ String |
+getType()
+
++ |
+
+ String |
+getUsername()
+
++ |
+
+ int |
+hashCode()
+
++ |
+
+ void |
+setDescription(String description)
+
++ |
+
+ void |
+setEditUrl(String editUrl)
+
++ |
+
+ void |
+setHostname(String hostname)
+
++ |
+
+ void |
+setName(String name)
+
++ |
+
+ void |
+setOsArch(String osArch)
+
++ |
+
+ void |
+setOsFamily(String osFamily)
+
++ |
+
+ void |
+setOsName(String osName)
+
++ |
+
+ void |
+setOsVersion(String osVersion)
+
++ |
+
+ void |
+setRemoteUrl(String remoteUrl)
+
++ |
+
+ void |
+setTags(List<String> tags)
+
++ |
+
+ void |
+setType(String type)
+
++ |
+
+ void |
+setUsername(String username)
+
++ |
+
+ String |
+toString()
+
++ |
+
Methods inherited from class java.lang.Object | +
---|
clone, finalize, getClass, notify, notifyAll, wait, wait, wait |
+
+Constructor Detail | +
---|
+public RundeckNode()+
+Method Detail | +
---|
+public String getName()+
+public void setName(String name)+
+public String getType()+
+public void setType(String type)+
+public String getDescription()+
+public void setDescription(String description)+
+public List<String> getTags()+
+public void setTags(List<String> tags)+
+public String getHostname()+
+public void setHostname(String hostname)+
+public String getOsArch()+
+public void setOsArch(String osArch)+
+public String getOsFamily()+
+public void setOsFamily(String osFamily)+
+public String getOsName()+
+public void setOsName(String osName)+
+public String getOsVersion()+
+public void setOsVersion(String osVersion)+
+public String getUsername()+
+public void setUsername(String username)+
+public String getEditUrl()+
+public void setEditUrl(String editUrl)+
+public String getRemoteUrl()+
+public void setRemoteUrl(String remoteUrl)+
+public String toString()+
toString
in class Object
+public int hashCode()+
hashCode
in class Object
+public boolean equals(Object obj)+
equals
in class Object
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use RundeckAbort.AbortStatus | +|
---|---|
org.rundeck.api.domain | +Domain classes that are returned to the client of the API. | +
+Uses of RundeckAbort.AbortStatus in org.rundeck.api.domain | +
---|
+ +
Methods in org.rundeck.api.domain that return RundeckAbort.AbortStatus | +|
---|---|
+ RundeckAbort.AbortStatus |
+RundeckAbort.getStatus()
+
++ |
+
+static RundeckAbort.AbortStatus |
+RundeckAbort.AbortStatus.valueOf(String name)
+
++ Returns the enum constant of this type with the specified name. |
+
+static RundeckAbort.AbortStatus[] |
+RundeckAbort.AbortStatus.values()
+
++ Returns an array containing the constants of this enum type, in +the order they are declared. |
+
+ +
Methods in org.rundeck.api.domain with parameters of type RundeckAbort.AbortStatus | +|
---|---|
+ void |
+RundeckAbort.setStatus(RundeckAbort.AbortStatus status)
+
++ |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use RundeckAbort | +|
---|---|
org.rundeck.api | +Java client for the RunDeck API. | +
org.rundeck.api.parser | +Internal parsers for parsing the RunDeck responses. | +
+Uses of RundeckAbort in org.rundeck.api | +
---|
+ +
Methods in org.rundeck.api that return RundeckAbort | +|
---|---|
+ RundeckAbort |
+RundeckClient.abortExecution(Long executionId)
+
++ Abort an execution (identified by the given ID). |
+
+Uses of RundeckAbort in org.rundeck.api.parser | +
---|
+ +
Methods in org.rundeck.api.parser that return RundeckAbort | +|
---|---|
+ RundeckAbort |
+AbortParser.parseXmlNode(org.dom4j.Node node)
+
++ |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Uses of RundeckExecution.ExecutionStatus in org.rundeck.api | +
---|
+ +
Methods in org.rundeck.api with parameters of type RundeckExecution.ExecutionStatus | +|
---|---|
+ List<RundeckExecution> |
+RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status)
+
++ Get the executions of the given job |
+
+ List<RundeckExecution> |
+RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status,
+ Long max,
+ Long offset)
+
++ Get the executions of the given job |
List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status)
+
+ List<RundeckExecution>
RundeckClient.getJobExecutions(String jobId,
+ RundeckExecution.ExecutionStatus status,
+ Long max,
+ Long offset)
+
+ List<RundeckExecution>
RundeckClient.getRunningExecutions()
+
+ List<RundeckExecution>
RundeckClient.getRunningExecutions(String project)
+Uses of RundeckExecution in org.rundeck.api.domain | +
---|
+ +
Methods in org.rundeck.api.domain that return RundeckExecution | +|
---|---|
+ RundeckExecution |
+RundeckAbort.getExecution()
+
++ |
+
+ +
Methods in org.rundeck.api.domain with parameters of type RundeckExecution | +|
---|---|
+ void |
+RundeckAbort.setExecution(RundeckExecution execution)
+
++ |
+
RundeckExecution |
-ExecutionParser.parseNode(org.dom4j.Node node)
+ | ExecutionParser.parseXmlNode(org.dom4j.Node node)
|
@@ -324,7 +397,7 @@ Uses of
List<RundeckExecution> |
-ExecutionsParser.parseNode(org.dom4j.Node node)
+ | ExecutionsParser.parseXmlNode(org.dom4j.Node node)
|
diff --git a/apidocs/org/rundeck/api/domain/class-use/RundeckJob.html b/apidocs/org/rundeck/api/domain/class-use/RundeckJob.html
index 4cc6d15..d66d459 100644
--- a/apidocs/org/rundeck/api/domain/class-use/RundeckJob.html
+++ b/apidocs/org/rundeck/api/domain/class-use/RundeckJob.html
@@ -2,13 +2,13 @@
-
+
org.rundeck.api | -+ | Java client for the RunDeck API. |
org.rundeck.api.domain | -+ | Domain classes that are returned to the client of the API. | ||||||
org.rundeck.api.parser | -+ | Internal parsers for parsing the RunDeck responses. |
RundeckJob
JobParser.parseNode(org.dom4j.Node node)
+JobParser.parseXmlNode(org.dom4j.Node node)
List<RundeckJob>
JobsParser.parseNode(org.dom4j.Node node)
+JobsParser.parseXmlNode(org.dom4j.Node node)
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use RundeckNode | +|
---|---|
org.rundeck.api | +Java client for the RunDeck API. | +
org.rundeck.api.parser | +Internal parsers for parsing the RunDeck responses. | +
+Uses of RundeckNode in org.rundeck.api | +
---|
+ +
Methods in org.rundeck.api that return RundeckNode | +|
---|---|
+ RundeckNode |
+RundeckClient.getNode(String name,
+ String project)
+
++ Get the definition of a single node |
+
+ +
Methods in org.rundeck.api that return types with arguments of type RundeckNode | +|
---|---|
+ List<RundeckNode> |
+RundeckClient.getNodes()
+
++ List all nodes (for all projects) |
+
+ List<RundeckNode> |
+RundeckClient.getNodes(String project)
+
++ List all nodes that belongs to the given project |
+
+ List<RundeckNode> |
+RundeckClient.getNodes(String project,
+ Properties nodeFilters)
+
++ List nodes that belongs to the given project |
+
+Uses of RundeckNode in org.rundeck.api.parser | +
---|
+ +
Methods in org.rundeck.api.parser that return RundeckNode | +|
---|---|
+ RundeckNode |
+NodeParser.parseXmlNode(org.dom4j.Node node)
+
++ |
+
+ +
Methods in org.rundeck.api.parser that return types with arguments of type RundeckNode | +|
---|---|
+ List<RundeckNode> |
+NodesParser.parseXmlNode(org.dom4j.Node node)
+
++ |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
RundeckProject
ProjectParser.parseNode(org.dom4j.Node node)
+ProjectParser.parseXmlNode(org.dom4j.Node node)
List<RundeckProject>
ProjectsParser.parseNode(org.dom4j.Node node)
+ProjectsParser.parseXmlNode(org.dom4j.Node node)
+See:
+
+ Description
+
RundeckAbort | +Represents an abort of a RundeckExecution |
+
RundeckExecution | Represents a RunDeck execution, usually triggered by an API call. | Represents a RunDeck job |
RundeckNode | +Represents a RunDeck node (server on which RunDeck can execute jobs and commands) | +
RundeckProject | Represents a RunDeck project |
RundeckAbort.AbortStatus | +The status of an abort | +
RundeckExecution.ExecutionStatus | The status of an execution |
+Domain classes that are returned to the client of the API. +
+
RundeckExecution
RundeckExecution
+See:
+
+ Description
+
NodeFiltersBuilder | +Builder for node filters | +|
OptionsBuilder | +Builder for job options | +|
RundeckClient | -Main entry point to talk to a RunDeck instance | +Main entry point to talk to a RunDeck instance. |
+Java client for the RunDeck API. +
+
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.parser.AbortParser +
public class AbortParser
+Parser for a single RundeckAbort
+
+ +
+
+Constructor Summary | +|
---|---|
AbortParser()
+
++ |
+|
AbortParser(String xpath)
+
++ |
+
+Method Summary | +|
---|---|
+ RundeckAbort |
+parseXmlNode(org.dom4j.Node node)
+
++ Parse the given XML Node |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public AbortParser()+
+public AbortParser(String xpath)+
xpath
- of the abort element if it is not the root node+Method Detail | +
---|
+public RundeckAbort parseXmlNode(org.dom4j.Node node)+
XmlNodeParser
Node
++
parseXmlNode
in interface XmlNodeParser<RundeckAbort>
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
public class ExecutionParser
public class ExecutionParser
@@ -150,7 +150,7 @@ Parser for a single
RundeckExecution
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public RundeckExecution parseNode(org.dom4j.Node node)+public RundeckExecution parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<RundeckExecution>
parseXmlNode
in interface XmlNodeParser<RundeckExecution>
public class ExecutionsParser
public class ExecutionsParser
@@ -144,7 +144,7 @@ Parser for a
List<RundeckExecution>
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public List<RundeckExecution> parseNode(org.dom4j.Node node)+public List<RundeckExecution> parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<List<RundeckExecution>>
parseXmlNode
in interface XmlNodeParser<List<RundeckExecution>>
public class JobParser
public class JobParser
@@ -150,7 +150,7 @@ Parser for a single
RundeckJob
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public RundeckJob parseNode(org.dom4j.Node node)+public RundeckJob parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<RundeckJob>
parseXmlNode
in interface XmlNodeParser<RundeckJob>
public class JobsParser
public class JobsParser
@@ -144,7 +144,7 @@ Parser for a
List<RundeckJob>
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public List<RundeckJob> parseNode(org.dom4j.Node node)+public List<RundeckJob> parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<List<RundeckJob>>
parseXmlNode
in interface XmlNodeParser<List<RundeckJob>>
+java.lang.Object +org.rundeck.api.parser.NodeParser +
public interface NodeParser<T>
public class NodeParser
-Interface to be implemented for parsers that handle XML Node
s
+Parser for a single RundeckNode
@@ -113,6 +117,28 @@ Interface to be implemented for parsers that handle XML Node
s
+Constructor Summary | +|
---|---|
NodeParser()
+
++ |
+|
NodeParser(String xpath)
+
++ |
+
Node
s
T
parseNode(org.dom4j.Node node)
+ RundeckNode
parseXmlNode(org.dom4j.Node node)
Node
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public NodeParser()+
+public NodeParser(String xpath)+
xpath
- of the rundeck-node element if it is not the root xml-nodeNode
s
-T parseNode(org.dom4j.Node node)+public RundeckNode parseXmlNode(org.dom4j.Node node)
XmlNodeParser
Node
node
-
+parseXmlNode
in interface XmlNodeParser<RundeckNode>
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.parser.NodesParser +
public class NodesParser
+Parser for a List
of RundeckNode
+
+ +
+
+Constructor Summary | +|
---|---|
NodesParser(String xpath)
+
++ |
+
+Method Summary | +|
---|---|
+ List<RundeckNode> |
+parseXmlNode(org.dom4j.Node node)
+
++ Parse the given XML Node |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public NodesParser(String xpath)+
xpath
- of the rundeck-nodes elements+Method Detail | +
---|
+public List<RundeckNode> parseXmlNode(org.dom4j.Node node)+
XmlNodeParser
Node
++
parseXmlNode
in interface XmlNodeParser<List<RundeckNode>>
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
public class ProjectParser
public class ProjectParser
@@ -150,7 +150,7 @@ Parser for a single
RundeckProject
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public RundeckProject parseNode(org.dom4j.Node node)+public RundeckProject parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<RundeckProject>
parseXmlNode
in interface XmlNodeParser<RundeckProject>
public class ProjectsParser
public class ProjectsParser
@@ -144,7 +144,7 @@ Parser for a
List<RundeckProject>
parseNode(org.dom4j.Node node)
+parseXmlNode(org.dom4j.Node node)
Node
-public List<RundeckProject> parseNode(org.dom4j.Node node)+public List<RundeckProject> parseXmlNode(org.dom4j.Node node)
NodeParser
XmlNodeParser
Node
parseNode
in interface NodeParser<List<RundeckProject>>
parseXmlNode
in interface XmlNodeParser<List<RundeckProject>>
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
public interface XmlNodeParser<T>
+Interface to be implemented for parsers that handle XML Node
s
+
+ +
+
+Method Summary | +|
---|---|
+ T |
+parseXmlNode(org.dom4j.Node node)
+
++ Parse the given XML Node |
+
+Method Detail | +
---|
+T parseXmlNode(org.dom4j.Node node)+
Node
++
node
-
+
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
-Packages that use NodeParser | -|
---|---|
org.rundeck.api.parser | -- |
-Uses of NodeParser in org.rundeck.api.parser | -
---|
- -
Classes in org.rundeck.api.parser that implement NodeParser | -|
---|---|
- class |
-ExecutionParser
-
-- Parser for a single RundeckExecution |
-
- class |
-ExecutionsParser
-
-- Parser for a List of RundeckExecution |
-
- class |
-JobParser
-
-- Parser for a single RundeckJob |
-
- class |
-JobsParser
-
-- Parser for a List of RundeckJob |
-
- class |
-ProjectParser
-
-- Parser for a single RundeckProject |
-
- class |
-ProjectsParser
-
-- Parser for a List of RundeckProject |
-
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+Packages that use XmlNodeParser | +|
---|---|
org.rundeck.api.parser | +Internal parsers for parsing the RunDeck responses. | +
+Uses of XmlNodeParser in org.rundeck.api.parser | +
---|
+ +
Classes in org.rundeck.api.parser that implement XmlNodeParser | +|
---|---|
+ class |
+AbortParser
+
++ Parser for a single RundeckAbort |
+
+ class |
+ExecutionParser
+
++ Parser for a single RundeckExecution |
+
+ class |
+ExecutionsParser
+
++ Parser for a List of RundeckExecution |
+
+ class |
+JobParser
+
++ Parser for a single RundeckJob |
+
+ class |
+JobsParser
+
++ Parser for a List of RundeckJob |
+
+ class |
+NodeParser
+
++ Parser for a single RundeckNode |
+
+ class |
+NodesParser
+
++ Parser for a List of RundeckNode |
+
+ class |
+ProjectParser
+
++ Parser for a single RundeckProject |
+
+ class |
+ProjectsParser
+
++ Parser for a List of RundeckProject |
+
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+See:
+
+ Description
+
NodeParser<T> | +XmlNodeParser<T> | Interface to be implemented for parsers that handle XML Node s |
RundeckAbort
RundeckExecution
List
of RundeckJob
RundeckNode
List
of RundeckNode
+Internal parsers for parsing the RunDeck responses. +
+
Node
s
+See:
+
+ Description
+
Utility class for assertions | |
NodeFiltersBuilder | -Builder for node filters | -
OptionsBuilder | -Builder for job options | -
ParametersUtil | Utility class for API parameters that should be passed in URLs. |
+Some utility classes. +
+
-Packages that use org.rundeck.api.util | -|
---|---|
org.rundeck.api.util | -- |
-Classes in org.rundeck.api.util used by org.rundeck.api.util | -|
---|---|
NodeFiltersBuilder
-
- - Builder for node filters |
-|
OptionsBuilder
-
- - Builder for job options |
-
+See:
+
+ Description
+
org.rundeck.api | -+ | Java client for the RunDeck API. |
org.rundeck.api.domain | -+ | Domain classes that are returned to the client of the API. |
org.rundeck.api.parser | -+ | Internal parsers for parsing the RunDeck responses. |
org.rundeck.api.util | -+ | Some utility classes. |
-
+
See the documentation of the RundeckClient class (main entry point of the API).
++ +
+
+Class org.rundeck.api.domain.RundeckAbort extends Object implements Serializable | +
---|
+serialVersionUID: 1L + +
+Serialized Fields | +
---|
+RundeckAbort.AbortStatus status+
+RundeckExecution execution+
+Class org.rundeck.api.domain.RundeckNode extends Object implements Serializable | +
---|
+serialVersionUID: 1L + +
+Serialized Fields | +
---|
+String name+
+
+String type+
+
+String description+
+
+List<E> tags+
+
+String hostname+
+
+String osArch+
+
+String osFamily+
+
+String osName+
+
+String osVersion+
+
+String username+
+
+String editUrl+
+
+String remoteUrl+
+
Filename | Size | Entries | Classes | Packages | JDK Rev | Debug | Sealed |
---|---|---|---|---|---|---|---|
icu4j-2.6.1.jar | 2.34 MB | 755 | 648 | 6 | 1.2 | debug | - |
commons-codec-1.4.jar | 56.80 kB | 47 | 30 | 5 | 1.4 | debug | - |
commons-lang-2.6.jar | 277.56 kB | 155 | 133 | 10 | 1.3 | debug | - |
commons-logging-1.1.1.jar | 59.26 kB | 42 | 28 | 2 | 1.1 | debug | - |
dom4j-1.6.1.jar | 306.54 kB | 208 | 190 | 14 | 1.3 | debug | - |
jaxen-1.1.1.jar | 221.60 kB | 236 | 214 | 17 | 1.2 | debug | - |
jdom-1.0.jar | 149.66 kB | 87 | 75 | 8 | 1.1 | debug | - |
junit-4.8.2.jar | 231.78 kB | 267 | 230 | 30 | 1.5 | debug | - |
httpclient-4.1.1.jar | 342.90 kB | 308 | 272 | 22 | 1.5 | debug | - |
httpcore-4.1.jar | 176.80 kB | 185 | 163 | 10 | 1.3 | debug | - |
xalan-2.6.0.jar | 3.00 MB | 1,625 | 1,548 | 50 | 1.1 | debug | - |
xercesImpl-2.6.2.jar | 986.99 kB | 845 | 784 | 37 | 1.1 | release | - |
xmlParserAPIs-2.6.2.jar | 121.80 kB | 238 | 207 | 17 | 1.1 | release | - |
xml-apis-1.0.b2.jar | 106.76 kB | 217 | 184 | 17 | 1.2 | release | - |
xom-1.0.jar | 106.32 kB | 108 | 96 | 6 | 1.2 | release | sealed |
Total | Size | Entries | Classes | Packages | JDK Rev | Debug | Sealed |
15 | 8.41 MB | 5,323 | 4,802 | 251 | 1.5 | 11 | 1 |
compile: 14 | compile: 8.19 MB | compile: 5,056 | compile: 4,572 | compile: 221 | - | compile: 10 | compile: 1 |
test: 1 | test: 231.78 kB | test: 267 | test: 230 | test: 30 | - | test: 1 | - |
Repo ID | URL | Release | Snapshot | |
---|---|---|---|---|
apache.snapshots | http://people.apache.org/repo/m2-snapshot-repository | - | Yes | - |
sonatype-nexus-snapshots | https://oss.sonatype.org/content/repositories/snapshots | - | Yes | - |
central | http://repo1.maven.org/maven2 | Yes | - | - |
Repository locations for each of the Dependencies.
The versions of the librairie are aligned with the versions of the API :
+The following document contains the results of FindBugs Report
FindBugs Version is 1.3.9
Threshold is medium
Effort is min
The following document contains the results of FindBugs Report
FindBugs Version is 1.3.9
Threshold is medium
Effort is min
You can also download the lib and all its dependencies in 1 big jar file, and add it to your classpath before running your script : save the following script in a file named "rundeck.groovy", and execute it with "groovy -cp /path/to/rundeck-api-java-client-VERSION-jar-with-dependencies.jar rundeck.groovy".
import org.rundeck.api.RundeckClient rundeck = new RundeckClient("http://localhost:4440", "admin", "admin") println "All RunDeck projects : ${rundeck.projects}" +println "All RunDeck nodes : ${rundeck.nodes}" println "All RunDeck jobs : ${rundeck.jobs}" +println "All RunDeck running executions : ${rundeck.runningExecutions}"
import org.rundeck.api.RundeckClient rundeck = new RundeckClient("http://localhost:4440", "admin", "admin") diff --git a/index.html b/index.html index 2b62957..027d3ce 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + @@ -10,7 +10,7 @@ @import url("./css/site.css"); - + @@ -49,7 +49,7 @@
A Java librairie that maps the RunDeck HTTP REST API. RunDeck is an open-source tool for automating tasks on multiple nodes, with a CLI, a web-based interface and an HTTP REST API. You can read more about its API on the RunDeck User Manual.
This librairie has been extracted from the Jenkins RunDeck plugin, so for the moment it is still incomplete (not all the RunDeck API is mapped). My goal is to have a complete mapping of the RunDeck API, and to publish the librairie on the Maven Central Repository, so that it can easily be used by Java (Maven) and Groovy (Grape) developers.
A Java librairie that maps the RunDeck HTTP REST API. RunDeck is an open-source tool for automating tasks on multiple nodes, with a CLI, a web-based interface and an HTTP REST API. You can read more about its API on the RunDeck User Manual.
This librairie has been extracted from the Jenkins RunDeck plugin, so for the moment it is still incomplete (not all the RunDeck API is mapped). My goal is to have a complete mapping of the RunDeck API, and to publish the librairie on the Maven Central Repository, so that it can easily be used by Java (Maven) and Groovy (Grape) developers.
You can also add the librairie to the classpath : save the following script in a file named "rundeck.rb", and execute it with "jruby -rjava -J-cp /path/to/rundeck-api-java-client-VERSION-jar-with-dependencies.jar rundeck.rb".
import org.rundeck.api.RundeckClient rundeck = RundeckClient.new("http://localhost:4440", "admin", "admin") puts "All RunDeck projects : #{rundeck.projects}" +puts "All RunDeck nodes : #{rundeck.nodes}" puts "All RunDeck jobs : #{rundeck.jobs}" +puts "All RunDeck running executions : #{rundeck.runningExecutions}"
import org.rundeck.api.RundeckClient -import org.rundeck.api.util.OptionsBuilder -import org.rundeck.api.util.NodeFiltersBuilder +import org.rundeck.api.OptionsBuilder +import org.rundeck.api.NodeFiltersBuilder rundeck = RundeckClient.new("http://localhost:4440", "admin", "admin") @@ -143,7 +150,7 @@ execution = rundeck.triggerJob("job-id", OptionsBuilder.new().addOptio execution = rundeck.runJob("job-id") puts "Execution finished ! Status : #{execution.status}, duration (in seconds) : #{execution.durationInSeconds}"
import org.rundeck.api.RundeckClient -import org.rundeck.api.util.NodeFiltersBuilder +import org.rundeck.api.NodeFiltersBuilder rundeck = RundeckClient.new("http://localhost:4440", "admin", "admin") diff --git a/jython.html b/jython.html index 36d7194..e6a5777 100644 --- a/jython.html +++ b/jython.html @@ -1,5 +1,5 @@ - + @@ -10,7 +10,7 @@ @import url("./css/site.css"); - + @@ -49,7 +49,7 @@
from org.rundeck.api import RundeckClient -from org.rundeck.api.util import OptionsBuilder -from org.rundeck.api.util import NodeFiltersBuilder +from org.rundeck.api import OptionsBuilder +from org.rundeck.api import NodeFiltersBuilder rundeck = RundeckClient("http://localhost:4440", "admin", "admin") @@ -135,7 +140,7 @@ execution = rundeck.triggerJob("job-id", OptionsBuilder().addOption(&q execution = rundeck.runJob("job-id") print("Execution finished ! Status : %s, duration (in seconds) : %s" % (execution.status, execution.durationInSeconds))
from org.rundeck.api import RundeckClient -from org.rundeck.api.util import NodeFiltersBuilder +from org.rundeck.api import NodeFiltersBuilder rundeck = RundeckClient("http://localhost:4440", "admin", "admin") diff --git a/license.html b/license.html index 0811d2e..5b5d07f 100644 --- a/license.html +++ b/license.html @@ -1,5 +1,5 @@ - + @@ -10,7 +10,7 @@ @import url("./css/site.css"); - + @@ -49,7 +49,7 @@
ExecutionParserTest + | AbortParserTest
+ +ExecutionParserTest ExecutionsParserTest @@ -30,6 +32,10 @@ All Classes (RunDeck API - Java Client 1.0-SNAPSHOT Test API) JobsParserTest +NodeParserTest + +NodesParserTest + ParametersUtilTest ParserHelperTest diff --git a/testapidocs/allclasses-noframe.html b/testapidocs/allclasses-noframe.html index 4139902..56ea3f3 100644 --- a/testapidocs/allclasses-noframe.html +++ b/testapidocs/allclasses-noframe.html @@ -2,13 +2,13 @@ - +
-parseRunningNode++parseRunningExecution-public void parseRunningNode() - throws Exception+public void parseRunningExecution() + throws Exception
|
-public void parseNode() - throws Exception+public void parseExecutions() + throws Exception
void
parseNode()
+parseJob()
-public void parseNode() - throws Exception+public void parseJob() + throws Exception
void
parseNode()
+parseJobs()
-public void parseNode() +public void parseJobs() throws Exception
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.parser.NodeParserTest +
public class NodeParserTest
+Test the NodeParser
+
+ +
+
+Constructor Summary | +|
---|---|
NodeParserTest()
+
++ |
+
+Method Summary | +|
---|---|
+ void |
+parseNode()
+
++ |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public NodeParserTest()+
+Method Detail | +
---|
+public void parseNode() + throws Exception+
Exception
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
+java.lang.Object ++org.rundeck.api.parser.NodesParserTest +
public class NodesParserTest
+Test the NodesParser
+
+ +
+
+Constructor Summary | +|
---|---|
NodesParserTest()
+
++ |
+
+Method Summary | +|
---|---|
+ void |
+parseNodes()
+
++ |
+
Methods inherited from class java.lang.Object | +
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
+
+Constructor Detail | +
---|
+public NodesParserTest()+
+Method Detail | +
---|
+public void parseNodes() + throws Exception+
Exception
+
+
|
++ + | +|||||||||
+ PREV CLASS + NEXT CLASS | ++ FRAMES + NO FRAMES + + + + + | +|||||||||
+ SUMMARY: NESTED | FIELD | CONSTR | METHOD | ++DETAIL: FIELD | CONSTR | METHOD | +
void
parseNode()
+parseProject()
-public void parseNode() - throws Exception+public void parseProject() + throws Exception
void
parseNode()
+parseProjects()
-public void parseNode() - throws Exception+public void parseProjects() + throws Exception
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
+
+
+
|
++ + | +|||||||||
+ PREV + NEXT | ++ FRAMES + NO FRAMES + + + + + | +
AbortParser
ExecutionParser
JobsParser
NodeParser
NodesParser
ParserHelper
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import org.dom4j.Document; +20 import org.junit.Assert; +21 import org.junit.Test; +22 import org.rundeck.api.domain.RundeckAbort; +23 import org.rundeck.api.domain.RundeckExecution; +24 import org.rundeck.api.domain.RundeckAbort.AbortStatus; +25 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; +26 +27 /** +28 * Test the {@link AbortParser} +29 * +30 * @author Vincent Behar +31 */ +32 public class AbortParserTest { +33 +34 @Test +35 public void parsePendingAbort() throws Exception { +36 InputStream input = getClass().getResourceAsStream("abort-pending.xml"); +37 Document document = ParserHelper.loadDocument(input); +38 +39 RundeckAbort abort = new AbortParser("result/abort").parseXmlNode(document); +40 RundeckExecution execution = abort.getExecution(); +41 +42 Assert.assertEquals(AbortStatus.PENDING, abort.getStatus()); +43 +44 Assert.assertEquals(new Long(1), execution.getId()); +45 Assert.assertEquals(ExecutionStatus.RUNNING, execution.getStatus()); +46 } +47 +48 @Test +49 public void parseFailedAbort() throws Exception { +50 InputStream input = getClass().getResourceAsStream("abort-failed.xml"); +51 Document document = ParserHelper.loadDocument(input); +52 +53 RundeckAbort abort = new AbortParser("result/abort").parseXmlNode(document); +54 RundeckExecution execution = abort.getExecution(); +55 +56 Assert.assertEquals(AbortStatus.FAILED, abort.getStatus()); +57 +58 Assert.assertEquals(new Long(1), execution.getId()); +59 Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus()); +60 } +61 +62 } ++
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import java.util.Date; -5 import org.dom4j.Document; -6 import org.junit.Assert; -7 import org.junit.Test; -8 import org.rundeck.api.domain.RundeckExecution; -9 import org.rundeck.api.domain.RundeckJob; -10 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; -11 -12 /** -13 * Test the {@link ExecutionParser} -14 * -15 * @author Vincent Behar -16 */ -17 public class ExecutionParserTest { -18 -19 @Test -20 public void parseRunningNode() throws Exception { -21 InputStream input = getClass().getResourceAsStream("execution-running.xml"); -22 Document document = ParserHelper.loadDocument(input); -23 -24 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseNode(document); -25 RundeckJob job = execution.getJob(); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.Date; +20 import org.dom4j.Document; +21 import org.junit.Assert; +22 import org.junit.Test; +23 import org.rundeck.api.domain.RundeckExecution; +24 import org.rundeck.api.domain.RundeckJob; +25 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; 26 -27 Assert.assertEquals(new Long(1), execution.getId()); -28 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); -29 Assert.assertEquals(ExecutionStatus.RUNNING, execution.getStatus()); -30 Assert.assertEquals("admin", execution.getStartedBy()); -31 Assert.assertEquals(new Date(1302183830082L), execution.getStartedAt()); -32 Assert.assertEquals(null, execution.getEndedAt()); -33 Assert.assertEquals(null, execution.getAbortedBy()); -34 Assert.assertEquals("ls ${option.dir}", execution.getDescription()); -35 -36 Assert.assertEquals("1", job.getId()); -37 Assert.assertEquals("ls", job.getName()); -38 Assert.assertEquals("system", job.getGroup()); -39 Assert.assertEquals("test", job.getProject()); -40 Assert.assertEquals("list files", job.getDescription()); -41 } -42 -43 @Test -44 public void parseSucceededNode() throws Exception { -45 InputStream input = getClass().getResourceAsStream("execution-succeeded.xml"); -46 Document document = ParserHelper.loadDocument(input); -47 -48 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseNode(document); -49 RundeckJob job = execution.getJob(); +27 /** +28 * Test the {@link ExecutionParser} +29 * +30 * @author Vincent Behar +31 */ +32 public class ExecutionParserTest { +33 +34 @Test +35 public void parseRunningExecution() throws Exception { +36 InputStream input = getClass().getResourceAsStream("execution-running.xml"); +37 Document document = ParserHelper.loadDocument(input); +38 +39 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseXmlNode(document); +40 RundeckJob job = execution.getJob(); +41 +42 Assert.assertEquals(new Long(1), execution.getId()); +43 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); +44 Assert.assertEquals(ExecutionStatus.RUNNING, execution.getStatus()); +45 Assert.assertEquals("admin", execution.getStartedBy()); +46 Assert.assertEquals(new Date(1302183830082L), execution.getStartedAt()); +47 Assert.assertEquals(null, execution.getEndedAt()); +48 Assert.assertEquals(null, execution.getAbortedBy()); +49 Assert.assertEquals("ls ${option.dir}", execution.getDescription()); 50 -51 Assert.assertEquals(new Long(1), execution.getId()); -52 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); -53 Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus()); -54 Assert.assertEquals("admin", execution.getStartedBy()); -55 Assert.assertEquals(new Date(1308322895104L), execution.getStartedAt()); -56 Assert.assertEquals(new Date(1308322959420L), execution.getEndedAt()); -57 Assert.assertEquals(null, execution.getAbortedBy()); -58 Assert.assertEquals("ls ${option.dir}", execution.getDescription()); -59 -60 Assert.assertEquals("1", job.getId()); -61 Assert.assertEquals("ls", job.getName()); -62 Assert.assertEquals("system", job.getGroup()); -63 Assert.assertEquals("test", job.getProject()); -64 Assert.assertEquals("list files", job.getDescription()); -65 } -66 -67 @Test -68 public void parseAdhocNode() throws Exception { -69 InputStream input = getClass().getResourceAsStream("execution-adhoc.xml"); -70 Document document = ParserHelper.loadDocument(input); -71 -72 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseNode(document); -73 RundeckJob job = execution.getJob(); +51 Assert.assertEquals("1", job.getId()); +52 Assert.assertEquals("ls", job.getName()); +53 Assert.assertEquals("system", job.getGroup()); +54 Assert.assertEquals("test", job.getProject()); +55 Assert.assertEquals("list files", job.getDescription()); +56 } +57 +58 @Test +59 public void parseSucceededExecution() throws Exception { +60 InputStream input = getClass().getResourceAsStream("execution-succeeded.xml"); +61 Document document = ParserHelper.loadDocument(input); +62 +63 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseXmlNode(document); +64 RundeckJob job = execution.getJob(); +65 +66 Assert.assertEquals(new Long(1), execution.getId()); +67 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); +68 Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus()); +69 Assert.assertEquals("admin", execution.getStartedBy()); +70 Assert.assertEquals(new Date(1308322895104L), execution.getStartedAt()); +71 Assert.assertEquals(new Date(1308322959420L), execution.getEndedAt()); +72 Assert.assertEquals(null, execution.getAbortedBy()); +73 Assert.assertEquals("ls ${option.dir}", execution.getDescription()); 74 -75 Assert.assertEquals(new Long(1), execution.getId()); -76 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); -77 Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus()); -78 Assert.assertEquals("admin", execution.getStartedBy()); -79 Assert.assertEquals(new Date(1309857539137L), execution.getStartedAt()); -80 Assert.assertEquals(new Date(1309857539606L), execution.getEndedAt()); -81 Assert.assertEquals(null, execution.getAbortedBy()); -82 Assert.assertEquals("w", execution.getDescription()); -83 -84 Assert.assertNull(job); -85 } +75 Assert.assertEquals("1", job.getId()); +76 Assert.assertEquals("ls", job.getName()); +77 Assert.assertEquals("system", job.getGroup()); +78 Assert.assertEquals("test", job.getProject()); +79 Assert.assertEquals("list files", job.getDescription()); +80 } +81 +82 @Test +83 public void parseAdhocExecution() throws Exception { +84 InputStream input = getClass().getResourceAsStream("execution-adhoc.xml"); +85 Document document = ParserHelper.loadDocument(input); 86 -87 @Test -88 public void parseMinimalistNode() throws Exception { -89 InputStream input = getClass().getResourceAsStream("execution-minimalist.xml"); -90 Document document = ParserHelper.loadDocument(input); -91 -92 RundeckExecution execution = new ExecutionParser("result/execution").parseNode(document); -93 RundeckJob job = execution.getJob(); -94 -95 Assert.assertEquals(new Long(1), execution.getId()); -96 Assert.assertNull(execution.getUrl()); -97 Assert.assertNull(execution.getStatus()); -98 Assert.assertNull(execution.getStartedBy()); -99 Assert.assertNull(execution.getStartedAt()); -100 Assert.assertNull(execution.getEndedAt()); -101 Assert.assertNull(execution.getAbortedBy()); -102 Assert.assertNull(execution.getDescription()); -103 -104 Assert.assertNull(job); -105 } +87 RundeckExecution execution = new ExecutionParser("result/executions/execution").parseXmlNode(document); +88 RundeckJob job = execution.getJob(); +89 +90 Assert.assertEquals(new Long(1), execution.getId()); +91 Assert.assertEquals("http://localhost:4440/execution/follow/1", execution.getUrl()); +92 Assert.assertEquals(ExecutionStatus.SUCCEEDED, execution.getStatus()); +93 Assert.assertEquals("admin", execution.getStartedBy()); +94 Assert.assertEquals(new Date(1309857539137L), execution.getStartedAt()); +95 Assert.assertEquals(new Date(1309857539606L), execution.getEndedAt()); +96 Assert.assertEquals(null, execution.getAbortedBy()); +97 Assert.assertEquals("w", execution.getDescription()); +98 +99 Assert.assertNull(job); +100 } +101 +102 @Test +103 public void parseMinimalistExecution() throws Exception { +104 InputStream input = getClass().getResourceAsStream("execution-minimalist.xml"); +105 Document document = ParserHelper.loadDocument(input); 106 -107 } +107 RundeckExecution execution = new ExecutionParser("result/execution").parseXmlNode(document); +108 RundeckJob job = execution.getJob(); +109 +110 Assert.assertEquals(new Long(1), execution.getId()); +111 Assert.assertNull(execution.getUrl()); +112 Assert.assertNull(execution.getStatus()); +113 Assert.assertNull(execution.getStartedBy()); +114 Assert.assertNull(execution.getStartedAt()); +115 Assert.assertNull(execution.getEndedAt()); +116 Assert.assertNull(execution.getAbortedBy()); +117 Assert.assertNull(execution.getDescription()); +118 +119 Assert.assertNull(job); +120 } +121 +122 }
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import java.util.Date; -5 import java.util.List; -6 import org.dom4j.Document; -7 import org.junit.Assert; -8 import org.junit.Test; -9 import org.rundeck.api.domain.RundeckExecution; -10 import org.rundeck.api.domain.RundeckJob; -11 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; -12 -13 /** -14 * Test the {@link ExecutionsParser} -15 * -16 * @author Vincent Behar -17 */ -18 public class ExecutionsParserTest { -19 -20 @Test -21 public void parseNode() throws Exception { -22 InputStream input = getClass().getResourceAsStream("executions.xml"); -23 Document document = ParserHelper.loadDocument(input); -24 -25 List<RundeckExecution> executions = new ExecutionsParser("result/executions/execution").parseNode(document); -26 Assert.assertEquals(2, executions.size()); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.Date; +20 import java.util.List; +21 import org.dom4j.Document; +22 import org.junit.Assert; +23 import org.junit.Test; +24 import org.rundeck.api.domain.RundeckExecution; +25 import org.rundeck.api.domain.RundeckJob; +26 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; 27 -28 RundeckExecution exec1 = executions.get(0); -29 Assert.assertEquals(new Long(1), exec1.getId()); -30 Assert.assertEquals("http://localhost:4440/execution/follow/1", exec1.getUrl()); -31 Assert.assertEquals(ExecutionStatus.SUCCEEDED, exec1.getStatus()); -32 Assert.assertEquals("admin", exec1.getStartedBy()); -33 Assert.assertEquals(new Date(1308322895104L), exec1.getStartedAt()); -34 Assert.assertEquals(new Date(1308322959420L), exec1.getEndedAt()); -35 Assert.assertEquals(null, exec1.getAbortedBy()); -36 Assert.assertEquals("ls ${option.dir}", exec1.getDescription()); -37 -38 RundeckExecution exec2 = executions.get(1); -39 Assert.assertEquals(new Long(2), exec2.getId()); -40 Assert.assertEquals("http://localhost:4440/execution/follow/2", exec2.getUrl()); -41 Assert.assertEquals(ExecutionStatus.SUCCEEDED, exec2.getStatus()); -42 Assert.assertEquals("admin", exec2.getStartedBy()); -43 Assert.assertEquals(new Date(1309524165388L), exec2.getStartedAt()); -44 Assert.assertEquals(new Date(1309524174635L), exec2.getEndedAt()); -45 Assert.assertEquals(null, exec2.getAbortedBy()); -46 Assert.assertEquals("ls ${option.dir}", exec2.getDescription()); -47 -48 RundeckJob job1 = exec1.getJob(); -49 Assert.assertEquals("1", job1.getId()); -50 Assert.assertEquals("ls", job1.getName()); -51 Assert.assertEquals("system", job1.getGroup()); -52 Assert.assertEquals("test", job1.getProject()); -53 Assert.assertEquals("list files", job1.getDescription()); -54 -55 RundeckJob job2 = exec2.getJob(); -56 Assert.assertEquals("1", job2.getId()); -57 Assert.assertEquals("ls", job2.getName()); -58 Assert.assertEquals("system", job2.getGroup()); -59 Assert.assertEquals("test", job2.getProject()); -60 Assert.assertEquals("list files", job2.getDescription()); -61 -62 Assert.assertEquals(job1, job2); -63 } -64 -65 } +28 /** +29 * Test the {@link ExecutionsParser} +30 * +31 * @author Vincent Behar +32 */ +33 public class ExecutionsParserTest { +34 +35 @Test +36 public void parseExecutions() throws Exception { +37 InputStream input = getClass().getResourceAsStream("executions.xml"); +38 Document document = ParserHelper.loadDocument(input); +39 +40 List<RundeckExecution> executions = new ExecutionsParser("result/executions/execution").parseXmlNode(document); +41 Assert.assertEquals(2, executions.size()); +42 +43 RundeckExecution exec1 = executions.get(0); +44 Assert.assertEquals(new Long(1), exec1.getId()); +45 Assert.assertEquals("http://localhost:4440/execution/follow/1", exec1.getUrl()); +46 Assert.assertEquals(ExecutionStatus.SUCCEEDED, exec1.getStatus()); +47 Assert.assertEquals("admin", exec1.getStartedBy()); +48 Assert.assertEquals(new Date(1308322895104L), exec1.getStartedAt()); +49 Assert.assertEquals(new Date(1308322959420L), exec1.getEndedAt()); +50 Assert.assertEquals(null, exec1.getAbortedBy()); +51 Assert.assertEquals("ls ${option.dir}", exec1.getDescription()); +52 +53 RundeckExecution exec2 = executions.get(1); +54 Assert.assertEquals(new Long(2), exec2.getId()); +55 Assert.assertEquals("http://localhost:4440/execution/follow/2", exec2.getUrl()); +56 Assert.assertEquals(ExecutionStatus.SUCCEEDED, exec2.getStatus()); +57 Assert.assertEquals("admin", exec2.getStartedBy()); +58 Assert.assertEquals(new Date(1309524165388L), exec2.getStartedAt()); +59 Assert.assertEquals(new Date(1309524174635L), exec2.getEndedAt()); +60 Assert.assertEquals(null, exec2.getAbortedBy()); +61 Assert.assertEquals("ls ${option.dir}", exec2.getDescription()); +62 +63 RundeckJob job1 = exec1.getJob(); +64 Assert.assertEquals("1", job1.getId()); +65 Assert.assertEquals("ls", job1.getName()); +66 Assert.assertEquals("system", job1.getGroup()); +67 Assert.assertEquals("test", job1.getProject()); +68 Assert.assertEquals("list files", job1.getDescription()); +69 +70 RundeckJob job2 = exec2.getJob(); +71 Assert.assertEquals("1", job2.getId()); +72 Assert.assertEquals("ls", job2.getName()); +73 Assert.assertEquals("system", job2.getGroup()); +74 Assert.assertEquals("test", job2.getProject()); +75 Assert.assertEquals("list files", job2.getDescription()); +76 +77 Assert.assertEquals(job1, job2); +78 } +79 +80 }
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import org.dom4j.Document; -5 import org.junit.Assert; -6 import org.junit.Test; -7 import org.rundeck.api.domain.RundeckJob; -8 -9 /** -10 * Test the {@link JobParser} -11 * -12 * @author Vincent Behar -13 */ -14 public class JobParserTest { -15 -16 @Test -17 public void parseNode() throws Exception { -18 InputStream input = getClass().getResourceAsStream("job.xml"); -19 Document document = ParserHelper.loadDocument(input); -20 -21 RundeckJob job = new JobParser("joblist/job").parseNode(document); -22 -23 Assert.assertEquals("1", job.getId()); -24 Assert.assertEquals("job-name", job.getName()); -25 Assert.assertEquals("job description", job.getDescription()); -26 Assert.assertEquals("group-name", job.getGroup()); -27 Assert.assertEquals("project-name", job.getProject()); -28 } -29 -30 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import org.dom4j.Document; +20 import org.junit.Assert; +21 import org.junit.Test; +22 import org.rundeck.api.domain.RundeckJob; +23 +24 /** +25 * Test the {@link JobParser} +26 * +27 * @author Vincent Behar +28 */ +29 public class JobParserTest { +30 +31 @Test +32 public void parseJob() throws Exception { +33 InputStream input = getClass().getResourceAsStream("job.xml"); +34 Document document = ParserHelper.loadDocument(input); +35 +36 RundeckJob job = new JobParser("joblist/job").parseXmlNode(document); +37 +38 Assert.assertEquals("1", job.getId()); +39 Assert.assertEquals("job-name", job.getName()); +40 Assert.assertEquals("job description", job.getDescription()); +41 Assert.assertEquals("group-name", job.getGroup()); +42 Assert.assertEquals("project-name", job.getProject()); +43 } +44 +45 }
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import java.util.List; -5 import org.dom4j.Document; -6 import org.junit.Assert; -7 import org.junit.Test; -8 import org.rundeck.api.domain.RundeckJob; -9 -10 /** -11 * Test the {@link JobsParser} -12 * -13 * @author Vincent Behar -14 */ -15 public class JobsParserTest { -16 -17 @Test -18 public void parseNode() throws Exception { -19 InputStream input = getClass().getResourceAsStream("jobs.xml"); -20 Document document = ParserHelper.loadDocument(input); -21 -22 List<RundeckJob> jobs = new JobsParser("result/jobs/job").parseNode(document); -23 Assert.assertEquals(2, jobs.size()); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.List; +20 import org.dom4j.Document; +21 import org.junit.Assert; +22 import org.junit.Test; +23 import org.rundeck.api.domain.RundeckJob; 24 -25 RundeckJob job1 = jobs.get(0); -26 Assert.assertEquals("1", job1.getId()); -27 Assert.assertEquals("ls", job1.getName()); -28 Assert.assertEquals("list files", job1.getDescription()); -29 Assert.assertEquals("system", job1.getGroup()); -30 Assert.assertEquals("test", job1.getProject()); +25 /** +26 * Test the {@link JobsParser} +27 * +28 * @author Vincent Behar +29 */ +30 public class JobsParserTest { 31 -32 RundeckJob job2 = jobs.get(1); -33 Assert.assertEquals("2", job2.getId()); -34 Assert.assertEquals("ps", job2.getName()); -35 Assert.assertEquals("list processes", job2.getDescription()); -36 Assert.assertEquals("system", job2.getGroup()); -37 Assert.assertEquals("test", job2.getProject()); -38 } +32 @Test +33 public void parseJobs() throws Exception { +34 InputStream input = getClass().getResourceAsStream("jobs.xml"); +35 Document document = ParserHelper.loadDocument(input); +36 +37 List<RundeckJob> jobs = new JobsParser("result/jobs/job").parseXmlNode(document); +38 Assert.assertEquals(2, jobs.size()); 39 -40 } +40 RundeckJob job1 = jobs.get(0); +41 Assert.assertEquals("1", job1.getId()); +42 Assert.assertEquals("ls", job1.getName()); +43 Assert.assertEquals("list files", job1.getDescription()); +44 Assert.assertEquals("system", job1.getGroup()); +45 Assert.assertEquals("test", job1.getProject()); +46 +47 RundeckJob job2 = jobs.get(1); +48 Assert.assertEquals("2", job2.getId()); +49 Assert.assertEquals("ps", job2.getName()); +50 Assert.assertEquals("list processes", job2.getDescription()); +51 Assert.assertEquals("system", job2.getGroup()); +52 Assert.assertEquals("test", job2.getProject()); +53 } +54 +55 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.Arrays; +20 import org.dom4j.Document; +21 import org.junit.Assert; +22 import org.junit.Test; +23 import org.rundeck.api.domain.RundeckNode; +24 +25 /** +26 * Test the {@link NodeParser} +27 * +28 * @author Vincent Behar +29 */ +30 public class NodeParserTest { +31 +32 @Test +33 public void parseNode() throws Exception { +34 InputStream input = getClass().getResourceAsStream("resources.xml"); +35 Document document = ParserHelper.loadDocument(input); +36 +37 RundeckNode node = new NodeParser("project/node").parseXmlNode(document); +38 +39 Assert.assertEquals("strongbad", node.getName()); +40 Assert.assertEquals("Node", node.getType()); +41 Assert.assertEquals("a development host", node.getDescription()); +42 Assert.assertEquals(Arrays.asList("dev"), node.getTags()); +43 Assert.assertEquals("strongbad.local", node.getHostname()); +44 Assert.assertEquals("i386", node.getOsArch()); +45 Assert.assertEquals("unix", node.getOsFamily()); +46 Assert.assertEquals("Linux", node.getOsName()); +47 Assert.assertEquals("2.6.35-30-generic-pae", node.getOsVersion()); +48 Assert.assertEquals("rundeck", node.getUsername()); +49 Assert.assertEquals(null, node.getEditUrl()); +50 Assert.assertEquals(null, node.getRemoteUrl()); +51 } +52 +53 } ++
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.Arrays; +20 import java.util.List; +21 import org.dom4j.Document; +22 import org.junit.Assert; +23 import org.junit.Test; +24 import org.rundeck.api.domain.RundeckNode; +25 +26 /** +27 * Test the {@link NodesParser} +28 * +29 * @author Vincent Behar +30 */ +31 public class NodesParserTest { +32 +33 @Test +34 public void parseNodes() throws Exception { +35 InputStream input = getClass().getResourceAsStream("resources.xml"); +36 Document document = ParserHelper.loadDocument(input); +37 +38 List<RundeckNode> nodes = new NodesParser("project/node").parseXmlNode(document); +39 Assert.assertEquals(1, nodes.size()); +40 +41 RundeckNode node1 = nodes.get(0); +42 Assert.assertEquals("strongbad", node1.getName()); +43 Assert.assertEquals("Node", node1.getType()); +44 Assert.assertEquals("a development host", node1.getDescription()); +45 Assert.assertEquals(Arrays.asList("dev"), node1.getTags()); +46 Assert.assertEquals("strongbad.local", node1.getHostname()); +47 Assert.assertEquals("i386", node1.getOsArch()); +48 Assert.assertEquals("unix", node1.getOsFamily()); +49 Assert.assertEquals("Linux", node1.getOsName()); +50 Assert.assertEquals("2.6.35-30-generic-pae", node1.getOsVersion()); +51 Assert.assertEquals("rundeck", node1.getUsername()); +52 Assert.assertEquals(null, node1.getEditUrl()); +53 Assert.assertEquals(null, node1.getRemoteUrl()); +54 } +55 +56 } ++
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import org.dom4j.Document; -5 import org.junit.Assert; -6 import org.junit.Test; -7 import org.rundeck.api.RundeckApiException; -8 -9 /** -10 * Test the {@link ParserHelper} -11 * -12 * @author Vincent Behar -13 */ -14 public class ParserHelperTest { -15 -16 /** -17 * XML with an explicit "error" result should throw an exception -18 */ -19 @Test -20 public void loadErrorDocument() throws Exception { -21 InputStream input = getClass().getResourceAsStream("error.xml"); -22 try { -23 ParserHelper.loadDocument(input); -24 Assert.fail("should have thrown an exception !"); -25 } catch (RundeckApiException e) { -26 Assert.assertEquals("This is the error message", e.getMessage()); -27 } -28 } -29 -30 /** -31 * XML with an explicit "success" result should NOT throw an exception -32 */ -33 @Test -34 public void loadSuccessDocument() throws Exception { -35 InputStream input = getClass().getResourceAsStream("success.xml"); -36 Document document = ParserHelper.loadDocument(input); -37 Assert.assertNotNull(document); -38 } -39 -40 /** -41 * XML with no result should NOT throw an exception -42 */ -43 @Test -44 public void loadEmptyDocument() throws Exception { -45 InputStream input = getClass().getResourceAsStream("empty.xml"); -46 Document document = ParserHelper.loadDocument(input); -47 Assert.assertNotNull(document); -48 } -49 -50 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import org.dom4j.Document; +20 import org.junit.Assert; +21 import org.junit.Test; +22 import org.rundeck.api.RundeckApiException; +23 +24 /** +25 * Test the {@link ParserHelper} +26 * +27 * @author Vincent Behar +28 */ +29 public class ParserHelperTest { +30 +31 /** +32 * XML with an explicit "error" result should throw an exception +33 */ +34 @Test +35 public void loadErrorDocument() throws Exception { +36 InputStream input = getClass().getResourceAsStream("error.xml"); +37 try { +38 ParserHelper.loadDocument(input); +39 Assert.fail("should have thrown an exception !"); +40 } catch (RundeckApiException e) { +41 Assert.assertEquals("This is the error message", e.getMessage()); +42 } +43 } +44 +45 /** +46 * XML with an explicit "success" result should NOT throw an exception +47 */ +48 @Test +49 public void loadSuccessDocument() throws Exception { +50 InputStream input = getClass().getResourceAsStream("success.xml"); +51 Document document = ParserHelper.loadDocument(input); +52 Assert.assertNotNull(document); +53 } +54 +55 /** +56 * XML with no result should NOT throw an exception +57 */ +58 @Test +59 public void loadEmptyDocument() throws Exception { +60 InputStream input = getClass().getResourceAsStream("empty.xml"); +61 Document document = ParserHelper.loadDocument(input); +62 Assert.assertNotNull(document); +63 } +64 +65 }
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import org.dom4j.Document; -5 import org.junit.Assert; -6 import org.junit.Test; -7 import org.rundeck.api.domain.RundeckProject; -8 -9 /** -10 * Test the {@link ProjectParser} -11 * -12 * @author Vincent Behar -13 */ -14 public class ProjectParserTest { -15 -16 @Test -17 public void parseNode() throws Exception { -18 InputStream input = getClass().getResourceAsStream("project.xml"); -19 Document document = ParserHelper.loadDocument(input); -20 -21 RundeckProject project = new ProjectParser("result/projects/project").parseNode(document); -22 -23 Assert.assertEquals("test", project.getName()); -24 Assert.assertEquals("test project", project.getDescription()); -25 } -26 -27 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import org.dom4j.Document; +20 import org.junit.Assert; +21 import org.junit.Test; +22 import org.rundeck.api.domain.RundeckProject; +23 +24 /** +25 * Test the {@link ProjectParser} +26 * +27 * @author Vincent Behar +28 */ +29 public class ProjectParserTest { +30 +31 @Test +32 public void parseProject() throws Exception { +33 InputStream input = getClass().getResourceAsStream("project.xml"); +34 Document document = ParserHelper.loadDocument(input); +35 +36 RundeckProject project = new ProjectParser("result/projects/project").parseXmlNode(document); +37 +38 Assert.assertEquals("test", project.getName()); +39 Assert.assertEquals("test project", project.getDescription()); +40 } +41 +42 }
-1 package org.rundeck.api.parser; -2 -3 import java.io.InputStream; -4 import java.util.List; -5 import org.dom4j.Document; -6 import org.junit.Assert; -7 import org.junit.Test; -8 import org.rundeck.api.domain.RundeckProject; -9 -10 /** -11 * Test the {@link ProjectsParser} -12 * -13 * @author Vincent Behar -14 */ -15 public class ProjectsParserTest { -16 -17 @Test -18 public void parseNode() throws Exception { -19 InputStream input = getClass().getResourceAsStream("projects.xml"); -20 Document document = ParserHelper.loadDocument(input); -21 -22 List<RundeckProject> projects = new ProjectsParser("result/projects/project").parseNode(document); -23 Assert.assertEquals(2, projects.size()); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.InputStream; +19 import java.util.List; +20 import org.dom4j.Document; +21 import org.junit.Assert; +22 import org.junit.Test; +23 import org.rundeck.api.domain.RundeckProject; 24 -25 RundeckProject project1 = projects.get(0); -26 Assert.assertEquals("test", project1.getName()); -27 Assert.assertEquals("test project", project1.getDescription()); -28 -29 RundeckProject project2 = projects.get(1); -30 Assert.assertEquals("other", project2.getName()); -31 Assert.assertEquals(null, project2.getDescription()); -32 } -33 -34 } +25 /** +26 * Test the {@link ProjectsParser} +27 * +28 * @author Vincent Behar +29 */ +30 public class ProjectsParserTest { +31 +32 @Test +33 public void parseProjects() throws Exception { +34 InputStream input = getClass().getResourceAsStream("projects.xml"); +35 Document document = ParserHelper.loadDocument(input); +36 +37 List<RundeckProject> projects = new ProjectsParser("result/projects/project").parseXmlNode(document); +38 Assert.assertEquals(2, projects.size()); +39 +40 RundeckProject project1 = projects.get(0); +41 Assert.assertEquals("test", project1.getName()); +42 Assert.assertEquals("test project", project1.getDescription()); +43 +44 RundeckProject project2 = projects.get(1); +45 Assert.assertEquals("other", project2.getName()); +46 Assert.assertEquals(null, project2.getDescription()); +47 } +48 +49 }
-1 package org.rundeck.api.util; -2 -3 import java.util.Properties; -4 import org.junit.Assert; -5 import org.junit.Test; -6 -7 /** -8 * Test the {@link ParametersUtil} -9 * -10 * @author Vincent Behar -11 */ -12 public class ParametersUtilTest { -13 -14 @Test -15 public void generateArgString() throws Exception { -16 Assert.assertNull(ParametersUtil.generateArgString(null)); -17 Assert.assertEquals("", ParametersUtil.generateArgString(new Properties())); -18 -19 Properties options = new Properties(); -20 options.put("key1", "value1"); -21 options.put("key2", "value 2 with spaces"); -22 String argString = ParametersUtil.generateArgString(options); -23 if (argString.startsWith("-key1")) { -24 Assert.assertEquals("-key1 value1 -key2 'value 2 with spaces'", argString); -25 } else { -26 Assert.assertEquals("-key2 'value 2 with spaces' -key1 value1", argString); -27 } -28 } -29 -30 @Test -31 public void generateNodeFiltersString() throws Exception { -32 Assert.assertNull(ParametersUtil.generateNodeFiltersString(null)); -33 Assert.assertEquals("", ParametersUtil.generateNodeFiltersString(new Properties())); -34 -35 Properties filters = new Properties(); -36 filters.put("tags", "appserv+front"); -37 filters.put("exclude-tags", "qa,dev"); -38 filters.put("os-family", "unix"); -39 String result = ParametersUtil.generateNodeFiltersString(filters); -40 Assert.assertEquals("os-family=unix&exclude-tags=qa%2Cdev&tags=appserv%2Bfront", result); -41 } -42 -43 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.util; +17 +18 import java.util.Properties; +19 import org.junit.Assert; +20 import org.junit.Test; +21 +22 /** +23 * Test the {@link ParametersUtil} +24 * +25 * @author Vincent Behar +26 */ +27 public class ParametersUtilTest { +28 +29 @Test +30 public void generateArgString() throws Exception { +31 Assert.assertNull(ParametersUtil.generateArgString(null)); +32 Assert.assertEquals("", ParametersUtil.generateArgString(new Properties())); +33 +34 Properties options = new Properties(); +35 options.put("key1", "value1"); +36 options.put("key2", "value 2 with spaces"); +37 String argString = ParametersUtil.generateArgString(options); +38 if (argString.startsWith("-key1")) { +39 Assert.assertEquals("-key1 value1 -key2 'value 2 with spaces'", argString); +40 } else { +41 Assert.assertEquals("-key2 'value 2 with spaces' -key1 value1", argString); +42 } +43 } +44 +45 @Test +46 public void generateNodeFiltersString() throws Exception { +47 Assert.assertNull(ParametersUtil.generateNodeFiltersString(null)); +48 Assert.assertEquals("", ParametersUtil.generateNodeFiltersString(new Properties())); +49 +50 Properties filters = new Properties(); +51 filters.put("tags", "appserv+front"); +52 filters.put("exclude-tags", "qa,dev"); +53 filters.put("os-family", "unix"); +54 String result = ParametersUtil.generateNodeFiltersString(filters); +55 Assert.assertEquals("os-family=unix&exclude-tags=qa%2Cdev&tags=appserv%2Bfront", result); +56 } +57 +58 }
-1 package org.rundeck.api; -2 -3 import java.io.IOException; -4 import java.security.KeyManagementException; -5 import java.security.KeyStoreException; -6 import java.security.NoSuchAlgorithmException; -7 import java.security.UnrecoverableKeyException; -8 import java.security.cert.CertificateException; -9 import java.security.cert.X509Certificate; -10 import java.util.ArrayList; -11 import java.util.List; -12 import org.apache.commons.lang.StringUtils; -13 import org.apache.http.HttpResponse; -14 import org.apache.http.NameValuePair; -15 import org.apache.http.ParseException; -16 import org.apache.http.client.HttpClient; -17 import org.apache.http.client.entity.UrlEncodedFormEntity; -18 import org.apache.http.client.methods.HttpGet; -19 import org.apache.http.client.methods.HttpPost; -20 import org.apache.http.conn.scheme.Scheme; -21 import org.apache.http.conn.ssl.SSLSocketFactory; -22 import org.apache.http.conn.ssl.TrustStrategy; -23 import org.apache.http.impl.client.DefaultHttpClient; -24 import org.apache.http.message.BasicNameValuePair; -25 import org.apache.http.protocol.HTTP; -26 import org.apache.http.util.EntityUtils; -27 import org.dom4j.Document; -28 import org.rundeck.api.RundeckApiException.RundeckApiLoginException; -29 import org.rundeck.api.parser.NodeParser; -30 import org.rundeck.api.parser.ParserHelper; -31 import org.rundeck.api.util.AssertUtil; -32 -33 /** -34 * Class responsible for making the HTTP API calls -35 * -36 * @author Vincent Behar -37 */ -38 class ApiCall { -39 -40 private final RundeckClient client; -41 -42 /** -43 * Build a new instance, linked to the given RunDeck client -44 * -45 * @param client holding the RunDeck url and the credentials -46 * @throws IllegalArgumentException if client is null -47 */ -48 public ApiCall(RundeckClient client) throws IllegalArgumentException { -49 super(); -50 this.client = client; -51 AssertUtil.notNull(client, "The RunDeck Client must not be null !"); -52 } -53 -54 /** -55 * Try to "ping" the RunDeck instance to see if it is alive -56 * -57 * @throws RundeckApiException if the ping fails -58 */ -59 public void ping() throws RundeckApiException { -60 HttpClient httpClient = instantiateHttpClient(); -61 try { -62 HttpResponse response = httpClient.execute(new HttpGet(client.getUrl())); -63 if (response.getStatusLine().getStatusCode() / 100 != 2) { -64 throw new RundeckApiException("Invalid HTTP response '" + response.getStatusLine() + "' when pinging " -65 + client.getUrl()); -66 } -67 } catch (IOException e) { -68 throw new RundeckApiException("Failed to ping RunDeck instance at " + client.getUrl(), e); -69 } finally { -70 httpClient.getConnectionManager().shutdown(); -71 } -72 } -73 -74 /** -75 * Test the credentials (login/password) on the RunDeck instance -76 * -77 * @throws RundeckApiLoginException if the login fails -78 */ -79 public void testCredentials() throws RundeckApiLoginException { -80 HttpClient httpClient = instantiateHttpClient(); -81 try { -82 login(httpClient); -83 } finally { -84 httpClient.getConnectionManager().shutdown(); -85 } -86 } -87 -88 /** -89 * Execute an HTTP GET request to the RunDeck instance, on the given path. We will login first, and then execute the -90 * API call. At the end, the given parser will be used to convert the response to a more useful result object. +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 import java.io.IOException; +19 import java.security.KeyManagementException; +20 import java.security.KeyStoreException; +21 import java.security.NoSuchAlgorithmException; +22 import java.security.UnrecoverableKeyException; +23 import java.security.cert.CertificateException; +24 import java.security.cert.X509Certificate; +25 import java.util.ArrayList; +26 import java.util.List; +27 import org.apache.commons.lang.StringUtils; +28 import org.apache.http.HttpResponse; +29 import org.apache.http.NameValuePair; +30 import org.apache.http.ParseException; +31 import org.apache.http.client.HttpClient; +32 import org.apache.http.client.entity.UrlEncodedFormEntity; +33 import org.apache.http.client.methods.HttpGet; +34 import org.apache.http.client.methods.HttpPost; +35 import org.apache.http.conn.scheme.Scheme; +36 import org.apache.http.conn.ssl.SSLSocketFactory; +37 import org.apache.http.conn.ssl.TrustStrategy; +38 import org.apache.http.impl.client.DefaultHttpClient; +39 import org.apache.http.message.BasicNameValuePair; +40 import org.apache.http.protocol.HTTP; +41 import org.apache.http.util.EntityUtils; +42 import org.dom4j.Document; +43 import org.rundeck.api.RundeckApiException.RundeckApiLoginException; +44 import org.rundeck.api.parser.XmlNodeParser; +45 import org.rundeck.api.parser.ParserHelper; +46 import org.rundeck.api.util.AssertUtil; +47 +48 /** +49 * Class responsible for making the HTTP API calls +50 * +51 * @author Vincent Behar +52 */ +53 class ApiCall { +54 +55 private final RundeckClient client; +56 +57 /** +58 * Build a new instance, linked to the given RunDeck client +59 * +60 * @param client holding the RunDeck url and the credentials +61 * @throws IllegalArgumentException if client is null +62 */ +63 public ApiCall(RundeckClient client) throws IllegalArgumentException { +64 super(); +65 this.client = client; +66 AssertUtil.notNull(client, "The RunDeck Client must not be null !"); +67 } +68 +69 /** +70 * Try to "ping" the RunDeck instance to see if it is alive +71 * +72 * @throws RundeckApiException if the ping fails +73 */ +74 public void ping() throws RundeckApiException { +75 HttpClient httpClient = instantiateHttpClient(); +76 try { +77 HttpResponse response = httpClient.execute(new HttpGet(client.getUrl())); +78 if (response.getStatusLine().getStatusCode() / 100 != 2) { +79 throw new RundeckApiException("Invalid HTTP response '" + response.getStatusLine() + "' when pinging " +80 + client.getUrl()); +81 } +82 } catch (IOException e) { +83 throw new RundeckApiException("Failed to ping RunDeck instance at " + client.getUrl(), e); +84 } finally { +85 httpClient.getConnectionManager().shutdown(); +86 } +87 } +88 +89 /** +90 * Test the credentials (login/password) on the RunDeck instance 91 * -92 * @param apiPath on which we will make the HTTP request -93 * @param parser used to parse the response -94 * @return the result of the call, as formatted by the parser -95 * @throws RundeckApiException in case of error when calling the API -96 * @throws RundeckApiLoginException if the login fails -97 */ -98 public <T> T get(String apiPath, NodeParser<T> parser) throws RundeckApiException, RundeckApiLoginException { -99 String apiUrl = client.getUrl() + RundeckClient.API_ENDPOINT + apiPath; -100 -101 HttpClient httpClient = instantiateHttpClient(); -102 try { -103 login(httpClient); -104 -105 // execute the HTTP request -106 HttpResponse response = null; -107 try { -108 response = httpClient.execute(new HttpGet(apiUrl)); -109 } catch (IOException e) { -110 throw new RundeckApiException("Failed to execute an HTTP GET on url : " + apiUrl, e); -111 } -112 if (response.getStatusLine().getStatusCode() / 100 != 2) { -113 throw new RundeckApiException("Invalid HTTP response '" + response.getStatusLine() + "' for " + apiUrl); -114 } -115 if (response.getEntity() == null) { -116 throw new RundeckApiException("Empty RunDeck response ! HTTP status line is : " -117 + response.getStatusLine()); -118 } +92 * @throws RundeckApiLoginException if the login fails +93 */ +94 public void testCredentials() throws RundeckApiLoginException { +95 HttpClient httpClient = instantiateHttpClient(); +96 try { +97 login(httpClient); +98 } finally { +99 httpClient.getConnectionManager().shutdown(); +100 } +101 } +102 +103 /** +104 * Execute an HTTP GET request to the RunDeck instance, on the given path. We will login first, and then execute the +105 * API call. At the end, the given parser will be used to convert the response to a more useful result object. +106 * +107 * @param apiPath on which we will make the HTTP request - see {@link ApiPathBuilder} +108 * @param parser used to parse the response +109 * @return the result of the call, as formatted by the parser +110 * @throws RundeckApiException in case of error when calling the API +111 * @throws RundeckApiLoginException if the login fails +112 */ +113 public <T> T get(ApiPathBuilder apiPath, XmlNodeParser<T> parser) throws RundeckApiException, RundeckApiLoginException { +114 String apiUrl = client.getUrl() + RundeckClient.API_ENDPOINT + apiPath; +115 +116 HttpClient httpClient = instantiateHttpClient(); +117 try { +118 login(httpClient); 119 -120 // read and parse the response -121 Document xmlDocument = ParserHelper.loadDocument(response); -122 T result = parser.parseNode(xmlDocument); -123 -124 // release the connection -125 try { -126 EntityUtils.consume(response.getEntity()); -127 } catch (IOException e) { -128 throw new RundeckApiException("Failed to consume entity (release connection)", e); +120 // execute the HTTP request +121 HttpResponse response = null; +122 try { +123 response = httpClient.execute(new HttpGet(apiUrl)); +124 } catch (IOException e) { +125 throw new RundeckApiException("Failed to execute an HTTP GET on url : " + apiUrl, e); +126 } +127 if (response.getStatusLine().getStatusCode() / 100 != 2) { +128 throw new RundeckApiException("Invalid HTTP response '" + response.getStatusLine() + "' for " + apiUrl); 129 } -130 return result; -131 } finally { -132 httpClient.getConnectionManager().shutdown(); -133 } -134 } -135 -136 /** -137 * Do the actual work of login, using the given {@link HttpClient} instance. You'll need to re-use this instance -138 * when making API calls (such as running a job). -139 * -140 * @param httpClient pre-instantiated -141 * @throws RundeckApiLoginException if the login failed -142 */ -143 private void login(HttpClient httpClient) throws RundeckApiLoginException { -144 String location = client.getUrl() + "/j_security_check"; -145 -146 while (true) { -147 HttpPost postLogin = new HttpPost(location); -148 List<NameValuePair> params = new ArrayList<NameValuePair>(); -149 params.add(new BasicNameValuePair("j_username", client.getLogin())); -150 params.add(new BasicNameValuePair("j_password", client.getPassword())); -151 params.add(new BasicNameValuePair("action", "login")); -152 -153 HttpResponse response = null; -154 try { -155 postLogin.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); -156 response = httpClient.execute(postLogin); -157 } catch (IOException e) { -158 throw new RundeckApiLoginException("Failed to post login form on " + location, e); -159 } +130 if (response.getEntity() == null) { +131 throw new RundeckApiException("Empty RunDeck response ! HTTP status line is : " +132 + response.getStatusLine()); +133 } +134 +135 // read and parse the response +136 Document xmlDocument = ParserHelper.loadDocument(response); +137 T result = parser.parseXmlNode(xmlDocument); +138 +139 // release the connection +140 try { +141 EntityUtils.consume(response.getEntity()); +142 } catch (IOException e) { +143 throw new RundeckApiException("Failed to consume entity (release connection)", e); +144 } +145 return result; +146 } finally { +147 httpClient.getConnectionManager().shutdown(); +148 } +149 } +150 +151 /** +152 * Do the actual work of login, using the given {@link HttpClient} instance. You'll need to re-use this instance +153 * when making API calls (such as running a job). +154 * +155 * @param httpClient pre-instantiated +156 * @throws RundeckApiLoginException if the login failed +157 */ +158 private void login(HttpClient httpClient) throws RundeckApiLoginException { +159 String location = client.getUrl() + "/j_security_check"; 160 -161 if (response.getStatusLine().getStatusCode() / 100 == 3) { -162 // HTTP client refuses to handle redirects (code 3xx) for POST, so we have to do it manually... -163 location = response.getFirstHeader("Location").getValue(); -164 try { -165 EntityUtils.consume(response.getEntity()); -166 } catch (IOException e) { -167 throw new RundeckApiLoginException("Failed to consume entity (release connection)", e); -168 } -169 continue; -170 } -171 if (response.getStatusLine().getStatusCode() / 100 != 2) { -172 throw new RundeckApiLoginException("Invalid HTTP response '" + response.getStatusLine() + "' for " -173 + location); +161 while (true) { +162 HttpPost postLogin = new HttpPost(location); +163 List<NameValuePair> params = new ArrayList<NameValuePair>(); +164 params.add(new BasicNameValuePair("j_username", client.getLogin())); +165 params.add(new BasicNameValuePair("j_password", client.getPassword())); +166 params.add(new BasicNameValuePair("action", "login")); +167 +168 HttpResponse response = null; +169 try { +170 postLogin.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); +171 response = httpClient.execute(postLogin); +172 } catch (IOException e) { +173 throw new RundeckApiLoginException("Failed to post login form on " + location, e); 174 } -175 try { -176 String content = EntityUtils.toString(response.getEntity(), HTTP.UTF_8); -177 if (StringUtils.contains(content, "j_security_check")) { -178 throw new RundeckApiLoginException("Login failed for user " + client.getLogin()); -179 } -180 try { -181 EntityUtils.consume(response.getEntity()); -182 } catch (IOException e) { -183 throw new RundeckApiLoginException("Failed to consume entity (release connection)", e); -184 } -185 } catch (IOException io) { -186 throw new RundeckApiLoginException("Failed to read RunDeck result", io); -187 } catch (ParseException p) { -188 throw new RundeckApiLoginException("Failed to parse RunDeck response", p); +175 +176 if (response.getStatusLine().getStatusCode() / 100 == 3) { +177 // HTTP client refuses to handle redirects (code 3xx) for POST, so we have to do it manually... +178 location = response.getFirstHeader("Location").getValue(); +179 try { +180 EntityUtils.consume(response.getEntity()); +181 } catch (IOException e) { +182 throw new RundeckApiLoginException("Failed to consume entity (release connection)", e); +183 } +184 continue; +185 } +186 if (response.getStatusLine().getStatusCode() / 100 != 2) { +187 throw new RundeckApiLoginException("Invalid HTTP response '" + response.getStatusLine() + "' for " +188 + location); 189 } -190 break; -191 } -192 } -193 -194 /** -195 * Instantiate a new {@link HttpClient} instance, configured to accept all SSL certificates -196 * -197 * @return an {@link HttpClient} instance - won't be null -198 */ -199 private HttpClient instantiateHttpClient() { -200 SSLSocketFactory socketFactory = null; -201 try { -202 socketFactory = new SSLSocketFactory(new TrustStrategy() { -203 -204 @Override -205 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { -206 return true; -207 } -208 }, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); -209 } catch (KeyManagementException e) { -210 throw new RuntimeException(e); -211 } catch (UnrecoverableKeyException e) { -212 throw new RuntimeException(e); -213 } catch (NoSuchAlgorithmException e) { -214 throw new RuntimeException(e); -215 } catch (KeyStoreException e) { -216 throw new RuntimeException(e); -217 } +190 try { +191 String content = EntityUtils.toString(response.getEntity(), HTTP.UTF_8); +192 if (StringUtils.contains(content, "j_security_check")) { +193 throw new RundeckApiLoginException("Login failed for user " + client.getLogin()); +194 } +195 try { +196 EntityUtils.consume(response.getEntity()); +197 } catch (IOException e) { +198 throw new RundeckApiLoginException("Failed to consume entity (release connection)", e); +199 } +200 } catch (IOException io) { +201 throw new RundeckApiLoginException("Failed to read RunDeck result", io); +202 } catch (ParseException p) { +203 throw new RundeckApiLoginException("Failed to parse RunDeck response", p); +204 } +205 break; +206 } +207 } +208 +209 /** +210 * Instantiate a new {@link HttpClient} instance, configured to accept all SSL certificates +211 * +212 * @return an {@link HttpClient} instance - won't be null +213 */ +214 private HttpClient instantiateHttpClient() { +215 SSLSocketFactory socketFactory = null; +216 try { +217 socketFactory = new SSLSocketFactory(new TrustStrategy() { 218 -219 HttpClient httpClient = new DefaultHttpClient(); -220 httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory)); -221 return httpClient; -222 } -223 -224 } +219 @Override +220 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { +221 return true; +222 } +223 }, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); +224 } catch (KeyManagementException e) { +225 throw new RuntimeException(e); +226 } catch (UnrecoverableKeyException e) { +227 throw new RuntimeException(e); +228 } catch (NoSuchAlgorithmException e) { +229 throw new RuntimeException(e); +230 } catch (KeyStoreException e) { +231 throw new RuntimeException(e); +232 } +233 +234 HttpClient httpClient = new DefaultHttpClient(); +235 httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", 443, socketFactory)); +236 return httpClient; +237 } +238 +239 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 import java.util.Properties; +19 import org.apache.commons.lang.StringUtils; +20 import org.rundeck.api.util.ParametersUtil; +21 +22 /** +23 * Builder for API paths +24 * +25 * @author Vincent Behar +26 */ +27 class ApiPathBuilder { +28 +29 /** Internally, we store everything in a {@link StringBuilder} */ +30 private final StringBuilder apiPath; +31 +32 /** Maker for using the right separator between parameters ("?" or "&") */ +33 private boolean firstParamDone = false; +34 +35 /** +36 * Build a new instance, for the given "path" (the "path" is the part before the parameters. The path and the +37 * parameters are separated by a "?") +38 * +39 * @param paths elements of the path +40 */ +41 public ApiPathBuilder(String... paths) { +42 apiPath = new StringBuilder(); +43 if (paths != null) { +44 for (String path : paths) { +45 if (StringUtils.isNotBlank(path)) { +46 append(path); +47 } +48 } +49 } +50 } +51 +52 /** +53 * Append the given parameter (key and value). This will only append the parameter if it is not blank (null, empty +54 * or whitespace), and make sure to add the right separator ("?" or "&") before. The key and value will be separated +55 * by the "=" character. Also, the value will be url-encoded. +56 * +57 * @param key of the parameter. Must not be null or empty +58 * @param value of the parameter. May be null/empty/blank. Will be url-encoded. +59 * @return this, for method chaining +60 */ +61 public ApiPathBuilder param(String key, String value) { +62 if (StringUtils.isNotBlank(value)) { +63 appendSeparator(); +64 append(key); +65 append("="); +66 append(ParametersUtil.urlEncode(value)); +67 } +68 return this; +69 } +70 +71 /** +72 * Append the given parameter (key and value). This will only append the parameter if it is not null, and make sure +73 * to add the right separator ("?" or "&") before. The key and value will be separated by the "=" character. +74 * +75 * @param key of the parameter. Must not be null or empty +76 * @param value of the parameter. May be null +77 * @return this, for method chaining +78 */ +79 public ApiPathBuilder param(String key, Long value) { +80 if (value != null) { +81 param(key, value.toString()); +82 } +83 return this; +84 } +85 +86 /** +87 * Append the given node filters, only if it is not null/empty +88 * +89 * @param nodeFilters may be null/empty +90 * @return this, for method chaining +91 * @see ParametersUtil#generateNodeFiltersString(Properties) +92 */ +93 public ApiPathBuilder nodeFilters(Properties nodeFilters) { +94 String filters = ParametersUtil.generateNodeFiltersString(nodeFilters); +95 if (StringUtils.isNotBlank(filters)) { +96 appendSeparator(); +97 append(filters); +98 } +99 return this; +100 } +101 +102 @Override +103 public String toString() { +104 return apiPath.toString(); +105 } +106 +107 /** +108 * Append the given string +109 * +110 * @param str to append +111 */ +112 private void append(String str) { +113 apiPath.append(str); +114 } +115 +116 /** +117 * Append the right separator "?" or "&" between 2 parameters +118 */ +119 private void appendSeparator() { +120 if (firstParamDone) { +121 append("&"); +122 } else { +123 append("?"); +124 firstParamDone = true; +125 } +126 } +127 +128 } ++
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 import java.util.Properties; +19 import org.apache.commons.lang.StringUtils; +20 +21 /** +22 * Builder for node filters +23 * +24 * @author Vincent Behar +25 */ +26 public class NodeFiltersBuilder { +27 +28 private final Properties filters; +29 +30 /** +31 * Build a new instance. At the end, use {@link #toProperties()}. +32 */ +33 public NodeFiltersBuilder() { +34 filters = new Properties(); +35 } +36 +37 /** +38 * Include nodes matching the given hostname +39 * +40 * @param hostname +41 * @return this, for method chaining +42 * @see #excludeHostname(String) +43 */ +44 public NodeFiltersBuilder hostname(String hostname) { +45 if (StringUtils.isNotBlank(hostname)) { +46 filters.put("hostname", hostname); +47 } +48 return this; +49 } +50 +51 /** +52 * Include nodes matching the given type +53 * +54 * @param type +55 * @return this, for method chaining +56 * @see #excludeType(String) +57 */ +58 public NodeFiltersBuilder type(String type) { +59 if (StringUtils.isNotBlank(type)) { +60 filters.put("type", type); +61 } +62 return this; +63 } +64 +65 /** +66 * Include nodes matching the given tags +67 * +68 * @param tags +69 * @return this, for method chaining +70 * @see #excludeTags(String) +71 */ +72 public NodeFiltersBuilder tags(String tags) { +73 if (StringUtils.isNotBlank(tags)) { +74 filters.put("tags", tags); +75 } +76 return this; +77 } +78 +79 /** +80 * Include nodes matching the given name +81 * +82 * @param name +83 * @return this, for method chaining +84 * @see #excludeName(String) +85 */ +86 public NodeFiltersBuilder name(String name) { +87 if (StringUtils.isNotBlank(name)) { +88 filters.put("name", name); +89 } +90 return this; +91 } +92 +93 /** +94 * Include nodes matching the given OS-name +95 * +96 * @param osName +97 * @return this, for method chaining +98 * @see #excludeOsName(String) +99 */ +100 public NodeFiltersBuilder osName(String osName) { +101 if (StringUtils.isNotBlank(osName)) { +102 filters.put("os-name", osName); +103 } +104 return this; +105 } +106 +107 /** +108 * Include nodes matching the given OS-family +109 * +110 * @param osFamily +111 * @return this, for method chaining +112 * @see #excludeOsFamily(String) +113 */ +114 public NodeFiltersBuilder osFamily(String osFamily) { +115 if (StringUtils.isNotBlank(osFamily)) { +116 filters.put("os-family", osFamily); +117 } +118 return this; +119 } +120 +121 /** +122 * Include nodes matching the given OS-arch +123 * +124 * @param osArch +125 * @return this, for method chaining +126 * @see #excludeOsArch(String) +127 */ +128 public NodeFiltersBuilder osArch(String osArch) { +129 if (StringUtils.isNotBlank(osArch)) { +130 filters.put("os-arch", osArch); +131 } +132 return this; +133 } +134 +135 /** +136 * Include nodes matching the given OS-version +137 * +138 * @param osVersion +139 * @return this, for method chaining +140 * @see #excludeOsVersion(String) +141 */ +142 public NodeFiltersBuilder osVersion(String osVersion) { +143 if (StringUtils.isNotBlank(osVersion)) { +144 filters.put("os-version", osVersion); +145 } +146 return this; +147 } +148 +149 /** +150 * Exclude nodes matching the given hostname +151 * +152 * @param hostname +153 * @return this, for method chaining +154 * @see #hostname(String) +155 * @see #excludePrecedence(boolean) +156 */ +157 public NodeFiltersBuilder excludeHostname(String hostname) { +158 if (StringUtils.isNotBlank(hostname)) { +159 filters.put("exclude-hostname", hostname); +160 } +161 return this; +162 } +163 +164 /** +165 * Exclude nodes matching the given type +166 * +167 * @param type +168 * @return this, for method chaining +169 * @see #type(String) +170 * @see #excludePrecedence(boolean) +171 */ +172 public NodeFiltersBuilder excludeType(String type) { +173 if (StringUtils.isNotBlank(type)) { +174 filters.put("exclude-type", type); +175 } +176 return this; +177 } +178 +179 /** +180 * Exclude nodes matching the given tags +181 * +182 * @param tags +183 * @return this, for method chaining +184 * @see #tags(String) +185 * @see #excludePrecedence(boolean) +186 */ +187 public NodeFiltersBuilder excludeTags(String tags) { +188 if (StringUtils.isNotBlank(tags)) { +189 filters.put("exclude-tags", tags); +190 } +191 return this; +192 } +193 +194 /** +195 * Exclude nodes matching the given name +196 * +197 * @param name +198 * @return this, for method chaining +199 * @see #name(String) +200 * @see #excludePrecedence(boolean) +201 */ +202 public NodeFiltersBuilder excludeName(String name) { +203 if (StringUtils.isNotBlank(name)) { +204 filters.put("exclude-name", name); +205 } +206 return this; +207 } +208 +209 /** +210 * Exclude nodes matching the given OS-name +211 * +212 * @param osName +213 * @return this, for method chaining +214 * @see #osName(String) +215 * @see #excludePrecedence(boolean) +216 */ +217 public NodeFiltersBuilder excludeOsName(String osName) { +218 if (StringUtils.isNotBlank(osName)) { +219 filters.put("exclude-os-name", osName); +220 } +221 return this; +222 } +223 +224 /** +225 * Exclude nodes matching the given OS-family +226 * +227 * @param osFamily +228 * @return this, for method chaining +229 * @see #osFamily(String) +230 * @see #excludePrecedence(boolean) +231 */ +232 public NodeFiltersBuilder excludeOsFamily(String osFamily) { +233 if (StringUtils.isNotBlank(osFamily)) { +234 filters.put("exclude-os-family", osFamily); +235 } +236 return this; +237 } +238 +239 /** +240 * Exclude nodes matching the given OS-arch +241 * +242 * @param osArch +243 * @return this, for method chaining +244 * @see #osArch(String) +245 * @see #excludePrecedence(boolean) +246 */ +247 public NodeFiltersBuilder excludeOsArch(String osArch) { +248 if (StringUtils.isNotBlank(osArch)) { +249 filters.put("exclude-os-arch", osArch); +250 } +251 return this; +252 } +253 +254 /** +255 * Exclude nodes matching the given OS-version +256 * +257 * @param osVersion +258 * @return this, for method chaining +259 * @see #osVersion(String) +260 * @see #excludePrecedence(boolean) +261 */ +262 public NodeFiltersBuilder excludeOsVersion(String osVersion) { +263 if (StringUtils.isNotBlank(osVersion)) { +264 filters.put("exclude-os-version", osVersion); +265 } +266 return this; +267 } +268 +269 /** +270 * Whether exclusion filters take precedence (default to yes). +271 * +272 * @param excludePrecedence +273 * @return this, for method chaining +274 */ +275 public NodeFiltersBuilder excludePrecedence(boolean excludePrecedence) { +276 filters.put("exclude-precedence", Boolean.toString(excludePrecedence)); +277 return this; +278 } +279 +280 /** +281 * @return a new {@link Properties} instance +282 */ +283 public Properties toProperties() { +284 Properties filters = new Properties(); +285 filters.putAll(this.filters); +286 return filters; +287 } +288 +289 } ++
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 import java.util.Properties; +19 +20 /** +21 * Builder for job options +22 * +23 * @author Vincent Behar +24 */ +25 public class OptionsBuilder { +26 +27 private final Properties options; +28 +29 /** +30 * Build a new instance. Use {@link #addOption(Object, Object)} to add some options, and then +31 * {@link #toProperties()} when you're done ! +32 */ +33 public OptionsBuilder() { +34 options = new Properties(); +35 } +36 +37 /** +38 * Add an option +39 * +40 * @param key of the option +41 * @param value of the option +42 * @return this, for method chaining +43 */ +44 public OptionsBuilder addOption(Object key, Object value) { +45 options.put(key, value); +46 return this; +47 } +48 +49 /** +50 * @return a new {@link Properties} instance +51 */ +52 public Properties toProperties() { +53 Properties options = new Properties(); +54 options.putAll(this.options); +55 return options; +56 } +57 +58 } ++
-1 package org.rundeck.api; -2 -3 /** -4 * A generic (unchecked) exception when using the RunDeck API -5 * -6 * @author Vincent Behar -7 */ -8 public class RundeckApiException extends RuntimeException { -9 -10 private static final long serialVersionUID = 1L; -11 -12 public RundeckApiException(String message) { -13 super(message); -14 } -15 -16 public RundeckApiException(String message, Throwable cause) { -17 super(message, cause); -18 } -19 -20 /** -21 * Specific login-related error -22 */ -23 public static class RundeckApiLoginException extends RundeckApiException { +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 /** +19 * A generic (unchecked) exception when using the RunDeck API +20 * +21 * @author Vincent Behar +22 */ +23 public class RundeckApiException extends RuntimeException { 24 -25 private static final long serialVersionUID = 1L; +25 private static final long serialVersionUID = 1L; 26 -27 public RundeckApiLoginException(String message) { -28 super(message); -29 } +27 public RundeckApiException(String message) { +28 super(message); +29 } 30 -31 public RundeckApiLoginException(String message, Throwable cause) { -32 super(message, cause); -33 } -34 } -35 -36 } +31 public RundeckApiException(String message, Throwable cause) { +32 super(message, cause); +33 } +34 +35 /** +36 * Specific login-related error +37 */ +38 public static class RundeckApiLoginException extends RundeckApiException { +39 +40 private static final long serialVersionUID = 1L; +41 +42 public RundeckApiLoginException(String message) { +43 super(message); +44 } +45 +46 public RundeckApiLoginException(String message, Throwable cause) { +47 super(message, cause); +48 } +49 } +50 +51 }
-1 package org.rundeck.api; -2 -3 import java.io.Serializable; -4 import java.util.ArrayList; -5 import java.util.List; -6 import java.util.Properties; -7 import java.util.concurrent.TimeUnit; -8 import org.apache.commons.lang.StringUtils; -9 import org.rundeck.api.RundeckApiException.RundeckApiLoginException; -10 import org.rundeck.api.domain.RundeckExecution; -11 import org.rundeck.api.domain.RundeckJob; -12 import org.rundeck.api.domain.RundeckProject; -13 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; -14 import org.rundeck.api.parser.ExecutionParser; -15 import org.rundeck.api.parser.ExecutionsParser; -16 import org.rundeck.api.parser.JobParser; -17 import org.rundeck.api.parser.JobsParser; -18 import org.rundeck.api.parser.ProjectParser; -19 import org.rundeck.api.parser.ProjectsParser; -20 import org.rundeck.api.util.AssertUtil; -21 import org.rundeck.api.util.NodeFiltersBuilder; -22 import org.rundeck.api.util.OptionsBuilder; -23 import org.rundeck.api.util.ParametersUtil; -24 -25 /** -26 * Main entry point to talk to a RunDeck instance -27 * -28 * @author Vincent Behar -29 */ -30 public class RundeckClient implements Serializable { -31 -32 private static final long serialVersionUID = 1L; -33 -34 public static final transient int API_VERSION = 1; -35 -36 public static final transient String API_ENDPOINT = "/api/" + API_VERSION; -37 -38 private final String url; -39 -40 private final String login; -41 -42 private final String password; -43 -44 /** -45 * Instantiate a new {@link RundeckClient} for the RunDeck instance at the given url -46 * -47 * @param url of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc) -48 * @param login -49 * @param password -50 * @throws IllegalArgumentException if the url, login or password is blank (null, empty or whitespace) -51 */ -52 public RundeckClient(String url, String login, String password) throws IllegalArgumentException { -53 super(); -54 this.url = url; -55 this.login = login; -56 this.password = password; -57 AssertUtil.notBlank(url, "The RunDeck URL is mandatory !"); -58 AssertUtil.notBlank(login, "The RunDeck login is mandatory !"); -59 AssertUtil.notBlank(password, "The RunDeck password is mandatory !"); -60 } -61 -62 /** -63 * Try to "ping" the RunDeck instance to see if it is alive -64 * -65 * @throws RundeckApiException if the ping fails -66 */ -67 public void ping() throws RundeckApiException { -68 new ApiCall(this).ping(); -69 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api; +17 +18 import java.io.Serializable; +19 import java.util.ArrayList; +20 import java.util.List; +21 import java.util.Properties; +22 import java.util.concurrent.TimeUnit; +23 import org.apache.commons.lang.StringUtils; +24 import org.rundeck.api.RundeckApiException.RundeckApiLoginException; +25 import org.rundeck.api.domain.RundeckAbort; +26 import org.rundeck.api.domain.RundeckExecution; +27 import org.rundeck.api.domain.RundeckJob; +28 import org.rundeck.api.domain.RundeckNode; +29 import org.rundeck.api.domain.RundeckProject; +30 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; +31 import org.rundeck.api.parser.AbortParser; +32 import org.rundeck.api.parser.ExecutionParser; +33 import org.rundeck.api.parser.ExecutionsParser; +34 import org.rundeck.api.parser.JobParser; +35 import org.rundeck.api.parser.JobsParser; +36 import org.rundeck.api.parser.NodeParser; +37 import org.rundeck.api.parser.NodesParser; +38 import org.rundeck.api.parser.ProjectParser; +39 import org.rundeck.api.parser.ProjectsParser; +40 import org.rundeck.api.util.AssertUtil; +41 import org.rundeck.api.util.ParametersUtil; +42 +43 /** +44 * Main entry point to talk to a RunDeck instance.<br> +45 * Usage : <br> +46 * <code> +47 * <pre> +48 * RundeckClient rundeck = new RundeckClient("http://localhost:4440", "admin", "admin"); +49 * List<RundeckJob> jobs = rundeck.getJobs(); +50 * +51 * RundeckJob job = rundeck.findJob("my-project", "main-group/sub-group", "job-name"); +52 * RundeckExecution execution = rundeck.triggerJob(job.getId(), +53 * new OptionsBuilder().addOption("version", "1.2.0").toProperties()); +54 * +55 * List<RundeckExecution> runningExecutions = rundeck.getRunningExecutions("my-project"); +56 * </pre> +57 * </code> +58 * +59 * @author Vincent Behar +60 */ +61 public class RundeckClient implements Serializable { +62 +63 private static final long serialVersionUID = 1L; +64 +65 public static final transient int API_VERSION = 1; +66 +67 public static final transient String API_ENDPOINT = "/api/" + API_VERSION; +68 +69 private final String url; 70 -71 /** -72 * Test your credentials (login/password) on the RunDeck instance -73 * -74 * @throws RundeckApiLoginException if the login fails -75 */ -76 public void testCredentials() throws RundeckApiLoginException { -77 new ApiCall(this).testCredentials(); -78 } -79 -80 /* -81 * Projects -82 */ -83 -84 /** -85 * List all projects -86 * -87 * @return a {@link List} of {@link RundeckProject} : might be empty, but won't be null -88 * @throws RundeckApiException in case of error when calling the API -89 * @throws RundeckApiLoginException if the login failed -90 */ -91 public List<RundeckProject> getProjects() throws RundeckApiException, RundeckApiLoginException { -92 return new ApiCall(this).get("/projects", new ProjectsParser("result/projects/project")); -93 } -94 -95 /** -96 * Get the definition of a single project, identified by the given name -97 * -98 * @param projectName name of the project - mandatory -99 * @return a {@link RundeckProject} instance - won't be null -100 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -101 * @throws RundeckApiLoginException if the login failed -102 * @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace) -103 */ -104 public RundeckProject getProject(String projectName) throws RundeckApiException, RundeckApiLoginException, -105 IllegalArgumentException { -106 AssertUtil.notBlank(projectName, "projectName is mandatory to get the details of a project !"); -107 return new ApiCall(this).get("/project/" + projectName, new ProjectParser("result/projects/project")); -108 } -109 -110 /* -111 * Jobs -112 */ -113 -114 /** -115 * List all jobs (for all projects) -116 * -117 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null -118 * @throws RundeckApiException in case of error when calling the API -119 * @throws RundeckApiLoginException if the login failed -120 */ -121 public List<RundeckJob> getJobs() throws RundeckApiException, RundeckApiLoginException { -122 List<RundeckJob> jobs = new ArrayList<RundeckJob>(); -123 for (RundeckProject project : getProjects()) { -124 jobs.addAll(getJobs(project.getName())); -125 } -126 return jobs; -127 } -128 -129 /** -130 * List all jobs that belongs to the given project -131 * -132 * @param project name of the project - mandatory -133 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null -134 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -135 * @throws RundeckApiLoginException if the login failed -136 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) -137 * @see #getJobs(String, String, String, String...) -138 */ -139 public List<RundeckJob> getJobs(String project) throws RundeckApiException, RundeckApiLoginException, -140 IllegalArgumentException { -141 return getJobs(project, null, null, new String[0]); -142 } -143 -144 /** -145 * List the jobs that belongs to the given project, and matches the given criteria (jobFilter, groupPath and jobIds) -146 * -147 * @param project name of the project - mandatory -148 * @param jobFilter a filter for the job Name - optional -149 * @param groupPath a group or partial group path to include all jobs within that group path - optional -150 * @param jobIds a list of Job IDs to include - optional -151 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null -152 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -153 * @throws RundeckApiLoginException if the login failed -154 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) -155 * @see #getJobs(String) -156 */ -157 public List<RundeckJob> getJobs(String project, String jobFilter, String groupPath, String... jobIds) -158 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -159 AssertUtil.notBlank(project, "project is mandatory to get all jobs !"); -160 StringBuilder apiPath = new StringBuilder("/jobs"); -161 apiPath.append("?project=").append(project); -162 if (StringUtils.isNotBlank(jobFilter)) { -163 apiPath.append("&jobFilter=").append(jobFilter); -164 } -165 if (StringUtils.isNotBlank(groupPath)) { -166 apiPath.append("&groupPath=").append(groupPath); -167 } -168 if (jobIds != null && jobIds.length > 0) { -169 apiPath.append("&idlist=").append(StringUtils.join(jobIds, ",")); -170 } -171 return new ApiCall(this).get(apiPath.toString(), new JobsParser("result/jobs/job")); -172 } -173 -174 /** -175 * Find a job, identified by its project, group and name. Note that the groupPath is optional, as a job does not -176 * need to belong to a group (either pass null, or an empty string). -177 * -178 * @param project name of the project - mandatory -179 * @param groupPath group to which the job belongs (if it belongs to a group) - optional -180 * @param name of the job to find - mandatory -181 * @return a {@link RundeckJob} instance - null if not found -182 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -183 * @throws RundeckApiLoginException if the login failed -184 * @throws IllegalArgumentException if the project or the name is blank (null, empty or whitespace) -185 */ -186 public RundeckJob findJob(String project, String groupPath, String name) throws RundeckApiException, -187 RundeckApiLoginException, IllegalArgumentException { -188 AssertUtil.notBlank(project, "project is mandatory to find a job !"); -189 AssertUtil.notBlank(name, "job name is mandatory to find a job !"); -190 List<RundeckJob> jobs = getJobs(project, name, groupPath, new String[0]); -191 return jobs.isEmpty() ? null : jobs.get(0); -192 } -193 -194 /** -195 * Get the definition of a single job, identified by the given ID -196 * -197 * @param jobId identifier of the job - mandatory -198 * @return a {@link RundeckJob} instance - won't be null -199 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -200 * @throws RundeckApiLoginException if the login failed -201 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -202 */ -203 public RundeckJob getJob(String jobId) throws RundeckApiException, RundeckApiLoginException, -204 IllegalArgumentException { -205 AssertUtil.notBlank(jobId, "jobId is mandatory to get the details of a job !"); -206 return new ApiCall(this).get("/job/" + jobId, new JobParser("joblist/job")); -207 } -208 -209 /** -210 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the -211 * end of the job execution) -212 * -213 * @param jobId identifier of the job - mandatory -214 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null -215 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -216 * @throws RundeckApiLoginException if the login failed -217 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -218 * @see #triggerJob(String, Properties, Properties) -219 * @see #runJob(String) -220 */ -221 public RundeckExecution triggerJob(String jobId) throws RundeckApiException, RundeckApiLoginException, -222 IllegalArgumentException { -223 return triggerJob(jobId, null); -224 } -225 -226 /** -227 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the -228 * end of the job execution) -229 * -230 * @param jobId identifier of the job - mandatory -231 * @param options of the job - optional. See {@link OptionsBuilder}. -232 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null -233 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -234 * @throws RundeckApiLoginException if the login failed -235 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -236 * @see #triggerJob(String, Properties, Properties) -237 * @see #runJob(String, Properties) -238 */ -239 public RundeckExecution triggerJob(String jobId, Properties options) throws RundeckApiException, -240 RundeckApiLoginException, IllegalArgumentException { -241 return triggerJob(jobId, options, null); -242 } -243 -244 /** -245 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the -246 * end of the job execution) -247 * -248 * @param jobId identifier of the job - mandatory -249 * @param options of the job - optional. See {@link OptionsBuilder}. -250 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See -251 * {@link NodeFiltersBuilder} -252 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null -253 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -254 * @throws RundeckApiLoginException if the login failed -255 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -256 * @see #triggerJob(String) -257 * @see #runJob(String, Properties, Properties) -258 */ -259 public RundeckExecution triggerJob(String jobId, Properties options, Properties nodeFilters) -260 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -261 AssertUtil.notBlank(jobId, "jobId is mandatory to trigger a job !"); -262 StringBuilder apiPath = new StringBuilder("/job/").append(jobId).append("/run?"); -263 String argString = ParametersUtil.generateArgString(options); -264 if (StringUtils.isNotBlank(argString)) { -265 apiPath.append("argString=").append(ParametersUtil.urlEncode(argString)).append("&"); -266 } -267 String filters = ParametersUtil.generateNodeFiltersString(nodeFilters); -268 if (StringUtils.isNotBlank(filters)) { -269 apiPath.append(filters); -270 } -271 return new ApiCall(this).get(apiPath.toString(), new ExecutionParser("result/executions/execution")); -272 } -273 -274 /** -275 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. -276 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or -277 * aborted) or is still running. -278 * -279 * @param jobId identifier of the job - mandatory -280 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -281 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -282 * @throws RundeckApiLoginException if the login failed -283 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -284 * @see #triggerJob(String) -285 * @see #runJob(String, Properties, Properties, long, TimeUnit) -286 */ -287 public RundeckExecution runJob(String jobId) throws RundeckApiException, RundeckApiLoginException, -288 IllegalArgumentException { -289 return runJob(jobId, null); -290 } -291 -292 /** -293 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. -294 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or -295 * aborted) or is still running. -296 * -297 * @param jobId identifier of the job - mandatory -298 * @param options of the job - optional. See {@link OptionsBuilder}. +71 private final String login; +72 +73 private final String password; +74 +75 /** +76 * Instantiate a new {@link RundeckClient} for the RunDeck instance at the given url +77 * +78 * @param url of the RunDeck instance ("http://localhost:4440", "http://rundeck.your-compagny.com/", etc) +79 * @param login +80 * @param password +81 * @throws IllegalArgumentException if the url, login or password is blank (null, empty or whitespace) +82 */ +83 public RundeckClient(String url, String login, String password) throws IllegalArgumentException { +84 super(); +85 this.url = url; +86 this.login = login; +87 this.password = password; +88 AssertUtil.notBlank(url, "The RunDeck URL is mandatory !"); +89 AssertUtil.notBlank(login, "The RunDeck login is mandatory !"); +90 AssertUtil.notBlank(password, "The RunDeck password is mandatory !"); +91 } +92 +93 /** +94 * Try to "ping" the RunDeck instance to see if it is alive +95 * +96 * @throws RundeckApiException if the ping fails +97 */ +98 public void ping() throws RundeckApiException { +99 new ApiCall(this).ping(); +100 } +101 +102 /** +103 * Test your credentials (login/password) on the RunDeck instance +104 * +105 * @throws RundeckApiLoginException if the login fails +106 */ +107 public void testCredentials() throws RundeckApiLoginException { +108 new ApiCall(this).testCredentials(); +109 } +110 +111 /* +112 * Projects +113 */ +114 +115 /** +116 * List all projects +117 * +118 * @return a {@link List} of {@link RundeckProject} : might be empty, but won't be null +119 * @throws RundeckApiException in case of error when calling the API +120 * @throws RundeckApiLoginException if the login failed +121 */ +122 public List<RundeckProject> getProjects() throws RundeckApiException, RundeckApiLoginException { +123 return new ApiCall(this).get(new ApiPathBuilder("/projects"), new ProjectsParser("result/projects/project")); +124 } +125 +126 /** +127 * Get the definition of a single project, identified by the given name +128 * +129 * @param projectName name of the project - mandatory +130 * @return a {@link RundeckProject} instance - won't be null +131 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +132 * @throws RundeckApiLoginException if the login failed +133 * @throws IllegalArgumentException if the projectName is blank (null, empty or whitespace) +134 */ +135 public RundeckProject getProject(String projectName) throws RundeckApiException, RundeckApiLoginException, +136 IllegalArgumentException { +137 AssertUtil.notBlank(projectName, "projectName is mandatory to get the details of a project !"); +138 return new ApiCall(this).get(new ApiPathBuilder("/project/", projectName), +139 new ProjectParser("result/projects/project")); +140 } +141 +142 /* +143 * Jobs +144 */ +145 +146 /** +147 * List all jobs (for all projects) +148 * +149 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null +150 * @throws RundeckApiException in case of error when calling the API +151 * @throws RundeckApiLoginException if the login failed +152 */ +153 public List<RundeckJob> getJobs() throws RundeckApiException, RundeckApiLoginException { +154 List<RundeckJob> jobs = new ArrayList<RundeckJob>(); +155 for (RundeckProject project : getProjects()) { +156 jobs.addAll(getJobs(project.getName())); +157 } +158 return jobs; +159 } +160 +161 /** +162 * List all jobs that belongs to the given project +163 * +164 * @param project name of the project - mandatory +165 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null +166 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +167 * @throws RundeckApiLoginException if the login failed +168 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) +169 * @see #getJobs(String, String, String, String...) +170 */ +171 public List<RundeckJob> getJobs(String project) throws RundeckApiException, RundeckApiLoginException, +172 IllegalArgumentException { +173 return getJobs(project, null, null, new String[0]); +174 } +175 +176 /** +177 * List the jobs that belongs to the given project, and matches the given criteria (jobFilter, groupPath and jobIds) +178 * +179 * @param project name of the project - mandatory +180 * @param jobFilter a filter for the job Name - optional +181 * @param groupPath a group or partial group path to include all jobs within that group path - optional +182 * @param jobIds a list of Job IDs to include - optional +183 * @return a {@link List} of {@link RundeckJob} : might be empty, but won't be null +184 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +185 * @throws RundeckApiLoginException if the login failed +186 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) +187 * @see #getJobs(String) +188 */ +189 public List<RundeckJob> getJobs(String project, String jobFilter, String groupPath, String... jobIds) +190 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +191 AssertUtil.notBlank(project, "project is mandatory to get all jobs !"); +192 return new ApiCall(this).get(new ApiPathBuilder("/jobs").param("project", project) +193 .param("jobFilter", jobFilter) +194 .param("groupPath", groupPath) +195 .param("idlist", StringUtils.join(jobIds, ",")), +196 new JobsParser("result/jobs/job")); +197 } +198 +199 /** +200 * Find a job, identified by its project, group and name. Note that the groupPath is optional, as a job does not +201 * need to belong to a group (either pass null, or an empty string). +202 * +203 * @param project name of the project - mandatory +204 * @param groupPath group to which the job belongs (if it belongs to a group) - optional +205 * @param name of the job to find - mandatory +206 * @return a {@link RundeckJob} instance - null if not found +207 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +208 * @throws RundeckApiLoginException if the login failed +209 * @throws IllegalArgumentException if the project or the name is blank (null, empty or whitespace) +210 */ +211 public RundeckJob findJob(String project, String groupPath, String name) throws RundeckApiException, +212 RundeckApiLoginException, IllegalArgumentException { +213 AssertUtil.notBlank(project, "project is mandatory to find a job !"); +214 AssertUtil.notBlank(name, "job name is mandatory to find a job !"); +215 List<RundeckJob> jobs = getJobs(project, name, groupPath, new String[0]); +216 return jobs.isEmpty() ? null : jobs.get(0); +217 } +218 +219 /** +220 * Get the definition of a single job, identified by the given ID +221 * +222 * @param jobId identifier of the job - mandatory +223 * @return a {@link RundeckJob} instance - won't be null +224 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +225 * @throws RundeckApiLoginException if the login failed +226 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +227 */ +228 public RundeckJob getJob(String jobId) throws RundeckApiException, RundeckApiLoginException, +229 IllegalArgumentException { +230 AssertUtil.notBlank(jobId, "jobId is mandatory to get the details of a job !"); +231 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId), new JobParser("joblist/job")); +232 } +233 +234 /** +235 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the +236 * end of the job execution) +237 * +238 * @param jobId identifier of the job - mandatory +239 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null +240 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +241 * @throws RundeckApiLoginException if the login failed +242 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +243 * @see #triggerJob(String, Properties, Properties) +244 * @see #runJob(String) +245 */ +246 public RundeckExecution triggerJob(String jobId) throws RundeckApiException, RundeckApiLoginException, +247 IllegalArgumentException { +248 return triggerJob(jobId, null); +249 } +250 +251 /** +252 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the +253 * end of the job execution) +254 * +255 * @param jobId identifier of the job - mandatory +256 * @param options of the job - optional. See {@link OptionsBuilder}. +257 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null +258 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +259 * @throws RundeckApiLoginException if the login failed +260 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +261 * @see #triggerJob(String, Properties, Properties) +262 * @see #runJob(String, Properties) +263 */ +264 public RundeckExecution triggerJob(String jobId, Properties options) throws RundeckApiException, +265 RundeckApiLoginException, IllegalArgumentException { +266 return triggerJob(jobId, options, null); +267 } +268 +269 /** +270 * Trigger the execution of a RunDeck job (identified by the given ID), and return immediately (without waiting the +271 * end of the job execution) +272 * +273 * @param jobId identifier of the job - mandatory +274 * @param options of the job - optional. See {@link OptionsBuilder}. +275 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See +276 * {@link NodeFiltersBuilder} +277 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null +278 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +279 * @throws RundeckApiLoginException if the login failed +280 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +281 * @see #triggerJob(String) +282 * @see #runJob(String, Properties, Properties) +283 */ +284 public RundeckExecution triggerJob(String jobId, Properties options, Properties nodeFilters) +285 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +286 AssertUtil.notBlank(jobId, "jobId is mandatory to trigger a job !"); +287 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId, "/run").param("argString", +288 ParametersUtil.generateArgString(options)) +289 .nodeFilters(nodeFilters), +290 new ExecutionParser("result/executions/execution")); +291 } +292 +293 /** +294 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. +295 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or +296 * aborted) or is still running. +297 * +298 * @param jobId identifier of the job - mandatory 299 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null 300 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) 301 * @throws RundeckApiLoginException if the login failed 302 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -303 * @see #triggerJob(String, Properties) +303 * @see #triggerJob(String) 304 * @see #runJob(String, Properties, Properties, long, TimeUnit) 305 */ -306 public RundeckExecution runJob(String jobId, Properties options) throws RundeckApiException, -307 RundeckApiLoginException, IllegalArgumentException { -308 return runJob(jobId, options, null); +306 public RundeckExecution runJob(String jobId) throws RundeckApiException, RundeckApiLoginException, +307 IllegalArgumentException { +308 return runJob(jobId, null); 309 } 310 311 /** @@ -325,340 +325,492 @@ 315 * 316 * @param jobId identifier of the job - mandatory 317 * @param options of the job - optional. See {@link OptionsBuilder}. -318 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See -319 * {@link NodeFiltersBuilder} -320 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -321 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -322 * @throws RundeckApiLoginException if the login failed -323 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -324 * @see #triggerJob(String, Properties, Properties) -325 * @see #runJob(String, Properties, Properties, long, TimeUnit) -326 */ -327 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters) -328 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -329 return runJob(jobId, options, nodeFilters, 5, TimeUnit.SECONDS); -330 } -331 -332 /** -333 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. -334 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to -335 * know if the execution is finished (or aborted) or is still running. -336 * -337 * @param jobId identifier of the job - mandatory -338 * @param options of the job - optional. See {@link OptionsBuilder}. -339 * @param poolingInterval for checking the status of the execution. Must be > 0. -340 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. -341 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -342 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -343 * @throws RundeckApiLoginException if the login failed -344 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -345 * @see #triggerJob(String, Properties) -346 * @see #runJob(String, Properties, Properties, long, TimeUnit) -347 */ -348 public RundeckExecution runJob(String jobId, Properties options, long poolingInterval, TimeUnit poolingUnit) -349 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -350 return runJob(jobId, options, null, poolingInterval, poolingUnit); -351 } -352 -353 /** -354 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. -355 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to -356 * know if the execution is finished (or aborted) or is still running. -357 * -358 * @param jobId identifier of the job - mandatory -359 * @param options of the job - optional. See {@link OptionsBuilder}. -360 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See -361 * {@link NodeFiltersBuilder} -362 * @param poolingInterval for checking the status of the execution. Must be > 0. -363 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. -364 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -365 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -366 * @throws RundeckApiLoginException if the login failed -367 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -368 * @see #triggerJob(String, Properties) -369 * @see #runJob(String, Properties, Properties, long, TimeUnit) -370 */ -371 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters, long poolingInterval, -372 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -373 if (poolingInterval <= 0) { -374 poolingInterval = 5; -375 poolingUnit = TimeUnit.SECONDS; -376 } -377 if (poolingUnit == null) { -378 poolingUnit = TimeUnit.SECONDS; -379 } -380 -381 RundeckExecution execution = triggerJob(jobId, options, nodeFilters); -382 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { -383 try { -384 Thread.sleep(poolingUnit.toMillis(poolingInterval)); -385 } catch (InterruptedException e) { -386 break; -387 } -388 execution = getExecution(execution.getId()); -389 } -390 return execution; -391 } -392 -393 /* -394 * Ad-hoc commands -395 */ -396 -397 /** -398 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). -399 * The command will not be dispatched to nodes, but be executed on the RunDeck server. -400 * -401 * @param project name of the project - mandatory -402 * @param command to be executed - mandatory -403 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null -404 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -405 * @throws RundeckApiLoginException if the login failed -406 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -407 * @see #triggerAdhocCommand(String, String, Properties) -408 * @see #runAdhocCommand(String, String) -409 */ -410 public RundeckExecution triggerAdhocCommand(String project, String command) throws RundeckApiException, -411 RundeckApiLoginException, IllegalArgumentException { -412 return triggerAdhocCommand(project, command, null); -413 } -414 -415 /** -416 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). -417 * The command will be dispatched to nodes, accordingly to the nodeFilters parameter. -418 * -419 * @param project name of the project - mandatory -420 * @param command to be executed - mandatory -421 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} +318 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +319 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +320 * @throws RundeckApiLoginException if the login failed +321 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +322 * @see #triggerJob(String, Properties) +323 * @see #runJob(String, Properties, Properties, long, TimeUnit) +324 */ +325 public RundeckExecution runJob(String jobId, Properties options) throws RundeckApiException, +326 RundeckApiLoginException, IllegalArgumentException { +327 return runJob(jobId, options, null); +328 } +329 +330 /** +331 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. +332 * We will poll the RunDeck server at regular interval (every 5 seconds) to know if the execution is finished (or +333 * aborted) or is still running. +334 * +335 * @param jobId identifier of the job - mandatory +336 * @param options of the job - optional. See {@link OptionsBuilder}. +337 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See +338 * {@link NodeFiltersBuilder} +339 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +340 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +341 * @throws RundeckApiLoginException if the login failed +342 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +343 * @see #triggerJob(String, Properties, Properties) +344 * @see #runJob(String, Properties, Properties, long, TimeUnit) +345 */ +346 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters) +347 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +348 return runJob(jobId, options, nodeFilters, 5, TimeUnit.SECONDS); +349 } +350 +351 /** +352 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. +353 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to +354 * know if the execution is finished (or aborted) or is still running. +355 * +356 * @param jobId identifier of the job - mandatory +357 * @param options of the job - optional. See {@link OptionsBuilder}. +358 * @param poolingInterval for checking the status of the execution. Must be > 0. +359 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. +360 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +361 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +362 * @throws RundeckApiLoginException if the login failed +363 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +364 * @see #triggerJob(String, Properties) +365 * @see #runJob(String, Properties, Properties, long, TimeUnit) +366 */ +367 public RundeckExecution runJob(String jobId, Properties options, long poolingInterval, TimeUnit poolingUnit) +368 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +369 return runJob(jobId, options, null, poolingInterval, poolingUnit); +370 } +371 +372 /** +373 * Run a RunDeck job (identified by the given ID), and wait until its execution is finished (or aborted) to return. +374 * We will poll the RunDeck server at regular interval (configured by the poolingInterval/poolingUnit couple) to +375 * know if the execution is finished (or aborted) or is still running. +376 * +377 * @param jobId identifier of the job - mandatory +378 * @param options of the job - optional. See {@link OptionsBuilder}. +379 * @param nodeFilters for overriding the nodes on which the job will be executed - optional. See +380 * {@link NodeFiltersBuilder} +381 * @param poolingInterval for checking the status of the execution. Must be > 0. +382 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. +383 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +384 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +385 * @throws RundeckApiLoginException if the login failed +386 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +387 * @see #triggerJob(String, Properties) +388 * @see #runJob(String, Properties, Properties, long, TimeUnit) +389 */ +390 public RundeckExecution runJob(String jobId, Properties options, Properties nodeFilters, long poolingInterval, +391 TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +392 if (poolingInterval <= 0) { +393 poolingInterval = 5; +394 poolingUnit = TimeUnit.SECONDS; +395 } +396 if (poolingUnit == null) { +397 poolingUnit = TimeUnit.SECONDS; +398 } +399 +400 RundeckExecution execution = triggerJob(jobId, options, nodeFilters); +401 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { +402 try { +403 Thread.sleep(poolingUnit.toMillis(poolingInterval)); +404 } catch (InterruptedException e) { +405 break; +406 } +407 execution = getExecution(execution.getId()); +408 } +409 return execution; +410 } +411 +412 /* +413 * Ad-hoc commands +414 */ +415 +416 /** +417 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). +418 * The command will not be dispatched to nodes, but be executed on the RunDeck server. +419 * +420 * @param project name of the project - mandatory +421 * @param command to be executed - mandatory 422 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null 423 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) 424 * @throws RundeckApiLoginException if the login failed 425 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -426 * @see #triggerAdhocCommand(String, String) -427 * @see #runAdhocCommand(String, String, Properties) +426 * @see #triggerAdhocCommand(String, String, Properties) +427 * @see #runAdhocCommand(String, String) 428 */ -429 public RundeckExecution triggerAdhocCommand(String project, String command, Properties nodeFilters) -430 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -431 AssertUtil.notBlank(project, "project is mandatory to trigger an ad-hoc command !"); -432 AssertUtil.notBlank(command, "command is mandatory to trigger an ad-hoc command !"); -433 StringBuilder apiPath = new StringBuilder("/run/command"); -434 apiPath.append("?project=").append(project); -435 apiPath.append("&exec=").append(ParametersUtil.urlEncode(command)); -436 String filters = ParametersUtil.generateNodeFiltersString(nodeFilters); -437 if (StringUtils.isNotBlank(filters)) { -438 apiPath.append("&").append(filters); -439 } -440 RundeckExecution execution = new ApiCall(this).get(apiPath.toString(), new ExecutionParser("result/execution")); -441 // the first call just returns the ID of the execution, so we need another call to get a "real" execution -442 return getExecution(execution.getId()); -443 } -444 -445 /** -446 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck -447 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still -448 * running. The command will not be dispatched to nodes, but be executed on the RunDeck server. -449 * -450 * @param project name of the project - mandatory -451 * @param command to be executed - mandatory -452 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -453 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -454 * @throws RundeckApiLoginException if the login failed -455 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -456 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) -457 * @see #triggerAdhocCommand(String, String) -458 */ -459 public RundeckExecution runAdhocCommand(String project, String command) throws RundeckApiException, -460 RundeckApiLoginException, IllegalArgumentException { -461 return runAdhocCommand(project, command, null); -462 } -463 -464 /** -465 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck -466 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is -467 * finished (or aborted) or is still running. The command will not be dispatched to nodes, but be executed on the -468 * RunDeck server. -469 * -470 * @param project name of the project - mandatory -471 * @param command to be executed - mandatory -472 * @param poolingInterval for checking the status of the execution. Must be > 0. -473 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. -474 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -475 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -476 * @throws RundeckApiLoginException if the login failed -477 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -478 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) -479 * @see #triggerAdhocCommand(String, String) -480 */ -481 public RundeckExecution runAdhocCommand(String project, String command, long poolingInterval, TimeUnit poolingUnit) -482 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -483 return runAdhocCommand(project, command, null, poolingInterval, poolingUnit); -484 } -485 -486 /** -487 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck -488 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still -489 * running. The command will be dispatched to nodes, accordingly to the nodeFilters parameter. -490 * -491 * @param project name of the project - mandatory -492 * @param command to be executed - mandatory -493 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} -494 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -495 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -496 * @throws RundeckApiLoginException if the login failed -497 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -498 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) -499 * @see #triggerAdhocCommand(String, String, Properties) -500 */ -501 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters) -502 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { -503 return runAdhocCommand(project, command, nodeFilters, 5, TimeUnit.SECONDS); -504 } -505 -506 /** -507 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck -508 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is -509 * finished (or aborted) or is still running. The command will be dispatched to nodes, accordingly to the -510 * nodeFilters parameter. -511 * -512 * @param project name of the project - mandatory -513 * @param command to be executed - mandatory -514 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} -515 * @param poolingInterval for checking the status of the execution. Must be > 0. -516 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. -517 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null -518 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -519 * @throws RundeckApiLoginException if the login failed -520 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) -521 * @see #triggerAdhocCommand(String, String, Properties) -522 */ -523 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters, -524 long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, -525 IllegalArgumentException { -526 if (poolingInterval <= 0) { -527 poolingInterval = 5; -528 poolingUnit = TimeUnit.SECONDS; -529 } -530 if (poolingUnit == null) { -531 poolingUnit = TimeUnit.SECONDS; -532 } -533 -534 RundeckExecution execution = triggerAdhocCommand(project, command, nodeFilters); -535 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { -536 try { -537 Thread.sleep(poolingUnit.toMillis(poolingInterval)); -538 } catch (InterruptedException e) { -539 break; -540 } -541 execution = getExecution(execution.getId()); -542 } -543 return execution; -544 } -545 -546 /* -547 * Executions -548 */ -549 -550 /** -551 * Get the running executions for the given project -552 * -553 * @param project name of the project - mandatory -554 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null -555 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) -556 * @throws RundeckApiLoginException if the login failed -557 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) -558 */ -559 public List<RundeckExecution> getRunningExecutions(String project) throws RundeckApiException, -560 RundeckApiLoginException, IllegalArgumentException { -561 AssertUtil.notBlank(project, "project is mandatory to trigger an ad-hoc command !"); -562 return new ApiCall(this).get("/executions/running?project=" + project, -563 new ExecutionsParser("result/executions/execution")); -564 } -565 -566 /** -567 * Get the executions of the given job -568 * -569 * @param jobId identifier of the job - mandatory -570 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null -571 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) -572 * @throws RundeckApiLoginException if the login failed -573 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) -574 */ -575 public List<RundeckExecution> getJobExecutions(String jobId) throws RundeckApiException, RundeckApiLoginException, -576 IllegalArgumentException { -577 AssertUtil.notBlank(jobId, "jobId is mandatory to get the executions of a job !"); -578 return new ApiCall(this).get("/job/" + jobId + "/executions", -579 new ExecutionsParser("result/executions/execution")); -580 } -581 -582 /** -583 * Get a single execution, identified by the given ID -584 * -585 * @param executionId identifier of the execution - mandatory -586 * @return a {@link RundeckExecution} instance - won't be null -587 * @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID) -588 * @throws RundeckApiLoginException if the login failed -589 * @throws IllegalArgumentException if the executionId is null -590 */ -591 public RundeckExecution getExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, -592 IllegalArgumentException { -593 AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !"); -594 return new ApiCall(this).get("/execution/" + executionId, new ExecutionParser("result/executions/execution")); -595 } -596 -597 public String getUrl() { -598 return url; -599 } -600 -601 public String getLogin() { -602 return login; -603 } -604 -605 public String getPassword() { -606 return password; -607 } -608 -609 @Override -610 public String toString() { -611 return "RundeckClient [url=" + url + ", login=" + login + ", password=" + password + "]"; -612 } -613 -614 @Override -615 public int hashCode() { -616 final int prime = 31; -617 int result = 1; -618 result = prime * result + ((login == null) ? 0 : login.hashCode()); -619 result = prime * result + ((password == null) ? 0 : password.hashCode()); -620 result = prime * result + ((url == null) ? 0 : url.hashCode()); -621 return result; -622 } -623 -624 @Override -625 public boolean equals(Object obj) { -626 if (this == obj) -627 return true; -628 if (obj == null) -629 return false; -630 if (getClass() != obj.getClass()) -631 return false; -632 RundeckClient other = (RundeckClient) obj; -633 if (login == null) { -634 if (other.login != null) -635 return false; -636 } else if (!login.equals(other.login)) -637 return false; -638 if (password == null) { -639 if (other.password != null) -640 return false; -641 } else if (!password.equals(other.password)) -642 return false; -643 if (url == null) { -644 if (other.url != null) -645 return false; -646 } else if (!url.equals(other.url)) -647 return false; -648 return true; -649 } -650 -651 } +429 public RundeckExecution triggerAdhocCommand(String project, String command) throws RundeckApiException, +430 RundeckApiLoginException, IllegalArgumentException { +431 return triggerAdhocCommand(project, command, null); +432 } +433 +434 /** +435 * Trigger the execution of an ad-hoc command, and return immediately (without waiting the end of the execution). +436 * The command will be dispatched to nodes, accordingly to the nodeFilters parameter. +437 * +438 * @param project name of the project - mandatory +439 * @param command to be executed - mandatory +440 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} +441 * @return a {@link RundeckExecution} instance for the newly created (and running) execution - won't be null +442 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +443 * @throws RundeckApiLoginException if the login failed +444 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) +445 * @see #triggerAdhocCommand(String, String) +446 * @see #runAdhocCommand(String, String, Properties) +447 */ +448 public RundeckExecution triggerAdhocCommand(String project, String command, Properties nodeFilters) +449 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +450 AssertUtil.notBlank(project, "project is mandatory to trigger an ad-hoc command !"); +451 AssertUtil.notBlank(command, "command is mandatory to trigger an ad-hoc command !"); +452 RundeckExecution execution = new ApiCall(this).get(new ApiPathBuilder("/run/command").param("project", project) +453 .param("exec", command) +454 .nodeFilters(nodeFilters), +455 new ExecutionParser("result/execution")); +456 // the first call just returns the ID of the execution, so we need another call to get a "real" execution +457 return getExecution(execution.getId()); +458 } +459 +460 /** +461 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck +462 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still +463 * running. The command will not be dispatched to nodes, but be executed on the RunDeck server. +464 * +465 * @param project name of the project - mandatory +466 * @param command to be executed - mandatory +467 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +468 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +469 * @throws RundeckApiLoginException if the login failed +470 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) +471 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) +472 * @see #triggerAdhocCommand(String, String) +473 */ +474 public RundeckExecution runAdhocCommand(String project, String command) throws RundeckApiException, +475 RundeckApiLoginException, IllegalArgumentException { +476 return runAdhocCommand(project, command, null); +477 } +478 +479 /** +480 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck +481 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is +482 * finished (or aborted) or is still running. The command will not be dispatched to nodes, but be executed on the +483 * RunDeck server. +484 * +485 * @param project name of the project - mandatory +486 * @param command to be executed - mandatory +487 * @param poolingInterval for checking the status of the execution. Must be > 0. +488 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. +489 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +490 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +491 * @throws RundeckApiLoginException if the login failed +492 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) +493 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) +494 * @see #triggerAdhocCommand(String, String) +495 */ +496 public RundeckExecution runAdhocCommand(String project, String command, long poolingInterval, TimeUnit poolingUnit) +497 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +498 return runAdhocCommand(project, command, null, poolingInterval, poolingUnit); +499 } +500 +501 /** +502 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck +503 * server at regular interval (every 5 seconds) to know if the execution is finished (or aborted) or is still +504 * running. The command will be dispatched to nodes, accordingly to the nodeFilters parameter. +505 * +506 * @param project name of the project - mandatory +507 * @param command to be executed - mandatory +508 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} +509 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +510 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +511 * @throws RundeckApiLoginException if the login failed +512 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) +513 * @see #runAdhocCommand(String, String, Properties, long, TimeUnit) +514 * @see #triggerAdhocCommand(String, String, Properties) +515 */ +516 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters) +517 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +518 return runAdhocCommand(project, command, nodeFilters, 5, TimeUnit.SECONDS); +519 } +520 +521 /** +522 * Run an ad-hoc command, and wait until its execution is finished (or aborted) to return. We will poll the RunDeck +523 * server at regular interval (configured by the poolingInterval/poolingUnit couple) to know if the execution is +524 * finished (or aborted) or is still running. The command will be dispatched to nodes, accordingly to the +525 * nodeFilters parameter. +526 * +527 * @param project name of the project - mandatory +528 * @param command to be executed - mandatory +529 * @param nodeFilters for selecting nodes on which the command will be executed. See {@link NodeFiltersBuilder} +530 * @param poolingInterval for checking the status of the execution. Must be > 0. +531 * @param poolingUnit unit (seconds, milli-seconds, ...) of the interval. Default to seconds. +532 * @return a {@link RundeckExecution} instance for the (finished/aborted) execution - won't be null +533 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +534 * @throws RundeckApiLoginException if the login failed +535 * @throws IllegalArgumentException if the project or command is blank (null, empty or whitespace) +536 * @see #triggerAdhocCommand(String, String, Properties) +537 */ +538 public RundeckExecution runAdhocCommand(String project, String command, Properties nodeFilters, +539 long poolingInterval, TimeUnit poolingUnit) throws RundeckApiException, RundeckApiLoginException, +540 IllegalArgumentException { +541 if (poolingInterval <= 0) { +542 poolingInterval = 5; +543 poolingUnit = TimeUnit.SECONDS; +544 } +545 if (poolingUnit == null) { +546 poolingUnit = TimeUnit.SECONDS; +547 } +548 +549 RundeckExecution execution = triggerAdhocCommand(project, command, nodeFilters); +550 while (ExecutionStatus.RUNNING.equals(execution.getStatus())) { +551 try { +552 Thread.sleep(poolingUnit.toMillis(poolingInterval)); +553 } catch (InterruptedException e) { +554 break; +555 } +556 execution = getExecution(execution.getId()); +557 } +558 return execution; +559 } +560 +561 /* +562 * Executions +563 */ +564 +565 /** +566 * Get all running executions (for all projects) +567 * +568 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null +569 * @throws RundeckApiException in case of error when calling the API +570 * @throws RundeckApiLoginException if the login failed +571 */ +572 public List<RundeckExecution> getRunningExecutions() throws RundeckApiException, RundeckApiLoginException { +573 List<RundeckExecution> executions = new ArrayList<RundeckExecution>(); +574 for (RundeckProject project : getProjects()) { +575 executions.addAll(getRunningExecutions(project.getName())); +576 } +577 return executions; +578 } +579 +580 /** +581 * Get the running executions for the given project +582 * +583 * @param project name of the project - mandatory +584 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null +585 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +586 * @throws RundeckApiLoginException if the login failed +587 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) +588 */ +589 public List<RundeckExecution> getRunningExecutions(String project) throws RundeckApiException, +590 RundeckApiLoginException, IllegalArgumentException { +591 AssertUtil.notBlank(project, "project is mandatory get all running executions !"); +592 return new ApiCall(this).get(new ApiPathBuilder("/executions/running").param("project", project), +593 new ExecutionsParser("result/executions/execution")); +594 } +595 +596 /** +597 * Get the executions of the given job +598 * +599 * @param jobId identifier of the job - mandatory +600 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null +601 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +602 * @throws RundeckApiLoginException if the login failed +603 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +604 */ +605 public List<RundeckExecution> getJobExecutions(String jobId) throws RundeckApiException, RundeckApiLoginException, +606 IllegalArgumentException { +607 return getJobExecutions(jobId, null); +608 } +609 +610 /** +611 * Get the executions of the given job +612 * +613 * @param jobId identifier of the job - mandatory +614 * @param status of the executions - optional (null for all) +615 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null +616 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +617 * @throws RundeckApiLoginException if the login failed +618 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +619 */ +620 public List<RundeckExecution> getJobExecutions(String jobId, ExecutionStatus status) throws RundeckApiException, +621 RundeckApiLoginException, IllegalArgumentException { +622 return getJobExecutions(jobId, status, null, null); +623 } +624 +625 /** +626 * Get the executions of the given job +627 * +628 * @param jobId identifier of the job - mandatory +629 * @param status of the executions - optional (null for all) +630 * @param max number of results to return - optional (null for all) +631 * @param offset the 0-indexed offset for the first result to return - optional +632 * @return a {@link List} of {@link RundeckExecution} : might be empty, but won't be null +633 * @throws RundeckApiException in case of error when calling the API (non-existent job with this ID) +634 * @throws RundeckApiLoginException if the login failed +635 * @throws IllegalArgumentException if the jobId is blank (null, empty or whitespace) +636 */ +637 public List<RundeckExecution> getJobExecutions(String jobId, ExecutionStatus status, Long max, Long offset) +638 throws RundeckApiException, RundeckApiLoginException, IllegalArgumentException { +639 AssertUtil.notBlank(jobId, "jobId is mandatory to get the executions of a job !"); +640 return new ApiCall(this).get(new ApiPathBuilder("/job/", jobId, "/executions").param("status", +641 status != null ? StringUtils.lowerCase(status.toString()) : null) +642 .param("max", max) +643 .param("offset", offset), +644 new ExecutionsParser("result/executions/execution")); +645 } +646 +647 /** +648 * Get a single execution, identified by the given ID +649 * +650 * @param executionId identifier of the execution - mandatory +651 * @return a {@link RundeckExecution} instance - won't be null +652 * @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID) +653 * @throws RundeckApiLoginException if the login failed +654 * @throws IllegalArgumentException if the executionId is null +655 */ +656 public RundeckExecution getExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, +657 IllegalArgumentException { +658 AssertUtil.notNull(executionId, "executionId is mandatory to get the details of an execution !"); +659 return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString()), +660 new ExecutionParser("result/executions/execution")); +661 } +662 +663 /** +664 * Abort an execution (identified by the given ID). The execution should be running... +665 * +666 * @param executionId identifier of the execution - mandatory +667 * @return a {@link RundeckAbort} instance - won't be null +668 * @throws RundeckApiException in case of error when calling the API (non-existent execution with this ID) +669 * @throws RundeckApiLoginException if the login failed +670 * @throws IllegalArgumentException if the executionId is null +671 */ +672 public RundeckAbort abortExecution(Long executionId) throws RundeckApiException, RundeckApiLoginException, +673 IllegalArgumentException { +674 AssertUtil.notNull(executionId, "executionId is mandatory to abort an execution !"); +675 return new ApiCall(this).get(new ApiPathBuilder("/execution/", executionId.toString(), "/abort"), +676 new AbortParser("result/abort")); +677 } +678 +679 /* +680 * Nodes +681 */ +682 +683 /** +684 * List all nodes (for all projects) +685 * +686 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null +687 * @throws RundeckApiException in case of error when calling the API +688 * @throws RundeckApiLoginException if the login failed +689 */ +690 public List<RundeckNode> getNodes() throws RundeckApiException, RundeckApiLoginException { +691 List<RundeckNode> nodes = new ArrayList<RundeckNode>(); +692 for (RundeckProject project : getProjects()) { +693 nodes.addAll(getNodes(project.getName())); +694 } +695 return nodes; +696 } +697 +698 /** +699 * List all nodes that belongs to the given project +700 * +701 * @param project name of the project - mandatory +702 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null +703 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +704 * @throws RundeckApiLoginException if the login failed +705 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) +706 * @see #getNodes(String, Properties) +707 */ +708 public List<RundeckNode> getNodes(String project) throws RundeckApiException, RundeckApiLoginException, +709 IllegalArgumentException { +710 return getNodes(project, null); +711 } +712 +713 /** +714 * List nodes that belongs to the given project +715 * +716 * @param project name of the project - mandatory +717 * @param nodeFilters for filtering the nodes - optional. See {@link NodeFiltersBuilder} +718 * @return a {@link List} of {@link RundeckNode} : might be empty, but won't be null +719 * @throws RundeckApiException in case of error when calling the API (non-existent project with this name) +720 * @throws RundeckApiLoginException if the login failed +721 * @throws IllegalArgumentException if the project is blank (null, empty or whitespace) +722 */ +723 public List<RundeckNode> getNodes(String project, Properties nodeFilters) throws RundeckApiException, +724 RundeckApiLoginException, IllegalArgumentException { +725 AssertUtil.notBlank(project, "project is mandatory to get all nodes !"); +726 return new ApiCall(this).get(new ApiPathBuilder("/resources").param("project", project) +727 .nodeFilters(nodeFilters), +728 new NodesParser("project/node")); +729 } +730 +731 /** +732 * Get the definition of a single node +733 * +734 * @param name of the node - mandatory +735 * @param project name of the project - mandatory +736 * @return a {@link RundeckNode} instance - won't be null +737 * @throws RundeckApiException in case of error when calling the API (non-existent name or project with this name) +738 * @throws RundeckApiLoginException if the login failed +739 * @throws IllegalArgumentException if the name or project is blank (null, empty or whitespace) +740 */ +741 public RundeckNode getNode(String name, String project) throws RundeckApiException, RundeckApiLoginException, +742 IllegalArgumentException { +743 AssertUtil.notBlank(name, "the name of the node is mandatory to get a node !"); +744 AssertUtil.notBlank(project, "project is mandatory to get a node !"); +745 return new ApiCall(this).get(new ApiPathBuilder("/resource/", name).param("project", project), +746 new NodeParser("project/node")); +747 } +748 +749 public String getUrl() { +750 return url; +751 } +752 +753 public String getLogin() { +754 return login; +755 } +756 +757 public String getPassword() { +758 return password; +759 } +760 +761 @Override +762 public String toString() { +763 return "RundeckClient [url=" + url + ", login=" + login + ", password=" + password + "]"; +764 } +765 +766 @Override +767 public int hashCode() { +768 final int prime = 31; +769 int result = 1; +770 result = prime * result + ((login == null) ? 0 : login.hashCode()); +771 result = prime * result + ((password == null) ? 0 : password.hashCode()); +772 result = prime * result + ((url == null) ? 0 : url.hashCode()); +773 return result; +774 } +775 +776 @Override +777 public boolean equals(Object obj) { +778 if (this == obj) +779 return true; +780 if (obj == null) +781 return false; +782 if (getClass() != obj.getClass()) +783 return false; +784 RundeckClient other = (RundeckClient) obj; +785 if (login == null) { +786 if (other.login != null) +787 return false; +788 } else if (!login.equals(other.login)) +789 return false; +790 if (password == null) { +791 if (other.password != null) +792 return false; +793 } else if (!password.equals(other.password)) +794 return false; +795 if (url == null) { +796 if (other.url != null) +797 return false; +798 } else if (!url.equals(other.url)) +799 return false; +800 return true; +801 } +802 +803 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.domain; +17 +18 import java.io.Serializable; +19 +20 /** +21 * Represents an abort of a {@link RundeckExecution} +22 * +23 * @author Vincent Behar +24 */ +25 public class RundeckAbort implements Serializable { +26 +27 private static final long serialVersionUID = 1L; +28 +29 private AbortStatus status; +30 +31 private RundeckExecution execution; +32 +33 public AbortStatus getStatus() { +34 return status; +35 } +36 +37 public void setStatus(AbortStatus status) { +38 this.status = status; +39 } +40 +41 public RundeckExecution getExecution() { +42 return execution; +43 } +44 +45 public void setExecution(RundeckExecution execution) { +46 this.execution = execution; +47 } +48 +49 @Override +50 public String toString() { +51 return "RundeckAbort [status=" + status + ", execution=" + execution + "]"; +52 } +53 +54 @Override +55 public int hashCode() { +56 final int prime = 31; +57 int result = 1; +58 result = prime * result + ((execution == null) ? 0 : execution.hashCode()); +59 result = prime * result + ((status == null) ? 0 : status.hashCode()); +60 return result; +61 } +62 +63 @Override +64 public boolean equals(Object obj) { +65 if (this == obj) +66 return true; +67 if (obj == null) +68 return false; +69 if (getClass() != obj.getClass()) +70 return false; +71 RundeckAbort other = (RundeckAbort) obj; +72 if (execution == null) { +73 if (other.execution != null) +74 return false; +75 } else if (!execution.equals(other.execution)) +76 return false; +77 if (status == null) { +78 if (other.status != null) +79 return false; +80 } else if (!status.equals(other.status)) +81 return false; +82 return true; +83 } +84 +85 /** +86 * The status of an abort +87 */ +88 public static enum AbortStatus { +89 PENDING, FAILED, ABORTED; +90 } +91 +92 } ++
-1 package org.rundeck.api.domain; -2 -3 import java.io.Serializable; -4 import java.util.Date; -5 import java.util.concurrent.TimeUnit; -6 -7 /** -8 * Represents a RunDeck execution, usually triggered by an API call. An execution could be a {@link RundeckJob} -9 * execution or an "ad-hoc" execution. -10 * -11 * @author Vincent Behar -12 */ -13 public class RundeckExecution implements Serializable { -14 -15 private static final long serialVersionUID = 1L; -16 -17 private Long id; -18 -19 private String url; -20 -21 private ExecutionStatus status; -22 -23 /** Optional - only if it is a job execution */ -24 private RundeckJob job; -25 -26 private String startedBy; -27 -28 private Date startedAt; +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.domain; +17 +18 import java.io.Serializable; +19 import java.util.Date; +20 import java.util.concurrent.TimeUnit; +21 +22 /** +23 * Represents a RunDeck execution, usually triggered by an API call. An execution could be a {@link RundeckJob} +24 * execution or an "ad-hoc" execution. +25 * +26 * @author Vincent Behar +27 */ +28 public class RundeckExecution implements Serializable { 29 -30 /** only if the execution has ended */ -31 private Date endedAt; -32 -33 /** only if the execution was aborted */ -34 private String abortedBy; +30 private static final long serialVersionUID = 1L; +31 +32 private Long id; +33 +34 private String url; 35 -36 private String description; +36 private ExecutionStatus status; 37 -38 /** -39 * @return the duration of the execution in milliseconds (or null if the duration is still running, or has been -40 * aborted) -41 */ -42 public Long getDurationInMillis() { -43 if (startedAt == null || endedAt == null) { -44 return null; -45 } -46 return endedAt.getTime() - startedAt.getTime(); -47 } -48 -49 /** -50 * @return the duration of the execution in seconds (or null if the duration is still running, or has been aborted) -51 */ -52 public Long getDurationInSeconds() { -53 Long durationInMillis = getDurationInMillis(); -54 if (durationInMillis == null) { -55 return null; -56 } -57 return TimeUnit.MILLISECONDS.toSeconds(durationInMillis); -58 } -59 -60 public Long getId() { -61 return id; +38 /** Optional - only if it is a job execution */ +39 private RundeckJob job; +40 +41 private String startedBy; +42 +43 private Date startedAt; +44 +45 /** only if the execution has ended */ +46 private Date endedAt; +47 +48 /** only if the execution was aborted */ +49 private String abortedBy; +50 +51 private String description; +52 +53 /** +54 * @return the duration of the execution in milliseconds (or null if the duration is still running, or has been +55 * aborted) +56 */ +57 public Long getDurationInMillis() { +58 if (startedAt == null || endedAt == null) { +59 return null; +60 } +61 return endedAt.getTime() - startedAt.getTime(); 62 } 63 -64 public void setId(Long id) { -65 this.id = id; -66 } -67 -68 public String getUrl() { -69 return url; -70 } -71 -72 public void setUrl(String url) { -73 this.url = url; -74 } -75 -76 /** -77 * @return the status of the execution - see {@link ExecutionStatus} -78 */ -79 public ExecutionStatus getStatus() { -80 return status; +64 /** +65 * @return the duration of the execution in seconds (or null if the duration is still running, or has been aborted) +66 */ +67 public Long getDurationInSeconds() { +68 Long durationInMillis = getDurationInMillis(); +69 if (durationInMillis == null) { +70 return null; +71 } +72 return TimeUnit.MILLISECONDS.toSeconds(durationInMillis); +73 } +74 +75 public Long getId() { +76 return id; +77 } +78 +79 public void setId(Long id) { +80 this.id = id; 81 } 82 -83 public void setStatus(ExecutionStatus status) { -84 this.status = status; +83 public String getUrl() { +84 return url; 85 } 86 -87 /** -88 * @return the {@link RundeckJob} associated with this execution, or null in the case of an ad-hoc execution -89 * (command or script) -90 */ -91 public RundeckJob getJob() { -92 return job; -93 } -94 -95 public void setJob(RundeckJob job) { -96 this.job = job; -97 } -98 -99 public String getStartedBy() { -100 return startedBy; -101 } -102 -103 public void setStartedBy(String startedBy) { -104 this.startedBy = startedBy; -105 } -106 -107 public Date getStartedAt() { -108 return (startedAt != null) ? new Date(startedAt.getTime()) : null; -109 } -110 -111 public void setStartedAt(Date startedAt) { -112 this.startedAt = ((startedAt != null) ? new Date(startedAt.getTime()) : null); -113 } -114 -115 public Date getEndedAt() { -116 return (endedAt != null) ? new Date(endedAt.getTime()) : null; -117 } -118 -119 public void setEndedAt(Date endedAt) { -120 this.endedAt = ((endedAt != null) ? new Date(endedAt.getTime()) : null); -121 } -122 -123 public String getAbortedBy() { -124 return abortedBy; -125 } -126 -127 public void setAbortedBy(String abortedBy) { -128 this.abortedBy = abortedBy; -129 } -130 -131 public String getDescription() { -132 return description; -133 } -134 -135 public void setDescription(String description) { -136 this.description = description; -137 } -138 -139 @Override -140 public String toString() { -141 return "RundeckExecution [id=" + id + ", description=" + description + ", url=" + url + ", status=" + status -142 + ", startedBy=" + startedBy + ", startedAt=" + startedAt + ", endedAt=" + endedAt -143 + ", durationInSeconds=" + getDurationInSeconds() + ", abortedBy=" + abortedBy + ", job=" + job + "]"; +87 public void setUrl(String url) { +88 this.url = url; +89 } +90 +91 /** +92 * @return the status of the execution - see {@link ExecutionStatus} +93 */ +94 public ExecutionStatus getStatus() { +95 return status; +96 } +97 +98 public void setStatus(ExecutionStatus status) { +99 this.status = status; +100 } +101 +102 /** +103 * @return the {@link RundeckJob} associated with this execution, or null in the case of an ad-hoc execution +104 * (command or script) +105 */ +106 public RundeckJob getJob() { +107 return job; +108 } +109 +110 public void setJob(RundeckJob job) { +111 this.job = job; +112 } +113 +114 public String getStartedBy() { +115 return startedBy; +116 } +117 +118 public void setStartedBy(String startedBy) { +119 this.startedBy = startedBy; +120 } +121 +122 public Date getStartedAt() { +123 return (startedAt != null) ? new Date(startedAt.getTime()) : null; +124 } +125 +126 public void setStartedAt(Date startedAt) { +127 this.startedAt = ((startedAt != null) ? new Date(startedAt.getTime()) : null); +128 } +129 +130 public Date getEndedAt() { +131 return (endedAt != null) ? new Date(endedAt.getTime()) : null; +132 } +133 +134 public void setEndedAt(Date endedAt) { +135 this.endedAt = ((endedAt != null) ? new Date(endedAt.getTime()) : null); +136 } +137 +138 public String getAbortedBy() { +139 return abortedBy; +140 } +141 +142 public void setAbortedBy(String abortedBy) { +143 this.abortedBy = abortedBy; 144 } 145 -146 @Override -147 public int hashCode() { -148 final int prime = 31; -149 int result = 1; -150 result = prime * result + ((abortedBy == null) ? 0 : abortedBy.hashCode()); -151 result = prime * result + ((description == null) ? 0 : description.hashCode()); -152 result = prime * result + ((endedAt == null) ? 0 : endedAt.hashCode()); -153 result = prime * result + ((id == null) ? 0 : id.hashCode()); -154 result = prime * result + ((job == null) ? 0 : job.hashCode()); -155 result = prime * result + ((startedAt == null) ? 0 : startedAt.hashCode()); -156 result = prime * result + ((startedBy == null) ? 0 : startedBy.hashCode()); -157 result = prime * result + ((status == null) ? 0 : status.hashCode()); -158 result = prime * result + ((url == null) ? 0 : url.hashCode()); -159 return result; -160 } -161 -162 @Override -163 public boolean equals(Object obj) { -164 if (this == obj) -165 return true; -166 if (obj == null) -167 return false; -168 if (getClass() != obj.getClass()) -169 return false; -170 RundeckExecution other = (RundeckExecution) obj; -171 if (abortedBy == null) { -172 if (other.abortedBy != null) -173 return false; -174 } else if (!abortedBy.equals(other.abortedBy)) -175 return false; -176 if (description == null) { -177 if (other.description != null) -178 return false; -179 } else if (!description.equals(other.description)) -180 return false; -181 if (endedAt == null) { -182 if (other.endedAt != null) -183 return false; -184 } else if (!endedAt.equals(other.endedAt)) -185 return false; -186 if (id == null) { -187 if (other.id != null) +146 public String getDescription() { +147 return description; +148 } +149 +150 public void setDescription(String description) { +151 this.description = description; +152 } +153 +154 @Override +155 public String toString() { +156 return "RundeckExecution [id=" + id + ", description=" + description + ", url=" + url + ", status=" + status +157 + ", startedBy=" + startedBy + ", startedAt=" + startedAt + ", endedAt=" + endedAt +158 + ", durationInSeconds=" + getDurationInSeconds() + ", abortedBy=" + abortedBy + ", job=" + job + "]"; +159 } +160 +161 @Override +162 public int hashCode() { +163 final int prime = 31; +164 int result = 1; +165 result = prime * result + ((abortedBy == null) ? 0 : abortedBy.hashCode()); +166 result = prime * result + ((description == null) ? 0 : description.hashCode()); +167 result = prime * result + ((endedAt == null) ? 0 : endedAt.hashCode()); +168 result = prime * result + ((id == null) ? 0 : id.hashCode()); +169 result = prime * result + ((job == null) ? 0 : job.hashCode()); +170 result = prime * result + ((startedAt == null) ? 0 : startedAt.hashCode()); +171 result = prime * result + ((startedBy == null) ? 0 : startedBy.hashCode()); +172 result = prime * result + ((status == null) ? 0 : status.hashCode()); +173 result = prime * result + ((url == null) ? 0 : url.hashCode()); +174 return result; +175 } +176 +177 @Override +178 public boolean equals(Object obj) { +179 if (this == obj) +180 return true; +181 if (obj == null) +182 return false; +183 if (getClass() != obj.getClass()) +184 return false; +185 RundeckExecution other = (RundeckExecution) obj; +186 if (abortedBy == null) { +187 if (other.abortedBy != null) 188 return false; -189 } else if (!id.equals(other.id)) +189 } else if (!abortedBy.equals(other.abortedBy)) 190 return false; -191 if (job == null) { -192 if (other.job != null) +191 if (description == null) { +192 if (other.description != null) 193 return false; -194 } else if (!job.equals(other.job)) +194 } else if (!description.equals(other.description)) 195 return false; -196 if (startedAt == null) { -197 if (other.startedAt != null) +196 if (endedAt == null) { +197 if (other.endedAt != null) 198 return false; -199 } else if (!startedAt.equals(other.startedAt)) +199 } else if (!endedAt.equals(other.endedAt)) 200 return false; -201 if (startedBy == null) { -202 if (other.startedBy != null) +201 if (id == null) { +202 if (other.id != null) 203 return false; -204 } else if (!startedBy.equals(other.startedBy)) +204 } else if (!id.equals(other.id)) 205 return false; -206 if (status == null) { -207 if (other.status != null) +206 if (job == null) { +207 if (other.job != null) 208 return false; -209 } else if (!status.equals(other.status)) +209 } else if (!job.equals(other.job)) 210 return false; -211 if (url == null) { -212 if (other.url != null) +211 if (startedAt == null) { +212 if (other.startedAt != null) 213 return false; -214 } else if (!url.equals(other.url)) +214 } else if (!startedAt.equals(other.startedAt)) 215 return false; -216 return true; -217 } -218 -219 /** -220 * The status of an execution -221 */ -222 public static enum ExecutionStatus { -223 RUNNING, SUCCEEDED, FAILED, ABORTED; -224 } -225 -226 } +216 if (startedBy == null) { +217 if (other.startedBy != null) +218 return false; +219 } else if (!startedBy.equals(other.startedBy)) +220 return false; +221 if (status == null) { +222 if (other.status != null) +223 return false; +224 } else if (!status.equals(other.status)) +225 return false; +226 if (url == null) { +227 if (other.url != null) +228 return false; +229 } else if (!url.equals(other.url)) +230 return false; +231 return true; +232 } +233 +234 /** +235 * The status of an execution +236 */ +237 public static enum ExecutionStatus { +238 RUNNING, SUCCEEDED, FAILED, ABORTED; +239 } +240 +241 }
-1 package org.rundeck.api.domain; -2 -3 import java.io.Serializable; -4 import org.apache.commons.lang.StringUtils; -5 -6 /** -7 * Represents a RunDeck job -8 * -9 * @author Vincent Behar -10 */ -11 public class RundeckJob implements Serializable { -12 -13 private static final long serialVersionUID = 1L; -14 -15 private String id; -16 -17 private String name; -18 -19 private String group; +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.domain; +17 +18 import java.io.Serializable; +19 import org.apache.commons.lang.StringUtils; 20 -21 private String project; -22 -23 private String description; -24 -25 /** -26 * @return the fullname : group + name (exact format is : "group/name") -27 */ -28 public String getFullName() { -29 StringBuilder fullName = new StringBuilder(); -30 if (StringUtils.isNotBlank(group)) { -31 fullName.append(group).append("/"); -32 } -33 fullName.append(name); -34 return fullName.toString(); -35 } -36 -37 public String getId() { -38 return id; -39 } -40 -41 public void setId(String id) { -42 this.id = id; -43 } -44 -45 public String getName() { -46 return name; -47 } -48 -49 public void setName(String name) { -50 this.name = name; -51 } -52 -53 public String getGroup() { -54 return group; -55 } -56 -57 public void setGroup(String group) { -58 this.group = group; -59 } -60 -61 public String getProject() { -62 return project; -63 } -64 -65 public void setProject(String project) { -66 this.project = project; -67 } -68 -69 public String getDescription() { -70 return description; -71 } -72 -73 public void setDescription(String description) { -74 this.description = description; -75 } -76 -77 @Override -78 public String toString() { -79 return "RundeckJob [id=" + id + ", name=" + name + ", group=" + group + ", project=" + project -80 + ", description=" + description + "]"; -81 } -82 -83 @Override -84 public int hashCode() { -85 final int prime = 31; -86 int result = 1; -87 result = prime * result + ((description == null) ? 0 : description.hashCode()); -88 result = prime * result + ((group == null) ? 0 : group.hashCode()); -89 result = prime * result + ((id == null) ? 0 : id.hashCode()); -90 result = prime * result + ((name == null) ? 0 : name.hashCode()); -91 result = prime * result + ((project == null) ? 0 : project.hashCode()); -92 return result; -93 } -94 -95 @Override -96 public boolean equals(Object obj) { -97 if (this == obj) -98 return true; -99 if (obj == null) -100 return false; -101 if (getClass() != obj.getClass()) -102 return false; -103 RundeckJob other = (RundeckJob) obj; -104 if (description == null) { -105 if (other.description != null) -106 return false; -107 } else if (!description.equals(other.description)) -108 return false; -109 if (group == null) { -110 if (other.group != null) -111 return false; -112 } else if (!group.equals(other.group)) -113 return false; -114 if (id == null) { -115 if (other.id != null) -116 return false; -117 } else if (!id.equals(other.id)) -118 return false; -119 if (name == null) { -120 if (other.name != null) +21 /** +22 * Represents a RunDeck job +23 * +24 * @author Vincent Behar +25 */ +26 public class RundeckJob implements Serializable { +27 +28 private static final long serialVersionUID = 1L; +29 +30 private String id; +31 +32 private String name; +33 +34 private String group; +35 +36 private String project; +37 +38 private String description; +39 +40 /** +41 * @return the fullname : group + name (exact format is : "group/name") +42 */ +43 public String getFullName() { +44 StringBuilder fullName = new StringBuilder(); +45 if (StringUtils.isNotBlank(group)) { +46 fullName.append(group).append("/"); +47 } +48 fullName.append(name); +49 return fullName.toString(); +50 } +51 +52 public String getId() { +53 return id; +54 } +55 +56 public void setId(String id) { +57 this.id = id; +58 } +59 +60 public String getName() { +61 return name; +62 } +63 +64 public void setName(String name) { +65 this.name = name; +66 } +67 +68 public String getGroup() { +69 return group; +70 } +71 +72 public void setGroup(String group) { +73 this.group = group; +74 } +75 +76 public String getProject() { +77 return project; +78 } +79 +80 public void setProject(String project) { +81 this.project = project; +82 } +83 +84 public String getDescription() { +85 return description; +86 } +87 +88 public void setDescription(String description) { +89 this.description = description; +90 } +91 +92 @Override +93 public String toString() { +94 return "RundeckJob [id=" + id + ", name=" + name + ", group=" + group + ", project=" + project +95 + ", description=" + description + "]"; +96 } +97 +98 @Override +99 public int hashCode() { +100 final int prime = 31; +101 int result = 1; +102 result = prime * result + ((description == null) ? 0 : description.hashCode()); +103 result = prime * result + ((group == null) ? 0 : group.hashCode()); +104 result = prime * result + ((id == null) ? 0 : id.hashCode()); +105 result = prime * result + ((name == null) ? 0 : name.hashCode()); +106 result = prime * result + ((project == null) ? 0 : project.hashCode()); +107 return result; +108 } +109 +110 @Override +111 public boolean equals(Object obj) { +112 if (this == obj) +113 return true; +114 if (obj == null) +115 return false; +116 if (getClass() != obj.getClass()) +117 return false; +118 RundeckJob other = (RundeckJob) obj; +119 if (description == null) { +120 if (other.description != null) 121 return false; -122 } else if (!name.equals(other.name)) +122 } else if (!description.equals(other.description)) 123 return false; -124 if (project == null) { -125 if (other.project != null) +124 if (group == null) { +125 if (other.group != null) 126 return false; -127 } else if (!project.equals(other.project)) +127 } else if (!group.equals(other.group)) 128 return false; -129 return true; -130 } -131 -132 } +129 if (id == null) { +130 if (other.id != null) +131 return false; +132 } else if (!id.equals(other.id)) +133 return false; +134 if (name == null) { +135 if (other.name != null) +136 return false; +137 } else if (!name.equals(other.name)) +138 return false; +139 if (project == null) { +140 if (other.project != null) +141 return false; +142 } else if (!project.equals(other.project)) +143 return false; +144 return true; +145 } +146 +147 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.domain; +17 +18 import java.io.Serializable; +19 import java.util.List; +20 +21 /** +22 * Represents a RunDeck node (server on which RunDeck can execute jobs and commands) +23 * +24 * @author Vincent Behar +25 */ +26 public class RundeckNode implements Serializable { +27 +28 private static final long serialVersionUID = 1L; +29 +30 /** The node name. This is a logical identifier from the node. (required) */ +31 private String name; +32 +33 /** The node type, such as "Node". (required) */ +34 private String type; +35 +36 /** A brief description about the node. (optional) */ +37 private String description; +38 +39 /** List of filtering tags. (optional) */ +40 private List<String> tags; +41 +42 /** The hostname or IP address of the remote host. (required) */ +43 private String hostname; +44 +45 /** The operating system architecture. (optional) */ +46 private String osArch; +47 +48 /** The operating system family, such as unix or windows. (optional) */ +49 private String osFamily; +50 +51 /** The operating system name such as Linux or Mac OS X. (optional) */ +52 private String osName; +53 +54 /** The operating system version. (optional) */ +55 private String osVersion; +56 +57 /** The username used for the remote connection. (required) */ +58 private String username; +59 +60 /** URL to an external resource model editor service (optional) */ +61 private String editUrl; +62 +63 /** URL to an external resource model service. (optional) */ +64 private String remoteUrl; +65 +66 public String getName() { +67 return name; +68 } +69 +70 public void setName(String name) { +71 this.name = name; +72 } +73 +74 public String getType() { +75 return type; +76 } +77 +78 public void setType(String type) { +79 this.type = type; +80 } +81 +82 public String getDescription() { +83 return description; +84 } +85 +86 public void setDescription(String description) { +87 this.description = description; +88 } +89 +90 public List<String> getTags() { +91 return tags; +92 } +93 +94 public void setTags(List<String> tags) { +95 this.tags = tags; +96 } +97 +98 public String getHostname() { +99 return hostname; +100 } +101 +102 public void setHostname(String hostname) { +103 this.hostname = hostname; +104 } +105 +106 public String getOsArch() { +107 return osArch; +108 } +109 +110 public void setOsArch(String osArch) { +111 this.osArch = osArch; +112 } +113 +114 public String getOsFamily() { +115 return osFamily; +116 } +117 +118 public void setOsFamily(String osFamily) { +119 this.osFamily = osFamily; +120 } +121 +122 public String getOsName() { +123 return osName; +124 } +125 +126 public void setOsName(String osName) { +127 this.osName = osName; +128 } +129 +130 public String getOsVersion() { +131 return osVersion; +132 } +133 +134 public void setOsVersion(String osVersion) { +135 this.osVersion = osVersion; +136 } +137 +138 public String getUsername() { +139 return username; +140 } +141 +142 public void setUsername(String username) { +143 this.username = username; +144 } +145 +146 public String getEditUrl() { +147 return editUrl; +148 } +149 +150 public void setEditUrl(String editUrl) { +151 this.editUrl = editUrl; +152 } +153 +154 public String getRemoteUrl() { +155 return remoteUrl; +156 } +157 +158 public void setRemoteUrl(String remoteUrl) { +159 this.remoteUrl = remoteUrl; +160 } +161 +162 @Override +163 public String toString() { +164 return "RundeckNode [name=" + name + ", hostname=" + hostname + ", description=" + description + ", tags=" +165 + tags + ", type=" + type + ", username=" + username + ", osArch=" + osArch + ", osFamily=" + osFamily +166 + ", osName=" + osName + ", osVersion=" + osVersion + ", editUrl=" + editUrl + ", remoteUrl=" +167 + remoteUrl + "]"; +168 } +169 +170 @Override +171 public int hashCode() { +172 final int prime = 31; +173 int result = 1; +174 result = prime * result + ((description == null) ? 0 : description.hashCode()); +175 result = prime * result + ((editUrl == null) ? 0 : editUrl.hashCode()); +176 result = prime * result + ((hostname == null) ? 0 : hostname.hashCode()); +177 result = prime * result + ((name == null) ? 0 : name.hashCode()); +178 result = prime * result + ((osArch == null) ? 0 : osArch.hashCode()); +179 result = prime * result + ((osFamily == null) ? 0 : osFamily.hashCode()); +180 result = prime * result + ((osName == null) ? 0 : osName.hashCode()); +181 result = prime * result + ((osVersion == null) ? 0 : osVersion.hashCode()); +182 result = prime * result + ((remoteUrl == null) ? 0 : remoteUrl.hashCode()); +183 result = prime * result + ((tags == null) ? 0 : tags.hashCode()); +184 result = prime * result + ((type == null) ? 0 : type.hashCode()); +185 result = prime * result + ((username == null) ? 0 : username.hashCode()); +186 return result; +187 } +188 +189 @Override +190 public boolean equals(Object obj) { +191 if (this == obj) +192 return true; +193 if (obj == null) +194 return false; +195 if (getClass() != obj.getClass()) +196 return false; +197 RundeckNode other = (RundeckNode) obj; +198 if (description == null) { +199 if (other.description != null) +200 return false; +201 } else if (!description.equals(other.description)) +202 return false; +203 if (editUrl == null) { +204 if (other.editUrl != null) +205 return false; +206 } else if (!editUrl.equals(other.editUrl)) +207 return false; +208 if (hostname == null) { +209 if (other.hostname != null) +210 return false; +211 } else if (!hostname.equals(other.hostname)) +212 return false; +213 if (name == null) { +214 if (other.name != null) +215 return false; +216 } else if (!name.equals(other.name)) +217 return false; +218 if (osArch == null) { +219 if (other.osArch != null) +220 return false; +221 } else if (!osArch.equals(other.osArch)) +222 return false; +223 if (osFamily == null) { +224 if (other.osFamily != null) +225 return false; +226 } else if (!osFamily.equals(other.osFamily)) +227 return false; +228 if (osName == null) { +229 if (other.osName != null) +230 return false; +231 } else if (!osName.equals(other.osName)) +232 return false; +233 if (osVersion == null) { +234 if (other.osVersion != null) +235 return false; +236 } else if (!osVersion.equals(other.osVersion)) +237 return false; +238 if (remoteUrl == null) { +239 if (other.remoteUrl != null) +240 return false; +241 } else if (!remoteUrl.equals(other.remoteUrl)) +242 return false; +243 if (tags == null) { +244 if (other.tags != null) +245 return false; +246 } else if (!tags.equals(other.tags)) +247 return false; +248 if (type == null) { +249 if (other.type != null) +250 return false; +251 } else if (!type.equals(other.type)) +252 return false; +253 if (username == null) { +254 if (other.username != null) +255 return false; +256 } else if (!username.equals(other.username)) +257 return false; +258 return true; +259 } +260 +261 } ++
-1 package org.rundeck.api.domain; -2 -3 import java.io.Serializable; -4 -5 /** -6 * Represents a RunDeck project -7 * -8 * @author Vincent Behar -9 */ -10 public class RundeckProject implements Serializable { -11 -12 private static final long serialVersionUID = 1L; -13 -14 private String name; -15 -16 private String description; +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.domain; 17 -18 public String getName() { -19 return name; -20 } -21 -22 public void setName(String name) { -23 this.name = name; -24 } -25 -26 public String getDescription() { -27 return description; -28 } -29 -30 public void setDescription(String description) { -31 this.description = description; -32 } -33 -34 @Override -35 public String toString() { -36 return "RundeckProject [name=" + name + ", description=" + description + "]"; -37 } -38 -39 @Override -40 public int hashCode() { -41 final int prime = 31; -42 int result = 1; -43 result = prime * result + ((description == null) ? 0 : description.hashCode()); -44 result = prime * result + ((name == null) ? 0 : name.hashCode()); -45 return result; -46 } -47 -48 @Override -49 public boolean equals(Object obj) { -50 if (this == obj) -51 return true; -52 if (obj == null) -53 return false; -54 if (getClass() != obj.getClass()) -55 return false; -56 RundeckProject other = (RundeckProject) obj; -57 if (description == null) { -58 if (other.description != null) -59 return false; -60 } else if (!description.equals(other.description)) -61 return false; -62 if (name == null) { -63 if (other.name != null) -64 return false; -65 } else if (!name.equals(other.name)) -66 return false; -67 return true; -68 } -69 -70 } +18 import java.io.Serializable; +19 +20 /** +21 * Represents a RunDeck project +22 * +23 * @author Vincent Behar +24 */ +25 public class RundeckProject implements Serializable { +26 +27 private static final long serialVersionUID = 1L; +28 +29 private String name; +30 +31 private String description; +32 +33 public String getName() { +34 return name; +35 } +36 +37 public void setName(String name) { +38 this.name = name; +39 } +40 +41 public String getDescription() { +42 return description; +43 } +44 +45 public void setDescription(String description) { +46 this.description = description; +47 } +48 +49 @Override +50 public String toString() { +51 return "RundeckProject [name=" + name + ", description=" + description + "]"; +52 } +53 +54 @Override +55 public int hashCode() { +56 final int prime = 31; +57 int result = 1; +58 result = prime * result + ((description == null) ? 0 : description.hashCode()); +59 result = prime * result + ((name == null) ? 0 : name.hashCode()); +60 return result; +61 } +62 +63 @Override +64 public boolean equals(Object obj) { +65 if (this == obj) +66 return true; +67 if (obj == null) +68 return false; +69 if (getClass() != obj.getClass()) +70 return false; +71 RundeckProject other = (RundeckProject) obj; +72 if (description == null) { +73 if (other.description != null) +74 return false; +75 } else if (!description.equals(other.description)) +76 return false; +77 if (name == null) { +78 if (other.name != null) +79 return false; +80 } else if (!name.equals(other.name)) +81 return false; +82 return true; +83 } +84 +85 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import org.apache.commons.lang.StringUtils; +19 import org.dom4j.Node; +20 import org.rundeck.api.domain.RundeckAbort; +21 import org.rundeck.api.domain.RundeckExecution; +22 import org.rundeck.api.domain.RundeckAbort.AbortStatus; +23 +24 /** +25 * Parser for a single {@link RundeckAbort} +26 * +27 * @author Vincent Behar +28 */ +29 public class AbortParser implements XmlNodeParser<RundeckAbort> { +30 +31 private String xpath; +32 +33 public AbortParser() { +34 super(); +35 } +36 +37 /** +38 * @param xpath of the abort element if it is not the root node +39 */ +40 public AbortParser(String xpath) { +41 super(); +42 this.xpath = xpath; +43 } +44 +45 @Override +46 public RundeckAbort parseXmlNode(Node node) { +47 Node abortNode = xpath != null ? node.selectSingleNode(xpath) : node; +48 +49 RundeckAbort abort = new RundeckAbort(); +50 +51 try { +52 abort.setStatus(AbortStatus.valueOf(StringUtils.upperCase(abortNode.valueOf("@status")))); +53 } catch (IllegalArgumentException e) { +54 } +55 +56 Node execNode = abortNode.selectSingleNode("execution"); +57 if (execNode != null) { +58 RundeckExecution execution = new ExecutionParser().parseXmlNode(execNode); +59 abort.setExecution(execution); +60 } +61 +62 return abort; +63 } +64 +65 } ++
-1 package org.rundeck.api.parser; -2 -3 import java.util.Date; -4 import org.apache.commons.lang.StringUtils; -5 import org.dom4j.Node; -6 import org.rundeck.api.domain.RundeckExecution; -7 import org.rundeck.api.domain.RundeckJob; -8 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; -9 -10 /** -11 * Parser for a single {@link RundeckExecution} -12 * -13 * @author Vincent Behar -14 */ -15 public class ExecutionParser implements NodeParser<RundeckExecution> { -16 -17 private String xpath; -18 -19 public ExecutionParser() { -20 super(); -21 } -22 -23 /** -24 * @param xpath of the execution element if it is not the root node -25 */ -26 public ExecutionParser(String xpath) { -27 super(); -28 this.xpath = xpath; -29 } -30 -31 @Override -32 public RundeckExecution parseNode(Node node) { -33 Node execNode = xpath != null ? node.selectSingleNode(xpath) : node; -34 -35 RundeckExecution execution = new RundeckExecution(); -36 -37 execution.setId(Long.valueOf(execNode.valueOf("@id"))); -38 execution.setUrl(StringUtils.trimToNull(execNode.valueOf("@href"))); -39 try { -40 execution.setStatus(ExecutionStatus.valueOf(StringUtils.upperCase(execNode.valueOf("@status")))); -41 } catch (IllegalArgumentException e) { -42 } -43 execution.setDescription(StringUtils.trimToNull(execNode.valueOf("description"))); -44 execution.setStartedBy(StringUtils.trimToNull(execNode.valueOf("user"))); -45 execution.setAbortedBy(StringUtils.trimToNull(execNode.valueOf("abortedby"))); -46 String startedAt = StringUtils.trimToNull(execNode.valueOf("date-started/@unixtime")); -47 if (startedAt != null) { -48 execution.setStartedAt(new Date(Long.valueOf(startedAt))); -49 } -50 String endedAt = StringUtils.trimToNull(execNode.valueOf("date-ended/@unixtime")); -51 if (endedAt != null) { -52 execution.setEndedAt(new Date(Long.valueOf(endedAt))); -53 } -54 -55 Node jobNode = execNode.selectSingleNode("job"); -56 if (jobNode != null) { -57 RundeckJob job = new JobParser().parseNode(jobNode); -58 execution.setJob(job); -59 } -60 -61 return execution; -62 } -63 -64 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.Date; +19 import org.apache.commons.lang.StringUtils; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckExecution; +22 import org.rundeck.api.domain.RundeckJob; +23 import org.rundeck.api.domain.RundeckExecution.ExecutionStatus; +24 +25 /** +26 * Parser for a single {@link RundeckExecution} +27 * +28 * @author Vincent Behar +29 */ +30 public class ExecutionParser implements XmlNodeParser<RundeckExecution> { +31 +32 private String xpath; +33 +34 public ExecutionParser() { +35 super(); +36 } +37 +38 /** +39 * @param xpath of the execution element if it is not the root node +40 */ +41 public ExecutionParser(String xpath) { +42 super(); +43 this.xpath = xpath; +44 } +45 +46 @Override +47 public RundeckExecution parseXmlNode(Node node) { +48 Node execNode = xpath != null ? node.selectSingleNode(xpath) : node; +49 +50 RundeckExecution execution = new RundeckExecution(); +51 +52 execution.setId(Long.valueOf(execNode.valueOf("@id"))); +53 execution.setUrl(StringUtils.trimToNull(execNode.valueOf("@href"))); +54 try { +55 execution.setStatus(ExecutionStatus.valueOf(StringUtils.upperCase(execNode.valueOf("@status")))); +56 } catch (IllegalArgumentException e) { +57 } +58 execution.setDescription(StringUtils.trimToNull(execNode.valueOf("description"))); +59 execution.setStartedBy(StringUtils.trimToNull(execNode.valueOf("user"))); +60 execution.setAbortedBy(StringUtils.trimToNull(execNode.valueOf("abortedby"))); +61 String startedAt = StringUtils.trimToNull(execNode.valueOf("date-started/@unixtime")); +62 if (startedAt != null) { +63 execution.setStartedAt(new Date(Long.valueOf(startedAt))); +64 } +65 String endedAt = StringUtils.trimToNull(execNode.valueOf("date-ended/@unixtime")); +66 if (endedAt != null) { +67 execution.setEndedAt(new Date(Long.valueOf(endedAt))); +68 } +69 +70 Node jobNode = execNode.selectSingleNode("job"); +71 if (jobNode != null) { +72 RundeckJob job = new JobParser().parseXmlNode(jobNode); +73 execution.setJob(job); +74 } +75 +76 return execution; +77 } +78 +79 }
-1 package org.rundeck.api.parser; -2 -3 import java.util.ArrayList; -4 import java.util.List; -5 import org.dom4j.Node; -6 import org.rundeck.api.domain.RundeckExecution; -7 -8 /** -9 * Parser for a {@link List} of {@link RundeckExecution} -10 * -11 * @author Vincent Behar -12 */ -13 public class ExecutionsParser implements NodeParser<List<RundeckExecution>> { -14 -15 private final String xpath; -16 -17 /** -18 * @param xpath of the executions elements -19 */ -20 public ExecutionsParser(String xpath) { -21 super(); -22 this.xpath = xpath; -23 } -24 -25 @Override -26 public List<RundeckExecution> parseNode(Node node) { -27 List<RundeckExecution> executions = new ArrayList<RundeckExecution>(); -28 -29 @SuppressWarnings("unchecked") -30 List<Node> execNodes = node.selectNodes(xpath); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.ArrayList; +19 import java.util.List; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckExecution; +22 +23 /** +24 * Parser for a {@link List} of {@link RundeckExecution} +25 * +26 * @author Vincent Behar +27 */ +28 public class ExecutionsParser implements XmlNodeParser<List<RundeckExecution>> { +29 +30 private final String xpath; 31 -32 for (Node execNode : execNodes) { -33 RundeckExecution execution = new ExecutionParser().parseNode(execNode); -34 executions.add(execution); -35 } -36 -37 return executions; +32 /** +33 * @param xpath of the executions elements +34 */ +35 public ExecutionsParser(String xpath) { +36 super(); +37 this.xpath = xpath; 38 } 39 -40 } +40 @Override +41 public List<RundeckExecution> parseXmlNode(Node node) { +42 List<RundeckExecution> executions = new ArrayList<RundeckExecution>(); +43 +44 @SuppressWarnings("unchecked") +45 List<Node> execNodes = node.selectNodes(xpath); +46 +47 for (Node execNode : execNodes) { +48 RundeckExecution execution = new ExecutionParser().parseXmlNode(execNode); +49 executions.add(execution); +50 } +51 +52 return executions; +53 } +54 +55 }
-1 package org.rundeck.api.parser; -2 -3 import org.apache.commons.lang.StringUtils; -4 import org.dom4j.Node; -5 import org.rundeck.api.domain.RundeckJob; -6 -7 /** -8 * Parser for a single {@link RundeckJob} -9 * -10 * @author Vincent Behar -11 */ -12 public class JobParser implements NodeParser<RundeckJob> { -13 -14 private String xpath; -15 -16 public JobParser() { -17 super(); -18 } -19 -20 /** -21 * @param xpath of the job element if it is not the root node -22 */ -23 public JobParser(String xpath) { -24 super(); -25 this.xpath = xpath; -26 } -27 -28 @Override -29 public RundeckJob parseNode(Node node) { -30 Node jobNode = xpath != null ? node.selectSingleNode(xpath) : node; -31 -32 RundeckJob job = new RundeckJob(); -33 -34 job.setName(StringUtils.trimToNull(jobNode.valueOf("name"))); -35 job.setDescription(StringUtils.trimToNull(jobNode.valueOf("description"))); -36 job.setGroup(StringUtils.trimToNull(jobNode.valueOf("group"))); -37 -38 // ID is either an attribute or an child element... -39 String jobId = null; -40 jobId = jobNode.valueOf("id"); -41 if (StringUtils.isBlank(jobId)) { -42 jobId = jobNode.valueOf("@id"); -43 } -44 job.setId(jobId); -45 -46 // project is either a nested element of context, or just a child element -47 Node contextNode = jobNode.selectSingleNode("context"); -48 if (contextNode != null) { -49 job.setProject(StringUtils.trimToNull(contextNode.valueOf("project"))); -50 } else { -51 job.setProject(StringUtils.trimToNull(jobNode.valueOf("project"))); -52 } -53 -54 return job; -55 } -56 -57 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import org.apache.commons.lang.StringUtils; +19 import org.dom4j.Node; +20 import org.rundeck.api.domain.RundeckJob; +21 +22 /** +23 * Parser for a single {@link RundeckJob} +24 * +25 * @author Vincent Behar +26 */ +27 public class JobParser implements XmlNodeParser<RundeckJob> { +28 +29 private String xpath; +30 +31 public JobParser() { +32 super(); +33 } +34 +35 /** +36 * @param xpath of the job element if it is not the root node +37 */ +38 public JobParser(String xpath) { +39 super(); +40 this.xpath = xpath; +41 } +42 +43 @Override +44 public RundeckJob parseXmlNode(Node node) { +45 Node jobNode = xpath != null ? node.selectSingleNode(xpath) : node; +46 +47 RundeckJob job = new RundeckJob(); +48 +49 job.setName(StringUtils.trimToNull(jobNode.valueOf("name"))); +50 job.setDescription(StringUtils.trimToNull(jobNode.valueOf("description"))); +51 job.setGroup(StringUtils.trimToNull(jobNode.valueOf("group"))); +52 +53 // ID is either an attribute or an child element... +54 String jobId = null; +55 jobId = jobNode.valueOf("id"); +56 if (StringUtils.isBlank(jobId)) { +57 jobId = jobNode.valueOf("@id"); +58 } +59 job.setId(jobId); +60 +61 // project is either a nested element of context, or just a child element +62 Node contextNode = jobNode.selectSingleNode("context"); +63 if (contextNode != null) { +64 job.setProject(StringUtils.trimToNull(contextNode.valueOf("project"))); +65 } else { +66 job.setProject(StringUtils.trimToNull(jobNode.valueOf("project"))); +67 } +68 +69 return job; +70 } +71 +72 }
-1 package org.rundeck.api.parser; -2 -3 import java.util.ArrayList; -4 import java.util.List; -5 import org.dom4j.Node; -6 import org.rundeck.api.domain.RundeckJob; -7 -8 /** -9 * Parser for a {@link List} of {@link RundeckJob} -10 * -11 * @author Vincent Behar -12 */ -13 public class JobsParser implements NodeParser<List<RundeckJob>> { -14 -15 private final String xpath; -16 -17 /** -18 * @param xpath of the jobs elements -19 */ -20 public JobsParser(String xpath) { -21 super(); -22 this.xpath = xpath; -23 } -24 -25 @Override -26 public List<RundeckJob> parseNode(Node node) { -27 List<RundeckJob> jobs = new ArrayList<RundeckJob>(); -28 -29 @SuppressWarnings("unchecked") -30 List<Node> jobNodes = node.selectNodes(xpath); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.ArrayList; +19 import java.util.List; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckJob; +22 +23 /** +24 * Parser for a {@link List} of {@link RundeckJob} +25 * +26 * @author Vincent Behar +27 */ +28 public class JobsParser implements XmlNodeParser<List<RundeckJob>> { +29 +30 private final String xpath; 31 -32 for (Node jobNode : jobNodes) { -33 RundeckJob job = new JobParser().parseNode(jobNode); -34 jobs.add(job); -35 } -36 -37 return jobs; +32 /** +33 * @param xpath of the jobs elements +34 */ +35 public JobsParser(String xpath) { +36 super(); +37 this.xpath = xpath; 38 } 39 -40 } +40 @Override +41 public List<RundeckJob> parseXmlNode(Node node) { +42 List<RundeckJob> jobs = new ArrayList<RundeckJob>(); +43 +44 @SuppressWarnings("unchecked") +45 List<Node> jobNodes = node.selectNodes(xpath); +46 +47 for (Node jobNode : jobNodes) { +48 RundeckJob job = new JobParser().parseXmlNode(jobNode); +49 jobs.add(job); +50 } +51 +52 return jobs; +53 } +54 +55 }
-1 package org.rundeck.api.parser; -2 -3 import org.dom4j.Node; -4 -5 /** -6 * Interface to be implemented for parsers that handle XML {@link Node}s -7 * -8 * @author Vincent Behar -9 */ -10 public interface NodeParser<T> { -11 -12 /** -13 * Parse the given XML {@link Node} -14 * -15 * @param node -16 * @return any object holding the converted value -17 */ -18 T parseNode(Node node); -19 -20 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.Arrays; +19 import org.apache.commons.lang.StringUtils; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckNode; +22 +23 /** +24 * Parser for a single {@link RundeckNode} +25 * +26 * @author Vincent Behar +27 */ +28 public class NodeParser implements XmlNodeParser<RundeckNode> { +29 +30 private String xpath; +31 +32 public NodeParser() { +33 super(); +34 } +35 +36 /** +37 * @param xpath of the rundeck-node element if it is not the root xml-node +38 */ +39 public NodeParser(String xpath) { +40 super(); +41 this.xpath = xpath; +42 } +43 +44 @Override +45 public RundeckNode parseXmlNode(Node node) { +46 Node rundeckNodeNode = xpath != null ? node.selectSingleNode(xpath) : node; +47 +48 RundeckNode rundeckNode = new RundeckNode(); +49 +50 rundeckNode.setName(StringUtils.trimToNull(rundeckNodeNode.valueOf("@name"))); +51 rundeckNode.setType(StringUtils.trimToNull(rundeckNodeNode.valueOf("@type"))); +52 rundeckNode.setDescription(StringUtils.trimToNull(rundeckNodeNode.valueOf("@description"))); +53 rundeckNode.setHostname(StringUtils.trimToNull(rundeckNodeNode.valueOf("@hostname"))); +54 rundeckNode.setOsArch(StringUtils.trimToNull(rundeckNodeNode.valueOf("@osArch"))); +55 rundeckNode.setOsFamily(StringUtils.trimToNull(rundeckNodeNode.valueOf("@osFamily"))); +56 rundeckNode.setOsName(StringUtils.trimToNull(rundeckNodeNode.valueOf("@osName"))); +57 rundeckNode.setOsVersion(StringUtils.trimToNull(rundeckNodeNode.valueOf("@osVersion"))); +58 rundeckNode.setUsername(StringUtils.trimToNull(rundeckNodeNode.valueOf("@username"))); +59 rundeckNode.setEditUrl(StringUtils.trimToNull(rundeckNodeNode.valueOf("@editUrl"))); +60 rundeckNode.setRemoteUrl(StringUtils.trimToNull(rundeckNodeNode.valueOf("@remoteUrl"))); +61 +62 String tags = StringUtils.trimToEmpty(rundeckNodeNode.valueOf("@tags")); +63 rundeckNode.setTags(Arrays.asList(StringUtils.split(tags, ","))); +64 +65 return rundeckNode; +66 } +67 +68 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.ArrayList; +19 import java.util.List; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckNode; +22 +23 /** +24 * Parser for a {@link List} of {@link RundeckNode} +25 * +26 * @author Vincent Behar +27 */ +28 public class NodesParser implements XmlNodeParser<List<RundeckNode>> { +29 +30 private final String xpath; +31 +32 /** +33 * @param xpath of the rundeck-nodes elements +34 */ +35 public NodesParser(String xpath) { +36 super(); +37 this.xpath = xpath; +38 } +39 +40 @Override +41 public List<RundeckNode> parseXmlNode(Node node) { +42 List<RundeckNode> rundeckNodes = new ArrayList<RundeckNode>(); +43 +44 @SuppressWarnings("unchecked") +45 List<Node> rundeckNodeNodes = node.selectNodes(xpath); +46 +47 for (Node rundeckNodeNode : rundeckNodeNodes) { +48 RundeckNode rundeckNode = new NodeParser().parseXmlNode(rundeckNodeNode); +49 rundeckNodes.add(rundeckNode); +50 } +51 +52 return rundeckNodes; +53 } +54 +55 } ++
-1 package org.rundeck.api.parser; -2 -3 import java.io.IOException; -4 import java.io.InputStream; -5 import org.apache.http.HttpResponse; -6 import org.dom4j.Document; -7 import org.dom4j.DocumentException; -8 import org.dom4j.Node; -9 import org.dom4j.io.SAXReader; -10 import org.rundeck.api.RundeckApiException; -11 -12 /** -13 * Helper for parsing RunDeck responses -14 * -15 * @author Vincent Behar -16 */ -17 public class ParserHelper { -18 -19 /** -20 * Load an XML {@link Document} from the given RunDeck {@link HttpResponse}. -21 * -22 * @param httpResponse from an API call to RunDeck -23 * @return an XML {@link Document} -24 * @throws RundeckApiException if we failed to read the response, or if the response is an error -25 * @see #loadDocument(InputStream) -26 */ -27 public static Document loadDocument(HttpResponse httpResponse) throws RundeckApiException { -28 InputStream inputStream = null; -29 -30 try { -31 inputStream = httpResponse.getEntity().getContent(); -32 } catch (IllegalStateException e) { -33 throw new RundeckApiException("Failed to read RunDeck reponse", e); -34 } catch (IOException e) { -35 throw new RundeckApiException("Failed to read RunDeck reponse", e); -36 } -37 -38 return loadDocument(inputStream); -39 } -40 -41 /** -42 * Load an XML {@link Document} from the given {@link InputStream} -43 * -44 * @param inputStream from an API call to RunDeck -45 * @return an XML {@link Document} -46 * @throws RundeckApiException if we failed to read the response, or if the response is an error -47 * @see #loadDocument(HttpResponse) -48 */ -49 public static Document loadDocument(InputStream inputStream) throws RundeckApiException { -50 SAXReader reader = new SAXReader(); -51 reader.setEncoding("UTF-8"); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.io.IOException; +19 import java.io.InputStream; +20 import org.apache.http.HttpResponse; +21 import org.dom4j.Document; +22 import org.dom4j.DocumentException; +23 import org.dom4j.Node; +24 import org.dom4j.io.SAXReader; +25 import org.rundeck.api.RundeckApiException; +26 +27 /** +28 * Helper for parsing RunDeck responses +29 * +30 * @author Vincent Behar +31 */ +32 public class ParserHelper { +33 +34 /** +35 * Load an XML {@link Document} from the given RunDeck {@link HttpResponse}. +36 * +37 * @param httpResponse from an API call to RunDeck +38 * @return an XML {@link Document} +39 * @throws RundeckApiException if we failed to read the response, or if the response is an error +40 * @see #loadDocument(InputStream) +41 */ +42 public static Document loadDocument(HttpResponse httpResponse) throws RundeckApiException { +43 InputStream inputStream = null; +44 +45 try { +46 inputStream = httpResponse.getEntity().getContent(); +47 } catch (IllegalStateException e) { +48 throw new RundeckApiException("Failed to read RunDeck reponse", e); +49 } catch (IOException e) { +50 throw new RundeckApiException("Failed to read RunDeck reponse", e); +51 } 52 -53 Document document; -54 try { -55 document = reader.read(inputStream); -56 } catch (DocumentException e) { -57 throw new RundeckApiException("Failed to read RunDeck reponse", e); -58 } -59 document.setXMLEncoding("UTF-8"); -60 -61 Node result = document.selectSingleNode("result"); -62 if (result != null) { -63 Boolean failure = Boolean.valueOf(result.valueOf("@error")); -64 if (failure) { -65 throw new RundeckApiException(result.valueOf("error/message")); -66 } -67 } -68 -69 return document; -70 } -71 -72 } +53 return loadDocument(inputStream); +54 } +55 +56 /** +57 * Load an XML {@link Document} from the given {@link InputStream} +58 * +59 * @param inputStream from an API call to RunDeck +60 * @return an XML {@link Document} +61 * @throws RundeckApiException if we failed to read the response, or if the response is an error +62 * @see #loadDocument(HttpResponse) +63 */ +64 public static Document loadDocument(InputStream inputStream) throws RundeckApiException { +65 SAXReader reader = new SAXReader(); +66 reader.setEncoding("UTF-8"); +67 +68 Document document; +69 try { +70 document = reader.read(inputStream); +71 } catch (DocumentException e) { +72 throw new RundeckApiException("Failed to read RunDeck reponse", e); +73 } +74 document.setXMLEncoding("UTF-8"); +75 +76 Node result = document.selectSingleNode("result"); +77 if (result != null) { +78 Boolean failure = Boolean.valueOf(result.valueOf("@error")); +79 if (failure) { +80 throw new RundeckApiException(result.valueOf("error/message")); +81 } +82 } +83 +84 return document; +85 } +86 +87 }
-1 package org.rundeck.api.parser; -2 -3 import org.apache.commons.lang.StringUtils; -4 import org.dom4j.Node; -5 import org.rundeck.api.domain.RundeckProject; -6 -7 /** -8 * Parser for a single {@link RundeckProject} -9 * -10 * @author Vincent Behar -11 */ -12 public class ProjectParser implements NodeParser<RundeckProject> { -13 -14 private String xpath; -15 -16 public ProjectParser() { -17 super(); -18 } -19 -20 /** -21 * @param xpath of the project element if it is not the root node -22 */ -23 public ProjectParser(String xpath) { -24 super(); -25 this.xpath = xpath; -26 } -27 -28 @Override -29 public RundeckProject parseNode(Node node) { -30 Node projectNode = xpath != null ? node.selectSingleNode(xpath) : node; -31 -32 RundeckProject project = new RundeckProject(); -33 -34 project.setName(StringUtils.trimToNull(projectNode.valueOf("name"))); -35 project.setDescription(StringUtils.trimToNull(projectNode.valueOf("description"))); -36 -37 return project; -38 } -39 -40 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import org.apache.commons.lang.StringUtils; +19 import org.dom4j.Node; +20 import org.rundeck.api.domain.RundeckProject; +21 +22 /** +23 * Parser for a single {@link RundeckProject} +24 * +25 * @author Vincent Behar +26 */ +27 public class ProjectParser implements XmlNodeParser<RundeckProject> { +28 +29 private String xpath; +30 +31 public ProjectParser() { +32 super(); +33 } +34 +35 /** +36 * @param xpath of the project element if it is not the root node +37 */ +38 public ProjectParser(String xpath) { +39 super(); +40 this.xpath = xpath; +41 } +42 +43 @Override +44 public RundeckProject parseXmlNode(Node node) { +45 Node projectNode = xpath != null ? node.selectSingleNode(xpath) : node; +46 +47 RundeckProject project = new RundeckProject(); +48 +49 project.setName(StringUtils.trimToNull(projectNode.valueOf("name"))); +50 project.setDescription(StringUtils.trimToNull(projectNode.valueOf("description"))); +51 +52 return project; +53 } +54 +55 }
-1 package org.rundeck.api.parser; -2 -3 import java.util.ArrayList; -4 import java.util.List; -5 import org.dom4j.Node; -6 import org.rundeck.api.domain.RundeckProject; -7 -8 /** -9 * Parser for a {@link List} of {@link RundeckProject} -10 * -11 * @author Vincent Behar -12 */ -13 public class ProjectsParser implements NodeParser<List<RundeckProject>> { -14 -15 private final String xpath; -16 -17 /** -18 * @param xpath of the projects elements -19 */ -20 public ProjectsParser(String xpath) { -21 super(); -22 this.xpath = xpath; -23 } -24 -25 @Override -26 public List<RundeckProject> parseNode(Node node) { -27 List<RundeckProject> projects = new ArrayList<RundeckProject>(); -28 -29 @SuppressWarnings("unchecked") -30 List<Node> projectNodes = node.selectNodes(xpath); +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import java.util.ArrayList; +19 import java.util.List; +20 import org.dom4j.Node; +21 import org.rundeck.api.domain.RundeckProject; +22 +23 /** +24 * Parser for a {@link List} of {@link RundeckProject} +25 * +26 * @author Vincent Behar +27 */ +28 public class ProjectsParser implements XmlNodeParser<List<RundeckProject>> { +29 +30 private final String xpath; 31 -32 for (Node projectNode : projectNodes) { -33 RundeckProject project = new ProjectParser().parseNode(projectNode); -34 projects.add(project); -35 } -36 -37 return projects; +32 /** +33 * @param xpath of the projects elements +34 */ +35 public ProjectsParser(String xpath) { +36 super(); +37 this.xpath = xpath; 38 } 39 -40 } +40 @Override +41 public List<RundeckProject> parseXmlNode(Node node) { +42 List<RundeckProject> projects = new ArrayList<RundeckProject>(); +43 +44 @SuppressWarnings("unchecked") +45 List<Node> projectNodes = node.selectNodes(xpath); +46 +47 for (Node projectNode : projectNodes) { +48 RundeckProject project = new ProjectParser().parseXmlNode(projectNode); +49 projects.add(project); +50 } +51 +52 return projects; +53 } +54 +55 }
+ +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.parser; +17 +18 import org.dom4j.Node; +19 +20 /** +21 * Interface to be implemented for parsers that handle XML {@link Node}s +22 * +23 * @author Vincent Behar +24 */ +25 public interface XmlNodeParser<T> { +26 +27 /** +28 * Parse the given XML {@link Node} +29 * +30 * @param node +31 * @return any object holding the converted value +32 */ +33 T parseXmlNode(Node node); +34 +35 } ++
-1 package org.rundeck.api.util; -2 -3 import org.apache.commons.lang.StringUtils; -4 -5 /** -6 * Utility class for assertions -7 * -8 * @author Vincent Behar -9 */ -10 public class AssertUtil { -11 -12 /** -13 * Test if the given {@link Object} is null -14 * -15 * @param object -16 * @param errorMessage to be used if the object is null -17 * @throws IllegalArgumentException if the given object is null -18 */ -19 public static void notNull(Object object, String errorMessage) throws IllegalArgumentException { -20 if (object == null) { -21 throw new IllegalArgumentException(errorMessage); -22 } -23 } -24 -25 /** -26 * Test if the given {@link String} is blank (null, empty or only whitespace) -27 * -28 * @param input string -29 * @param errorMessage to be used if the string is blank -30 * @throws IllegalArgumentException if the given string is blank -31 */ -32 public static void notBlank(String input, String errorMessage) throws IllegalArgumentException { -33 if (StringUtils.isBlank(input)) { -34 throw new IllegalArgumentException(errorMessage); -35 } -36 } -37 -38 } +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.util; +17 +18 import org.apache.commons.lang.StringUtils; +19 +20 /** +21 * Utility class for assertions +22 * +23 * @author Vincent Behar +24 */ +25 public class AssertUtil { +26 +27 /** +28 * Test if the given {@link Object} is null +29 * +30 * @param object +31 * @param errorMessage to be used if the object is null +32 * @throws IllegalArgumentException if the given object is null +33 */ +34 public static void notNull(Object object, String errorMessage) throws IllegalArgumentException { +35 if (object == null) { +36 throw new IllegalArgumentException(errorMessage); +37 } +38 } +39 +40 /** +41 * Test if the given {@link String} is blank (null, empty or only whitespace) +42 * +43 * @param input string +44 * @param errorMessage to be used if the string is blank +45 * @throws IllegalArgumentException if the given string is blank +46 */ +47 public static void notBlank(String input, String errorMessage) throws IllegalArgumentException { +48 if (StringUtils.isBlank(input)) { +49 throw new IllegalArgumentException(errorMessage); +50 } +51 } +52 +53 }
-1 package org.rundeck.api.util; -2 -3 import java.io.UnsupportedEncodingException; -4 import java.net.URLEncoder; -5 import java.util.ArrayList; -6 import java.util.List; -7 import java.util.Properties; -8 import java.util.Map.Entry; -9 import org.apache.commons.lang.StringUtils; -10 -11 /** -12 * Utility class for API parameters that should be passed in URLs. -13 * -14 * @author Vincent Behar -15 */ -16 public class ParametersUtil { +1 /* +2 * Copyright 2011 Vincent Behar +3 * +4 * Licensed under the Apache License, Version 2.0 (the "License"); +5 * you may not use this file except in compliance with the License. +6 * You may obtain a copy of the License at +7 * +8 * http://www.apache.org/licenses/LICENSE-2.0 +9 * +10 * Unless required by applicable law or agreed to in writing, software +11 * distributed under the License is distributed on an "AS IS" BASIS, +12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +13 * See the License for the specific language governing permissions and +14 * limitations under the License. +15 */ +16 package org.rundeck.api.util; 17 -18 /** -19 * URL-encode the given string -20 * -21 * @param input string to be encoded -22 * @return an url-encoded string -23 */ -24 public static String urlEncode(String input) { -25 if (StringUtils.isBlank(input)) { -26 return input; -27 } -28 try { -29 return URLEncoder.encode(input, "UTF-8"); -30 } catch (UnsupportedEncodingException e) { -31 throw new RuntimeException(e); -32 } -33 } -34 -35 /** -36 * Generates a RunDeck "argString" representing the given options. Format of the argString is -37 * <code>"-key1 value1 -key2 'value 2 with spaces'"</code>. You might want to url-encode this string... -38 * -39 * @param options to be converted -40 * @return a string. null if options is null, empty if there are no valid options. -41 */ -42 public static String generateArgString(Properties options) { -43 if (options == null) { -44 return null; -45 } -46 -47 StringBuilder argString = new StringBuilder(); -48 for (Entry<Object, Object> option : options.entrySet()) { -49 String key = String.valueOf(option.getKey()); -50 String value = String.valueOf(option.getValue()); -51 -52 if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { -53 if (argString.length() > 0) { -54 argString.append(" "); -55 } -56 argString.append("-").append(key); -57 argString.append(" "); -58 if (value.indexOf(" ") >= 0 -59 && !(0 == value.indexOf("'") && (value.length() - 1) == value.lastIndexOf("'"))) { -60 argString.append("'").append(value).append("'"); -61 } else { -62 argString.append(value); -63 } -64 } -65 } -66 return argString.toString(); -67 } -68 -69 /** -70 * Generates an url-encoded string representing the given nodeFilters. Format of the string is -71 * <code>"filter1=value1&filter2=value2"</code>. -72 * -73 * @param nodeFilters to be converted -74 * @return an url-encoded string. null if nodeFilters is null, empty if there are no valid filters. -75 */ -76 public static String generateNodeFiltersString(Properties nodeFilters) { -77 if (nodeFilters == null) { -78 return null; -79 } -80 -81 List<String> filters = new ArrayList<String>(); -82 for (Entry<Object, Object> filter : nodeFilters.entrySet()) { -83 String key = String.valueOf(filter.getKey()); -84 String value = String.valueOf(filter.getValue()); -85 -86 if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { -87 try { -88 filters.add(URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8")); -89 } catch (UnsupportedEncodingException e) { -90 throw new RuntimeException(e); -91 } -92 } -93 } -94 return StringUtils.join(filters, "&"); -95 } -96 -97 } +18 import java.io.UnsupportedEncodingException; +19 import java.net.URLEncoder; +20 import java.util.ArrayList; +21 import java.util.List; +22 import java.util.Properties; +23 import java.util.Map.Entry; +24 import org.apache.commons.lang.StringUtils; +25 +26 /** +27 * Utility class for API parameters that should be passed in URLs. +28 * +29 * @author Vincent Behar +30 */ +31 public class ParametersUtil { +32 +33 /** +34 * URL-encode the given string +35 * +36 * @param input string to be encoded +37 * @return an url-encoded string +38 */ +39 public static String urlEncode(String input) { +40 if (StringUtils.isBlank(input)) { +41 return input; +42 } +43 try { +44 return URLEncoder.encode(input, "UTF-8"); +45 } catch (UnsupportedEncodingException e) { +46 throw new RuntimeException(e); +47 } +48 } +49 +50 /** +51 * Generates a RunDeck "argString" representing the given options. Format of the argString is +52 * <code>"-key1 value1 -key2 'value 2 with spaces'"</code>. You might want to url-encode this string... +53 * +54 * @param options to be converted +55 * @return a string. null if options is null, empty if there are no valid options. +56 */ +57 public static String generateArgString(Properties options) { +58 if (options == null) { +59 return null; +60 } +61 +62 StringBuilder argString = new StringBuilder(); +63 for (Entry<Object, Object> option : options.entrySet()) { +64 String key = String.valueOf(option.getKey()); +65 String value = String.valueOf(option.getValue()); +66 +67 if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { +68 if (argString.length() > 0) { +69 argString.append(" "); +70 } +71 argString.append("-").append(key); +72 argString.append(" "); +73 if (value.indexOf(" ") >= 0 +74 && !(0 == value.indexOf("'") && (value.length() - 1) == value.lastIndexOf("'"))) { +75 argString.append("'").append(value).append("'"); +76 } else { +77 argString.append(value); +78 } +79 } +80 } +81 return argString.toString(); +82 } +83 +84 /** +85 * Generates an url-encoded string representing the given nodeFilters. Format of the string is +86 * <code>"filter1=value1&filter2=value2"</code>. +87 * +88 * @param nodeFilters to be converted +89 * @return an url-encoded string. null if nodeFilters is null, empty if there are no valid filters. +90 */ +91 public static String generateNodeFiltersString(Properties nodeFilters) { +92 if (nodeFilters == null) { +93 return null; +94 } +95 +96 List<String> filters = new ArrayList<String>(); +97 for (Entry<Object, Object> filter : nodeFilters.entrySet()) { +98 String key = String.valueOf(filter.getKey()); +99 String value = String.valueOf(filter.getValue()); +100 +101 if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(value)) { +102 try { +103 filters.add(URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8")); +104 } catch (UnsupportedEncodingException e) { +105 throw new RuntimeException(e); +106 } +107 } +108 } +109 return StringUtils.join(filters, "&"); +110 } +111 +112 }