HTTP Target-Aufgaben erstellen

Mit dieser Version von HTTP Targets können Cloud Tasks-Handler jetzt auf jedem HTTP-Endpunkt mit einer öffentlichen IP-Adresse ausgeführt werden, z. B. in Cloud Functions, Cloud Run, GKE, Compute Engine oder sogar auf einem lokalen Webserver. Ihre Aufgaben können mit jedem dieser Dienste zuverlässig und konfigurierbar ausgeführt werden.

Diese Seite zeigt, wie HTTP Target-Aufgaben programmgesteuert erstellt und in Warteschlangen für Cloud Tasks gestellt werden. Bitte beachten Sie, dass einige der auf dieser Seite verlinkten Ressourcen ggf. nur auf Englisch verfügbar sind. Wenn Sie eine Aufgabe verarbeiten möchten, müssen Sie zuerst ein neues Aufgabenobjekt erstellen und in eine Warteschlange einreihen. Sie können den Dienst und den Handler, mit denen die Aufgabe verarbeitet wird, ausdrücklich angeben und optional aufgabenspezifische Daten an den Handler weiterleiten. Außerdem können Sie die Konfiguration der Aufgabe genauer festlegen. Beispielsweise können Sie einen zukünftigen Zeitpunkt angeben, an dem die Aufgabe ausgeführt werden soll, oder die Anzahl ihrer Wiederholungen im Fall von Fehlversuchen beschränken. Wenn Sie einen Namen für die Aufgabe angeben, kann Cloud Tasks diesen Namen verwenden, um die Deduplizierung von Aufgaben zu gewährleisten. Die erforderliche Verarbeitung kann jedoch die Latenz erhöhen.

Im Allgemeinen erstellen Sie Aufgaben in Form einer HTTP-Anfrage. Wenn Sie die Google Cloud-Clientbibliotheken und ein Dienstkonto wie in den folgenden Beispielen verwenden, können Sie die Kommunikationsdetails mit dem Cloud Tasks-Server verwalten und Aufgaben leichter erstellen.

HTTP Target-Aufgaben erstellen

In den folgenden Beispielen werden HTTP Target-Aufgabenanfragen beschrieben, die eine vollständige Aufgabe, einschließlich der URL des Aufgaben-Handlers, erstellen.

C#


using Google.Cloud.Tasks.V2;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using System;

class CreateHttpTask
{
    public string CreateTask(
        string projectId = "YOUR-PROJECT-ID",
        string location = "us-central1",
        string queue = "my-queue",
        string url = "http://example.com/taskhandler",
        string payload = "Hello World!",
        int inSeconds = 0)
    {
        CloudTasksClient client = CloudTasksClient.Create();
        QueueName parent = new QueueName(projectId, location, queue);

        var response = client.CreateTask(new CreateTaskRequest
        {
            Parent = parent.ToString(),
            Task = new Task
            {
                HttpRequest = new HttpRequest
                {
                    HttpMethod = HttpMethod.Post,
                    Url = url,
                    Body = ByteString.CopyFromUtf8(payload)
                },
                ScheduleTime = Timestamp.FromDateTime(
                    DateTime.UtcNow.AddSeconds(inSeconds))
            }
        });

        Console.WriteLine($"Created Task {response.Name}");
        return response.Name;
    }
}

Python

"""Create a task for a given queue with an arbitrary payload."""

from google.cloud import tasks_v2
from google.protobuf import timestamp_pb2
import datetime
import json

# Create a client.
client = tasks_v2.CloudTasksClient()

# TODO(developer): Uncomment these lines and replace with your values.
# project = 'my-project-id'
# queue = 'my-queue'
# location = 'us-central1'
# url = 'https://example.com/task_handler'
# payload = 'hello' or {'param': 'value'} for application/json

# Construct the fully qualified queue name.
parent = client.queue_path(project, location, queue)

# Construct the request body.
task = {
    "http_request": {  # Specify the type of request.
        "http_method": tasks_v2.HttpMethod.POST,
        "url": url,  # The full url path that the task will be sent to.
    }
}
if payload is not None:
    if isinstance(payload, dict):
        # Convert dict to JSON string
        payload = json.dumps(payload)
        # specify http content-type to application/json
        task["http_request"]["headers"] = {"Content-type": "application/json"}

    # The API expects a payload of type bytes.
    converted_payload = payload.encode()

    # Add the payload to the request.
    task["http_request"]["body"] = converted_payload

