Política ExternalCallout

Esta página se aplica a Apigee y Apigee Hybrid.

Consulta la documentación de Apigee Edge.

ícono de política

Qué

La política ExternalExternal te permite enviar solicitudes gRPC a tu servidor gRPC para implementar un comportamiento personalizado que no sea compatible con las políticas Apigee. En el código de tu servidor, puedes acceder fácilmente a las variables de flujo dentro del flujo de un proxy y modificarlas.

Apigee se comunica con un servidor de gRPC mediante una política de ExternalCallout a través de una API. Apigee usa la API para enviar variables de flujo al servidor de gRPC. Dentro de tu servidor de gRPC, puedes leer y, según la variable, modificar las variables de flujo enumeradas en la página de referencia de Variables de flujo, así como las variables adicionales que puedes dentro del XML de la política.

Si configuras el servidor de gRPC con Apigee y, además, incluyes esta política en un proxy, Apigee manejará las solicitudes a la API de la siguiente manera:

  1. Apigee envía un mensaje que contiene las variables de flujo a tu servidor de gRPC.
  2. Se ejecuta el código del servidor de gRPC, ya que accede a las variables y las modifica según se define en el código. Luego, el servidor de gRPC envía una respuesta que contiene todas las variables de flujo a Apigee.
  3. Apigee lee la respuesta desde tu servidor de gRPC. Si se agregan variables o se modifican las variables de flujo modificables, se actualizan en Apigee.

Esta es una política estándar y se puede implementar en cualquier tipo de entorno. Para obtener información sobre los tipos de políticas y la disponibilidad con cada tipo de entorno, consulta Tipos de políticas.

Si deseas obtener más información para enviar solicitudes de gRPC, consulta los siguientes vínculos:

<ExternalCallout>

Define una política de ExternalCallout.

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

Este elemento tiene los siguientes atributos que son comunes a todas las políticas:

Atributo Predeterminada (obligatorio) Descripción
name N/A Obligatorio

El nombre interno de la política. El valor del atributo name puede contener letras, números, espacios, guiones, guiones bajos y puntos. Este valor no puede superar los 255 caracteres.

De forma opcional, usa el elemento <DisplayName> para etiquetar la política en el editor de proxy de la IU de administración con un nombre de lenguaje natural diferente.

continueOnError falso Opcional Configúralo como false para mostrar un error cuando una política falla. Este es el comportamiento previsto para la mayoría de las políticas. Configúralo como true para continuar con la ejecución del flujo incluso después de que una política falle. También consulta:
enabled true Opcional Configúralo como true para aplicar la política. Configúralo como false para desactivar la política. La política no se aplicará, incluso si permanece conectada a un flujo.
async   falso Obsoleta Este atributo dejó de estar disponible.

En la siguiente tabla, se describen los elementos secundarios de <ExternalCallout>.

Elemento secundario Obligatorio Descripción
<TimeoutMs> Obligatorio El tiempo de espera de la solicitud en milisegundos para las solicitudes de gRPC.
<GrpcConnection> Obligatorio Especifica el nombre de un TargetServer existente que será el servidor de gRPC al que se enviarán las solicitudes.
<Configurations> Opcional Te permite configurar varios aspectos de la política ExternalCallout, incluidos los elementos <Property> y <FlowVariable>.

Ejemplo 1

Los ejemplos prácticos de ExternalCallout están disponibles en Muestras de texto destacado externo en GitHub.

En el siguiente ejemplo, se ilustra una configuración de política de 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>

En el ejemplo, se envía una solicitud a un servidor de gRPC externo representado por el TargetServer llamado external-target-server, con la siguiente configuración:

  • <Property>: Incluye el contenido de la solicitud y la respuesta, pero no los encabezados de solicitud y respuesta, en la solicitud enviada al servidor de gRPC.
  • <FlowVariable>: Incluye variables de flujo example1.flow.variable y example2.flow.variable adicionales, especificadas por los elementos FlowVariable, en la solicitud enviada al Servidor de gRPC.

