Política ExternalCallout

Esta página se aplica à Apigee e à Apigee híbrida.

Confira a documentação da Apigee Edge.

Ícone da política

O que

A política ExternalCallout permite enviar solicitações gRPC ao servidor gRPC para implementar um comportamento personalizado que não é compatível com as políticas da Apigee. No código do servidor, é fácil acessar e modificar variáveis de fluxo no fluxo de um proxy.

A Apigee se comunica com um servidor gRPC por uma política ExternalCallout por uma API. A Apigee usa a API para enviar variáveis de fluxo ao servidor gRPC. No seu servidor gRPC, é possível ler e, dependendo da variável, modificar as variáveis de fluxo listadas na página de referência Variáveis de fluxo, bem como outras variáveis especificadas no XML da política.

Se você configurar o servidor gRPC com a Apigee e incluir essa política em um proxy, a Apigee processará as solicitações da API da seguinte maneira:

  1. A Apigee enviará uma mensagem contendo as variáveis de fluxo para o servidor gRPC.
  2. O código do servidor gRPC executará, acessará e modificará variáveis conforme definido no código. O servidor gRPC então enviará uma resposta contendo todas as variáveis de fluxo de volta para a Apigee.
  3. A Apigee lerá a resposta pelo servidor gRPC. Se alguma variável for adicionada ou modificá-las, elas serão atualizadas na Apigee.

Esta é uma política padrão e pode ser implantada em qualquer tipo de ambiente. Para informações sobre os tipos de políticas e a disponibilidade de cada tipo de ambiente, consulte Tipos de políticas.

Para saber mais sobre o envio de solicitações gRPC, consulte os seguintes links:

<ExternalCallout>

Define uma política ExternalCallout.

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

Este elemento tem os seguintes atributos comuns a todas as políticas:

Atributo Padrão Obrigatório? Descrição
name N/A Valor

O nome interno da política. O valor do atributo name pode conter letras, números, espaços, hifens, sublinhados e pontos. Esse valor não pode exceder 255 caracteres.

Opcionalmente, use o elemento <DisplayName> para rotular a política no editor de proxy da IU de gerenciamento com um nome de linguagem natural diferente.

continueOnError falso Opcional Defina como false para retornar um erro quando uma política falhar. Esse é o comportamento esperado para a maioria das políticas. Defina como true para que a execução do fluxo continue, mesmo depois que uma política falhar. Consulte também:
enabled true Opcional Defina como true para aplicar a política. Defina como false para desativar a política. A política não será aplicada mesmo que permaneça vinculada a um fluxo.
async   falso Obsoleto Esse atributo está obsoleto.

A tabela a seguir descreve os elementos filhos de <ExternalCallout>:

Elemento filho Obrigatório Descrição
<TimeoutMs> Obrigatório O tempo limite da solicitação em milissegundos para solicitações gRPC.
<GrpcConnection> Obrigatório Especifica o nome de um TargetServer atual que será o servidor gRPC para onde as solicitações serão enviadas.
<Configurations> Opcional Permite configurar vários aspectos da política ExternalCallout, incluindo os elementos <Property> e <FlowVariable>.

Exemplo 1

Exemplos de trabalho de ExternalCallout estão disponíveis em Amostras de frase de destaque externa no GitHub (link em inglês).

No exemplo a seguir, ilustramos uma configuração de política 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>

O exemplo envia uma solicitação para um servidor gRPC externo representado pelo TargetServer chamado external-target-server, com as seguintes configurações:

  • <Property>: inclui o conteúdo da solicitação e da resposta, mas não os cabeçalhos de solicitação e resposta, na solicitação enviada ao servidor gRPC.
  • <FlowVariable>: inclua outras variáveis de fluxo example1.flow.variable e example2.flow.variable, especificadas pelos elementos FlowVariable, na solicitação enviada ao servidor gRPC.

Exemplo 2

No exemplo a seguir, o atributo useTargetUrl do elemento Audience está definido como true. Quando useTargetUrl for true, o nome do host do servidor de destino gRPC será usado como público-alvo. Por exemplo, se o host do servidor for my-grpc-server-java.a.run.app, o público-alvo usado 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>

Referência a elementos filhos

As seções a seguir descrevem os elementos filhos de ExternalCallout.

<TimeoutMs>

O tempo limite da solicitação em milissegundos para solicitações gRPC. <TimeoutMs> precisa ser um número positivo

<GrpcConnection>

O elemento <GrpcConnection> define o servidor gRPC como um TargetServer existente, especificado pelo atributo name. Consulte a página de referência do recurso TargetServer.

Observação: o protocolo do TargetServer precisa ser GRPC.

Por exemplo, o código a seguir

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

especifica o servidor gRPC a ser um TargetServer existente chamado external-target-server.

Use o elemento <Authentication> (descrito mais adiante nesta seção) para gerar um token OpenID Connect emitido pelo Google para fazer chamadas autenticadas para serviços baseados em gRPC, como serviços personalizados hospedado no Cloud Run.

