Skip to content

Commit 133f87f

Browse files
authored
fix: apply CORS, timeout, streaming, and error-handling policies to agent APIs (#958) (#959)
1 parent e0ab951 commit 133f87f

3 files changed

Lines changed: 105 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<policies>
2+
<inbound>
3+
<base />
4+
<cors allow-credentials="false">
5+
<allowed-origins>
6+
{{cors-origins}}
7+
</allowed-origins>
8+
<allowed-methods preflight-result-max-age="300">
9+
<method>*</method>
10+
</allowed-methods>
11+
<allowed-headers>
12+
<header>*</header>
13+
</allowed-headers>
14+
<expose-headers>
15+
<header>*</header>
16+
</expose-headers>
17+
</cors>
18+
</inbound>
19+
<backend>
20+
<forward-request timeout="120" />
21+
</backend>
22+
<outbound>
23+
<base />
24+
<set-header name="Access-Control-Allow-Origin" exists-action="override">
25+
<value>@(context.Request.Headers.GetValueOrDefault("Origin", "http://localhost:3000"))</value>
26+
</set-header>
27+
<set-header name="Access-Control-Allow-Methods" exists-action="override">
28+
<value>GET,POST,OPTIONS</value>
29+
</set-header>
30+
<set-header name="Access-Control-Allow-Headers" exists-action="override">
31+
<value>*</value>
32+
</set-header>
33+
</outbound>
34+
<on-error>
35+
<base />
36+
<return-response>
37+
<set-status code="502" reason="Bad Gateway" />
38+
<set-header name="Access-Control-Allow-Origin" exists-action="override">
39+
<value>@(context.Request.Headers.GetValueOrDefault("Origin", "http://localhost:3000"))</value>
40+
</set-header>
41+
<set-header name="Access-Control-Allow-Methods" exists-action="override">
42+
<value>GET,POST,OPTIONS</value>
43+
</set-header>
44+
<set-header name="Access-Control-Allow-Headers" exists-action="override">
45+
<value>*</value>
46+
</set-header>
47+
<set-header name="Content-Type" exists-action="override">
48+
<value>application/json</value>
49+
</set-header>
50+
<set-body>{"detail":"APIM upstream error while routing to agent backend."}</set-body>
51+
</return-response>
52+
</on-error>
53+
</policies>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<policies>
2+
<inbound>
3+
<base />
4+
</inbound>
5+
<backend>
6+
<forward-request timeout="180" buffer-response="false" />
7+
</backend>
8+
<outbound>
9+
<base />
10+
<set-header name="Cache-Control" exists-action="override">
11+
<value>no-cache</value>
12+
</set-header>
13+
<set-header name="X-Accel-Buffering" exists-action="override">
14+
<value>no</value>
15+
</set-header>
16+
</outbound>
17+
<on-error>
18+
<base />
19+
</on-error>
20+
</policies>

.infra/azd/hooks/sync-apim-agents.ps1

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,8 @@ function Ensure-AgentApi {
592592
Write-Host "[preview] + operation: $($op.method) $($op.template) ($($op.name))"
593593
}
594594
}
595+
Write-Host "[preview] + API-level policy (CORS, timeout=120s, on-error)"
596+
Write-Host "[preview] + Operation-level streaming policy (invoke-stream, timeout=180s, buffer-response=false)"
595597
return
596598
}
597599

@@ -692,6 +694,36 @@ function Ensure-AgentApi {
692694
}
693695
Write-Host "Registered $($serviceSpecificOperations[$Service].Count) extra operations for $Service"
694696
}
697+
698+
# --- Apply API-level policy ---
699+
$subscriptionId = az account show --query id -o tsv 2>$null
700+
if (-not $subscriptionId) {
701+
throw "Failed to resolve Azure subscription id for agent API policy update ($Service)."
702+
}
703+
704+
$agentPolicyPath = Join-Path $PSScriptRoot '..\..\apim-policies\agent-api-policy.xml'
705+
if (Test-Path $agentPolicyPath) {
706+
$corsOriginXml = Get-CorsOriginXml -OriginsCsv $ApimCorsAllowedOrigins
707+
$agentPolicyXml = (Get-Content -Path $agentPolicyPath -Raw) -replace '\{\{cors-origins\}\}', $corsOriginXml
708+
$policyPayload = @{ properties = @{ format = 'rawxml'; value = $agentPolicyXml } } | ConvertTo-Json -Depth 8
709+
$policyTempFile = Join-Path ([System.IO.Path]::GetTempPath()) "apim-agent-policy-$Service.json"
710+
Set-Content -Path $policyTempFile -Value $policyPayload -Encoding UTF8
711+
$policyUrl = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$Rg/providers/Microsoft.ApiManagement/service/$Apim/apis/$apiId/policies/policy?api-version=2022-08-01"
712+
az rest --method put --url $policyUrl --headers 'Content-Type=application/json' --body "@$policyTempFile" --only-show-errors *> $null
713+
Write-Host "Applied API-level policy for $Service"
714+
}
715+
716+
# --- Apply operation-level streaming policy for /invoke/stream ---
717+
$streamPolicyPath = Join-Path $PSScriptRoot '..\..\apim-policies\agent-stream-operation-policy.xml'
718+
if (Test-Path $streamPolicyPath) {
719+
$streamPolicyXml = Get-Content -Path $streamPolicyPath -Raw
720+
$streamPayload = @{ properties = @{ format = 'rawxml'; value = $streamPolicyXml } } | ConvertTo-Json -Depth 8
721+
$streamTempFile = Join-Path ([System.IO.Path]::GetTempPath()) "apim-agent-stream-policy-$Service.json"
722+
Set-Content -Path $streamTempFile -Value $streamPayload -Encoding UTF8
723+
$streamOpUrl = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$Rg/providers/Microsoft.ApiManagement/service/$Apim/apis/$apiId/operations/invoke-stream/policies/policy?api-version=2022-08-01"
724+
az rest --method put --url $streamOpUrl --headers 'Content-Type=application/json' --body "@$streamTempFile" --only-show-errors *> $null
725+
Write-Host "Applied streaming operation policy for $Service"
726+
}
695727
}
696728

697729
function Update-CrudApi {

0 commit comments

Comments
 (0)