ExternalCallout-Richtlinie

Diese Seite gilt für Apigee und Apigee Hybrid.

Apigee Edge-Dokumentation aufrufen

Richtliniensymbol

Was

Mit der ExternalCallout-Richtlinie können Sie gRPC an Ihren gRPC-Server senden, um benutzerdefiniertes Verhalten zu implementieren, das von den Apigee-Richtlinien nicht unterstützt wird. Im Code Ihres Servers können Sie einfach auf Ablaufvariablen im Ablauf eines Proxys zugreifen und diese ändern.

Apigee kommuniziert mit einem gRPC-Server über eine ExternalCallout-Richtlinie über eine API. Apigee verwendet die API, um Ablaufvariablen an den gRPC-Server zu senden. Auf Ihrem gRPC-Server können Sie die auf der Referenzseite für Ablaufvariablen aufgeführten Ablaufvariablen sowie zusätzliche Variablen, die Sie in der XML-Datei der Richtlinie angeben, lesen und je nach Variable ändern.

Wenn Sie den gRPC-Server mit Apigee konfigurieren und diese Richtlinie in einen Proxy einfügen, behandelt Apigee API-Anfragen so:

  1. Apigee sendet eine Nachricht mit den Ablaufvariablen an Ihren gRPC-Server.
  2. Ihr gRPC-Servercode wird ausgeführt, greift auf die Variablen zu und ändert sie so, wie im Code definiert. Der gRPC-Server sendet dann eine Antwort mit allen Ablaufvariablen zurück an Apigee.
  3. Apigee liest die Antwort Ihres gRPC-Servers. Wenn Variablen hinzugefügt oder veränderbare Ablaufvariablen geändert werden, werden sie in Apigee aktualisiert.

Diese Richtlinie ist eine Standardrichtlinie, die in jeder Umgebung bereitgestellt werden kann. Informationen zu Richtlinientypen und zur Verfügbarkeit bei jedem Umgebungstyp finden Sie unter Richtlinientypen.

Weitere Informationen zum Senden von gRPC-Anfragen finden Sie unter den folgenden Links:

<ExternalCallout>

Definiert eine ExternalCallout-Richtlinie.

<ExternalCallout async="true" continueOnError="true" enabled="true" name="EC">

Dieses Element hat folgende Attribute, die allen Richtlinien gemeinsam sind:

Attribut Standard Erforderlich? Beschreibung
name - Erforderlich

Der interne Name der Richtlinie. Der Wert des Attributs name kann Buchstaben, Ziffern, Leerzeichen, Bindestriche, Unterstriche und Punkte enthalten. Dieser Wert darf 255 Zeichen nicht überschreiten.

Optional können Sie das Element <DisplayName> verwenden, um die Richtlinie im Proxy-Editor der Verwaltungs-UI mit einem anderen Namen in einer natürlichen Sprache zu versehen.

continueOnError false Optional Legen Sie false fest, um einen Fehler zurückzugeben, wenn eine Richtlinie fehlschlägt. Dies ist für die meisten Richtlinien das erwartete Verhalten. Legen Sie true fest, damit die Ablaufausführung auch nach dem Fehlschlagen einer Richtlinie fortgesetzt wird. Weitere Informationen:
enabled wahr Optional Setzen Sie den Wert auf true, um die Richtlinie zu erzwingen. Legen Sie false fest, um die Richtlinie zu deaktivieren. Die Richtlinie wird nicht durchgesetzt, selbst wenn sie mit einem Ablauf verknüpft ist.
async   false Verworfen Dieses Attribut wurde verworfen.

In der folgenden Tabelle werden die untergeordneten Elemente von <ExternalCallout> beschrieben.

Untergeordnetes Element Erforderlich Beschreibung
<TimeoutMs> Erforderlich Das Zeitlimit für Anfragen in Millisekunden für gRPC-Anfragen.
<GrpcConnection> Erforderlich Gibt den Namen eines vorhandenen TargetServer an, der der gRPC-Server sein soll und an den Anfragen gesendet werden sollen.
<Configurations> Optional Hiermit können Sie verschiedene Aspekte der ExternalCallout-Richtlinie konfigurieren, einschließlich der Elemente <Property> und <FlowVariable>.

