このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントはこちらをご覧ください。
概要
ExternalCallout ポリシーを使用すると、gRPC サーバーに gRPC リクエストを送信し、Apigee ポリシーでサポートされていないカスタム動作を実装できます。サーバーのコードでは、プロキシのフロー内でフロー変数に簡単にアクセスして変更できます。
Apigee は、API を介して ExternalCallout ポリシーを介して gRPC サーバーと通信します。 Apigee は、API を使用してフロー変数を gRPC サーバーに送信します。gRPC サーバー内では、フロー変数のリファレンス ページに記載されているフロー変数と、ポリシーの XML 内で指定した追加の変数の読み取りが可能です。また、変数によっては修正することもできます。
Apigee で gRPC サーバーを構成し、このポリシーをプロキシに含めると、Apigee は次のように API リクエストを処理します。
- Apigee では、フロー変数を含むメッセージが gRPC サーバーに送信されます。
- gRPC サーバーコードは、そのコードで定義されているように、変数へのアクセスと変更を実行します。次に、gRPC サーバーはすべてのフロー変数を含むレスポンスを Apigee に送り返します。
- Apigee は gRPC サーバーからレスポンスを読み取ります。変数が追加されたり、変更可能なフロー変数が変更されたりすると、Apigee でそれらが更新されます。
このポリシーは、標準ポリシーであり、任意の環境タイプにデプロイできます。すべてのユーザーがポリシーや環境のタイプを知る必要はありません。ポリシータイプと各環境タイプで使用可能かどうかは、ポリシータイプをご覧ください。
gRPC リクエストの送信について詳しくは、次のリンクをご覧ください。
<ExternalCallout>
ExternalCallout ポリシーを定義します。
<ExternalCallout async="true" continueOnError="true" enabled="true" name="EC">
この要素には、すべてのポリシーに共通する次の属性があります。
属性 | デフォルト | 必須かどうか | 説明 |
---|---|---|---|
name |
なし | 必須 |
ポリシーの内部名。 管理 UI プロキシ エディタで |
continueOnError |
false | 省略可 | ポリシーが失敗したときにエラーを返す場合は、false に設定します。これは、ほとんどのポリシーで想定される動作です。ポリシーが失敗した後もフローの実行を続行する場合は、true に設定します。関連情報:
|
enabled |
true | 省略可 | ポリシーを適用するには、true に設定します。ポリシーを無効にするには、false に設定します。ポリシーがフローに接続されている場合でも適用されません。 |
async |
false | 非推奨 | この属性は非推奨となりました。 |
次の表に、<ExternalCallout>
の子要素を示します。
子要素 | 必須 | 説明 |
---|---|---|
<TimeoutMs> |
必須 | gRPC リクエストのリクエスト タイムアウト(ミリ秒)。 |
<GrpcConnection> |
必須 | リクエストを送信する gRPC サーバーにする既存の TargetServer の名前を指定します。 |
<Configurations> |
省略可 | ExternalCallout ポリシーのさまざまな側面(<Property> 要素や <FlowVariable> 要素など)を構成できます。 |
例 1
ExternalCallout の実用的な例については、GitHub の ExternalCallout サンプルをご覧ください。
次の例は、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>
この例では、次の構成を使用して、external-target-server
という名前の TargetServer で表される外部 gRPC サーバーにリクエストを送信します。
<Property>
: gRPC サーバーに送信されるリクエストに、リクエストとレスポンスのヘッダーではなく、リクエストとレスポンスのコンテンツは含めます。<FlowVariable>
:FlowVariable
要素で指定された追加のフロー変数(example1.flow.variable
とexample2.flow.variable
)を、gRPC サーバーに送信されたリクエストに含めます。
例 2
次の例では、Audience
要素の useTargetUrl
属性が true
に設定されています。useTargetUrl
が true
の場合、gRPC ターゲット サーバーのホスト名がオーディエンスとして使用されます。たとえば、サーバーのホストが my-grpc-server-java.a.run.app
の場合、使用されるオーディエンスは 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>
子要素のリファレンス
以降のセクションでは、ExternalCallout
の子要素について説明します。
<TimeoutMs>
gRPC リクエストのリクエスト タイムアウト(ミリ秒)。<TimeoutMs>
は正の数にする必要があります。
<GrpcConnection>
<GrpcConnection>
要素により、gRPC サーバーが、name
属性で指定された既存の TargetServer
に設定されます。TargetServer
リソースのリファレンス ページをご覧ください。
注: TargetServer
のプロトコルは GRPC
にする必要があります。
たとえば、次のコードがあるとします。
<GrpcConnection> <Server name="external-target-server"/> </GrpcConnection>
external-target-server
という名前の既存の TargetServer
となる gRPC サーバーを指定します。
<Authentication>
要素(このセクションで後述)を使用して、Google 発行の OpenID Connect トークンを生成し、Cloud Run でホストされるカスタム サービスなどの gRPC ベースのサービスに対する認証済み呼び出しを行います。
次の表に、<GrpcConnection>
の子要素を示します。
子要素 | 必須かどうか | 説明 |
---|---|---|
<Server> 要素 |
必須 | gRPC サーバーを指定します。 |
<Authentication> 要素 |
省略可 | Google 発行の OpenID Connect トークンを生成し、Cloud Run などの gRPC ベースのサービスに対する認証された呼び出しを行います。 |
<Server>
要素
gRPC サーバーを指定します。
次の表に、<Server>
要素の属性を示します。
属性 | 説明 | デフォルト | 要否 | 型 |
---|---|---|---|---|
name |
リクエストの送信先の gRPC サーバーとなる既存の |
なし | 必須 | 文字列 |
<Authentication>
要素
Google 発行の OpenID Connect トークンを生成し、Cloud Run でホストされているカスタム サービスなど、gRPC ベースのサービスに対する認証された呼び出しを行います。この要素を使用するには、Google 認証システムの使用で説明されている設定とデプロイの手順が必要です。適切に設定すると、ポリシーは認証トークンを作成し、それをサービス リクエストに追加します。
この要素には必須の子要素 GoogleIDToken
が 1 つあります。
デフォルト | なし |
必須かどうか | 省略可。 |
型 | 複合型 |
親要素 | <GrpcConnection> |
子要素 |
<GoogleIDToken> |
Authentication
要素の構文は次のとおりです。
構文
<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>
例
次の例は、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>
属性
なし。
<HeaderName> 子要素
デフォルトでは、認証構成が存在する場合、Apigee は署名なしトークンを生成し、ターゲット システムに送信されるメッセージの Authorization
ヘッダーにそれを挿入します。HeaderName
要素を使用すると、別のヘッダーの名前を指定して、その署名なしトークンを保持できます。この機能は、ターゲットが X-Serverless-Authorization
ヘッダーを使用する Cloud Run サービスである場合に特に役立ちます。Authorization
ヘッダーが存在する場合は、そのヘッダーも変更されない状態でリクエストで送信されます。
デフォルト | なし |
必須かどうか | いいえ |
型 | 文字列 |
親要素 | <Authentication> |
子要素 | なし |
HeaderName
要素の構文は次のとおりです。
構文
<ExternalCallout> ... <Authentication> <HeaderName ref="FLOW_VARIABLE">STRING</HeaderName> <GoogleIDToken> ... </GoogleIDToken> </Authentication> ... </ExternalCallout>
静的文字列を使用する場合
この例では、生成された署名なしトークンがデフォルトでは X-Serverless-Authorization
という名前のヘッダーに追加され、ターゲット システムに送信されます。Authorization
ヘッダーが存在する場合は、そのヘッダーも変更されない状態でリクエストで送信されます。
<Authentication> <HeaderName>X-Serverless-Authorization</HeaderName> <GoogleIDToken> <Audience>https://cloudrun-hostname.a.run.app</Audience> </GoogleIDToken> </Authentication>
変数参照を使用する場合
この例では、生成された署名なしトークンがデフォルトでは X-Serverless-Authorization
という名前のヘッダーに追加され、ターゲット システムに送信されます。my-variable
に値がある場合は、デフォルトの文字列の代わりにその値が使用されます。Authorization
ヘッダーが存在する場合は、そのヘッダーも変更されない状態でリクエストで送信されます。
<Authentication> <HeaderName ref='my-variable'>X-Serverless-Authorization</HeaderName> <GoogleIDToken> <Audience>https://cloudrun-hostname.a.run.app</Audience> </GoogleIDToken> </Authentication>
<GoogleIDToken> 子要素
Google 発行の OpenID Connect トークンを生成し、Cloud Run でホストされているカスタム サービスなど、Google サービスに対して認証された呼び出しを行います。
デフォルト | なし |
必須かどうか | 必須 |
型 | 文字列 |
親要素 | <Authentication> |
子要素 | <Audience> <IncludeEmail> |
GoogleIDToken
要素の構文は次のとおりです。
構文
<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>
例
次の例は、GoogleIDToken
要素を示しています。
<Authentication> <GoogleIDToken> <Audience>https://httpserver0-bar.run.app</Audience> <IncludeEmail>true</IncludeEmail> </GoogleIDToken> </Authentication>
<Audience> 子要素
生成された認証トークンのオーディエンス(トークンがアクセス権を付与する API やアカウントなど)。
Audience
の値が空の場合、ref
が空か、空の値に解決されます。useTargetUrl
が true
の場合は、「https://」+(gRPC ターゲット サーバーのホスト名)がオーディエンスとして使用されます。たとえば、サーバーのホストが my-grpc-server-java.a.run.app
の場合、使用されるオーディエンスは https://my-grpc-server-java.a.run.app
になります。
デフォルトでは、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'/>
デフォルト | なし |
必須かどうか | 必須 |
型 | 文字列 |
親要素 | <GoogleIDToken> |
子要素 | なし。 |
<IncludeEmail> 子要素
true
に設定すると、生成された認証トークンには、サービス アカウント email
と email_verified
クレームが含まれます。
デフォルト | false |
必須かどうか | 省略可 |
型 | ブール値 |
親要素 | <GoogleIDToken> |
子要素 | なし。 |
<Configurations>
<Configurations>
要素を使用すると、ExternalCallout ポリシーのさまざまな側面(<Property>
や <FlowVariable>
など)を構成できます。
次の表に、<Configurations>
の子要素を示します。
子要素 | 必須かどうか | 説明 |
---|---|---|
<Property> |
必須 | リクエスト / レスポンス ヘッダーやコンテンツをサーバーに送信するかどうかを指定します。指定可能な値は |
<FlowVariable> |
必須 | サーバーに送信する必要がある追加のフロー変数を指定します。 |
<Property>
<Property>
要素は、リクエスト / レスポンス ヘッダーやコンテンツをサーバーに送信するかどうかを指定します。指定できる値は true
(アイテムが送信される)または false
(アイテムが送信されない)です。デフォルト値は false
です。
次の表に、<Property>
要素の属性を示します。
属性 | 説明 | デフォルト | 要否 | 型 |
---|---|---|---|---|
name |
サーバーに送信するコンテンツを指定します。
|
なし | 必須 | 文字列 |
<FlowVariable>
<FlowVariable>
要素には、サーバーに送信される追加のフロー変数を指定します。<FlowVariable>
の値は、完全な変数名ではなく、変数の接頭辞です。たとえば、a.b.c
の場合、a.b.c
という名前の変数の値がサーバーに送信されます。同様に、a.b.c.my-variable
という名前の変数の値がサーバーに送信されます。ただし、a.x.another-variable
という名前の変数には接頭辞 a.b.c
がないため、値は送信されません。次に例を示します。
<Configurations> <FlowVariable>a.b.c</FlowVariable> <FlowVariable>d.e.f</FlowVariable> </Configurations>
エラー リファレンス
デプロイエラー
エラー名 | 原因 |
---|---|
FAILED_PRECONDITION |
このエラーは、プロキシが <Authentication> タグで構成されている場合に、サービス アカウントがないと発生します。例: Deployment of \"organizations/foo/apis/apiproxy/revisions/1\" requires a service account identity, but one was not provided with the request. |
PERMISSION_DENIED |
プロキシが <Authentication> タグを使用して構成されている場合に、サービス アカウントに権限の問題があると、このエラーが発生します。考えられる原因:
|
ランタイム エラー
次の表では、ポリシーの実行時に発生する可能性のあるランタイム エラーについて説明します。
障害コード | HTTP ステータス | 原因 |
---|---|---|
GrpcTlsInitFailed |
500 |
gRPC サーバーで TLS を初期化に問題(キーストアやトラストストアに関する問題など)がある場合、このエラーが発生します。 |
steps.externalcallout.[error_code] |
500 |
|
steps.externalcallout.ExecutionError |
500 |
このエラーは、このポリシーの実行中に他の例外が発生すると発生します。根本的な例外は障害文字列で公開されます。gRPC サーバーの認証情報に問題がある場合は、次のようなエラーが表示されます。 { "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" } } } 詳細なデバッグ ポインタについては、MP のログを確認できます。 |
googletoken.EmptyIDTokenAudience |
500 |
|
steps.externalcallout.ExecutionError
次の障害文字列を含みます。
|
500 |
このエラーは、API プロキシが
|
steps.externalcallout.ExecutionError は、PERMISSION DENIED を含む障害文字列に使用されます。たとえば、Cloud Run で障害文字列は次のようになります。
|
500 |
このエラーは、API プロキシが
|
その他のエラー
次の表に、その他のエラーを示します。詳しくは、原因をご確認ください。
障害コード | 原因 |
---|---|
ReferencesExistToGrpcServer |
このエラーは、ユーザーが gRPC ターゲット サーバーを削除しようとしたものの、そのサーバーが他のポリシーによって使用されている場合に発生します。 |
障害
次の表に示す障害変数は、デフォルトですべてのポリシーに対して設定されています。ポリシーエラーに固有の変数をご覧ください。
変数 | 場所 | 例 |
---|---|---|
fault.name="fault_name" |
fault_name は、上記のランタイム エラーの表に記載されている障害の名前です。障害名は、障害コードの最後の部分です。 |
fault.name は「ExecutionError」と一致します。 |
externalcallout.[policy_name].failed |
policy_name は、障害が発生したポリシーのユーザー指定の名前です。 |
externalcallout.ExternalCallout-1.failed = true |