A tabela a seguir descreve os elementos filhos de <GrpcConnection>:

Elemento filho Obrigatório? Descrição
Elemento <Server> Obrigatório Especifica o servidor gRPC.
Elemento <Authentication> Opcional Gera um token OpenID Connect emitido pelo Google para fazer chamadas autenticadas para serviços baseados em gRPC, como o Cloud Run.

Elemento <Server>

Especifica o servidor gRPC.

A tabela a seguir descreve os atributos do elemento <Server>:

Atributo Descrição Padrão Presence Tipo
name

O nome de um TargetServer atual que será o servidor gRPC para onde as solicitações serão enviadas.

N/A Obrigatório String

Elemento <Authentication>

Gera um token OpenID Connect emitido pelo Google para fazer chamadas autenticadas para serviços baseados em gRPC, como serviços personalizados hospedados no Cloud Run. O uso desse elemento requer etapas de configuração e implantação descritas em Como usar a autenticação do Google. Com a configuração adequada, a política cria um token de autenticação para você e o adiciona à solicitação de serviço.

Este elemento tem um elemento filho obrigatório: GoogleIDToken.

Padrão N/A
Obrigatório? Opcional.
Tipo Tipo complexo
Elemento pai <GrpcConnection>
Elemento filho <GoogleIDToken>

O elemento Authentication usa a seguinte sintaxe:

Sintaxe

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

Exemplo

O exemplo a seguir mostra o 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

Nenhuma.

Elemento filho <HeaderName>

Por padrão, quando uma configuração de autenticação está presente, a Apigee gera um token do portador e o injeta no cabeçalho Authorization na mensagem enviada ao sistema de destino. O elemento HeaderName permite especificar o nome de um cabeçalho diferente para armazenar o token do portador. Esse recurso é particularmente útil quando o destino é um serviço do Cloud Run que usa o cabeçalho X-Serverless-Authorization. O cabeçalho Authorization, se presente, não é modificado e também é enviado na solicitação.

Padrão N/A
Obrigatório? Não
Tipo String
Elemento pai <Authentication>
Elemento filho Nenhum

O elemento HeaderName usa a seguinte sintaxe:

Sintaxe

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

Com string estática

Neste exemplo, o token do portador gerado é adicionado, por padrão, a um cabeçalho chamado X-Serverless-Authorization, que é enviado ao sistema de destino. O cabeçalho Authorization, se presente, não é modificado e também é enviado na solicitação.

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

Com referência de variável

Neste exemplo, o token do portador gerado é adicionado, por padrão, a um cabeçalho chamado X-Serverless-Authorization, que é enviado ao sistema de destino. Se my-variable tiver um valor, esse valor será usado no lugar da string padrão. O cabeçalho Authorization, se presente, não é modificado e também é enviado na solicitação.

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

Gera tokens do OpenID Connect emitidos pelo Google para fazer chamadas autenticadas para serviços do Google, como serviços personalizados hospedados no Cloud Run.

Padrão N/A
Obrigatório? Obrigatório
Tipo String
Elemento pai <Authentication>
Elemento filho <Audience>
<IncludeEmail>

O elemento GoogleIDToken usa a seguinte sintaxe:

Sintaxe

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

Exemplo

O exemplo a seguir mostra o elemento GoogleIDToken:

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

O público-alvo do token de autenticação gerado, como a API ou a conta à qual o token concede acesso.

Se o valor de Audience estiver vazio, a ref estiver vazia ou se resultar em um valor vazio e useTargetUrl for true, "https://" + (nome do host do servidor de destino gRPC) é usado como público-alvo. Por exemplo, se o host do servidor for my-grpc-server-java.a.run.app, o público-alvo usado será https://my-grpc-server-java.a.run.app.

Por padrão, 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'/>
Padrão N/A
Obrigatório? Obrigatório
Tipo String
Elemento pai <GoogleIDToken>
Elemento filho Nenhuma.
Elemento filho <IncludeEmail>

Se definido como true, o token de autenticação gerado conterá as declarações email e email_verified da conta de serviço.

Padrão false
Obrigatório? Opcional
Tipo Booleano
Elemento pai <GoogleIDToken>
Elemento filho Nenhuma.

<Configurations>

O elemento <Configurations> permite que você configure vários aspectos da política ExternalCallout, incluindo <Property> e <FlowVariable>.

A tabela a seguir descreve os elementos filhos de <Configurations>:

Elemento filho Obrigatório? Descrição
<Property> Obrigatório

Especifica se os cabeçalhos de solicitação/resposta e/ou conteúdo serão enviados ao servidor. Os valores possíveis são true ou false. O padrão é false.

<FlowVariable> Obrigatório

Especifica quais outras variáveis de fluxo devem ser enviadas ao servidor.

<Property>

O elemento <Property> especifica se os cabeçalhos de solicitação/resposta e/ou o conteúdo serão enviados ao servidor. Os valores possíveis são true (o item será enviado) ou false (o item não será enviado). O valor padrão é false.