Ejemplo 2

En el siguiente ejemplo, el atributo useTargetUrl del elemento Audience se establece en true. Cuando useTargetUrl es true, el nombre de host del servidor de destino de gRPC se usa como público. Por ejemplo, si el host del servidor es my-grpc-server-java.a.run.app, el público que se usará será 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>

Referencia del elemento secundario

En las siguientes secciones, se describen los elementos secundarios de ExternalCallout.

<TimeoutMs>

El tiempo de espera de la solicitud en milisegundos para las solicitudes de gRPC. <TimeoutMs> debe ser un número positivo.

<GrpcConnection>

El elemento <GrpcConnection> establece el servidor de gRPC para que sea un TargetServer existente, especificado por el atributo name. Consulta la página de referencia del recurso TargetServer.

Nota: El protocolo para TargetServer debe ser GRPC.

Por ejemplo, el siguiente código

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

Especifica que el servidor de gRPC sea un TargetServer existente llamado external-target-server.

Usa el elemento <Authentication> (que se describe más adelante en esta sección) a fin de generar un token de OpenID Connect emitido por Google para realizar llamadas autenticadas a servicios basados en gRPC, como servicios personalizados. alojadas en Cloud Run.

En la siguiente tabla, se describen los elementos secundarios de <GrpcConnection>.

Elemento secundario ¿Es obligatorio? Descripción
Elemento <Server> Obligatorio Especifica el servidor de gRPC.
Elemento <Authentication> Opcional Genera un token OpenID Connect emitido por Google para realizar llamadas autenticadas a servicios basados en gRPC, como Cloud Run.

Elemento <Server>

Especifica el servidor de gRPC.

En la siguiente tabla, se describen los atributos del elemento <Server>

Atributo Descripción Configuración predeterminada Presence Tipo
name

El nombre de un TargetServer existente que será el servidor de gRPC al que se enviarán las solicitudes.

N/A Obligatorio String

Elemento <Authentication>

Genera un token OpenID Connect emitido por Google para realizar llamadas autenticadas a servicios basados en gRPC, como servicios personalizados alojados en Cloud Run. Para usar este elemento, se requieren pasos de configuración y de implementación que se describen en Usa la autenticación de Google. Con una configuración adecuada, la política crea un token de autenticación y lo agrega a la solicitud de servicio.

Este elemento tiene un elemento secundario requerido: GoogleIDToken.

Valor predeterminado N/A
¿Es obligatorio? Opcional.
Tipo Tipo complejo
Elemento principal <GrpcConnection>
Elementos secundarios <GoogleIDToken>

El elemento Authentication usa la siguiente sintaxis:

Sintaxis

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

Ejemplo

En el siguiente ejemplo, se muestra el 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>
Atributos

Ninguno

Elemento secundario <HeaderName>

De forma predeterminada, cuando hay una configuración de autenticación, Apigee genera un token del portador y lo inserta en el encabezado Authorization en el mensaje enviado al sistema de destino. El elemento HeaderName te permite especificar el nombre de un encabezado diferente para contener ese token del portador. Esta función es útil en especial cuando el destino es un servicio de Cloud Run que usa el encabezado X-Serverless-Authorization. El encabezado Authorization, si está presente, se deja sin modificar y también se envía en la solicitud.

Valor predeterminado N/A
¿Es obligatorio? No
Tipo String
Elemento principal <Authentication>
Elementos secundarios Ninguno

El elemento HeaderName usa la siguiente sintaxis:

Sintaxis

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

Con cadena estática

En este ejemplo, el token del portador generado se agrega, de forma predeterminada, a un encabezado llamado X-Serverless-Authorization que se envía al sistema de destino. El encabezado Authorization, si está presente, se deja sin modificar y también se envía en la solicitud.

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

Con referencia de variable