Beispiel 1

Arbeitsbeispiele für ExternalCallout finden Sie auf GitHub-Beispielen für externe Callouts.

Das folgende Beispiel zeigt eine ExternalCallout-Richtlinienkonfiguration.

<ExternalCallout enabled="true" continueOnError="false" name="ExternalCallout-1">
  <DisplayName>External Callout 1</DisplayName>
  <TimeoutMs>5000</TimeoutMs>
  <GrpcConnection>
    <Server name="external-target-server"/>
  </GrpcConnection>
  <Configurations>
    <Property name="with.request.content">true</Property>
    <Property name="with.request.headers">false</Property>
    <Property name="with.response.content">true</Property>
    <Property name="with.response.headers">false</Property>
    <FlowVariable>example1.flow.variable</FlowVariable>
    <FlowVariable>example2.flow.variable</FlowVariable>
  </Configurations>
<ExternalCallout>

In diesem Beispiel wird eine Anfrage an einen externen gRPC-Server gesendet, der durch den TargetServer namens external-target-server mit den folgenden Konfigurationen repräsentiert wird:

  • <Property>: Schließt Anfrage- und Antwortinhalte, aber keine Anfrage- und Antwortheader in die Anfrage ein, die an den gRPC-Server gesendet wird.
  • <FlowVariable>: Schließt zusätzliche Ablaufvariablen example1.flow.variable und example2.flow.variable, die durch die FlowVariable-Elemente angegeben sind, in die Anfrage an den gRPC-Server ein.

Beispiel 2

Im folgenden Beispiel ist das Attribut useTargetUrl des Elements Audience auf true festgelegt. Wenn useTargetUrl den Wert true hat, wird der Hostname des gRPC-Zielservers als Zielgruppe verwendet. Wenn der Host des Servers beispielsweise my-grpc-server-java.a.run.app ist, ist die verwendete Zielgruppe https://my-grpc-server-java.a.run.app.

<ExternalCallout continueOnError="false" enabled="true" name="External-Callout-1">
  <DisplayName>External-Callout-1</DisplayName>
  <GrpcConnection>
    <Server name="cloud_run_server_name"/>
    <Authentication>
      <GoogleIDToken>
        <Audience useTargetUrl="true"/>
      </GoogleIDToken>
    </Authentication>
  </GrpcConnection>
  <TimeoutMs>5000</TimeoutMs>
  <Configurations>
    <Property name="with.request.content">true</Property>
    <Property name="with.request.headers">true</Property>
    <Property name="with.response.content">true</Property>
    <Property name="with.response.headers">true</Property>
    <FlowVariable>example.flow.variable</FlowVariable>
    <FlowVariable>another.flow.variable</FlowVariable>
  </Configurations>
</ExternalCallout>

Verweis auf untergeordnetes Element

In den folgenden Abschnitten werden die untergeordneten Elemente von ExternalCallout beschrieben.

<TimeoutMs>

Das Zeitlimit für Anfragen in Millisekunden für gRPC-Anfragen. <TimeoutMs> muss eine positive Zahl sein.

<GrpcConnection>

Das Element <GrpcConnection> legt den gRPC-Server auf einen vorhandenen TargetServer fest, der durch das Attribut name angegeben wird. Weitere Informationen finden Sie auf der Ressourcenreferenzseite zu TargetServer.

Hinweis: Das Protokoll für den TargetServer muss GRPC lauten.

Der folgende Code zum Beispiel:

<GrpcConnection>
  <Server name="external-target-server"/>
</GrpcConnection>

gibt den gRPC-Server als vorhandenen TargetServer mit dem Namen external-target-server an.

Verwenden Sie das Element <Authentication> (weiter unten in diesem Abschnitt beschrieben), um ein von Google ausgestelltes OpenID Connect-Token zu generieren und authentifizierte Aufrufe an gRPC-basierte Dienste durchzuführen, wie z. B. in Cloud Run gehostete benutzerdefinierte Dienste.