A tabela a seguir descreve os atributos do elemento <Property>:

Atributo Descrição Padrão Presence Tipo
name

Especifica qual conteúdo será enviado ao servidor. Os valores possíveis para name são:

  • with.request.content
  • with.request.headers
  • with.response.content
  • with.response.headers
N/A Obrigatório String

<FlowVariable>

O elemento <FlowVariable> especifica quais variáveis de fluxo adicionais serão enviadas ao servidor. O valor de <FlowVariable> é o prefixo de uma variável, e não o nome completo dela. Por exemplo, se o elemento for a.b.c, o valor de uma variável chamada a.b.c será enviado ao servidor. Da mesma forma, o valor de uma variável chamada a.b.c.my-variable será enviado ao servidor. Mas o valor de uma variável chamada a.x.another-variable não será enviado, porque não tem o prefixo a.b.c. Veja alguns exemplos

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

Referência de erros

Erros na implantação

Nome do erro Causa
FAILED_PRECONDITION Esse erro ocorrerá se a conta de serviço estiver ausente quando o proxy estiver configurado com a tag <Authentication>.

Exemplo:

Deployment of \"organizations/foo/apis/apiproxy/revisions/1\"
requires a service account identity, but one was not provided
with the request.
PERMISSION_DENIED Esse erro ocorrerá se houver um problema de permissão com a conta de serviço se o proxy estiver configurado com a tag <Authentication>. Causas possíveis:
  • A conta de serviço não existe.
  • A conta de serviço não foi criada no mesmo projeto do Google Cloud que a organização da Apigee.
  • O implantador tem a permissão iam.serviceAccounts.actAs na conta de serviço. Para ver detalhes, consulte Sobre as permissões da conta de serviço.

Erros de execução

A tabela abaixo descreve os erros no ambiente de execução, que podem ocorrer ao executar a política.

Código de falha Status do HTTP Causa
GrpcTlsInitFailed 500

Esse erro ocorrerá se houver algum problema com a inicialização do TLS com o servidor gRPC (como problemas de Keystore ou truststore).

steps.externalcallout.[error_code] 500

[error_code] é determinado pelo campo errorCode da mensagem de falha. A string de falha do erro será o campo faultstring da mensagem de falha.

steps.externalcallout.ExecutionError 500

Esse erro ocorrerá se ocorrer outra exceção durante a execução dessa política. A exceção subjacente será exposta na string de falha. Se houver um problema com as credenciais do servidor gRPC, o erro será semelhante a este:

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

É possível analisar os registros do MP para encontrar mais ponteiros de depuração.

googletoken.EmptyIDTokenAudience 500

<GoogleIDToken> está ativado, mas useTargetUrl está definido como falso, e nenhum valor é fornecido para <Audience> diretamente ou por referência no momento do erro.

steps.externalcallout.ExecutionError

com string de falha:

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

500

Esse erro ocorrerá se o proxy da API estiver configurado com o elemento <Authentication>. Possíveis causas:

  • A conta de serviço implantada com o proxy:
    • não existe em seu projeto (ele existia quando implantado, mas foi excluído após a implantação)
    • foi desativado
    • (Somente Apigee híbrida) não concedeu o papel roles/iam.serviceAccountTokenCreator na conta de serviço apigee-runtime.
  • (Somente híbridos da Apigee) A API IAMCredentials está desativada no projeto de origem da conta de serviço apigee-runtime.

    Observação: Somente para a Apigee híbrida, verifique o registro do contêiner de ambiente de execução e procure externalcallout.ExecutionError para encontrar mensagens de erro mais detalhadas que podem ajudar na depuração do problema.

steps.externalcallout.ExecutionError com faultstring contendo PERMISSION DENIED.

Por exemplo, a string de falha será semelhante a esta para o 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

Esse erro ocorrerá se o proxy de API estiver configurado com o elemento <Authentication>. Possíveis causas:

  • A conta de serviço do proxy existe e está ativada, mas não tem as permissões corretas para acessar o serviço.
  • O serviço requer autenticação, mas a solicitação não tinha um cabeçalho de autenticação (por exemplo: o XML de autenticação não foi incluído no XML da política).

Erros diversos

A tabela abaixo descreve erros diversos. Veja a causa para mais detalhes.

Código de falha Causa
ReferencesExistToGrpcServer

Esse erro ocorrerá se um usuário tentar excluir um servidor de destino gRPC, mas o servidor ainda estiver sendo usado por outras políticas.

Falhas

As variáveis de falha na tabela a seguir são definidas para todas as políticas por padrão. Consulte Variáveis específicas de erros de política.

Variáveis Onde Exemplos
fault.name="fault_name" fault_name é o nome da falha, conforme listado na tabela Erros de ambiente de execução acima. O nome da falha é a última parte do código de falha. fault.name corresponde a "ExecutionError".
externalcallout.[policy_name].failed policy_name é o nome da política especificada pelo usuário que gerou a falha. externalcallout.ExternalCallout-1.failed = true

Temas relacionados