if in_seconds is not None:
    # Convert "seconds from now" into an rfc3339 datetime string.
    d = datetime.datetime.utcnow() + datetime.timedelta(seconds=in_seconds)

    # Create Timestamp protobuf.
    timestamp = timestamp_pb2.Timestamp()
    timestamp.FromDatetime(d)

    # Add the timestamp to the tasks.
    task["schedule_time"] = timestamp

if task_name is not None:
    # Add the name to tasks.
    task["name"] = task_name

# Use the client to build and send the task.
response = client.create_task(request={"parent": parent, "task": task})

print("Created task {}".format(response.name))

Beachten Sie die Datei requirements.txt:

google-cloud-tasks==2.0.0

Java

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.HttpRequest;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;

public class CreateHttpTask {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    createTask(projectId, locationId, queueId);
  }

  // Create a task with a HTTP target using the Cloud Tasks client.
  public static void createTask(String projectId, String locationId, String queueId)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url = "https://example.com/taskhandler";
      String payload = "Hello, World!";

      // Construct the fully qualified queue name.
      String queuePath = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setUrl(url)
                      .setHttpMethod(HttpMethod.POST)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

Beachten Sie die Datei pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2018 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <version>1.0-SNAPSHOT</version>
  <groupId>com.example.task</groupId>
  <artifactId>tasks-samples</artifactId>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.0.18</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>

  <dependencies>
    <!-- Compile/runtime dependencies -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
      <version>1.30.1</version>
    </dependency>
    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>3.13.0</version>
    </dependency>

    <!-- Test dependencies -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.0.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.3.0</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

PHP

use Google\Cloud\Tasks\V2\CloudTasksClient;
use Google\Cloud\Tasks\V2\HttpMethod;
use Google\Cloud\Tasks\V2\HttpRequest;
use Google\Cloud\Tasks\V2\Task;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The Location ID';
// $queueId = 'The Cloud Tasks Queue ID';
// $url = 'The full url path that the task request will be sent to.'
// $payload = 'The payload your task should carry to the task handler. Optional';

// Instantiate the client and queue name.
$client = new CloudTasksClient();
$queueName = $client->queueName($projectId, $locationId, $queueId);

// Create an Http Request Object.
$httpRequest = new HttpRequest();
// The full url path that the task request will be sent to.
$httpRequest->setUrl($url);
// POST is the default HTTP method, but any HTTP method can be used.
$httpRequest->setHttpMethod(HttpMethod::POST);
// Setting a body value is only compatible with HTTP POST and PUT requests.
if (isset($payload)) {
    $httpRequest->setBody($payload);
}

// Create a Cloud Task object.
$task = new Task();
$task->setHttpRequest($httpRequest);

// Send request and print the task name.
$response = $client->createTask($queueName, $task);
printf('Created task %s' . PHP_EOL, $response->getName());

Beachten Sie die Datei composer.json:

{
    "require": {
        "google/cloud-tasks": "^1.4.0"
    }
}

Go


// Command createHTTPtask constructs and adds a task to a Cloud Tasks Queue.
package main

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2"
)

// createHTTPTask creates a new task with a HTTP target then adds it to a Queue.
func createHTTPTask(projectID, locationID, queueID, url, message string) (*taskspb.Task, error) {

	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", err)
	}

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %v", err)
	}

	return createdTask, nil
}

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

// Instantiates a client.
const client = new CloudTasksClient();

// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-queue';
// const location = 'us-central1';
// const url = 'https://example.com/taskhandler';
// const payload = 'Hello, World!';

// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);

const task = {
  httpRequest: {
    httpMethod: 'POST',
    url,
  },
};

if (payload) {
  task.httpRequest.body = Buffer.from(payload).toString('base64');
}

if (inSeconds) {
  // The time when the task is scheduled to be attempted.
  task.scheduleTime = {
    seconds: inSeconds + Date.now() / 1000,
  };
}

// Send create task request.
console.log('Sending task:');
console.log(task);
const request = {parent, task};
const [response] = await client.createTask(request);
console.log(`Created task ${response.name}`);

