Question

I am using the google storage API to persist and retrieve images from an app deployed on GAE. I successfully retrieve the images but when it comes to persisting I am getting error 400 with this in the details:

400 OK
{
    "code" : 400,
    "errors" : [ {
        "domain" : "global",
        "message" : "Required",
        "reason" : "required"
     }],
     "message" : "Required"
}

Based on this information I thought I may not need it so I tried without. When I added the appspot URL I'm communicating with google cloud storage from I got this:

400 OK
{
    "code" : 400,
    "errors" : [ {
        "domain" : "global",
        "message" : "Required",
        "reason" : "required"
     }, {
        "domain" : "global",
        "message" : "Could not find domain \"mydomain.appspot.com\".",
        "reason" : "invalid"
     } ],
     "message" : "Required"
}

I have followed the following steps:

  1. turned on JSON API access to Google Cloud Service
  2. created a service account
  3. downloaded the p12 file
  4. configured maven to not encode the file
  5. configured maven to include the storage service api
  6. created a GoogleCredential using the service account email address as the service account, added StorageScopes.DEVSTORAGE_FULL_CONTROL to the scopes and linked to the private key file (p12)
  7. instantiated a Storage object using the credential above, http transport, etc

I am using a List of ObjectAccessControl objects that get set on the StorageObject object like such:

...
//email from the service account client id configuration in the google cloud console
myAclList.add(new ObjectAccessControl()
            .setEntity("user-" + settings.getEmail()).setRole("OWNER")); 
//confused about what domain I should use; tried none, 
myAclList.add(new ObjectAccessControl()
            .setEntity("domain-" + settings.getDomain())
            .setRole("READER"));
StorageObject objectMetadata = new StorageObject()
            .setName("blahblah")
            .setAcl(myAclList)
            .setContentDisposition("attachment");
Storage.Objects.Insert insertObject = storage.objects()
            .insert(settings.getBucket(), objectMetadata, mediaContent);
insertObject.execute();  //400 error happens here
...

What exactly should I be sending for the domain? Am I missing configuring something in the console maybe? I'm out of ideas.

Thank you so very much for any suggestions!

EDIT: I am using the v1beta2-rev2-1.15.0-rc version of the google-api-services-storage jar.

Was it helpful?

Solution

The reason you're seeing "Could not find domain \"mydomain.appspot.com\"." is that the "domain-" prefix refers to all accounts within a Google Apps for Business domain, not appengine domain names. For example, if you were using Google Apps for your company, fakecompany.com, and you wanted to grant read access for a bucket for all accounts under fakecompany.com, you could specify "domain-fakecompany.com" to refer to all such accounts.

I'm guessing mydomain.appspot.com is an appengine domain name and not a Google Apps for Business domain, which would cause that sort of error.

Updates: There was another misunderstanding that is worth pointing out. A service account does not necessarily have permission to insert new objects into buckets that you own. Make sure that it either has explicit WRITE or better permission on a bucket, or, if you're using the default bucket ACL, that it is at least an "editor" on your project.

Finally, make sure that your bucket names and object names are present and not null when inserting objects. This is a surprisingly easy problem to have, and the error message provided doesn't always make this very clear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top