Norme relative a ExternalCallout

Questa pagina si applica ad Apigee e Apigee hybrid.

Visualizza la documentazione di Apigee Edge.

icona delle norme

Cosa

Il criterio ExternalCallout ti consente di inviare richieste gRPC al tuo server gRPC per implementare un comportamento personalizzato non supportato dai criteri Apigee. Nel codice del server, puoi accedere e modificare facilmente le variabili di flusso all'interno del flusso di un proxy.

Apigee comunica con un server gRPC tramite un criterio ExternalCallout tramite un'API. Apigee utilizza l'API per inviare variabili di flusso al server gRPC. Nel server gRPC, puoi leggere e, a seconda della variabile, modificare le variabili di flusso elencate nella pagina di riferimento Voci di flusso, nonché le variabili aggiuntive specificate nel file XML del criterio.

Se configuri il server gRPC con Apigee e includi questo criterio in un proxy, Apigee gestirà le richieste API come segue:

  1. Apigee invia un messaggio contenente le variabili di flusso al tuo server gRPC.
  2. Il codice del server gRPC viene eseguito, accedendo e modificando le variabili come definito nel codice. Il server gRPC invia quindi una risposta contenente tutte le variabili di flusso ad Apigee.
  3. Apigee legge la risposta del server gRPC. Se vengono aggiunte variabili o se le variabili di flusso modificabili vengono modificate, queste vengono aggiornate in Apigee.

Questo criterio è un criterio standard e può essere implementato in qualsiasi tipo di ambiente. Per informazioni sui tipi di criteri e sulla loro disponibilità in base a ciascun tipo di ambiente, consulta Tipi di criteri.

Per scoprire di più sull'invio di richieste gRPC, consulta i seguenti link:

<ExternalCallout>

Definisce un criterio ExternalCallout.

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

Questo elemento ha i seguenti attributi comuni a tutti i criteri:

Attributo Predefinito Obbligatorio? Descrizione
name N/D Obbligatorio

Il nome interno del criterio. Il valore dell'attributo name può contenere lettere, numeri, spazi, trattini, trattini bassi e punti. Questo valore non può superare i 255 caratteri.

Se vuoi, utilizza l'elemento <DisplayName> per etichettare il criterio nell'editor proxy dell'interfaccia utente di gestione con un nome diverso in linguaggio naturale.

continueOnError falso Facoltativo Imposta su false per restituire un errore quando un criterio non va a buon fine. Questo è un comportamento previsto per la maggior parte dei criteri. Imposta su true per continuare l'esecuzione del flusso anche dopo un fallimento del criterio. Vedi anche:
enabled true Facoltativo Imposta su true per applicare il criterio. Imposta su false per disattivare il criterio. Il criterio non verrà applicato anche se rimane collegato a un flusso.
async   falso Ritirato Questo attributo è stato ritirato.

La tabella seguente descrive gli elementi secondari di <ExternalCallout>.

Elemento secondario Obbligatorio Descrizione
<TimeoutMs> Obbligatorio Il timeout della richiesta in millisecondi per le richieste gRPC.
<GrpcConnection> Obbligatorio Specifica il nome di un TargetServer esistente da utilizzare come server gRPC a cui inviare le richieste.
<Configurations> Facoltativo Consente di configurare vari aspetti del criterio ExternalCallout, inclusi gli elementi <Property> e <FlowVariable>.

Esempio 1

Esempi funzionanti di ExternalCallout sono disponibili nella pagina Esempi di callout esterno su GitHub.

L'esempio seguente illustra una configurazione del criterio ExternalCallout.

<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>

L'esempio invia una richiesta a un server gRPC esterno rappresentato da TargetServer denominato external-target-server, con le seguenti configurazioni:

  • <Property>: includi i contenuti della richiesta e della risposta, ma non le intestazioni della richiesta e della risposta, nella richiesta inviata al server gRPC.
  • <FlowVariable>: includi altre variabili di flusso example1.flow.variable e example2.flow.variable, specificate dagli elementi FlowVariable, nella richiesta inviata al server gRPC.