In der folgenden Tabelle werden die untergeordneten Elemente von <GrpcConnection> beschrieben.

Untergeordnetes Element Erforderlich? Beschreibung
Element <Server> Erforderlich Gibt den gRPC-Server an.
Element <Authentication> Optional Generiert ein von Google ausgestelltes OpenID Connect-Token, um authentifizierte Aufrufe an gRPC-basierte Dienste wie Cloud Run durchzuführen.

Element <Server>

Gibt den gRPC-Server an.

In der folgenden Tabelle werden die Attribute des Elements <Server> beschrieben.

Attribut Beschreibung Standard Presence Typ
name

Der Name eines vorhandenen TargetServer als gRPC-Server, an den Anfragen gesendet werden sollen.

Erforderlich String

Element <Authentication>

Generiert ein von Google ausgestelltes OpenID Connect-Token, um authentifizierte Aufrufe an gRPC-basierte Dienste vorzunehmen, z. B. benutzerdefinierte Dienste, die in Cloud Run gehostet werden. Die Verwendung dieses Elements erfordert eine Einrichtung und Bereitstellung wie unter Google-Authentifizierung verwenden erläutert. Bei korrekter Einrichtung erstellt die Richtlinie automatisch ein Authentifizierungstoken und fügt es der Dienstanfrage hinzu.

Dieses Element hat ein erforderliches untergeordnetes Element: GoogleIDToken.

Standard
Erforderlich? Optional.
Typ Komplexer Typ
Übergeordnetes Element <GrpcConnection>
Untergeordnete Elemente <GoogleIDToken>

Das Authentication-Element verwendet die folgende Syntax:

Syntax

<ExternalCallout>
...
  <GrpcConnection>
    <Server name="cloud_run_server_name"/>
    <Authentication>
      <HeaderName ref="FLOW_VARIABLE">STRING</HeaderName>
      <GoogleIDToken>
         <Audience ref="variable-1">STRING</Audience>
         <IncludeEmail ref="variable-2">BOOLEAN</IncludeEmail>
      </GoogleIDToken>
    </Authentication>
  </GrpcConnection>
</ExternalCallout>

Beispiel

Das folgende Beispiel zeigt das Element GoogleIDToken:

<ExternalCallout continueOnError="false" enabled="true" name="External-Callout-1">
  <DisplayName>External-Callout-1</DisplayName>
  <GrpcConnection>
     <Server name="cloud_run_server_name"/>
     <Authentication>
        <HeaderName ref='my-variable'>X-Serverless-Authorization</HeaderName>
        <GoogleIDToken>
           <Audience>https://cloudrun-hostname.a.run.app</Audience>
        </GoogleIDToken>
     </Authentication>
  </GrpcConnection>
  <TimeoutMs>5000</TimeoutMs>
  <Configurations>
    <Property name="with.request.content">true</Property>
    <Property name="with.request.headers">true</Property>
    <Property name="with.response.content">true</Property>
    <Property name="with.response.headers">true</Property>
    <FlowVariable>example.flow.variable</FlowVariable>
    <FlowVariable>another.flow.variable</FlowVariable>
  </Configurations>
</ExternalCallout>
Attribute

Keine.

Untergeordnetes <HeaderName>-Element

Wenn eine Authentifizierungskonfiguration vorhanden ist, generiert Apigee standardmäßig ein Inhabertoken und fügt es in den Header Authorization in die Nachricht ein, die an das Zielsystem gesendet wird. Mit dem Element HeaderName können Sie den Namen eines anderen Headers angeben, der dieses Inhabertoken enthält. Dieses Feature ist besonders nützlich, wenn das Ziel ein Cloud Run-Dienst ist, der den Header X-Serverless-Authorization verwendet. Der Authorization-Header, falls vorhanden, bleibt unverändert und wird auch in der Anfrage gesendet.

Standard
Erforderlich? Nein
Typ String
Übergeordnetes Element <Authentication>
Untergeordnete Elemente

