我正在尝试使用在Google App Engine中运行的jaxrs服务将文件存储到Google云端存储。在尝试存储文件时,我遇到了错误。
com.google.appengine.tools.cloudstorage.NonRetriableException:com.google.appengine.api.appidentity.AppIdentityServiceFailureException:AppIdentity服务引发了意外错误。详情:
我正在尝试将文件保存到新存储桶,并为存储桶提供以下ID(计算,应用引擎和服务帐户)权限。我还创建了一个单独的服务帐户,并为此服务帐户提供了Writer权限(此帐户的编辑角色为项目)
我理解不需要服务帐户,因为从具有默认服务的应用引擎我们应该能够存储该文件。但只是为了尝试我也创建了上面的服务帐户并将文件存储在WEB-INF / resources / service_account_credentials.json位置,并在appengine-web.xml中设置以下属性
<property name="GOOGLE_APPLICATION_CREDENTIALS" value="WEB-INF/resources/service_account_credentials.json"/>
我尝试了以下两种存储文件的方法,但两者都给出了错误。
第一种方式......
获得服务
GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
.initialRetryDelayMillis(10)
.retryMaxAttempts(10)
.totalRetryPeriodMillis(15000)
.build());
存储文件
GcsFileOptions gcsFileOptions = null ;
GcsFileOptions.Builder builder = new GcsFileOptions.Builder() ;
if(aclEntityName != null)
builder = builder.acl(aclEntityName) ;
if(fileMetaData != null && !fileMetaData.isEmpty())
for(Map.Entry<String, String> entry : fileMetaData.entrySet()){
builder = builder.addUserMetadata(entry.getKey(), entry.getValue()) ;
}
gcsFileOptions = builder.build() ;
GcsFilename fileName = new GcsFilename(bucketName, name) ;
GcsService gcsService = StorageFactory.getGcsService() ;
GcsOutputChannel outputChannel = gcsService.createOrReplace(fileName, gcsFileOptions);
copy(contentStream, Channels.newOutputStream(outputChannel));
下面给出的第二种方法也会出现同样的错误......
获得服务
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential =
GoogleCredential.getApplicationDefault(transport, jsonFactory);
if (credential.createScopedRequired()) {
Collection<String> scopes = StorageScopes.all();
credential = credential.createScoped(scopes);
}
return new Storage.Builder(transport, jsonFactory, credential)
.setApplicationName("GCS Samples")
.build();
以第二种方式存储文件
StorageObject objectMetaData = new StorageObject();
objectMetaData.setName(name);
if(fileMetaData != null && fileMetaData.isEmpty() == false )
objectMetaData.setMetadata(fileMetaData) ;
// Set the access control list to publicly read-only
if(aclEntityName != null && !aclEntityName.trim().equals("")
&& aclRole != null && !aclRole.trim().equals("") ) {
objectMetaData.setAcl(Arrays.asList(
new ObjectAccessControl().setEntity(aclEntityName).setRole(aclRole)));
}
InputStreamContent mediaContent = new InputStreamContent("application/octet-stream", contentStream);
// Do the insert
Storage client = StorageFactory.getService();
Storage.Objects.Insert insertRequest = client.objects().insert(
bucketName, objectMetaData, mediaContent);
if (mediaContent.getLength() > 0 && mediaContent.getLength() <= 2 * 1000 * 1000 /* 2MB */) {
insertRequest.getMediaHttpUploader().setDirectUploadEnabled(true);
}
insertRequest.execute();
我做错了什么?我有什么设置来修复此错误吗?请帮忙!!!
答案 0 :(得分:0)
根据我对Google Application Default Credentials的理解,使用GOOGLE_APPLICATION_CREDENTIALS
环境变量应该指向本地文件,并且通常与gcloud
命令行工具一起用于在本地测试代码时进行身份验证。 / p>
据说https://stackoverflow.com/a/36408645/374638,或许这应该在<env-variables>
中。