Esempio 2

Nell'esempio seguente, l'attributo useTargetUrl dell'elemento Audience è impostato su true. Quando useTargetUrl è true, il nome host del server di destinazione gRPC viene utilizzato come pubblico. Ad esempio, se l'host del server è my-grpc-server-java.a.run.app, il segmento di pubblico utilizzato sarà 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>

Riferimento all'elemento secondario

Le sezioni seguenti descrivono gli elementi secondari di ExternalCallout.

<TimeoutMs>

Il timeout della richiesta in millisecondi per le richieste gRPC. <TimeoutMs> deve essere un numero positivo.

<GrpcConnection>

L'elemento <GrpcConnection> imposta il server gRPC come un TargetServer esistente, specificato dall'attributo name. Consulta la pagina di riferimento della risorsa TargetServer.

Nota: il protocollo per TargetServer deve essere GRPC.

Ad esempio, il seguente codice

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

specifica che il server gRPC deve essere un TargetServer esistente chiamato external-target-server.

Utilizza l'elemento <Authentication> (descritto più avanti in questa sezione) per generare un token OpenID Connect emesso da Google per effettuare chiamate autenticate a servizi basati su gRPC, come i servizi personalizzati ospitati in Cloud Run.

La tabella seguente descrive gli elementi secondari di <GrpcConnection>.

Elemento secondario Obbligatorio? Descrizione
Elemento <Server> Obbligatorio Specifica il server gRPC.
Elemento <Authentication> Optional Genera un token OpenID Connect emesso da Google per effettuare chiamate autenticate a servizi basati su gRPC, come Cloud Run.

Elemento <Server>

Specifica il server gRPC.

La tabella seguente descrive gli attributi dell'elemento <Server>.

Attributo Descrizione Predefinito Presenza Tipo
name

Il nome di un TargetServer esistente che deve essere il server gRPC a cui inviare le richieste.

N/D Obbligatorio Stringa

Elemento <Authentication>

Genera un token OpenID Connect emesso da Google per effettuare chiamate autenticate a servizi basati su gRPC, come i servizi personalizzati ospitati in Cloud Run. L'utilizzo di questo elemento richiede i passaggi di configurazione e deployment descritti in Utilizzare l'autenticazione Google. Con la configurazione corretta, il criterio crea un token di autenticazione e lo aggiunge alla richiesta di servizio.

Questo elemento ha un elemento secondario obbligatorio: GoogleIDToken.

Predefinito N/D
Obbligatorio? Facoltativo.
Tipo Tipo complesso
Elemento principale <GrpcConnection>
Elementi secondari <GoogleIDToken>

La sintassi dell'elemento Authentication è la seguente:

Sintassi

<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>

Esempio

L'esempio seguente mostra l'elemento 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>
Attributi

Nessuno.

Elemento secondario <HeaderName>

Per impostazione predefinita, quando è presente una configurazione di autenticazione, Apigee genera un token di accesso e lo inserisce nell'intestazione Authorization del messaggio inviato al sistema di destinazione. L'elemento HeaderName consente di specificare il nome di un'altra intestazione per contenere il token di accesso. Questa funzionalità è particolarmente utile quando la destinazione è un servizio Cloud Run che utilizza l'intestazione X-Serverless-Authorization. L'intestazione Authorization, se presente, viene lasciata invariata e inviata anche nella richiesta.

Predefinito N/D
Obbligatorio? No
Tipo Stringa
Elemento principale <Authentication>
Elementi secondari Nessuno

La sintassi dell'elemento HeaderName è la seguente:

Sintassi

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

Con stringa statica

In questo esempio, il token bearer generato viene aggiunto, per impostazione predefinita, a un'intestazione denominata X-Serverless-Authorization che viene inviata al sistema di destinazione. L'intestazione Authorization, se presente, viene lasciata invariata e inviata anche nella richiesta.

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

Con riferimento a una variabile