Das HeaderName-Element verwendet die folgende Syntax:

Syntax

<ExternalCallout>
...
  <Authentication>
    <HeaderName ref="FLOW_VARIABLE">STRING</HeaderName>
    <GoogleIDToken>
    ... 
    </GoogleIDToken>
  </Authentication>
  ...
</ExternalCallout>

Mit statischem String

In diesem Beispiel wird das generierte Inhabertoken standardmäßig einem Header namens X-Serverless-Authorization hinzugefügt, der an das Zielsystem gesendet wird. Der Authorization-Header, falls vorhanden, bleibt unverändert und wird auch in der Anfrage gesendet.

<Authentication>
  <HeaderName>X-Serverless-Authorization</HeaderName>
  <GoogleIDToken>
    <Audience>https://cloudrun-hostname.a.run.app</Audience>
  </GoogleIDToken>
</Authentication>

Mit Variablenverweis

In diesem Beispiel wird das generierte Inhabertoken standardmäßig einem Header namens X-Serverless-Authorization hinzugefügt, der an das Zielsystem gesendet wird. Wenn my-variable einen Wert hat, wird dieser Wert anstelle des Standardstrings verwendet. Der Authorization-Header, falls vorhanden, bleibt unverändert und wird auch in der Anfrage gesendet.

<Authentication>
  <HeaderName ref='my-variable'>X-Serverless-Authorization</HeaderName>
  <GoogleIDToken>
    <Audience>https://cloudrun-hostname.a.run.app</Audience>
  </GoogleIDToken>
</Authentication>
Untergeordnetes <GoogleIDToken>-Element

Generiert von Google ausgestellte OpenID Connect-Tokens für authentifizierte Aufrufe an Google-Dienste wie benutzerdefinierte Dienste, die in Cloud Run gehostet werden.

Standard
Erforderlich? Erforderlich
Typ String
Übergeordnetes Element <Authentication>
Untergeordnete Elemente <Audience>
<IncludeEmail>

Das GoogleIDToken-Element verwendet die folgende Syntax:

Syntax

<ExternalCallout>
...
  <GrpcConnection>
    <Server name="cloud_run_server_name"/>
    <Authentication>
      <GoogleIDToken>
        <Audience ref="context-variable" useTargetUrl='BOOLEAN'>STRING</Audience>
        <IncludeEmail ref="context-variable">BOOLEAN</IncludeEmail>
      </GoogleIDToken>
    </Authentication>
  </GrpcConnection>
</ExternalCallout>

Beispiel

Das folgende Beispiel zeigt das Element GoogleIDToken:

<Authentication>
  <GoogleIDToken>
      <Audience>https://httpserver0-bar.run.app</Audience>
      <IncludeEmail>true</IncludeEmail>
  </GoogleIDToken>
</Authentication>
Untergeordnetes <Audience>-Element

Das Zielobjekt für das generierte Authentifizierungstoken, z. B. die API oder das Konto, auf das das Token Zugriff gewährt.

Wenn der Wert von Audience leer ist (ref ist leer oder wird in einen leeren Wert aufgelöst) und useTargetUrl ist true, dann wird "https://" + (Hostname des gRPC-Zielservers) als Zielgruppe verwendet. Wenn der Host des Servers beispielsweise my-grpc-server-java.a.run.app ist, ist die Zielgruppe https://my-grpc-server-java.a.run.app.

Standardmäßig ist useTargetUrl auf false festgelegt.

<Audience>explicit-audience-value-here</Audience>

or:

<Audience ref='variable-name-here'/>

or:

<Audience ref='variable-name-here' useTargetUrl='true'/>

or:

<Audience useTargetUrl='true'/>
Standard
Erforderlich? Erforderlich
Typ String
Übergeordnetes Element <GoogleIDToken>
Untergeordnete Elemente
Untergeordnetes <IncludeEmail>-Element

Wenn dafür true festgelegt ist, enthält das generierte Authentifizierungstoken die Anforderungen email und email_verified des Dienstkontos.

