1717package io .spring .concourse .releasescripts .bintray ;
1818
1919import java .net .URI ;
20- import java .util .Objects ;
21- import java .util .concurrent .TimeUnit ;
20+ import java .time .Duration ;
21+ import java .util .HashSet ;
22+ import java .util .Set ;
2223
2324import io .spring .concourse .releasescripts .ReleaseInfo ;
2425import io .spring .concourse .releasescripts .sonatype .SonatypeProperties ;
2526import io .spring .concourse .releasescripts .sonatype .SonatypeService ;
26- import io .spring .concourse .releasescripts .system .ConsoleLogger ;
2727import org .awaitility .core .ConditionTimeoutException ;
28+ import org .slf4j .Logger ;
29+ import org .slf4j .LoggerFactory ;
2830
2931import org .springframework .boot .web .client .RestTemplateBuilder ;
30- import org .springframework .http .HttpStatus ;
3132import org .springframework .http .MediaType ;
3233import org .springframework .http .RequestEntity ;
3334import org .springframework .stereotype .Component ;
4546@ Component
4647public class BintrayService {
4748
49+ private static final Logger logger = LoggerFactory .getLogger (BintrayService .class );
50+
4851 private static final String BINTRAY_URL = "https://api.bintray.com/" ;
4952
5053 private static final String GRADLE_PLUGIN_REQUEST = "[ { \" name\" : \" gradle-plugin\" , \" values\" : [\" org.springframework.boot:org.springframework.boot:spring-boot-gradle-plugin\" ] } ]" ;
@@ -57,8 +60,6 @@ public class BintrayService {
5760
5861 private final SonatypeService sonatypeService ;
5962
60- private static final ConsoleLogger console = new ConsoleLogger ();
61-
6263 public BintrayService (RestTemplateBuilder builder , BintrayProperties bintrayProperties ,
6364 SonatypeProperties sonatypeProperties , SonatypeService sonatypeService ) {
6465 this .bintrayProperties = bintrayProperties ;
@@ -72,32 +73,48 @@ public BintrayService(RestTemplateBuilder builder, BintrayProperties bintrayProp
7273 this .restTemplate = builder .build ();
7374 }
7475
75- public boolean isDistributionComplete (ReleaseInfo releaseInfo ) {
76- RequestEntity <Void > allFilesRequest = getRequest (releaseInfo , 1 );
77- Object [] allFiles = waitAtMost (5 , TimeUnit .MINUTES ).with ().pollDelay (20 , TimeUnit .SECONDS ).until (() -> {
78- try {
79- return this .restTemplate .exchange (allFilesRequest , Object [].class ).getBody ();
80- }
81- catch (HttpClientErrorException ex ) {
82- if (ex .getStatusCode () != HttpStatus .NOT_FOUND ) {
83- throw ex ;
84- }
85- return null ;
86- }
87- }, Objects ::nonNull );
88- RequestEntity <Void > publishedFilesRequest = getRequest (releaseInfo , 0 );
76+ public boolean isDistributionComplete (ReleaseInfo releaseInfo , Set <String > requiredDigets , Duration timeout ) {
77+ return isDistributionComplete (releaseInfo , requiredDigets , timeout , Duration .ofSeconds (20 ));
78+ }
79+
80+ public boolean isDistributionComplete (ReleaseInfo releaseInfo , Set <String > requiredDigets , Duration timeout ,
81+ Duration pollInterval ) {
82+ logger .debug ("Checking if distribution is complete" );
83+ RequestEntity <Void > request = getRequest (releaseInfo , 0 );
8984 try {
90- waitAtMost (40 , TimeUnit .MINUTES ).with ().pollDelay (20 , TimeUnit .SECONDS ).until (() -> {
91- Object [] publishedFiles = this .restTemplate .exchange (publishedFilesRequest , Object [].class ).getBody ();
92- return allFiles .length == publishedFiles .length ;
85+ waitAtMost (timeout ).with ().pollDelay (Duration .ZERO ).pollInterval (pollInterval ).until (() -> {
86+ logger .debug ("Checking bintray" );
87+ PackageFile [] published = this .restTemplate .exchange (request , PackageFile [].class ).getBody ();
88+ return hasPublishedAll (published , requiredDigets );
9389 });
9490 }
9591 catch (ConditionTimeoutException ex ) {
92+ logger .debug ("Timeout checking bintray" );
9693 return false ;
9794 }
9895 return true ;
9996 }
10097
98+ private boolean hasPublishedAll (PackageFile [] published , Set <String > requiredDigets ) {
99+ if (published == null || published .length == 0 ) {
100+ logger .debug ("Bintray returned no published files" );
101+ return false ;
102+ }
103+ Set <String > remaining = new HashSet <>(requiredDigets );
104+ for (PackageFile publishedFile : published ) {
105+ logger .debug (
106+ "Found published file " + publishedFile .getName () + " with digest " + publishedFile .getSha256 ());
107+ remaining .remove (publishedFile .getSha256 ());
108+ }
109+ if (remaining .isEmpty ()) {
110+ logger .debug ("Found all required digests" );
111+ return true ;
112+ }
113+ logger .debug ("Some digests have not been published:" );
114+ remaining .forEach (logger ::debug );
115+ return false ;
116+ }
117+
101118 private RequestEntity <Void > getRequest (ReleaseInfo releaseInfo , int includeUnpublished ) {
102119 return RequestEntity .get (URI .create (BINTRAY_URL + "packages/" + this .bintrayProperties .getSubject () + "/"
103120 + this .bintrayProperties .getRepo () + "/" + releaseInfo .getGroupId () + "/versions/"
@@ -109,16 +126,18 @@ private RequestEntity<Void> getRequest(ReleaseInfo releaseInfo, int includeUnpub
109126 * @param releaseInfo the release information
110127 */
111128 public void publishGradlePlugin (ReleaseInfo releaseInfo ) {
129+ logger .debug ("Publishing Gradle Pluging" );
112130 RequestEntity <String > requestEntity = RequestEntity
113131 .post (URI .create (BINTRAY_URL + "packages/" + this .bintrayProperties .getSubject () + "/"
114132 + this .bintrayProperties .getRepo () + "/" + releaseInfo .getGroupId () + "/versions/"
115133 + releaseInfo .getVersion () + "/attributes" ))
116134 .contentType (MediaType .APPLICATION_JSON ).body (GRADLE_PLUGIN_REQUEST );
117135 try {
118136 this .restTemplate .exchange (requestEntity , Object .class );
137+ logger .debug ("Publishing Gradle Pluging complete" );
119138 }
120139 catch (HttpClientErrorException ex ) {
121- console . log ("Failed to add attribute to gradle plugin." );
140+ logger . info ("Failed to add attribute to gradle plugin." );
122141 throw ex ;
123142 }
124143 }
@@ -128,8 +147,9 @@ public void publishGradlePlugin(ReleaseInfo releaseInfo) {
128147 * @param releaseInfo the release information
129148 */
130149 public void syncToMavenCentral (ReleaseInfo releaseInfo ) {
131- console . log ("Calling Bintray to sync to Sonatype" );
150+ logger . info ("Calling Bintray to sync to Sonatype" );
132151 if (this .sonatypeService .artifactsPublished (releaseInfo )) {
152+ logger .info ("Artifacts already published" );
133153 return ;
134154 }
135155 RequestEntity <SonatypeProperties > requestEntity = RequestEntity
@@ -139,9 +159,10 @@ public void syncToMavenCentral(ReleaseInfo releaseInfo) {
139159 .contentType (MediaType .APPLICATION_JSON ).body (this .sonatypeProperties );
140160 try {
141161 this .restTemplate .exchange (requestEntity , Object .class );
162+ logger .debug ("Sync complete" );
142163 }
143164 catch (HttpClientErrorException ex ) {
144- console . log ("Failed to sync." );
165+ logger . info ("Failed to sync." );
145166 throw ex ;
146167 }
147168 }
0 commit comments