En este ejemplo, el token del portador generado se agrega, de forma predeterminada, a un encabezado llamado X-Serverless-Authorization que se envía al sistema de destino. Si my-variable tiene un valor, se usa ese valor en lugar de la cadena predeterminada. El encabezado Authorization, si está presente, se deja sin modificar y también se envía en la solicitud.

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

Genera tokens de OpenID Connect emitidos por Google para realizar llamadas autenticadas a servicios de Google, como servicios personalizados alojados en Cloud Run.

Valor predeterminado N/A
¿Es obligatorio? Obligatorio
Tipo String
Elemento principal <Authentication>
Elementos secundarios <Audience>
<IncludeEmail>

El elemento GoogleIDToken usa la siguiente sintaxis:

Sintaxis

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

Ejemplo

En el siguiente ejemplo, se muestra el elemento GoogleIDToken:

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

El público del token de autenticación que se generó, como la API o la cuenta a la que el token otorga acceso.

Si el valor de Audience está vacío, ref está vacío o se resuelve como un valor vacío, y useTargetUrl es true, entonces “https://” + (nombre de host del servidor de destino de gRPC) se usa como público. Por ejemplo, si el host del servidor es my-grpc-server-java.a.run.app, el público que se usará será https://my-grpc-server-java.a.run.app.

El valor predeterminado de useTargetUrl es 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'/>
Valor predeterminado N/A
¿Es obligatorio? Obligatorio
Tipo String
Elemento principal <GoogleIDToken>
Elementos secundarios Ninguno
Elemento secundario <IncludeEmail>

Si se configura como true, el token de autenticación generado contendrá las reclamaciones de cuenta de servicio email y email_verified.

Valor predeterminado false
¿Es obligatorio? Opcional
Tipo Booleano
Elemento principal <GoogleIDToken>
Elementos secundarios Ninguno

<Configurations>

El elemento <Configurations> te permite configurar varios aspectos de la política de ExternalCallout, incluidos <Property> y <FlowVariable>.

En la siguiente tabla, se describen los elementos secundarios de <Configurations>.

Elemento secundario ¿Es obligatorio? Descripción
<Property> Obligatorio

Especifica si el encabezado o el contenido de la solicitud o respuesta se enviarán al servidor. Los valores posibles son true o false. El valor predeterminado es false.

<FlowVariable> Obligatorio

Especifica qué variables de flujo adicionales se deben enviar al servidor.

<Property>

El elemento <Property> especifica si los encabezados o el contenido de la solicitud o respuesta se enviarán al servidor. Los valores posibles son true (el elemento se enviará) o false (el elemento no se enviará). El valor predeterminado es false.

En la siguiente tabla, se describen los atributos del elemento <Property>

Atributo Descripción Configuración predeterminada Presence Tipo
name

Especifica qué contenido se enviará al servidor. Los valores posibles de name son los siguientes:

  • with.request.content
  • with.request.headers
  • with.response.content
  • with.response.headers
N/A Obligatorio String

<FlowVariable>

Con el elemento <FlowVariable>, se especifica qué variables de flujo adicionales se enviarán al servidor. El valor de <FlowVariable> es un prefijo de una variable, en lugar del nombre completo de la variable. Por ejemplo, si el elemento es a.b.c, el valor de una variable llamada a.b.c se enviará al servidor. Del mismo modo, el valor de una variable llamada a.b.c.my-variable se enviará al servidor. Sin embargo, no se enviará el valor de una variable llamada a.x.another-variable porque no tiene el prefijo a.b.c. Estos son algunos ejemplos

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

Referencia de errores

Errores en la implementación

Nombre del error Causa
FAILED_PRECONDITION Este error ocurre si la cuenta de servicio no se encuentra cuando el proxy está configurado con la etiqueta <Authentication>.

Por ejemplo:

