I've encountered a problem using the Google Cloud Storage GCS Client API, running on the local development server. I'm trying to write the bytes from a PDF file, and then read them back.
The code appears to write the (local fake)GCS file ok: (1) There appears to be an appropriate entry in the Development Console, and (2) there's a physical file in ~war/WEB-APP/appengine-generated (details below). However, when I attempt to read the bytes from the GCS file, it throws a FileNotFound exception when it attempts to get the metadata (filesize).
First, here's the core code, versions of GCS client read/write, with my debugging stmts left in for reference:
private void writeToFile(GcsFilename fullGcsFilename, byte[] content)
throws IOException
{
System.out.println("writeToFile:full="+fullGcsFilename.toString());
GcsOutputChannel outputChannel =
gcsService.createOrReplace(fullGcsFilename, GcsFileOptions.getDefaultInstance());
outputChannel.write(ByteBuffer.wrap(content));
outputChannel.close();
}
private byte[] readFromFile(GcsFilename fullGcsFilename)
throws IOException
{
System.out.println("readFromFile:full="+fullGcsFilename.toString());
int fileSize = (int) gcsService.getMetadata(fullGcsFilename).getLength(); [*][Exception thrown here]
ByteBuffer result = ByteBuffer.allocate(fileSize);
GcsInputChannel readChannel = gcsService.openReadChannel(fullGcsFilename, 0);
try {
readChannel.read(result);
} finally {
readChannel.close();
}
return result.array();
}
Here's the debugging output (in/out filenames appear to be the same):
----
writeToFile:full=GcsFilename(formrunnerbucket-r7yh23nb2, FA/MasterFormStore-6649846324789248)
----
readFromFile:full=GcsFilename(formrunnerbucket-r7yh23nb2, FA/MasterFormStore-6649846324789248)
----
Here's the observed results:
IN ~war/WEB-APP/appengine-generated:
-rw-r--r-- 1 ken staff 1679407 Nov 19 09:19 encoded_gs_key:L2dzL2Zvcm1ydW5uZXJidWNrZXQtcjd5aDIzbmIyL0ZBL01hc3RlckZvcm1TdG9yZS02NjQ5ODQ2MzI0Nzg5MjQ4
This is the expected PDF file, which can be opened (with Preview on a Mac).
----
In __GsFileInfo__ (in the empty Namespace)
Key: ag5mb3JtcnVubmVyLWhyZHJ7CxIOX19Hc0ZpbGVJbmZvX18iZ2VuY29kZWRfZ3Nfa2V5OkwyZHpMMlp2Y20xeWRXNXVaWEppZFdOclpYUXRjamQ1YURJemJtSXlMMFpCTDAxaGMzUmxja1p2Y20xVGRHOXlaUzAyTmpRNU9EUTJNekkwTnpnNU1qUTQM
ID/Name: encoded_gs_key:L2dzL2Zvcm1ydW5uZXJidWNrZXQtcjd5aDIzbmIyL0ZBL01hc3RlckZvcm1TdG9yZS02NjQ5ODQ2MzI0Nzg5MjQ4
content_type: application/octet-stream
filename: /gs/formrunnerbucket-r7yh23nb2/FA/MasterFormStore-6649846324789248
size: 1679407
[[The ID/Name appears to be identical to the filename appearing in ~war/WEB-APP/appengine-generated]]
---------------
In _ah_FakeCloudStorate_formrunnerbucket-r7yh23nb2:
Key: ag5mb3JtcnVubmVyLWhyZHJZCxIwX2FoX0Zha2VDbG91ZFN0b3JhZ2VfX2Zvcm1ydW5uZXJidWNrZXQtcjd5aDIzbmIyIiNGQS9NYXN0ZXJGb3JtU3RvcmUtNjY0OTg0NjMyNDc4OTI0OAyiARA1NjI5NDk5NTM0MjEzMTIw
ID/Name: FA/MasterFormStore-6649846324789248
options: <Blob: 483 bytes>
---------------
Here's the exception thrown in readFromFile above, at:
int fileSize = (int) gcsService.getMetadata(fullGcsFilename).getLength(); [*][Exception thrown here]
java.lang.RuntimeException: java.io.FileNotFoundException
at com.formrunner.pdf.PDFMaker.makePDFfromFormInstance(PDFMaker.java:132)
.........
Caused by: java.io.FileNotFoundException
at com.google.appengine.api.files.FileServiceImpl.translateException(FileServiceImpl.java:614)
at com.google.appengine.api.files.FileServiceImpl.makeSyncCall(FileServiceImpl.java:593)
at com.google.appengine.api.files.FileServiceImpl.stat(FileServiceImpl.java:383)
at com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.getObjectMetadata(LocalRawGcsService.java:215)
at com.google.appengine.tools.cloudstorage.GcsServiceImpl$2.run(GcsServiceImpl.java:73)
at com.google.appengine.tools.cloudstorage.GcsServiceImpl$2.run(GcsServiceImpl.java:70)
at com.google.appengine.tools.cloudstorage.RetryHelper.doRetry(RetryHelper.java:93)
at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:138)
at com.google.appengine.tools.cloudstorage.GcsServiceImpl.getMetadata(GcsServiceImpl.java:70)
at com.formrunner.data.GoogleCloudStorage.readFromFile(GoogleCloudStorage.java:62)
at com.formrunner.data.GoogleCloudStorage.getBytesAt(GoogleCloudStorage.java:55)
at com.formrunner.db.MasterFormStore.getContent(MasterFormStore.java:92)
at com.formrunner.forms.FormUtils.getFormBlob(FormUtils.java:314)
at com.formrunner.pdf.PDFUtils.getPDFDocFromInstance(PDFUtils.java:50)
at com.formrunner.pdf.PDFMaker.makePDFfromFormInstance(PDFMaker.java:75)
It may be worth noting that the LocalExample from the GCS Client API runs fine, but does not leave any trace in the
folder ~war/WEB-APP/appengine-generated nor in the Development Consolte (so far as I can find).
I hope someone can point out to me where I'm stumbling.
Thanks in advance,
Ken Bowen