Standard false
Erforderlich? Optional
Typ Boolesch
Übergeordnetes Element <GoogleIDToken>
Untergeordnete Elemente

<Configurations>

Mit dem Element <Configurations> können Sie verschiedene Aspekte der ExternalCallout-Richtlinie konfigurieren, einschließlich <Property> und <FlowVariable>.

In der folgenden Tabelle werden die untergeordneten Elemente von <Configurations> beschrieben.

Untergeordnetes Element Erforderlich? Beschreibung
<Property> Erforderlich

Gibt an, ob Anfrage-/Antwortheader und/oder -inhalte an den Server gesendet werden. Mögliche Werte sind true und false. Der Standardwert ist false.

<FlowVariable> Erforderlich

Gibt an, welche zusätzlichen Ablaufvariablen an den Server gesendet werden sollen.

<Property>

Das <Property>-Element gibt an, ob Anfrage-/Antwortheader und/oder -inhalte an den Server gesendet werden. Mögliche Werte sind true (das Element wird gesendet) oder false (das Element wird nicht gesendet). Der Standardwert ist false.

In der folgenden Tabelle werden die Attribute des Elements <Property> beschrieben.

Attribut Beschreibung Standard Presence Typ
name

Gibt an, welche Inhalte an den Server gesendet werden. Folgende Werte sind für name möglich:

  • with.request.content
  • with.request.headers
  • with.response.content
  • with.response.headers
Erforderlich String

<FlowVariable>

Das <FlowVariable>-Element gibt an, welche zusätzlichen Ablaufvariablen an den Server gesendet werden. Der Wert von <FlowVariable> ist ein Präfix einer Variablen anstelle des vollständigen Variablennamens. Ist das Element beispielsweise a.b.c, wird der Wert einer Variablen namens a.b.c an den Server gesendet. Ebenso wird der Wert einer Variablen namens a.b.c.my-variable an den Server gesendet. Der Wert einer Variablen namens a.x.another-variable wird jedoch nicht gesendet, da sie nicht das Präfix a.b.c hat. Hier sind einige Beispiele:

<Configurations>
  <FlowVariable>a.b.c</FlowVariable>
  <FlowVariable>d.e.f</FlowVariable>
</Configurations>

Fehlerreferenz

Bereitstellungsfehler

Fehlername Ursache
FAILED_PRECONDITION Dieser Fehler tritt auf, wenn das Dienstkonto fehlt und der Proxy mit dem Tag <Authentication> konfiguriert ist.

Beispiel:

Deployment of \"organizations/foo/apis/apiproxy/revisions/1\"
requires a service account identity, but one was not provided
with the request.
PERMISSION_DENIED Dieser Fehler tritt auf, wenn ein Berechtigungsproblem mit dem Dienstkonto besteht und der Proxy mit dem Tag <Authentication> konfiguriert ist. Mögliche Ursachen:
  • Das Dienstkonto ist nicht vorhanden.
  • Das Dienstkonto wurde nicht im selben Google Cloud-Projekt wie die Apigee-Organisation erstellt.
  • Der Bereitsteller hat die Berechtigung iam.serviceAccounts.actAs für das Dienstkonto. Weitere Informationen finden Sie im Hilfeartikel Dienstkontoberechtigungen.

Laufzeitfehler

In der folgenden Tabelle werden Laufzeitfehler beschrieben, die beim Ausführen der Richtlinie auftreten können.

Fehlercode HTTP-Status Ursache
GrpcTlsInitFailed 500

Dieser Fehler tritt auf, wenn bei der Initialisierung von TLS mit dem gRPC-Server Probleme auftreten (z. B. Probleme mit dem Schlüsselspeicher oder Truststore).

steps.externalcallout.[error_code] 500

[error_code] wird durch das Feld errorCode der Fehlernachricht bestimmt. Der Fehlerstring des Fehlers ist das Feld faultstring der Fehlernachricht.

steps.externalcallout.ExecutionError 500

