in google-storage-agent/src/main/kotlin/jetbrains/buildServer/artifacts/google/publish/GoogleSignedUrlFileUploader.kt [28:100]
override fun publishFiles(
build: AgentRunningBuild,
pathPrefix: String,
filesToPublish: Map<File, String>
) = runBlocking {
filesToPublish.map { (file, path) ->
FilePublishingContext(file, path, pathPrefix)
}.map {
var signedUrl = getSignedUrl(build, it.blobName, it.contentType)
var locationUrl = getLocationUrl(signedUrl, it.contentType)
async(Dispatchers.IO) {
with(it) {
exceptionsWrapper {
var range = 0L
var response: HttpResponse
retry(
build.buildLogger,
ExponentialBackOff(),
{
logExceptions(build.buildLogger) {
if (range < 0) {
range = getCurrentRange(locationUrl, file)
}
val fileLength = file.length()
val content = FileRangeContent(contentType, file).apply {
this.range = range
}
val putRequest =
requestFactory.buildPutRequest(GenericUrl(locationUrl), content).apply {
if (range > 0) {
this.headers.contentRange =
"bytes ${range + 1}-${fileLength - 1}/$fileLength"
}
}
response = putRequest.execute()
// reset range for non-success cases
range = -1
when {
response.isSuccessStatusCode -> {
ArtifactDataInstance.create(filePath, fileLength)
}
HttpBackOffUnsuccessfulResponseHandler.BackOffRequired.ON_SERVER_ERROR.isRequired(
response
) -> {
// will throw regular IllegalStateException
// which will allow regular retry mechanism to handle it (see also handler below)
error(getHttpError(response))
}
else -> {
throw IOException("Invalid response code ${response.statusCode}. Response body:\n" + response.parseAsString())
}
}
}
},
{ err ->
if (err !is IllegalStateException) {
// let's try to recreate signed URL
signedUrl = getSignedUrl(build, it.blobName, it.contentType)
locationUrl = getLocationUrl(signedUrl, it.contentType)
}
}
)
}
}
}
}.map { it.await() }
}