Skip to content

Commit b340fc4

Browse files
committed
Return model instead of just number when triggering a build
1 parent 6c2d628 commit b340fc4

File tree

8 files changed

+296
-27
lines changed

8 files changed

+296
-27
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@ Create job:
1111
client.createJob("java-client-job1","https://github.com/wtrocki/helloworld-android-gradle","master");
1212
```
1313

14+
Trigger a job:
15+
16+
```
17+
...
18+
BuildStatus buildStatus = client.build("java-client-job1");
19+
```
20+
1421
## Requirements
1522

1623
Client works with Java6 and above.
1724

1825
## Building
1926

20-
`mvn clean package`
27+
`mvn clean package`
28+

pom.xml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
</licenses>
1919

2020
<dependencies>
21+
<!--Compile time-->
2122
<dependency>
2223
<groupId>com.offbytwo.jenkins</groupId>
2324
<artifactId>jenkins-client</artifactId>
@@ -38,13 +39,35 @@
3839
<artifactId>slf4j-log4j12</artifactId>
3940
<version>1.7.21</version>
4041
</dependency>
42+
43+
<!--Testing-->
44+
<dependency>
45+
<groupId>junit</groupId>
46+
<artifactId>junit</artifactId>
47+
<version>4.12</version>
48+
<scope>test</scope>
49+
</dependency>
50+
51+
<dependency>
52+
<groupId>org.mockito</groupId>
53+
<artifactId>mockito-core</artifactId>
54+
<version>1.10.19</version>
55+
<scope>test</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.assertj</groupId>
59+
<artifactId>assertj-core</artifactId>
60+
<version>3.6.1</version>
61+
<scope>test</scope>
62+
</dependency>
4163
</dependencies>
4264
<repositories>
4365
<repository>
4466
<id>jcenter</id>
4567
<url>https://jcenter.bintray.com/</url>
4668
</repository>
4769
</repositories>
70+
4871
<build>
4972
<plugins>
5073
<plugin>
@@ -56,6 +79,11 @@
5679
<target>1.6</target>
5780
</configuration>
5881
</plugin>
82+
<plugin>
83+
<groupId>org.apache.maven.plugins</groupId>
84+
<artifactId>maven-surefire-plugin</artifactId>
85+
<version>2.12.4</version>
86+
</plugin>
5987
</plugins>
6088
</build>
6189
</project>

src/main/java/com/redhat/digkins/DiggerClient.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.redhat.digkins;
22

33
import com.offbytwo.jenkins.JenkinsServer;
4+
import com.redhat.digkins.model.BuildStatus;
45
import com.redhat.digkins.services.CreateJobService;
56
import com.redhat.digkins.services.TriggerBuildService;
67
import com.redhat.digkins.util.DiggerClientException;
@@ -69,27 +70,32 @@ public void createJob(String name, String gitRepo, String gitBranch) throws Digg
6970
* it and a build number is assigned to the build.
7071
* <p>
7172
* This method will block until there is a build number, or the given timeout period is passed. If the build is still in the queue
72-
* after the given timeout period, -1 is returned as the build number.
73+
* after the given timeout period, a {@code BuildStatus} is returned with state {@link BuildStatus.State#TIMED_OUT}.
7374
* <p>
7475
* Please note that timeout period is never meant to be very precise. It has the resolution of {@link TriggerBuildService#POLL_PERIOD} because
7576
* timeout is checked before every pull.
7677
* <p>
77-
* Similarly, -1 is returned if the build is stuck or cancelled on Jenkins side.
78+
* Similarly, {@link BuildStatus.State#CANCELLED_IN_QUEUE} is returned if the build is cancelled on Jenkins side and
79+
* {@link BuildStatus.State#STUCK_IN_QUEUE} is returned if the build is stuck.
7880
*
7981
* @param jobName name of the job to trigger the build
80-
* @param timeout how many milliseconds should this call block before returning -1. Should be larger than {@link TriggerBuildService#FIRST_CHECK_DELAY}
81-
* @return the build number. -1 if build is cancelled, stuck or in queue more than the given timeout period
82+
* @param timeout how many milliseconds should this call block before returning {@link BuildStatus.State#TIMED_OUT}.
83+
* Should be larger than {@link TriggerBuildService#FIRST_CHECK_DELAY}
84+
* @return the build status
8285
* @throws DiggerClientException if connection problems occur during connecting to Jenkins
8386
*/
84-
public long build(String jobName, long timeout) throws DiggerClientException {
87+
public BuildStatus build(String jobName, long timeout) throws DiggerClientException {
8588
final TriggerBuildService triggerBuildService = new TriggerBuildService(jenkins);
8689
try {
8790
return triggerBuildService.build(jobName, timeout);
8891
} catch (IOException e) {
8992
LOG.debug("Exception while connecting to Jenkins", e);
9093
throw new DiggerClientException(e);
9194
} catch (InterruptedException e) {
92-
LOG.debug("Exception while sleeping between checks", e);
95+
LOG.debug("Exception while waiting on Jenkins", e);
96+
throw new DiggerClientException(e);
97+
} catch (Throwable e) {
98+
LOG.debug("Exception while triggering a build", e);
9399
throw new DiggerClientException(e);
94100
}
95101
}
@@ -100,11 +106,11 @@ public long build(String jobName, long timeout) throws DiggerClientException {
100106
* Calls {@link #build(String, long)} with a default timeout of {@link #DEFAULT_BUILD_TIMEOUT}.
101107
*
102108
* @param jobName name of the job
103-
* @return the build number
109+
* @return the build status
104110
* @throws DiggerClientException if connection problems occur during connecting to Jenkins
105111
* @see #build(String, long)
106112
*/
107-
public long build(String jobName) throws DiggerClientException {
113+
public BuildStatus build(String jobName) throws DiggerClientException {
108114
return this.build(jobName, DEFAULT_BUILD_TIMEOUT);
109115
}
110116

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.redhat.digkins.model;
2+
3+
/**
4+
* Represents the status of a build.
5+
* <p>
6+
* The field {@link #buildNumber} will only be set if the
7+
* {@link #state} is {@link State#BUILDING}.
8+
**/
9+
public class BuildStatus {
10+
11+
public enum State {
12+
/**
13+
* Build is out of the queue and it is currently being executed.
14+
*/
15+
BUILDING,
16+
17+
/**
18+
* The max time to wait for the build get executed has passed.
19+
* This state doesn't have to mean build is stuck or etc.
20+
* It just means, the max waiting time has passed on the client side.
21+
*/
22+
TIMED_OUT,
23+
24+
/**
25+
* The build is cancelled in Jenkins before it started being executed.
26+
*/
27+
CANCELLED_IN_QUEUE,
28+
29+
/**
30+
* The build is stuck on Jenkins queue.
31+
*/
32+
STUCK_IN_QUEUE
33+
}
34+
35+
private final State state;
36+
private final int buildNumber;
37+
38+
public BuildStatus(State state, int buildNumber) {
39+
this.state = state;
40+
this.buildNumber = buildNumber;
41+
}
42+
43+
/**
44+
* @return state of the build
45+
*/
46+
public State getState() {
47+
return state;
48+
}
49+
50+
/**
51+
* This should only be valid if the
52+
* {@link #state} is {@link State#BUILDING}.
53+
*
54+
* @return the build number assigned by Jenkins
55+
*/
56+
public int getBuildNumber() {
57+
return buildNumber;
58+
}
59+
60+
@Override
61+
public String toString() {
62+
return "BuildStatus{" +
63+
"state=" + state +
64+
", buildNumber=" + buildNumber +
65+
'}';
66+
}
67+
}

src/main/java/com/redhat/digkins/services/TriggerBuildService.java

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.offbytwo.jenkins.model.JobWithDetails;
66
import com.offbytwo.jenkins.model.QueueItem;
77
import com.offbytwo.jenkins.model.QueueReference;
8+
import com.redhat.digkins.model.BuildStatus;
89
import org.slf4j.Logger;
910
import org.slf4j.LoggerFactory;
1011

@@ -28,39 +29,41 @@ public class TriggerBuildService {
2829
public static final long POLL_PERIOD = 2 * 1000L;
2930

3031

31-
private JenkinsServer jenkins;
32+
private JenkinsServer jenkinsServer;
3233

3334
/**
34-
* @param jenkins jenkins api instance
35+
* @param jenkinsServer jenkins api instance
3536
*/
36-
public TriggerBuildService(JenkinsServer jenkins) {
37-
this.jenkins = jenkins;
37+
public TriggerBuildService(JenkinsServer jenkinsServer) {
38+
this.jenkinsServer = jenkinsServer;
3839
}
3940

4041
/**
4142
* See the documentation in {@link com.redhat.digkins.DiggerClient#build(String, long)}
4243
*
4344
* @param jobName name of the job
4445
* @param timeout timeout
45-
* @return the build number
46+
* @return the build status
4647
* @throws IOException if connection problems occur during connecting to Jenkins
4748
* @throws InterruptedException if a problem occurs during sleeping between checks
4849
* @see com.redhat.digkins.DiggerClient#build(String, long)
4950
*/
50-
public long build(String jobName, long timeout) throws IOException, InterruptedException {
51-
final long timeoutTime = System.currentTimeMillis() + timeout;
51+
public BuildStatus build(String jobName, long timeout) throws IOException, InterruptedException {
52+
final long whenToTimeout = System.currentTimeMillis() + timeout;
5253

5354
LOG.debug("Going to build job with name: {}", jobName);
5455
LOG.debug("Going to timeout in {} msecs if build didn't start executing", timeout);
5556

56-
JobWithDetails job = jenkins.getJob(jobName);
57+
JobWithDetails job = jenkinsServer.getJob(jobName);
5758
if (job == null) {
59+
LOG.debug("Unable to find job for name '{}'", jobName);
5860
throw new IllegalArgumentException("Unable to find job for name '" + jobName + "'");
5961
}
6062

6163
final QueueReference queueReference = job.build();
6264
if (queueReference == null) {
6365
// this is probably an implementation problem we have here
66+
LOG.debug("Queue reference cannot be null!");
6467
throw new IllegalStateException("Queue reference cannot be null!");
6568
}
6669
LOG.debug("Build triggered; queue item reference: {}", queueReference.getQueueItemUrlPart());
@@ -74,22 +77,23 @@ public long build(String jobName, long timeout) throws IOException, InterruptedE
7477

7578
QueueItem queueItem;
7679
while (true) {
77-
queueItem = jenkins.getQueueItem(queueReference);
80+
queueItem = jenkinsServer.getQueueItem(queueReference);
7881
LOG.debug("Queue item : {}", queueItem);
7982

8083
if (queueItem == null) {
8184
// this is probably an implementation problem we have here
85+
LOG.debug("Queue item cannot be null!");
8286
throw new IllegalStateException("Queue item cannot be null!");
8387
}
8488

8589
LOG.debug("Build item cancelled:{}, blocked:{}, buildable:{}, stuck:{}", queueItem.isCancelled(), queueItem.isBlocked(), queueItem.isBuildable(), queueItem.isStuck());
8690

8791
if (queueItem.isCancelled()) {
88-
LOG.debug("Queue item is cancelled. Returning -1");
89-
return -1;
92+
LOG.debug("Queue item is cancelled. Returning CANCELLED_IN_QUEUE");
93+
return new BuildStatus(BuildStatus.State.CANCELLED_IN_QUEUE, -1);
9094
} else if (queueItem.isStuck()) {
91-
LOG.debug("Queue item is stuck. Returning -1");
92-
return -1;
95+
LOG.debug("Queue item is stuck. Returning STUCK_IN_QUEUE");
96+
return new BuildStatus(BuildStatus.State.STUCK_IN_QUEUE, -1);
9397
}
9498

9599
// do not return -1 if blocked.
@@ -99,15 +103,15 @@ public long build(String jobName, long timeout) throws IOException, InterruptedE
99103

100104
if (executable != null) {
101105
LOG.debug("Build has an executable. Returning build number: {}", executable.getNumber());
102-
return executable.getNumber();
106+
return new BuildStatus(BuildStatus.State.BUILDING, executable.getNumber().intValue());
103107
} else {
104108
LOG.debug("Build did not start executing yet.");
105-
if (timeoutTime < System.currentTimeMillis()) {
109+
if (whenToTimeout > System.currentTimeMillis()) {
106110
LOG.debug("Timeout period has not exceeded yet. Sleeping for {} msecs", POLL_PERIOD);
107111
Thread.sleep(POLL_PERIOD);
108112
} else {
109-
LOG.debug("Timeout period has exceeded. Returning -1.");
110-
return -1;
113+
LOG.debug("Timeout period has exceeded. Returning TIMED_OUT.");
114+
return new BuildStatus(BuildStatus.State.TIMED_OUT, -1);
111115
}
112116
}
113117

src/main/resources/log4j.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
</appender>
1212

1313
<logger name="com.redhat.digkins">
14-
<level value="DEBUG"/>
14+
<level value="INFO"/>
1515
</logger>
1616

1717
<root>

0 commit comments

Comments
 (0)