Beachten Sie die Datei package.json:

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=10"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "mocha",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^2.1.1",
    "body-parser": "^1.18.3",
    "express": "^4.16.3",
    "yargs": "^16.0.0"
  },
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^8.0.0",
    "uuid": "^8.0.0"
  }
}

Ruby

require "google/cloud/tasks"

# Create a Task with an HTTP Target
#
# @param [String] project_id Your Google Cloud Project ID.
# @param [String] location_id Your Google Cloud Project Location ID.
# @param [String] queue_id Your Google Cloud Tasks Queue ID.
# @param [String] url The full path to sent the task request to.
# @param [String] payload The request body of your task.
# @param [Integer] seconds The delay, in seconds, to process your task.
def create_http_task project_id, location_id, queue_id, url, payload: nil, seconds: nil
  # Instantiates a client.
  client = Google::Cloud::Tasks.cloud_tasks

  # Construct the fully qualified queue name.
  parent = client.queue_path project: project_id, location: location_id, queue: queue_id

  # Construct task.
  task = {
    http_request: {
      http_method: "POST",
      url:         url
    }
  }

  # Add payload to task body.
  task[:http_request][:body] = payload if payload

  # Add scheduled time to task.
  if seconds
    timestamp = Google::Protobuf::Timestamp.new
    timestamp.seconds = Time.now.to_i + seconds.to_i
    task[:schedule_time] = timestamp
  end

  # Send create task request.
  puts "Sending task #{task}"

  response = client.create_task parent: parent, task: task

  puts "Created task #{response.name}" if response.name
end

Dienstkonten für die HTTP Target-Handler-Authentifizierung einrichten

Cloud Tasks kann HTTP Target-Handler aufrufen, die eine Authentifizierung erfordern, wenn Ihr Dienstkonto die entsprechenden Anmeldeinformationen für den Zugriff auf den Handler hat.

Wenn Sie ein aktuelles Dienstkonto haben, das Sie verwenden möchten, können Sie das tun. Gewähren Sie ihm einfach die entsprechenden Rollen. In dieser Anleitung wird das Erstellen eines neuen Dienstkontos speziell für diese Funktion beschrieben.

  1. Rufen Sie die Konsolenseite Dienstkonten auf.

    Zur Seite "Dienstkonten"

  2. Wählen Sie bei Bedarf das entsprechende Projekt aus.

  3. Klicken Sie auf + Dienstkonto erstellen.

  4. Geben Sie dem Konto einen Anzeigenamen. Die Konsole erstellt einen zugehörigen E-Mail-Kontonamen für das Konto. So verweisen Sie auf das Konto. Sie können bei Bedarf auch eine Beschreibung des Kontos hinzufügen.

  5. Klicken Sie auf Erstellen. Sie gelangen zum Bildschirm Dienstkontoberechtigungen.

  6. Klicken Sie in der Dropdown-Liste auf Eine Rolle auswählen.

  7. Scrollen Sie in der linken Spalte zu Cloud Tasks und wählen Sie rechts Cloud Tasks Enqueuer aus. Dadurch erhält das Dienstkonto die Berechtigung, Aufgaben zur Warteschlange hinzuzufügen.

  8. Klicken Sie auf + Weitere Rolle hinzufügen.

  9. Klicken Sie in der Dropdown-Liste auf Eine Rolle auswählen.

  10. Scrollen Sie in der linken Spalte zu Dienstkonten und wählen Sie auf der rechten Seite Dienstkonto-Nutzer aus. Mit dieser Rolle kann das Dienstkonto die Warteschlange autorisieren, mithilfe der Anmeldedaten des Dienstkontos in seinem Namen Tokens zu erstellen.

  11. Wenn Ihr Handler Teil von Google Cloud ist, weisen Sie dem Dienstkonto die Rolle zu, die mit dem Zugriff auf den Dienst verknüpft ist, auf dem der Handler ausgeführt wird. Jeder Dienst innerhalb von Google Cloud benötigt eine andere Rolle. Um beispielsweise auf einen Handler in Cloud Run zuzugreifen, ist die Rolle Cloud Run Invoker erforderlich usw. Sie können das gerade erstellte Dienstkonto oder ein anderes Dienstkonto in Ihrem Projekt verwenden.

  12. Cloud Tasks selbst muss ein eigenes Dienstkonto haben, dem die Rolle Cloud Tasks Service Agent zugewiesen ist. Auf diese Weise können Header-Tokens basierend auf den Anmeldedaten generiert werden, die mit dem Cloud Tasks-Dienstkonto verknüpft sind, um sich bei Ihrem Handler-Ziel zu authentifizieren. Das Cloud Tasks-Dienstkonto mit dieser Rolle wird automatisch erstellt, wenn Sie die Cloud Tasks API aktivieren, es sei denn, Sie haben sie vor dem 19. März 2019 aktiviert. In diesem Fall müssen Sie die Rolle manuell hinzufügen.

