如何在我的本地开发服务器上启用 Google 云存储?

How do I enable Google Cloud Storage on my local development server?

我想使用 GCS 存储桶作为我的 blobstore 的支持,但我不知道如何在我的开发服务器上设置一个。

有使用实时服务器上的开发人员控制台执行此操作的说明,但我找不到有关如何在我的本地开发机器上执行此操作的任何信息...

事实证明您根本不需要执行任何设置。我只是假设在使用 blobstore 上传时有一个具有特定名称的,并且自动为我创建了一个。

顺便说一句,似乎没有任何地方记录如何浏览开发服务器存储中的文件。您可以通过在 Datastore Viewer 管理访问本地开发服务器中选择 __GsFileInfo__ 实体来实现。

您需要下载并集成 App Engine 的 Google Cloud Storage Client Library

本库为您提供了与BlobstoreService类似的GcsService,您可以使用提供的写文件、读文件、删除文件等功能云存储

当您在开发环境中使用代码时,上传的文件存储在 appengine-generated 文件夹中,并在本地数据存储中创建一个 __GsFileInfo__ 实体,该实体保留附加到文件的元数据

这个库也可以在线使用,因此您的代码将适用于开发和生产环境。

在这里您可以找到 Getting Started guide and the full JavaDoc 参考资料

对于那些试图让 Google Cloud Storage 从本地 Java 开发应用程序服务器完全正常工作的人,我认为再提供一个答案会有所帮助。我设法让我的本地开发应用程序服务器与非本地 Google 云存储一起工作,但只是通过代码挖掘并弄清楚需要什么 - 似乎没有这方面的文档。

目标是让这段代码在本地工作,它从 GCS 读取文件:

    GcsService gcsService =
       GcsServiceFactory.createGcsService(RetryParams.getDefaultInstance());
    int fileSize = (int) gcsService.getMetadata(gcsFilename).getLength();
    ByteBuffer byteBuffer = ByteBuffer.allocate(fileSize);
    GcsInputChannel inputChannel = gcsService.openReadChannel(gcsFilename, 0);
    int readResult = inputChannel.read(byteBuffer);
    byte[] fileBytes = byteBuffer.array();

如果您尝试在本地执行此操作,您将找不到已上传到 GCS 的任何文件,因为它会尝试使用伪造的本地 GCS。不幸的是,我还没有找到上传到这个本地 GCS 的好方法,所以这不是很有用(没有文件资源管理器,因为在云版本中有,并且 gsutil 不适用于它)。因此,当 运行 在本地开发应用程序服务器中时,我们将让它与非本地(云)GCS 一起工作。

为此,请注意 GcsService 是通过以下代码块在 com.google.appengine.tools.cloudstorage.GcsServiceFactory 中创建的:

if (location == SystemProperty.Environment.Value.Production || hasCustomAccessTokenProvider()) {
  rawGcsService = OauthRawGcsServiceFactory.createOauthRawGcsService(builder.build());
} else if (location == SystemProperty.Environment.Value.Development) {
  rawGcsService = LocalRawGcsServiceFactory.createLocalRawGcsService();

上面说你需要指定一个自定义的访问令牌提供者来获取非本地服务,你通过定义一个系统来做到这一点属性。对于 App Engine 应用程序,您可以在 appengine-web.xml 中这样做:

<system-properties>
    <property name="gcs_access_token_provider" value="com.mypackage.MyAccessTokenProvider" />
</system-properties>

属性 的这个值是您定义的 class 实现 com.google.appengine.tools.cloudstorage.oauth.AccessTokenProvider,它为您的应用程序提供访问令牌。 class 需要创建一个 Google 凭据,可用于获取访问令牌,使用 "Other" 的说明获取 https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests 上的 Google 凭据.

现在它将创建一个与云对话的 OAuth GcsService,您不需要使用伪造的本地存储。

认为这可以使用一些更新的发现。对我来说,本地云存储根本不起作用。它失败并显示 GsFileInfo 是受保护实体的错误。如果您不启动本地数据存储模拟器(意味着它使用远程云存储),它工作正常。

这似乎与 google 的最新文档不谋而合:https://cloud.google.com/appengine/docs/standard/java/using-cloud-storage#using_cloud_storage_with_the_local_development_server

The App Engine local development server doesn't emulate Cloud Storage, so all Cloud Storage requests must be sent over the Internet to an actual Cloud Storage bucket.

因此@learnj12 的答案是最好的方法。然而,GoogleCredential 已被弃用,并且不清楚如何实施 com.google.appengine.tools.cloudstorage.oauth.AccessTokenProvider。

以下是对我有用的方法:

import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import com.google.appengine.tools.cloudstorage.oauth.AccessTokenProvider;

public class GCSTokenProvider implements AccessTokenProvider {
  @Override
  public AppIdentityService.GetAccessTokenResult getNewAccessToken(List<String> list) {
    return AppIdentityServiceFactory.getAppIdentityService().getAccessToken(Collections.singleton("cloud-platform"));
  }
}

注意。我正在使用服务帐户,并使用 gcloud.

登录