Skip to content

Commit

Permalink
Fixed JENKINS-23049
Browse files Browse the repository at this point in the history
Better error handling in BlobStore upload
  • Loading branch information
felfert committed Nov 11, 2016
1 parent c288237 commit 13fa332
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
Expand Up @@ -3,6 +3,9 @@
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import shaded.com.google.common.base.Strings;
import shaded.com.google.common.collect.ImmutableSet;
Expand Down Expand Up @@ -34,7 +37,9 @@
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.domain.Location;
import org.jclouds.enterprise.config.EnterpriseConfigurationModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.providers.Providers;

import org.kohsuke.stapler.AncestorInPath;
Expand Down Expand Up @@ -126,7 +131,13 @@ public void setCredentialsId(final String value) {
credentialsId = value;
}

static final Iterable<Module> MODULES = ImmutableSet.<Module>of(new EnterpriseConfigurationModule());
static final Iterable<Module> MODULES = ImmutableSet.<Module>of(new JDKLoggingModule() {
@Override
public org.jclouds.logging.Logger.LoggerFactory createLoggerFactory() {
return new BlobStoreLogger.Factory();
}
}, new EnterpriseConfigurationModule());


static BlobStoreContext ctx(String providerName, String credentialsId, Properties overrides) {
StandardUsernameCredentials u = CredentialsHelper.getCredentialsById(credentialsId);
Expand Down Expand Up @@ -166,20 +177,17 @@ static BlobStoreContext ctx(String providerName, String credentialsId, String en
* @throws IOException if an IO error occurs.
* @throws InterruptedException If the upload gets interrupted.
*/
public void upload(String container, String path, FilePath filePath) throws IOException, InterruptedException {
public void upload(final String container, final String path, final FilePath filePath) throws IOException, InterruptedException {
if (filePath.isDirectory()) {
throw new IOException(filePath + " is a directory");
}
final BlobStoreContext context = ctx(providerName, credentialsId, endPointUrl, trustAll);
BlobStoreContext context = ctx(providerName, credentialsId, endPointUrl, trustAll);
try {
final BlobStore blobStore = context.getBlobStore();
BlobStore blobStore = context.getBlobStore();
final Location location = Iterables.getOnlyElement(blobStore.listAssignableLocations());
if (!blobStore.containerExists(container)) {
LOGGER.info("Creating container " + container);
blobStore.createContainerInLocation(null, container);
}
if (!path.isEmpty() && !blobStore.directoryExists(container, path)) {
LOGGER.info("Creating directory " + path + " in container " + container);
blobStore.createDirectory(container, path);
blobStore.createContainerInLocation(location, container);
}
String destPath;
if (path.isEmpty()) {
Expand All @@ -188,9 +196,39 @@ public void upload(String container, String path, FilePath filePath) throws IOEx
destPath = path + "/" + filePath.getName();
}
LOGGER.info("Publishing now to container: " + container + " path: " + destPath);
Blob blob = context.getBlobStore().blobBuilder(destPath).payload(filePath.read()).build();
context.getBlobStore().putBlob(container, blob);
LOGGER.info("Published " + destPath + " to container " + container + " with profile " + profileName);
MessageDigest md5 = MessageDigest.getInstance("MD5");
DigestInputStream dis = new DigestInputStream(filePath.read(), md5);

Blob blob = blobStore.blobBuilder(destPath)
.payload(dis).contentLength(filePath.length()).build();
blobStore.putBlob(container, blob);
String md5local = Util.toHexString(md5.digest()).toLowerCase();

do {
context.close();
context = ctx(providerName, credentialsId, endPointUrl, trustAll);
blobStore = context.getBlobStore();
try {
LOGGER.info("Fetching remote MD5sum for " + destPath);
String md5remote = blobStore.blobMetadata(container, destPath)
.getContentMetadata().getContentMD5AsHashCode().toString();
if (md5local.equals(md5remote)) {
LOGGER.info("Published " + destPath + " to container " + container + " with profile " + profileName);
} else {
LOGGER.warning("MD5 mismatch while publishing " + destPath + " to container " + container + " with profile " + profileName);
throw new IOException("MD5 mismatch while publishing");
}
break;
} catch (IllegalStateException ise) {
// Happens, if the remote MD5sum is not yet available.
if (!ise.getMessage().contains("absent value")) {
throw ise;
}
Thread.sleep(1000);
}
} while (true);
} catch (NoSuchAlgorithmException e) {
throw new IOException("MD5 not installed (should never happen).");
} finally {
context.close();
}
Expand Down
Expand Up @@ -205,8 +205,8 @@ private String getDestinationPath(String path, boolean appendFilePath, String ws
if (resultPath.endsWith("/")) {
resultPath = resultPath.substring(0, resultPath.length() - 1);
}

return resultPath;
// Eliminate double slashes /./ and /../ for the same reason.
return resultPath.replaceAll("//+", "/").replaceAll("/\\.+/", "/");
}

/**
Expand Down

0 comments on commit 13fa332

Please sign in to comment.