HTTP Target-Aufgaben mit Authentifizierungstokens verwenden

Zur Authentifizierung zwischen Cloud Tasks und einem HTTP Target-Handler erstellt Cloud Tasks ein Header-Token. Dieses Token basiert auf den Anmeldedaten im Dienstkonto Cloud Tasks Enqueuer, die durch ihre E-Mail-Adresse identifiziert werden. Die Anfrage mit dem Token wird über HTTPS von der Warteschlange an den Handler gesendet. Sie können entweder ein OIDC-Token oder ein OAuth-Token verwenden. OIDC-Tokens sind signierte JSON Web Tokens (JWT). Sie werden im Gegensatz zu OAuth-Tokens, die Zugriff gewähren, hauptsächlich dazu verwendet, die Identität zu bestätigen und keine implizite Autorisierung für eine Ressource durchzuführen. OIDC-Tokens sollten im Allgemeinen für jeden Handler verwendet werden, der in Google Cloud ausgeführt wird, z. B. in Cloud Functions oder Cloud Run. Die Hauptausnahme betrifft Google-APIs, die auf *.googleapis.com gehostet werden: Diese APIs erwarten ein OAuth-Token. Sie geben entweder OIDC oder OAuth in der Anfrage selbst an.

In den folgenden Beispielen werden Aufgabenanfragen beschrieben, die auch die Erstellung eines Header-Tokens umfassen. In den Beispielen werden OIDC-Token verwendet. Wenn Sie ein OAuth-Token verwenden, ersetzen Sie den OIDC-Parameter beim Erstellen der Anfrage durch den sprachspezifischen OAuth-Parameter.

Python

"""Create a task for a given queue with an arbitrary payload."""

from google.cloud import tasks_v2
from google.protobuf import timestamp_pb2

# Create a client.
client = tasks_v2.CloudTasksClient()

# TODO(developer): Uncomment these lines and replace with your values.
# project = 'my-project-id'
# queue = 'my-queue'
# location = 'us-central1'
# url = 'https://example.com/task_handler'
# service_account_email = 'service-account@my-project-id.iam.gserviceaccount.com';
# payload = 'hello'

# Construct the fully qualified queue name.
parent = client.queue_path(project, location, queue)

# Construct the request body.
task = {
    "http_request": {  # Specify the type of request.
        "http_method": tasks_v2.HttpMethod.POST,
        "url": url,  # The full url path that the task will be sent to.
        "oidc_token": {"service_account_email": service_account_email},
    }
}

if payload is not None:
    # The API expects a payload of type bytes.
    converted_payload = payload.encode()

    # Add the payload to the request.
    task["http_request"]["body"] = converted_payload

if in_seconds is not None:
    # Convert "seconds from now" into an rfc3339 datetime string.
    d = datetime.datetime.utcnow() + datetime.timedelta(seconds=in_seconds)

    # Create Timestamp protobuf.
    timestamp = timestamp_pb2.Timestamp()
    timestamp.FromDatetime(d)

    # Add the timestamp to the tasks.
    task["schedule_time"] = timestamp

if task_name is not None:
    # Add the name to tasks.
    task["name"] = task_name

# Use the client to build and send the task.
response = client.create_task(request={"parent": parent, "task": task})

print("Created task {}".format(response.name))
return response

Beachten Sie die Datei requirements.txt:

google-cloud-tasks==2.0.0

Java

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.HttpRequest;
import com.google.cloud.tasks.v2.OidcToken;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;

