Merge branch '2.3.x'

pull/21936/head
Phillip Webb 4 years ago
commit 961b7cdf81

@ -124,26 +124,27 @@ public class ArtifactoryService {
*/ */
public void distribute(String sourceRepo, ReleaseInfo releaseInfo, Set<String> artifactDigests) { public void distribute(String sourceRepo, ReleaseInfo releaseInfo, Set<String> artifactDigests) {
logger.debug("Attempting distribute via Artifactory"); logger.debug("Attempting distribute via Artifactory");
if (this.bintrayService.isDistributionComplete(releaseInfo, artifactDigests, Duration.ofMinutes(2))) { if (!this.bintrayService.isDistributionStarted(releaseInfo)) {
logger.info("Distribution already complete"); startDistribute(sourceRepo, releaseInfo);
return;
} }
if (!this.bintrayService.isDistributionComplete(releaseInfo, artifactDigests, Duration.ofMinutes(60))) {
throw new DistributionTimeoutException("Distribution timed out.");
}
}
private void startDistribute(String sourceRepo, ReleaseInfo releaseInfo) {
DistributionRequest request = new DistributionRequest(new String[] { sourceRepo }); DistributionRequest request = new DistributionRequest(new String[] { sourceRepo });
RequestEntity<DistributionRequest> requestEntity = RequestEntity RequestEntity<DistributionRequest> requestEntity = RequestEntity
.post(URI.create(DISTRIBUTION_URL + releaseInfo.getBuildName() + "/" + releaseInfo.getBuildNumber())) .post(URI.create(DISTRIBUTION_URL + releaseInfo.getBuildName() + "/" + releaseInfo.getBuildNumber()))
.contentType(MediaType.APPLICATION_JSON).body(request); .contentType(MediaType.APPLICATION_JSON).body(request);
try { try {
this.restTemplate.exchange(requestEntity, Object.class); this.restTemplate.exchange(requestEntity, Object.class);
logger.debug("Distribution call completed"); logger.debug("Distribute call completed");
} }
catch (HttpClientErrorException ex) { catch (HttpClientErrorException ex) {
logger.info("Failed to distribute."); logger.info("Failed to distribute.");
throw ex; throw ex;
} }
if (!this.bintrayService.isDistributionComplete(releaseInfo, artifactDigests, Duration.ofMinutes(60))) {
throw new DistributionTimeoutException("Distribution timed out.");
}
} }
private PromotionRequest getPromotionRequest(String targetRepo) { private PromotionRequest getPromotionRequest(String targetRepo) {

@ -29,6 +29,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity; import org.springframework.http.RequestEntity;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -73,6 +74,22 @@ public class BintrayService {
this.restTemplate = builder.build(); this.restTemplate = builder.build();
} }
public boolean isDistributionStarted(ReleaseInfo releaseInfo) {
logger.debug("Checking if distribution is started");
RequestEntity<Void> request = getPackageFilesRequest(releaseInfo, 1);
try {
logger.debug("Checking bintray");
this.restTemplate.exchange(request, PackageFile[].class).getBody();
return true;
}
catch (HttpClientErrorException ex) {
if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
throw ex;
}
return false;
}
}
public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set<String> requiredDigests, Duration timeout) { public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set<String> requiredDigests, Duration timeout) {
return isDistributionComplete(releaseInfo, requiredDigests, timeout, Duration.ofSeconds(20)); return isDistributionComplete(releaseInfo, requiredDigests, timeout, Duration.ofSeconds(20));
} }
@ -80,7 +97,7 @@ public class BintrayService {
public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set<String> requiredDigests, Duration timeout, public boolean isDistributionComplete(ReleaseInfo releaseInfo, Set<String> requiredDigests, Duration timeout,
Duration pollInterval) { Duration pollInterval) {
logger.debug("Checking if distribution is complete"); logger.debug("Checking if distribution is complete");
RequestEntity<Void> request = getRequest(releaseInfo, 0); RequestEntity<Void> request = getPackageFilesRequest(releaseInfo, 0);
try { try {
waitAtMost(timeout).with().pollDelay(Duration.ZERO).pollInterval(pollInterval).until(() -> { waitAtMost(timeout).with().pollDelay(Duration.ZERO).pollInterval(pollInterval).until(() -> {
logger.debug("Checking bintray"); logger.debug("Checking bintray");
@ -115,7 +132,7 @@ public class BintrayService {
return false; return false;
} }
private RequestEntity<Void> getRequest(ReleaseInfo releaseInfo, int includeUnpublished) { private RequestEntity<Void> getPackageFilesRequest(ReleaseInfo releaseInfo, int includeUnpublished) {
return RequestEntity.get(URI.create(BINTRAY_URL + "packages/" + this.bintrayProperties.getSubject() + "/" return RequestEntity.get(URI.create(BINTRAY_URL + "packages/" + this.bintrayProperties.getSubject() + "/"
+ this.bintrayProperties.getRepo() + "/" + releaseInfo.getGroupId() + "/versions/" + this.bintrayProperties.getRepo() + "/" + releaseInfo.getGroupId() + "/versions/"
+ releaseInfo.getVersion() + "/files?include_unpublished=" + includeUnpublished)).build(); + releaseInfo.getVersion() + "/files?include_unpublished=" + includeUnpublished)).build();

@ -63,9 +63,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
@EnableConfigurationProperties(ArtifactoryProperties.class) @EnableConfigurationProperties(ArtifactoryProperties.class)
class ArtifactoryServiceTests { class ArtifactoryServiceTests {
private static final Duration SHORT_TIMEOUT = Duration.ofMinutes(2); private static final Duration TIMEOUT = Duration.ofMinutes(60);
private static final Duration LONG_TIMEOUT = Duration.ofMinutes(60);
@Autowired @Autowired
private ArtifactoryService service; private ArtifactoryService service;
@ -133,8 +131,8 @@ class ArtifactoryServiceTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
void distributeWhenSuccessful() throws Exception { void distributeWhenSuccessful() throws Exception {
ReleaseInfo releaseInfo = getReleaseInfo(); ReleaseInfo releaseInfo = getReleaseInfo();
given(this.bintrayService.isDistributionComplete(eq(releaseInfo), (Set<String>) any(), any())).willReturn(false, given(this.bintrayService.isDistributionStarted(eq(releaseInfo))).willReturn(false);
true); given(this.bintrayService.isDistributionComplete(eq(releaseInfo), (Set<String>) any(), any())).willReturn(true);
this.server.expect(requestTo("https://repo.spring.io/api/build/distribute/example-build/example-build-1")) this.server.expect(requestTo("https://repo.spring.io/api/build/distribute/example-build/example-build-1"))
.andExpect(method(HttpMethod.POST)) .andExpect(method(HttpMethod.POST))
.andExpect(content().json( .andExpect(content().json(
@ -146,8 +144,7 @@ class ArtifactoryServiceTests {
this.service.distribute("libs-release-local", releaseInfo, artifactDigests); this.service.distribute("libs-release-local", releaseInfo, artifactDigests);
this.server.verify(); this.server.verify();
InOrder ordered = inOrder(this.bintrayService); InOrder ordered = inOrder(this.bintrayService);
ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, SHORT_TIMEOUT); ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, TIMEOUT);
ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, LONG_TIMEOUT);
} }
@Test @Test
@ -165,7 +162,7 @@ class ArtifactoryServiceTests {
assertThatExceptionOfType(HttpClientErrorException.class) assertThatExceptionOfType(HttpClientErrorException.class)
.isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests)); .isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests));
this.server.verify(); this.server.verify();
verify(this.bintrayService, times(1)).isDistributionComplete(releaseInfo, artifactDigests, SHORT_TIMEOUT); verify(this.bintrayService, times(1)).isDistributionStarted(releaseInfo);
verifyNoMoreInteractions(this.bintrayService); verifyNoMoreInteractions(this.bintrayService);
} }
@ -189,8 +186,7 @@ class ArtifactoryServiceTests {
.isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests)); .isThrownBy(() -> this.service.distribute("libs-release-local", releaseInfo, artifactDigests));
this.server.verify(); this.server.verify();
InOrder ordered = inOrder(this.bintrayService); InOrder ordered = inOrder(this.bintrayService);
ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, SHORT_TIMEOUT); ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, TIMEOUT);
ordered.verify(this.bintrayService).isDistributionComplete(releaseInfo, artifactDigests, LONG_TIMEOUT);
} }
private ReleaseInfo getReleaseInfo() { private ReleaseInfo getReleaseInfo() {

Loading…
Cancel
Save