建立 Google API 程式庫適用的 Storage 移轉服務用戶端

在您向 Storage 移轉服務發出要求前,請先確認已啟用專案中的 Storage Transfer Service API,且您的應用程式已使用 OAuth 2.0 通訊協定來設定授權作業。如果要求失敗,建議也採用指數輪詢來處理重試。

啟用服務

您需要啟用 Google Storage Transfer API,才能透過 Google API 程式庫或是直接使用 Storage Transfer Service API 存取 Storage 移轉服務。方法如下: 啟用Google Storage Transfer API。

啟用 API

驗證流程

由於所有 Storage 移轉服務作業皆無須人為作業或使用者同意即可執行,因此最適合 Storage 移轉服務應用程式的驗證流程即是使用服務帳戶的伺服器對伺服器作業。Google App Engine 和 Google Compute Engine 皆內建了可供運用的服務帳戶,或是也可以在 Google Cloud Platform 主控台中建立服務憑證。

使用服務帳戶時,Google API 用戶端程式庫會在以下情境為您處理驗證和授權程序:

Google App Engine 應用程式

如果您的應用程式是在 App Engine 上執行,就會以 App Engine 應用程式的預設服務帳戶執行驗證。

注意:只要您使用的是 Google Cloud SDK (mvn gcloud:run),此程式碼也可用於 App Engine 本機模擬器,方法是使用服務帳戶並設定 GOOGLE_APPLICATION_CREDENTIALS 環境變數。詳情請參閱本機或第三方主機一文。

Google Compute Engine 應用程式

如果您的應用程式是在 Google Compute Engine 執行個體上執行,則會使用與專案相關聯的預設 Compute Engine 服務帳戶執行驗證。

本機或第三方主機

如果執行的是本機用戶端,或是要在 Google Cloud 以外的環境上執行程式,請建立新服務帳戶,下載其 JSON 金鑰檔案,然後將環境變數 GOOGLE_APPLICATION_CREDENTIALS 設定為指向該 JSON 金鑰檔案。詳情請參閱應用程式預設憑證的運作方式一文。

授權範圍

使用 OAuth 2.0 存取 Storage 移轉服務的應用程式,必須指定 cloud-platform 授權範圍。

範圍 意義
https://www.googleapis.com/auth/cloud-platform 完整存取權。

建立用戶端

您可以使用下列程式碼範例,在驗證流程一節論及的任何環境中建立 Storage 移轉服務用戶端。此程式碼使用的是 Google 應用程式預設憑證,所以會選擇合適的服務帳戶來使用。

Java

此範例使用 Google API Java 專用用戶端程式庫重試處理一節有介紹自訂的 RetryHttpInitializerWrapper 類別。

package com.google.cloud.storage.storagetransfer.samples;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.services.storagetransfer.v1.Storagetransfer;
import com.google.api.services.storagetransfer.v1.StoragetransferScopes;
import com.google.common.base.Preconditions;
import java.io.IOException;

/**
 * Create a client to make calls to Storage Transfer API.
 */
public final class TransferClientCreator {

  /**
   * Create a Storage Transfer client using application default credentials and other default
   * settings.
   *
   * @return a Storage Transfer client
   * @throws IOException
   *           there was an error obtaining application default credentials
   */
  public static Storagetransfer createStorageTransferClient() throws IOException {
    HttpTransport httpTransport = Utils.getDefaultTransport();
    JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
    GoogleCredential credential =
        GoogleCredential.getApplicationDefault(httpTransport, jsonFactory);
    return createStorageTransferClient(httpTransport, jsonFactory, credential);
  }

  /**
   * Create a Storage Transfer client using user-supplied credentials and other settings.
   *
   * @param httpTransport
   *          a user-supplied HttpTransport
   * @param jsonFactory
   *          a user-supplied JsonFactory
   * @param credential
   *          a user-supplied Google credential
   * @return a Storage Transfer client
   */
  public static Storagetransfer createStorageTransferClient(
      HttpTransport httpTransport, JsonFactory jsonFactory, GoogleCredential credential) {
    Preconditions.checkNotNull(httpTransport);
    Preconditions.checkNotNull(jsonFactory);
    Preconditions.checkNotNull(credential);

    // In some cases, you need to add the scope explicitly.
    if (credential.createScopedRequired()) {
      credential = credential.createScoped(StoragetransferScopes.all());
    }
    // Please use custom HttpRequestInitializer for automatic
    // retry upon failures. We provide a simple reference
    // implementation in the "Retry Handling" section.
    HttpRequestInitializer initializer = new RetryHttpInitializerWrapper(credential);
    return new Storagetransfer.Builder(httpTransport, jsonFactory, initializer)
        .setApplicationName("storagetransfer-sample")
        .build();
  }
}