public class CreateHttpTaskWithToken {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    String serviceAccountEmail =
        "java-docs-samples-testing@java-docs-samples-testing.iam.gserviceaccount.com";
    createTask(projectId, locationId, queueId, serviceAccountEmail);
  }

  // Create a task with a HTTP target and authorization token using the Cloud Tasks client.
  public static void createTask(
      String projectId, String locationId, String queueId, String serviceAccountEmail)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url =
          "https://example.com/taskhandler"; // The full url path that the request will be sent to
      String payload = "Hello, World!"; // The task HTTP request body

      // Construct the fully qualified queue name.
      String queuePath = QueueName.of(projectId, locationId, queueId).toString();

      // Add your service account email to construct the OIDC token.
      // in order to add an authentication header to the request.
      OidcToken.Builder oidcTokenBuilder =
          OidcToken.newBuilder().setServiceAccountEmail(serviceAccountEmail);

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setHttpMethod(HttpMethod.POST)
                      .setUrl(url)
                      .setOidcToken(oidcTokenBuilder)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

Beachten Sie die Datei pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2018 Google LLC

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <version>1.0-SNAPSHOT</version>
  <groupId>com.example.task</groupId>
  <artifactId>tasks-samples</artifactId>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.0.18</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <failOnMissingWebXml>false</failOnMissingWebXml>
  </properties>

  <dependencies>
    <!-- Compile/runtime dependencies -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
      <version>1.30.1</version>
    </dependency>
    <dependency>
      <groupId>com.google.protobuf</groupId>
      <artifactId>protobuf-java</artifactId>
      <version>3.13.0</version>
    </dependency>

    <!-- Test dependencies -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13</version>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.0.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.3.0</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Go

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "google.golang.org/genproto/googleapis/cloud/tasks/v2"
)

// createHTTPTaskWithToken constructs a task with a authorization token
// and HTTP target then adds it to a Queue.
func createHTTPTaskWithToken(projectID, locationID, queueID, url, email, message string) (*taskspb.Task, error) {
	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %v", err)
	}

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
					AuthorizationHeader: &taskspb.HttpRequest_OidcToken{
						OidcToken: &taskspb.OidcToken{
							ServiceAccountEmail: email,
						},
					},
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %v", err)
	}

	return createdTask, nil
}

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

// Instantiates a client.
const client = new CloudTasksClient();

// TODO(developer): Uncomment these lines and replace with your values.
// const project = 'my-project-id';
// const queue = 'my-queue';
// const location = 'us-central1';
// const url = 'https://example.com/taskhandler';
// const serviceAccountEmail = 'client@<project-id>.iam.gserviceaccount.com';
// const payload = 'Hello, World!';

// Construct the fully qualified queue name.
const parent = client.queuePath(project, location, queue);

const task = {
  httpRequest: {
    httpMethod: 'POST',
    url,
    oidcToken: {
      serviceAccountEmail,
    },
  },
};

if (payload) {
  task.httpRequest.body = Buffer.from(payload).toString('base64');
}

if (inSeconds) {
  // The time when the task is scheduled to be attempted.
  task.scheduleTime = {
    seconds: inSeconds + Date.now() / 1000,
  };
}

console.log('Sending task:');
console.log(task);
// Send create task request.
const request = {parent, task};
const [response] = await client.createTask(request);
const name = response.name;
console.log(`Created task ${name}`);

Beachten Sie die Datei package.json:

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=10"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "mocha",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^2.1.1",
    "body-parser": "^1.18.3",
    "express": "^4.16.3",
    "yargs": "^16.0.0"
  },
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^8.0.0",
    "uuid": "^8.0.0"
  }
}

Eigenen HTTP Target-Aufgaben-Handler bereitstellen

