Skip to content

Commit 891c712

Browse files
committed
Wait for distribution to reach Bintray before checking its completeness
Previously, as soon as the distribution of a release from Artifactory to Bintray had been initiated we would start checking if it was complete. This created a race condition between the distribution being created and us checking if it was complete. If the check won the race and happened before the creation, Bintray would respond with a 404. This commit updates BintrayService to wait for up to 5 minutes for the distribution to be created on Bintray. Once it has been created we then wait for up to 40 minutes for it to be complete as we did before. The use of Awaitility has been introduced in this commit to simplify the logic required to wait for the distribution's creation and completion. Closes gh-18902
1 parent 8b1ff0a commit 891c712

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

ci/images/releasescripts/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
<groupId>com.fasterxml.jackson.module</groupId>
4545
<artifactId>jackson-module-parameter-names</artifactId>
4646
</dependency>
47+
<dependency>
48+
<groupId>org.awaitility</groupId>
49+
<artifactId>awaitility</artifactId>
50+
</dependency>
4751
<dependency>
4852
<groupId>org.springframework.boot</groupId>
4953
<artifactId>spring-boot-starter-test</artifactId>

ci/images/releasescripts/src/main/java/io/spring/concourse/releasescripts/bintray/BintrayService.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,25 @@
1717
package io.spring.concourse.releasescripts.bintray;
1818

1919
import java.net.URI;
20+
import java.util.Objects;
21+
import java.util.concurrent.TimeUnit;
2022

2123
import io.spring.concourse.releasescripts.ReleaseInfo;
2224
import io.spring.concourse.releasescripts.sonatype.SonatypeProperties;
2325
import io.spring.concourse.releasescripts.sonatype.SonatypeService;
2426
import io.spring.concourse.releasescripts.system.ConsoleLogger;
27+
import org.awaitility.core.ConditionTimeoutException;
2528

2629
import org.springframework.boot.web.client.RestTemplateBuilder;
30+
import org.springframework.http.HttpStatus;
2731
import org.springframework.http.MediaType;
2832
import org.springframework.http.RequestEntity;
2933
import org.springframework.stereotype.Component;
3034
import org.springframework.web.client.HttpClientErrorException;
3135
import org.springframework.web.client.RestTemplate;
3236

37+
import static org.awaitility.Awaitility.waitAtMost;
38+
3339
/**
3440
* Central class for interacting with Bintray's REST API.
3541
*
@@ -64,25 +70,29 @@ public BintrayService(RestTemplateBuilder builder, BintrayProperties bintrayProp
6470
}
6571

6672
public boolean isDistributionComplete(ReleaseInfo releaseInfo) {
67-
RequestEntity<Void> publishedFilesRequest = getRequest(releaseInfo, 0);
6873
RequestEntity<Void> allFilesRequest = getRequest(releaseInfo, 1);
69-
Object[] allFiles = this.restTemplate.exchange(allFilesRequest, Object[].class).getBody();
70-
int count = 0;
71-
while (count < 120) {
72-
Object[] publishedFiles = this.restTemplate.exchange(publishedFilesRequest, Object[].class).getBody();
73-
int unpublished = allFiles.length - publishedFiles.length;
74-
if (unpublished == 0) {
75-
return true;
76-
}
77-
count++;
74+
Object[] allFiles = waitAtMost(5, TimeUnit.MINUTES).with().pollDelay(20, TimeUnit.SECONDS).until(() -> {
7875
try {
79-
Thread.sleep(20000);
76+
return this.restTemplate.exchange(allFilesRequest, Object[].class).getBody();
8077
}
81-
catch (InterruptedException e) {
82-
78+
catch (HttpClientErrorException ex) {
79+
if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
80+
throw ex;
81+
}
82+
return null;
8383
}
84+
}, Objects::nonNull);
85+
RequestEntity<Void> publishedFilesRequest = getRequest(releaseInfo, 0);
86+
try {
87+
waitAtMost(40, TimeUnit.MINUTES).with().pollDelay(20, TimeUnit.SECONDS).until(() -> {
88+
Object[] publishedFiles = this.restTemplate.exchange(publishedFilesRequest, Object[].class).getBody();
89+
return allFiles.length == publishedFiles.length;
90+
});
91+
}
92+
catch (ConditionTimeoutException ex) {
93+
return false;
8494
}
85-
return false;
95+
return true;
8696
}
8797

8898
private RequestEntity<Void> getRequest(ReleaseInfo releaseInfo, int includeUnpublished) {

ci/images/releasescripts/src/test/java/io/spring/concourse/releasescripts/bintray/BintrayServiceTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.boot.test.mock.mockito.MockBean;
2929
import org.springframework.core.io.ClassPathResource;
3030
import org.springframework.http.HttpMethod;
31+
import org.springframework.http.HttpStatus;
3132
import org.springframework.http.MediaType;
3233
import org.springframework.test.web.client.ExpectedCount;
3334
import org.springframework.test.web.client.MockRestServiceServer;
@@ -40,6 +41,7 @@
4041
import static org.springframework.test.web.client.match.MockRestRequestMatchers.header;
4142
import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
4243
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
44+
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
4345
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
4446

4547
/**
@@ -73,6 +75,11 @@ void tearDown() {
7375

7476
@Test
7577
void isDistributionComplete() throws Exception {
78+
this.server
79+
.expect(requestTo(String.format(
80+
"https://api.bintray.com/packages/%s/%s/%s/versions/%s/files?include_unpublished=%s",
81+
this.properties.getSubject(), this.properties.getRepo(), "example", "1.1.0.RELEASE", 1)))
82+
.andRespond(withStatus(HttpStatus.NOT_FOUND));
7683
setupGetPackageFiles(1, "all-package-files.json");
7784
setupGetPackageFiles(0, "published-files.json");
7885
setupGetPackageFiles(0, "all-package-files.json");

0 commit comments

Comments
 (0)