use of com.aws.greengrass.componentmanager.exceptions.ArtifactChecksumMismatchException in project aws-greengrass-nucleus by aws-greengrass.
the class ArtifactDownloader method download.
/**
* Download an artifact from remote. This call can take a long time if the network is intermittent.
*
* @return file handle of the downloaded file
* @throws IOException if I/O error occurred in network/disk
* @throws InterruptedException if interrupted in downloading
* @throws PackageDownloadException if error occurred in download process
*/
@SuppressWarnings({ "PMD.AvoidCatchingGenericException", "PMD.AvoidRethrowingException" })
public File download() throws PackageDownloadException, IOException, InterruptedException {
MessageDigest messageDigest;
try {
if (artifact.getAlgorithm() == null) {
throw new ArtifactChecksumMismatchException(getErrorString("Algorithm missing from artifact."));
}
messageDigest = MessageDigest.getInstance(artifact.getAlgorithm());
} catch (NoSuchAlgorithmException e) {
throw new ArtifactChecksumMismatchException(getErrorString("Algorithm requested for artifact checksum is not supported"), e);
}
saveToPath = getArtifactFile().toPath();
long artifactSize = getDownloadSize();
final AtomicLong offset = new AtomicLong(0);
// If there are partially downloaded artifact existing on device
if (Files.exists(saveToPath)) {
if (Files.size(saveToPath) > artifactSize) {
// Existing file is corrupted, it's larger than defined in artifact.
// Normally shouldn't happen, corrupted files are deleted every time.
logger.atError().log("existing file corrupted. Expected size: {}, Actual size: {}." + " Removing and retrying download.", artifactSize, Files.size(saveToPath));
Files.deleteIfExists(saveToPath);
} else {
offset.set(Files.size(saveToPath));
updateDigestFromFile(saveToPath, messageDigest);
}
}
try {
// download for 10 times before giving up.
return RetryUtils.runWithRetry(checksumMismatchRetryConfig, () -> {
while (offset.get() < artifactSize) {
long downloadedBytes = download(offset.get(), artifactSize - 1, messageDigest);
offset.addAndGet(downloadedBytes);
}
String digest = Base64.getEncoder().encodeToString(messageDigest.digest());
if (!digest.equals(artifact.getChecksum())) {
// Handle failure in integrity check, delete bad file then throw
Files.deleteIfExists(saveToPath);
offset.set(0);
messageDigest.reset();
throw new ArtifactChecksumMismatchException("Integrity check for downloaded artifact failed. " + "Probably due to file corruption.");
}
logger.atDebug().setEventType("download-artifact").log("Passed integrity check");
return saveToPath.toFile();
}, "download-artifact", logger);
} catch (InterruptedException e) {
throw e;
} catch (Exception e) {
throw new PackageDownloadException(getErrorString("Failed to download the artifact"), e);
}
}
Aggregations