HTTP Target-Aufgaben-Handler sind den App Engine-Aufgaben-Handlern mit den folgenden Ausnahmen sehr ähnlich:

  • Zeitüberschreitungen: Für alle HTTP Target-Aufgaben-Handler beträgt die Standardzeitüberschreitung 10 Minuten, maximal 30 Minuten.
  • Authentifizierungslogik: Wenn Sie Ihren eigenen Code in den Zieldienst schreiben, um das Token zu validieren, sollten Sie ein OIDC-Token verwenden. Weitere Informationen dazu finden Sie unter OpenID Connect im Abschnitt Validating an ID token.
  • Header: Eine HTTP Target-Anfrage enthält von der Warteschlange festgelegte Header, die aufgabenspezifische Informationen enthalten, die vom Handler verwendet werden können. Diese ähneln den in App Engine-Aufgabenanfragen festgelegten Headern, sind jedoch nicht mit diesen identisch. Diese Header enthalten nurnur Informationen. Sie sollten nicht als Identitätsquelle verwenden werden.

    Wenn diese Header in einer externen Nutzeranfrage an Ihre Anwendung vorhanden waren, werden sie durch die internen ersetzt. Die einzige Ausnahme dabei sind Anfragen von angemeldeten Administratoren der Anwendung, die Header für Testzwecke festlegen dürfen.

    HTTP-Zielanfragen enthalten immer die folgenden Header:

    Header Beschreibung
    X-CloudTasks-QueueName Der Name der Warteschlange.
    X-CloudTasks-TaskName Der "kurze" Name der Aufgabe oder, wenn bei der Erstellung kein Name festgelegt wurde, eine vom System generierte eindeutige ID. Dies ist der my-task-id-Wert im vollständigen Aufgabennamen, also task_name = projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id.
    X-CloudTasks-TaskRetryCount Die Anzahl der Ausführungsversuche für diese Aufgabe. Für den ersten Versuch lautet dieser Wert 0. Diese Anzahl enthält Versuche, bei denen die Aufgabe aufgrund fehlender verfügbarer Instanzen fehlgeschlagen ist und die Ausführungsphase nicht erreicht wurde.
    X-CloudTasks-TaskExecutionCount Die Gesamtzahl der Antworten, die die Aufgabe vom Handler erhalten hat. Da Cloud Tasks eine Aufgabe löscht, sobald eine erfolgreiche Antwort empfangen wurde, sind alle vorherigen Handler-Antworten fehlgeschlagen. Bei diesem Wert werden Fehler aufgrund fehlender verfügbarer Instanzen nicht berücksichtigt.
    X-CloudTasks-TaskETA Die geplante Zeit für eine Aufgabe, angegeben in Sekunden seit dem 1. Januar 1970.

    Außerdem können Anfragen von Cloud Tasks die folgenden Header enthalten:

    Header Beschreibung
    X-CloudTasks-TaskPreviousResponse Der HTTP-Antwortcode aus der vorangegangenen Wiederholung.
    X-CloudTasks-TaskRetryReason Der Grund für die Wiederholung der Aufgabe.

Cloud Tasks-Dienst-Agent-Rolle manuell zu Ihrem Cloud Tasks-Dienstkonto hinzufügen

Dies ist nur erforderlich, wenn Sie die Cloud Tasks API vor dem 19. März 2019 aktiviert haben.

Konsole verwenden

  1. Suchen Sie auf der Seite mit den Google Cloud-Projekteinstellungen nach der Projektnummer Ihres Projekts.
  2. Notieren Sie die Nummer.
  3. Öffnen Sie die Seite der IAM-Admin-Konsole.
  4. Klicken Sie auf Add. Der Bildschirm Add members wird geöffnet.
  5. Fügen Sie im Dialogfeld "Neue Mitglieder" eine E-Mail-Adresse im folgenden Format hinzu:

    service-[project-number]@gcp-sa-cloudtasks.iam.gserviceaccount.com
    

    Ersetzen Sie [project-number] durch Ihre Projektnummer von oben.

  6. Wählen Sie im Drop-down-Menü Select a role die Option Service Management -> Cloud Tasks Service Agent aus.

  7. Klicken Sie auf Save.

gcloud verwenden

  1. Suchen Sie Ihre Projektnummer:

    gcloud projects describe [project-id] --format='table(projectNumber)'
    

    Dabei wird [project-id] durch Ihre Projekt-ID ersetzt.

  2. Notieren Sie die Nummer.

  3. Weisen Sie dem Cloud Tasks-Dienstkonto die Rolle Cloud Tasks Service Agent mit der Projektnummer zu, die Sie kopiert haben:

    gcloud projects add-iam-policy-binding [project-id] --member serviceAccount:service-[project-number]@gcp-sa-cloudtasks.iam.gserviceaccount.com --role roles/cloudtasks.serviceAgent
    

    Ersetzen Sie [project-id] durch Ihre Projekt-ID und [project-number] durch die Projektnummer von weiter oben.

Nächste Schritte