final String url = instance.getFullAttachmentUrl(info.getPath());
final Long expectedBytes = info.hasSizeBytes() ? info.getSizeBytes() : null;
final String mimeType = info.hasMimeType() ? info.getMimeType() : null;
final String filename = info.hasFilename() ? info.getFilename() : DEFAULT_FILE_NAME;
try {
return new RetryHelper().run(
new RetryHelper.Body<AttachmentId>() {
@Override public AttachmentId run() throws RetryableFailure, PermanentFailure {
log.info("Fetching attachment " + url);
try {
// We could fetch several attachments asynchronously in parallel to save instance
// hours, but let's hope that the connection between App Engine and Google Wave
// is fast enough to make that irrelevant.
HTTPResponse response = urlfetch.fetch(
new HTTPRequest(new URL(url), HTTPMethod.GET));
if (response.getResponseCode() != 200) {
throw new RetryableFailure("Unexpected response code: "
+ response.getResponseCode());
}
byte[] bytes = response.getContent();
if (expectedBytes != null) {
Assert.check(expectedBytes == bytes.length, "Expected %s bytes, got %s: %s",
expectedBytes, bytes.length, prettyBytes(bytes));
}
final AppEngineFile file = dump(mimeType, filename, ByteBuffer.wrap(bytes));
log.info("Wrote file " + file);
BlobKey blobKey =
// NOTE(ohler): When running locally with unapplied jobs
// enabled, getBlobKey() sometimes returns null here even
// though it shouldn't, according to its documentation. So
// we retry. Not sure if this is needed when deployed.
new RetryHelper().run(
new RetryHelper.Body<BlobKey>() {
@Override public BlobKey run() throws RetryableFailure {
BlobKey key = getFileService().getBlobKey(file);
if (key != null) {
return key;