Dieser Fehler tritt auf, wenn während der Ausführung dieser Richtlinie eine andere Ausnahme auftritt. Die zugrunde liegende Ausnahme wird im Fehlerstring angezeigt. Wenn ein Problem mit den Anmeldedaten für den gRPC-Server aufgetreten ist, sieht der Fehler etwa so aus:

{
  "fault": {
    "faultstring": "Encountered the following exception while sending the gRPC request or
     processing the response: [io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed
     to obtain metadata].",
    "detail": {
      "errorcode": "steps.externalcallout.ExecutionError"
    }
  }
}

In den Logs des MP finden Sie weitere Hinweise zum Debugging.

googletoken.EmptyIDTokenAudience 500

<GoogleIDToken> ist aktiviert, aber useTargetUrl ist auf „false“ gesetzt und es wird kein Wert für <Audience> angegeben, weder direkt noch durch Verweis zum Zeitpunkt des Fehlers.

steps.externalcallout.ExecutionError

mit Fehlerstring:

Encountered the following exception while sending the gRPC request or processing the response: [io.grpc.StatusRuntimeException: UNAVAILABLE: Credentials failed to obtain metadata]

500

Dieser Fehler tritt auf, wenn der API-Proxy mit dem Element <Authentication> konfiguriert ist. Mögliche Ursachen:

  • Das mit dem Proxy bereitgestellte Dienstkonto:
    • existiert nicht in Ihrem Projekt (war bei der Bereitstellung vorhanden, wurde aber nach der Bereitstellung gelöscht)
    • wurde deaktiviert
    • (Nur Apigee Hybrid) hat dem Dienstkonto apigee-runtime die Rolle roles/iam.serviceAccountTokenCreator nicht zugewiesen.
  • (Nur Apigee Hybrid) Die IAMCredentials API ist im Quellprojekt des Dienstkontos apigee-runtime deaktiviert.

    Hinweis (nur Apigee Hybrid): Überprüfen Sie das Log des Laufzeitcontainers und suchen Sie nach externalcallout.ExecutionError, um detailliertere Fehlermeldungen zu finden, die bei der Fehlersuche helfen können.

steps.externalcallout.ExecutionError mit einem Fehlerstring, der PERMISSION DENIED enthält.

Der Fehlerstring sieht für Cloud Run beispielsweise so aus:

Encountered the following exception while sending the gRPC request or processing the response: [io.grpc.StatusRuntimeException: PERMISSION_DENIED: HTTP status code 403 …]

500

Dieser Fehler tritt auf, wenn der API-Proxy mit dem Element <Authentication> konfiguriert ist. Mögliche Ursachen:

  • Das Proxy-Dienstkonto ist vorhanden und aktiviert, hat jedoch nicht die erforderlichen Berechtigungen für den Zugriff auf den Dienst.
  • Der Dienst erfordert eine Authentifizierung, aber die Anfrage hat keinen Authentifizierungs-Header. Beispiel: Die Authentifizierungs-XML war nicht in der Richtlinien-XML enthalten.

Sonstige Fehler

In der folgenden Tabelle werden verschiedene Fehler beschrieben. Weitere Informationen finden Sie unter der Ursache.

Fehlercode Ursache
ReferencesExistToGrpcServer

Dieser Fehler tritt auf, wenn ein Nutzer versucht, einen gRPC-Zielserver zu löschen, der Server jedoch weiterhin von anderen Richtlinien verwendet wird.

Fehler

Die Fehlervariablen in der folgenden Tabelle sind standardmäßig für alle Richtlinien festgelegt. Weitere Informationen finden Sie unter Spezifische Variablen für Richtlinienfehler.

Variablen Wo Beispiele
fault.name="fault_name" fault_name ist der Name des Fehlers, der in der obigen Tabelle der Laufzeitfehler aufgeführt ist. Der Fehlername ist der letzte Teil des Fehlercodes. fault.name stimmt mit "ExecutionError" überein.
externalcallout.[policy_name].failed policy_name ist der benutzerdefinierte Name der Richtlinie, die den Fehler ausgelöst hat. externalcallout.ExternalCallout-1.failed = true

Weitere Informationen