Python

此範例使用 Google API Python 專用用戶端程式庫

import googleapiclient.discovery

def create_transfer_client():
    return googleapiclient.discovery.build('storagetransfer', 'v1')

重試處理

在 RPC 失敗的情況下,建議執行程式碼,以指數輪詢策略處理重試。

Java

此範例使用 Google API Java 專用用戶端程式庫。會由 RetryHttpInitializerWrapper 類別處理重試。

package com.google.cloud.storage.storagetransfer.samples;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.http.HttpBackOffIOExceptionHandler;
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpUnsuccessfulResponseHandler;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.client.util.Sleeper;
import com.google.common.base.Preconditions;
import java.io.IOException;
import java.util.logging.Logger;

/**
 * RetryHttpInitializerWrapper will automatically retry upon RPC failures, preserving the
 * auto-refresh behavior of the Google Credentials.
 */
public class RetryHttpInitializerWrapper implements HttpRequestInitializer {

  private static final Logger LOG = Logger.getLogger(RetryHttpInitializerWrapper.class.getName());
  private final Credential wrappedCredential;
  private final Sleeper sleeper;
  private static final int MILLIS_PER_MINUTE = 60 * 1000;

  /**
   * A constructor using the default Sleeper.
   *
   * @param wrappedCredential
   *          the credential used to authenticate with a Google Cloud Platform project
   */
  public RetryHttpInitializerWrapper(Credential wrappedCredential) {
    this(wrappedCredential, Sleeper.DEFAULT);
  }

  /**
   * A constructor used only for testing.
   *
   * @param wrappedCredential
   *          the credential used to authenticate with a Google Cloud Platform project
   * @param sleeper
   *          a user-supplied Sleeper
   */
  RetryHttpInitializerWrapper(Credential wrappedCredential, Sleeper sleeper) {
    this.wrappedCredential = Preconditions.checkNotNull(wrappedCredential);
    this.sleeper = sleeper;
  }

  /**
   * Initialize an HttpRequest.
   *
   * @param request
   *          an HttpRequest that should be initialized
   */
  public void initialize(HttpRequest request) {
    request.setReadTimeout(2 * MILLIS_PER_MINUTE); // 2 minutes read timeout
    final HttpUnsuccessfulResponseHandler backoffHandler =
        new HttpBackOffUnsuccessfulResponseHandler(new ExponentialBackOff()).setSleeper(sleeper);
    request.setInterceptor(wrappedCredential);
    request.setUnsuccessfulResponseHandler(
        new HttpUnsuccessfulResponseHandler() {
          public boolean handleResponse(
              final HttpRequest request, final HttpResponse response, final boolean supportsRetry)
              throws IOException {
            if (wrappedCredential.handleResponse(request, response, supportsRetry)) {
              // If credential decides it can handle it, the return code or message indicated
              // something specific to authentication, and no backoff is desired.
              return true;
            } else if (backoffHandler.handleResponse(request, response, supportsRetry)) {
              // Otherwise, we defer to the judgement of our internal backoff handler.
              LOG.info("Retrying " + request.getUrl().toString());
              return true;
            } else {
              return false;
            }
          }
        });
    request.setIOExceptionHandler(
        new HttpBackOffIOExceptionHandler(new ExponentialBackOff()).setSleeper(sleeper));
  }
}

Python

您可以將 num_retries=n 引數傳送至資料庫的 execute 方法,在發生可重試的失敗時,使用指數輪詢進行重試。

resp = client.projects().subscriptions().pull(
subscription=subscription, body=body).execute(num_retries=3)
本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Cloud Storage 移轉服務說明文件