Deployment of \"organizations/foo/apis/apiproxy/revisions/1\"
requires a service account identity, but one was not provided
with the request.
PERMISSION_DENIED Este error se produce si hay un problema de permisos con la cuenta de servicio si el proxy está configurado con la etiqueta <Authentication>. Causas posibles:
  • La cuenta de servicio no existe.
  • La cuenta de servicio no se creó en el mismo proyecto de Google Cloud que la organización de Apigee.
  • El implementador tiene el permiso iam.serviceAccounts.actAs en la cuenta de servicio. Para obtener más detalles, consulta Permisos de cuenta de servicio.

Errores de entorno de ejecución

En la siguiente tabla, se describen los errores en el entorno de ejecución que pueden ocurrir cuando se ejecuta la política.

Código de falla Estado de HTTP Causa
GrpcTlsInitFailed 500

Este error se producirá si hay problemas durante la inicialización de TLS con el servidor gRPC (como los problemas de almacén de claves o almacén de confianza).

steps.externalcallout.[error_code] 500

[error_code] se determina mediante el campo errorCode del mensaje de error. La string con errores del error será el campo faultstring del mensaje con errores.

steps.externalcallout.ExecutionError 500

Este error se producirá si se produce otra excepción durante la ejecución de esta política. La excepción subyacente se expondrá en la string con errores. Si hubo un problema con las credenciales en el servidor de gRPC, el error será similar al siguiente:

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

Puede ver los registros del MP para obtener más punteros de depuración.

googletoken.EmptyIDTokenAudience 500

<GoogleIDToken> está habilitado, pero useTargetUrl se configura como falso y no se proporciona ningún valor para <Audience>, ya sea directamente o mediante referencia en el momento del error.

steps.externalcallout.ExecutionError

con string con errores:

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

500

Este error ocurre si el proxy de API está configurado con el elemento <Authentication>. Causas posibles:

  • La cuenta de servicio implementada con el proxy:
    • No existe en tu proyecto (existía cuando se implementó, pero se borró después de la implementación).
    • Se inhabilitó
    • (Solo para Apigee Hybrid) no otorgó la función roles/iam.serviceAccountTokenCreator en la cuenta de servicio apigee-runtime.
  • La API IAMCredentials está inhabilitada en el proyecto de origen de la cuenta de servicio apigee-runtime (solo para Apigee Hybrid).

    Nota: Solo para Apigee Hybrid, revisa el registro del contenedor del entorno de ejecución y busca externalcallout.ExecutionError para encontrar mensajes de error más detallados que puedan ayudar a depurar el problema.

steps.externalcallout.ExecutionError con string con errores que contiene PERMISSION DENIED.

Por ejemplo, la string con errores se verá de la siguiente manera para Cloud Run:

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

500

Este error se genera si el proxy de API se configura con el elemento <Authentication>. Causas posibles:

  • La cuenta de servicio de proxy existe y está habilitada, pero no tiene los permisos adecuados para acceder al servicio.
  • El servicio requiere autenticación, pero la solicitud no tenía un encabezado de autenticación (por ejemplo: el XML de autenticación no se incluyó en el XML de la política).

Otros errores

En la siguiente tabla, se describen varios errores. Consulta la causa para obtener más detalles.

Código de falla Causa
ReferencesExistToGrpcServer

Este error se producirá si un usuario intenta borrar un servidor de destino de gRPC, pero otras políticas aún usan el servidor.

Fallas

Las variables con fallas en la siguiente tabla se configuran para todas las políticas de forma predeterminada. Consulta Variables específicas para errores de políticas.

Variables Aquí Ejemplos
fault.name="fault_name" fault_name es el nombre de la falla, como se indica en la tabla de errores del entorno de ejecución anterior. El nombre de la falla es la última parte del código de la falla. fault.name coincide con "ExecutionError".
externalcallout.[policy_name].failed policy_name es el nombre especificado por el usuario de la política que generó la falla. externalcallout.ExternalCallout-1.failed = true

Temas relacionados