Storage Transfer Service-Client für eine Google API-Bibliothek erstellen

Für das Senden von Anfragen an Storage Transfer Service müssen Sie zuerst die Cloud Storage Transfer Service API für Ihr Projekt aktivieren und Ihre Anwendung für die Autorisierung mit dem OAuth 2.0-Protokoll einrichten. Für den Fall, dass Anfragefehler auftreten, empfehlen wir außerdem die Implementierung des abgeschnittenen exponentiellen Backoffs für Wiederholungsversuche.

Dienst aktivieren

Für den Zugriff auf Storage Transfer Service über eine Google APIs-Bibliothek oder direkt über die Storage Transfer Service API muss die Google Storage Transfer API aktiviert werden.

Enable the Google Storage Transfer API.

Enable the API

Authentifizierungsvorgang

Da Storage Transfer Service-Vorgänge ohne menschliche Eingriffe oder die Einwilligung des Nutzers ablaufen, sollte die Authentifizierung für Storage Transfer Service-Anwendungen von Server zu Server über ein Dienstkonto erfolgen. App Engine und Compute Engine haben integrierte Dienstkonten, die Ihnen zur Verfügung stehen. Alternativ können Sie Dienstanmeldedaten in der Google Cloud Console erstellen.

Wenn Sie ein Dienstkonto verwenden, übernehmen die Google APIs-Clientbibliotheken die Authentifizierung und Autorisierung in den folgenden Szenarien:

App Engine-Anwendung

Wenn Ihre Anwendung auf App Engine ausgeführt wird, wird sie mit dem zugehörigen Standarddienstkonto authentifiziert.

Der Code funktioniert auch mit Ihrem lokalen App Engine-Emulator, solange Sie die Google Cloud CLI (mvn gcloud:run) nutzen. Verwenden Sie dazu ein Dienstkonto und legen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS fest.

Weitere Informationen finden Sie unter Lokaler oder externer Host.

Compute Engine-Anwendung

Wenn Ihre Anwendung auf einer Compute Engine-Instanz ausgeführt wird, authentifiziert sie sich über das Standard-Compute Engine-Dienstkonto des Projekts.

Konfigurieren Sie die Instanz für die Verwendung von Dienstkonten und fügen Sie den im Abschnitt Autorisierungsbereich aufgeführten Bereich hinzu.

Weitere Informationen finden Sie in der Compute Engine-Dokumentation unter Zugriff auf Dienstkontobereich für Instanzen einrichten.

Lokaler oder externer Host

Wenn Sie einen lokalen Client ausführen oder Ihr Programm in einer anderen Umgebung als Google Cloud ausgeführt wird, erstellen Sie ein neues Dienstkonto und laden Sie die zugehörige JSON-Schlüsseldatei herunter. Legen Sie dann die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS so fest, dass sie auf die JSON-Schlüsseldatei verweist.

Weitere Informationen finden Sie unter Authentifizierung als Dienstkonto.

Autorisierungsbereich

Für Anwendungen, die mit OAuth 2.0 auf Storage Transfer Service zugreifen, muss der Autorisierungsbereich cloud-platform angegeben werden.

Bereich Bedeutung
https://www.googleapis.com/auth/cloud-platform Uneingeschränkter Zugriff

Client erstellen

Mit dem folgenden Beispielcode können Sie in jeder der unter Authentifizierungsvorgang beschriebenen Umgebungen einen Storage Transfer Service-Client erstellen. Da der Code die Standardanmeldedaten für Google-Anwendungen nutzt, wird das entsprechende Dienstkonto automatisch ausgewählt.

Dem Dienstkonto muss eine der folgenden Rollen zugewiesen sein:

Dies können Sie auf der Seite „Berechtigungen“ für Ihr Projekt prüfen.

Java

In diesem Beispiel wird die Google APIs-Clientbibliothek für Java verwendet. Die benutzerdefinierte Klasse RetryHttpInitializerWrapper wird im Abschnitt Umgang mit Wiederholungen beschrieben.

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.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.base.Preconditions;
import java.io.IOException;

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

  /**
   * 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();
    GoogleCredentials credential = GoogleCredentials.getApplicationDefault();
    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, GoogleCredentials 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 HttpCredentialsAdapter(credential);
    return new Storagetransfer.Builder(httpTransport, jsonFactory, initializer)
        .setApplicationName("storagetransfer-sample")
        .build();
  }
}

Python

In diesem Beispiel wird die Google APIs-Clientbibliothek für Python verwendet.

import googleapiclient.discovery

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

Umgang mit Wiederholungen

Im Fall von RPC-Fehlern sollten Sie Code für den Umgang mit Wiederholungsversuchen gemäß einer Strategie mit abgeschnittenem exponentiellem Backoff implementieren.

Java

In diesem Beispiel wird die Google APIs-Clientbibliothek für Java verwendet. Die Klasse RetryHttpInitializerWrapper ist für den Umgang mit Wiederholungsversuchen definiert.

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


"""Command-line sample that gets a transfer job using retries
"""

import googleapiclient.discovery

def get_transfer_job_with_retries(project_id, job_name, retries):
    """Check the latest transfer operation associated with a transfer job."""
    storagetransfer = googleapiclient.discovery.build("storagetransfer", "v1")

    transferJob = (
        storagetransfer.transferJobs()
        .get(projectId=project_id, jobName=job_name)
        .execute(num_retries=retries)
    )
    print(
        "Fetched transfer job: "
        + transferJob.get("name")
        + " using {} retries".format(retries)
    )