In questo esempio, il token bearer generato viene aggiunto, per impostazione predefinita, a un'intestazione denominata X-Serverless-Authorization che viene inviata al sistema di destinazione. Se my-variable ha un valore, viene utilizzato questo valore anziché la stringa predefinita. L'intestazione Authorization, se presente, viene lasciata invariata e inviata anche nella richiesta.

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

Genera token OpenID Connect emessi da Google per effettuare chiamate autenticate ai servizi Google, ad esempio i servizi personalizzati ospitati in Cloud Run.

Predefinito N/D
Obbligatorio? Obbligatorio
Tipo Stringa
Elemento principale <Authentication>
Elementi secondari <Audience>
<IncludeEmail>

La sintassi dell'elemento GoogleIDToken è la seguente:

Sintassi

<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>

Esempio

L'esempio seguente mostra l'elemento GoogleIDToken:

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

Il pubblico per il token di autenticazione generato, ad esempio l'API o l'account a cui il token concede l'accesso.

Se il valore di Audience è vuoto, ref è vuoto o si risolve in un valore vuoto e useTargetUrl è true, viene utilizzato "https://" + (nome host del server di destinazione gRPC) come pubblico. Ad esempio, se l'host del server è my-grpc-server-java.a.run.app, il pubblico utilizzato sarà https://my-grpc-server-java.a.run.app.

Per impostazione predefinita, useTargetUrl è false.

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

or:

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

or:

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

or:

<Audience useTargetUrl='true'/>
Predefinito N/D
Obbligatorio? Obbligatorio
Tipo Stringa
Elemento principale <GoogleIDToken>
Elementi secondari Nessuno.
Elemento secondario <IncludeEmail>

Se impostato su true, il token di autenticazione generato conterrà i claim email e email_verified dell'account di servizio.

Predefinito falso
Obbligatorio? Facoltativo
Tipo Booleano
Elemento principale <GoogleIDToken>
Elementi secondari Nessuno.

<Configurations>

L'elemento <Configurations> consente di configurare vari aspetti del criterio ExternalCallout, inclusi <Property> e <FlowVariable>.

La tabella seguente descrive gli elementi secondari di <Configurations>.

Elemento secondario Obbligatorio? Descrizione
<Property> Obbligatorio

Specifica se le intestazioni e/o i contenuti di richiesta/risposta verranno inviati al server. I valori possibili sono true o false. Il valore predefinito è false.

<FlowVariable> Obbligatorio

Specifica quali variabili di flusso aggiuntive devono essere inviate al server.

<Property>

L'elemento <Property> specifica se le intestazioni e/o i contenuti di richiesta/risposta verranno inviati al server. I valori possibili sono true (l'elemento verrà inviato) o false (l'elemento non verrà inviato). Il valore predefinito è false.

La tabella seguente descrive gli attributi dell'elemento <Property>.

Attributo Descrizione Predefinito Presenza Tipo
name

Specifica i contenuti che verranno inviati al server. I valori possibili per name sono:

  • with.request.content
  • with.request.headers
  • with.response.content
  • with.response.headers
N/D Obbligatorio Stringa

<FlowVariable>

L'elemento <FlowVariable> specifica quali variabili di flusso aggiuntive verranno inviate al server. Il valore di <FlowVariable> è un prefisso di una variabile anziché il nome completo della variabile. Ad esempio , se l'elemento è a.b.c, il valore di una variabile denominata a.b.c verrà inviato al server. Analogamente, il valore di una variabile denominata a.b.c.my-variable verrà inviato al server. Tuttavia, il valore di una variabile denominata a.x.another-variable non verrà inviato, perché non ha il prefisso a.b.c. Ecco alcuni esempi

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

Riferimento all'errore

Errori di deployment

Nome dell'errore Causa
FAILED_PRECONDITION Questo errore si verifica se il account di servizio non è presente quando il proxy è configurato con il tag <Authentication>.

Ad esempio:

Deployment of \"organizations/foo/apis/apiproxy/revisions/1\"
requires a service account identity, but one was not provided
with the request.
PERMISSION_DENIED Questo errore si verifica se si verifica un problema di autorizzazione con l'account di servizio se il proxy è configurato con il tag <Authentication>. Possibili cause:
  • L'account di servizio non esiste.
  • L'account di servizio non è stato creato nello stesso progetto Google Cloud dell'organizzazione Apigee.
  • Il programmatore dispone dell'autorizzazione iam.serviceAccounts.actAs per l'account di servizio. Per maggiori dettagli, vedi Informazioni sulle autorizzazioni degli account di servizio.

Errori di runtime

La tabella seguente descrive gli errori di runtime che possono verificarsi durante l'esecuzione del criterio.

Codice guasto Stato HTTP Causa
GrpcTlsInitFailed 500

Questo errore si verifica se si verificano problemi di inizializzazione di TLS con il server gRPC (ad esempio problemi relativi a Keystore o Truststore).

steps.externalcallout.[error_code] 500

[error_code] viene determinato dal campo errorCode del messaggio di errore. La stringa dell'errore sarà il campo faultstring del messaggio di errore.

steps.externalcallout.ExecutionError 500

Questo errore si verifica se si verifica un'altra eccezione durante l'esecuzione di questo criterio. L'eccezione sottostante verrà esposta in faultstring. Se si è verificato un problema con le credenziali del server gRPC, l'errore sarà simile al seguente:

{
  "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"
    }
  }
}

