本頁適用於 Apigee 和 Apigee Hybrid。
查看
Apigee Edge 說明文件。
結果
您可以使用 ExternalCallout 政策,將 gRPC 要求傳送至 gRPC 伺服器,藉此實作 Apigee 政策不支援的自訂行為。在伺服器程式碼中,您可以輕鬆存取及修改 Proxy 流程中的流程變數。
Apigee 會透過 API 的 ExternalCallout 政策與 gRPC 伺服器通訊。 Apigee 會使用 API 將流程變數傳送至 gRPC 伺服器。您可以在 gRPC 伺服器中讀取「流程變數」參考頁面中列出的流程變數,並視需要變更這些變數,以及您在政策 XML 中指定的其他變數。
如果您使用 Apigee 設定 gRPC 伺服器,並在 Proxy 中加入這項政策,Apigee 會依下列方式處理 API 要求:
- Apigee 會將包含流程變數的訊息傳送至 gRPC 伺服器。
- gRPC 伺服器程式碼會執行、存取及修改程式碼中定義的變數。然後 gRPC 伺服器會傳送包含所有流程變數的回應,傳回至 Apigee。
- Apigee 會讀取 gRPC 伺服器的回應。如果新增任何變數或修改可變更的流程變數,這些變數會在 Apigee 中更新。
這項政策是標準政策,可部署至任何環境類型。如要瞭解政策類型和各環境類型的可用性,請參閱「政策類型」。
如要進一步瞭解如何傳送 gRPC 要求,請參閱下列連結:
<ExternalCallout>
定義 ExternalCallout 政策。
<ExternalCallout async="true" continueOnError="true" enabled="true" name="EC">
這個元素包含下列所有政策都適用的屬性:
屬性 | 預設 | 是否必要? | 說明 |
---|---|---|---|
name |
不適用 | 必要 |
政策的內部名稱。 您可以選擇使用 |
continueOnError |
false | 選用 | 將其設為 false ,即可在政策失敗時傳回錯誤。這是大多數政策的預期行為。將其設為 true ,即使政策失敗,流程執行作業仍會繼續進行。另請參閱:
|
enabled |
是 | 選用 | 設為 true 即可強制執行政策。設為 false 即可關閉政策。即使政策仍附加至流程,系統也不會強制執行這項政策。 |
async |
false | 已淘汰 | 此屬性已淘汰。 |
下表說明 <ExternalCallout>
的子元素。
子元素 | 必填 | 說明 |
---|---|---|
<TimeoutMs> |
必填 | gRPC 要求的逾時時間 (以毫秒為單位)。 |
<GrpcConnection> |
必填 | 指定要將現有 TargetServer 的名稱設為 gRPC 伺服器,以便傳送要求。 |
<Configurations> |
選用 | 可讓您設定 ExternalCallout 政策的各個層面,包括 <Property> 和 <FlowVariable> 元素。 |
範例 1
您可以在 GitHub 的 External Callout 範例中找到 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>
這個範例會向外部 gRPC 伺服器傳送要求,該伺服器由名為 external-target-server
的
TargetServer 代表,並採用以下設定:
<Property>
:在傳送至 gRPC 伺服器的要求中,加入要求和回應內容,但不加入要求和回應標頭。<FlowVariable>
:在傳送至 gRPC 伺服器的要求中,加入由FlowVariable
元素指定的其他流程變數example1.flow.variable
和example2.flow.variable
。
範例 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 伺服器設為 TargetServer
,由 name
屬性指定。請參閱
TargetServer
資源參考資料頁面。
注意:TargetServer
的
通訊協定必須為 GRPC
。
例如,下列程式碼
<GrpcConnection> <Server name="external-target-server"/> </GrpcConnection>
指定 gRPC 伺服器為名為 external-target-server
的現有 TargetServer
。
使用 <Authentication>
元素 (請參閱本節後續說明) 產生 Google 核發的 OpenID Connect 權杖,以便對以 gRPC 為基礎的服務 (例如在 Cloud Run 中代管的自訂服務) 發出經過驗證的呼叫。
下表說明 <GrpcConnection>
的子元素。
子元素 | 是否必要 | 說明 |
---|---|---|
<Server> 元素 |
必要 | 指定 gRPC 伺服器。 |
<Authentication> 元素 |
選用 | 產生 Google 核發的 OpenID Connect 權杖,以便對 Cloud Run 等以 gRPC 為基礎的服務發出已驗證的呼叫。 |
<Server>
元素
指定 gRPC 伺服器。
下表說明 <Server>
元素的屬性。
屬性 | 說明 | 預設 | 存在必要性 | 類型 |
---|---|---|---|---|
name |
現有 |
不適用 | 必填 | 字串 |
<Authentication>
元素
產生 Google 核發的 OpenID Connect 權杖,以便對以 gRPC 為基礎的服務 (例如在 Cloud Run 中代管的自訂服務) 進行驗證呼叫。如要使用這個元素,您必須按照「使用 Google 驗證」一文所述的步驟進行設定和部署作業。在適當設定下,政策會為您建立驗證權杖,並將其新增至服務要求。
這個元素有一個必要的子元素:GoogleIDToken
。
預設 | 不適用 |
是否必要? | 選填。 |
類型 | 複雜類型 |
上層元素 | <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 權杖,以便對 Google 服務 (例如在 Cloud Run 中代管的自訂服務) 發出經過驗證的呼叫。
預設 | 不適用 |
是否必要? | 必填 |
類型 | 字串 |
上層元素 | <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 |
如果 Proxy 使用 <Authentication> 標記進行設定時缺少服務帳戶,就會發生這個錯誤。例如: Deployment of \"organizations/foo/apis/apiproxy/revisions/1\" requires a service account identity, but one was not provided with the request. |
PERMISSION_DENIED |
如果 Proxy 是使用 <Authentication> 標記設定,而服務帳戶有權限問題,就會發生這個錯誤。可能的原因:
|
執行階段錯誤
下表說明執行政策時可能發生的執行階段錯誤。
錯誤代碼 | HTTP 狀態 | 原因 |
---|---|---|
GrpcTlsInitFailed |
500 |
如果使用 gRPC 伺服器初始化 TLS 時發生任何問題 (例如 Keystore 或 truststore 問題),就會發生這個錯誤。 |
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 Proxy 是使用
|
steps.externalcallout.ExecutionError ,faultstring 包含 PERMISSION DENIED 。舉例來說,Cloud Run 的錯誤字串會如下所示:
|
500 |
如果 API Proxy 是使用
|
其他錯誤
下表說明各種錯誤。請參閱原因瞭解詳情。
錯誤代碼 | 原因 |
---|---|
ReferencesExistToGrpcServer |
如果使用者嘗試刪除 gRPC 目標伺服器,但該伺服器仍在使用其他政策,就會發生這個錯誤。 |
錯誤
下表中的錯誤變數預設為所有政策設定。請參閱 政策錯誤專屬變數。
變數 | 地點 | 範例 |
---|---|---|
fault.name="fault_name" |
fault_name 是錯誤名稱,如上表的「執行階段錯誤」所列。錯誤名稱是錯誤代碼的最後一個部分。 |
fault.name 與「ExecutionError」相符。 |
externalcallout.[policy_name].failed |
policy_name 是使用者指定的政策名稱,該政策會擲回錯誤。 |
externalcallout.ExternalCallout-1.failed = true |