userDSSR
userDSSR

Reputation: 657

Java based Google App Engine and Google Drive API for Service Accounts

I have the following program on Eclipse in the Google App Engine Framework and it is working with Google Drive API. New files are created in Google Drive. I have a folder ID - that is being shared between the Service Account and my personal Gmail account. When I run the program on eclipse, I can see the files being generated on google drive.

However, when I deploy the same program on GAE, it fails to create the files on Google Drive. Any pointers that could help.

public class GDrive implements Callable<String> {

private static HttpTransport    httpTransport;
private static String           APPLICATION_NAME        = "xxxxxxx";
private static String           USER_EMAIL              = "[email protected]";
private static JacksonFactory   JSON_FACTORY            =  JacksonFactory.getDefaultInstance();
private static String           SERVICE_ACCOUNT_EMAIL   =  "[email protected]";
private static String           CLIENT_ID               =  "xx06238724813717381290";
private static String           KEY_PASSWORD            =  "notasecret";
private static String           CLIENT_SECRET_P12_LOC   =  "file.p12";

MyConstants  obMyConstants = new MyConstants();


public void insertLog(RootLog obRootLog) throws IOException, GeneralSecurityException {

    String LogFolderId = obLBLSSS_Constants.LogFolderId;
    //ID of the Parent Folder in Google Drive

    httpTransport = GoogleNetHttpTransport.newTrustedTransport(); 


    GoogleCredential credential = new GoogleCredential.Builder()
              .setTransport(httpTransport)
              .setJsonFactory(JSON_FACTORY)
              .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
              .setClientSecrets(CLIENT_ID, KEY_PASSWORD)
              .setServiceAccountScopes(DriveScopes.all())
              .setServiceAccountPrivateKeyFromP12File(
                      new java.io.File(CLIENT_SECRET_P12_LOC))
              .build();


    Drive driveService = new Drive.Builder(httpTransport, JSON_FACTORY,credential)
              .setApplicationName(APPLICATION_NAME).build();

    Gson gson           = new GsonBuilder().create();   
    String eJsonOutput  = gson.toJson(obRootLog);


    Instant instant = Instant.now();
    String filename = instant + "_" + obRootLog.requestURI;


     // File's metadata.
    File child = new File();
    child.setTitle(filename);
    child.setDescription("My File Description");
    child.setMimeType("application/json");
    child.setParents(
            Arrays.asList(new ParentReference().setId(LogFolderId)));

    // File's content.
    java.io.File fileContent = new java.io.File(filename);
    PrintWriter writer = new PrintWriter(fileContent, "UTF-8");
    writer.println(eJsonOutput);
    writer.close();
    FileContent mediaContent = new FileContent("application/json", fileContent);

    File filetemp = driveService.files().insert(child, mediaContent).execute();


}

Upvotes: 1

Views: 316

Answers (1)

konqi
konqi

Reputation: 5227

The GAE file system is read-only, so you cannot write into a file like you attempt with

java.io.File fileContent = new java.io.File(filename);
PrintWriter writer = new PrintWriter(fileContent, "UTF-8");
writer.println(eJsonOutput);
writer.close();

Why don't you put your json data in a byte array and wrap that with a ByteArrayInputStream. Like this:

InputStream bais = new ByteArrayInputStream(gson.toJson(obRootLog).getBytes());

Then use the input stream as a parameter for your

FileContent mediaContent = new InputStreamContent("application/json", bais);

call.

Additionally, you cannot use

httpTransport = GoogleNetHttpTransport.newTrustedTransport();

on App Engine. As descriped here you would use the UrlFetchTransport in AppEngine. It should look something like this:

httpTransport = new UrlFetchTransport.Builder().build();

By the way. You should add the error from your appengine logs since that makes it way easier to diagnose your code.

Upvotes: 2

Related Questions