英文:
deploying xml policy to apim using bicep
问题
我想将以下策略部署到Azure API管理:
```xml
<policies>
    <inbound>
    <base />
    <choose>
        <when condition="@(!context.Variables.ContainsKey('cachedAccessToken') || DateTime.UtcNow >= (DateTime)context.Variables['tokenExpiry'])">
            <set-backend-service id="apim-generated-policy" backend-id="{0}" />
            <send-request mode="new" response-variable-name="tokenResponse" timeout="20" ignore-error="false">
                <set-url>{1}/token</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/x-www-form-urlencoded</value>
                </set-header>
                <set-body>@("grant_type=password&username={2}&password=thisShouldRefThe-AmxPassword-NamedValue")</set-body>
            </send-request>
            <set-variable name="tokenResponseJson" value="@{{ return JsonConvert.DeserializeObject((string)context.Variables['tokenResponse'].Body.As<string>()); }}" />
            <set-variable name="cachedAccessToken" value="@{{(string)context.Variables['tokenResponseJson']['access_token']}}" />
            <set-variable name="tokenExpiry" value="@{{ return DateTime.UtcNow.AddSeconds((int)context.Variables['tokenResponseJson']['expires_in'] - 60); }}" />
            <cache-store-value key="cachedAccessToken" value="@{{context.Variables['cachedAccessToken']}}" duration="@{{(new TimeSpan(0, (int)context.Variables['tokenResponseJson']['expires_in'], 0))}}" />
            <cache-store-value key="tokenExpiry" value="@{{context.Variables['tokenExpiry']}}" duration="@{{(new TimeSpan(0, (int)context.Variables['tokenResponseJson']['expires_in'], 0))}}" />
        </when>
        <otherwise>
            <cache-lookup-value key="cachedAccessToken" variable-name="cachedAccessToken" />
            <cache-lookup-value key="tokenExpiry" variable-name="tokenExpiry" />
        </otherwise>
    </choose>
    <set-header name="Authorization" exists-action="override">
        <value>@{{$"Bearer {{context.Variables['cachedAccessToken']}}}}</value>
    </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
这是由DevOps管道运行的Bicep代码:
resource apim 'Microsoft.ApiManagement/service@2022-04-01-preview' existing = {
    name: apimName
    resource apiVersionSet 'api-version-sets@2018-06-01-preview' = if (enableApiVersioning) {
        name: apiName
        properties: {
            displayName: displayName
            versioningScheme: versionScheme
            versionHeaderName: 'X-Api-Version'
            versionQueryName: 'api-version'
        }
    }
    resource api 'apis' = {
        name: enableApiVersioning ? apiNameVersioned : apiName
        properties: {
            displayName: displayName
            path: '${pathPrefix}${apiName}'
            format: definitionFormat
            protocols: [
                'https'
            ]
            subscriptionRequired: true
            value: definition
            apiVersion: enableApiVersioning ? version : null
            apiVersionSetId: enableApiVersioning ? apiVersionSet.id : null
            subscriptionKeyParameterNames: {
                header: 'Ocp-Apim-Subscription-Key'
                query: 'subscription-key'
            }
        }
        resource apiPolicy 'policies' = if (!empty(policy)) {
            name: 'policy'
            properties: {
                value: policy
            }
        }
    }
}
我收到以下错误:
'='是意外的标记。预期的标记是';'。第13行,位置58。
<details>
<summary>英文:</summary>
I'd like to deploy the following policy to azure api management:
````xml
<policies>
    <inbound>
    <base />
    <choose>
        <when condition="@(!context.Variables.ContainsKey(''cachedAccessToken'') || DateTime.UtcNow >= (DateTime)context.Variables[''tokenExpiry''])">
            <set-backend-service id="apim-generated-policy" backend-id="{0}" />
            <send-request mode="new" response-variable-name="tokenResponse" timeout="20" ignore-error="false">
                <set-url>{1}/token</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/x-www-form-urlencoded</value>
                </set-header>
                <set-body>@("grant_type=password&username={2}&password=thisShouldRefThe-AmxPassword-NamedValue")</set-body>
            </send-request>
            <set-variable name="tokenResponseJson" value="@{{ return JsonConvert.DeserializeObject((string)context.Variables[''tokenResponse''].Body.As<string>()); }}" />
            <set-variable name="cachedAccessToken" value="@{{(string)context.Variables[''tokenResponseJson''][''access_token'']}}" />
            <set-variable name="tokenExpiry" value="@{{ return DateTime.UtcNow.AddSeconds((int)context.Variables[''tokenResponseJson''][''expires_in''] - 60); }}" />
            <cache-store-value key="cachedAccessToken" value="@{{context.Variables[''cachedAccessToken'']}}" duration="@{{(new TimeSpan(0, (int)context.Variables[''tokenResponseJson''][''expires_in''], 0))}}" />
            <cache-store-value key="tokenExpiry" value="@{{context.Variables[''tokenExpiry'']}}" duration="@{{(new TimeSpan(0, (int)context.Variables[''tokenResponseJson''][''expires_in''], 0))}}" />
        </when>
        <otherwise>
            <cache-lookup-value key="cachedAccessToken" variable-name="cachedAccessToken" />
            <cache-lookup-value key="tokenExpiry" variable-name="tokenExpiry" />
        </otherwise>
    </choose>
    <set-header name="Authorization" exists-action="override">
        <value>@{{$"Bearer {{context.Variables[''cachedAccessToken'']}}"}}</value>
    </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
This is the bicep that gets run by a devops pipeline:
resource apim 'Microsoft.ApiManagement/service@2022-04-01-preview' existing = {
    name: apimName
    resource apiVersionSet 'api-version-sets@2018-06-01-preview' = if (enableApiVersioning) {
        name: apiName
        properties: {
            displayName: displayName
            versioningScheme: versionScheme
            versionHeaderName: 'X-Api-Version'
            versionQueryName: 'api-version'
        }
    }
    resource api 'apis' = {
        name: enableApiVersioning ? apiNameVersioned : apiName
        properties: {
            displayName: displayName
            path: '${pathPrefix}${apiName}'
            format: definitionFormat
            protocols: [
                'https'
            ]
            subscriptionRequired: true
            value: definition
            apiVersion: enableApiVersioning ? version : null
            apiVersionSetId: enableApiVersioning ? apiVersionSet.id : null
            subscriptionKeyParameterNames: {
                header: 'Ocp-Apim-Subscription-Key'
                query: 'subscription-key'
            }
        }
        resource apiPolicy 'policies' = if (!empty(policy)) {
            name: 'policy'
            properties: {
                value: policy
            }
        }
    }
}
I get the following error:
> '=' is an unexpected token. The expected token is ';'. Line 13, position 58.
答案1
得分: 1
以下是您要翻译的内容:
"Lesson learned - pay more attention to what chatgpt pumps out!
The main problem was the syntax for the C# code block. Here's the working policy:
<policies>
    <inbound>
    <base />
    <choose>
        <when condition="@(!context.Variables.ContainsKey("cachedAccessToken") || DateTime.UtcNow >= (DateTime)context.Variables["tokenExpiry"])">
            <set-backend-service id="apim-generated-policy" backend-id="func-amx-api-dev-001" />
            <send-request mode="new" response-variable-name="tokenResponse" timeout="20" ignore-error="false">
                <set-url>{{baseurl}}.azurewebsites.net/token</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/x-www-form-urlencoded</value>
                </set-header>
                <set-body>@("grant_type=password&username={{user}}&password={{AmxPassword}}")</set-body>
            </send-request>
            <set-variable name="cachedAccessToken" value="@((String)((IResponse)context.Variables["jwt"]).Body.As<JObject>()["access_token"])" />
            <set-variable name="tokenExpiry" value="@((String)((IResponse)context.Variables["jwt"]).Body.As<JObject>()["expires_in"])" />
            <cache-store-value key="cachedAccessToken" value="@((String)context.Variables["cachedAccessToken"])" duration="3600" caching-type="internal" />
            <cache-store-value key="tokenExpiry" value="@((String)context.Variables["tokenExpiry"])" duration="3600" caching-type="internal" />
        </when>
        <otherwise>
            <cache-lookup-value key="cachedAccessToken" variable-name="cachedAccessToken" />
            <cache-lookup-value key="tokenExpiry" variable-name="tokenExpiry" />
        </otherwise>
    </choose>
    <set-header name="Authorization" exists-action="override">
        <value>@{
                return $"Bearer {(String)context.Variables["cachedAccessToken"]}";
            }</value>
    </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
I also moved the policy to a separate file and deployed at apim operation level with the following bicep:
resource apiPolicy 'Microsoft.ApiManagement/service/apis/operations/policies@2022-09-01-preview' = {
    name: '${apimName}/amxapi_v1_0_0/entity/policy'
    properties: {
        value: loadTextContent('./createEntityPolicy.xml')
    }
}
英文:
Lesson learned - pay more attention to what chatgpt pumps out!
The main problem was the syntax for the C# code block. Here's the working policy:
<policies>
    <inbound>
    <base />
    <choose>
        <when condition="@(!context.Variables.ContainsKey("cachedAccessToken") || DateTime.UtcNow >= (DateTime)context.Variables["tokenExpiry"])">
            <set-backend-service id="apim-generated-policy" backend-id="func-amx-api-dev-001" />
            <send-request mode="new" response-variable-name="tokenResponse" timeout="20" ignore-error="false">
                <set-url>{{baseurl}}.azurewebsites.net/token</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/x-www-form-urlencoded</value>
                </set-header>
                <set-body>@("grant_type=password&username={{user}}&password={{AmxPassword}}")</set-body>
            </send-request>
            <set-variable name="cachedAccessToken" value="@((String)((IResponse)context.Variables["jwt"]).Body.As<JObject>()["access_token"])" />
            <set-variable name="tokenExpiry" value="@((String)((IResponse)context.Variables["jwt"]).Body.As<JObject>()["expires_in"])" />
            <cache-store-value key="cachedAccessToken" value="@((String)context.Variables["cachedAccessToken"])" duration="3600" caching-type="internal" />
            <cache-store-value key="tokenExpiry" value="@((String)context.Variables["tokenExpiry"])" duration="3600" caching-type="internal" />
        </when>
        <otherwise>
            <cache-lookup-value key="cachedAccessToken" variable-name="cachedAccessToken" />
            <cache-lookup-value key="tokenExpiry" variable-name="tokenExpiry" />
        </otherwise>
    </choose>
    <set-header name="Authorization" exists-action="override">
        <value>@{
                return $"Bearer {(String)context.Variables["cachedAccessToken"]}";
            }</value>
    </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
I also moved the policy to a separate file and deployed at apim operation level with the following bicep:
resource apiPolicy 'Microsoft.ApiManagement/service/apis/operations/policies@2022-09-01-preview' = {
    name: '${apimName}/amxapi_v1_0_0/entity/policy'
    properties: {
        value: loadTextContent('./createEntityPolicy.xml')
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论