Puoi esaminare i log del modulo per ulteriori indicazioni di debug.

googletoken.EmptyIDTokenAudience 500

<GoogleIDToken> è abilitato, ma useTargetUrl è impostato su false e non viene fornito alcun valore per <Audience> direttamente o tramite riferimento al momento dell'errore.

steps.externalcallout.ExecutionError

con stringa di errore:

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

500

Questo errore si verifica se il proxy API è configurato con l'elemento <Authentication>. Cause possibili:

  • L'account di servizio di cui è stato eseguito il deployment con il proxy:
    • non esiste nel tuo progetto (esisteva al momento del deployment, ma è stata eliminata dopo il deployment)
    • è stata disattivata
    • (Solo Apigee Hybrid) non ha concesso il ruolo roles/iam.serviceAccountTokenCreator all'account di servizio apigee-runtime.
  • (Solo Apigee Hybrid) L'API IAMCredentials è disattivata nel progetto di origine dell'account di servizio apigee-runtime.

    Nota: solo per Apigee Hybrid, controlla il log del contenitore di runtime e cerca externalcallout.ExecutionError per trovare messaggi di errore più dettagliati che potrebbero essere utili per il debug del problema.

steps.externalcallout.ExecutionError con faultstring contenente PERMISSION DENIED.

Ad esempio, per Cloud Run, la stringa di errore sarà simile alla seguente:

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

500

Questo errore si verifica se il proxy API è configurato con l'elemento <Authentication>. Cause possibili:

  • L'account di servizio proxy esiste ed è abilitato, ma non dispone delle autorizzazioni necessarie per accedere al servizio.
  • Il servizio richiede l'autenticazione, ma la richiesta non conteneva un'intestazione di autenticazione (ad esempio, il file XML di autenticazione non era incluso nel file XML dei criteri).

Errori vari

La tabella seguente descrive gli errori vari. Per maggiori dettagli, consulta la causa.

Codice guasto Causa
ReferencesExistToGrpcServer

Questo errore si verifica se un utente tenta di eliminare un server di destinazione gRPC, ma il server è ancora in uso da altri criteri.

Guasti

Le variabili di errore nella tabella seguente sono impostate per tutti i criteri per impostazione predefinita. Consulta Variabili specifiche per gli errori delle norme.

Variabili Dove Esempi
fault.name="fault_name" fault_name è il nome dell'errore, come indicato nella tabella Errori di runtime sopra. Il nome dell'errore è l'ultima parte del codice dell'errore. fault.name corrisponde a "ExecutionError".
externalcallout.[policy_name].failed policy_name è il nome specificato dall'utente del criterio che ha generato l'errore. externalcallout.ExternalCallout-1.failed = true

Argomenti correlati