Search code examples
azurepolicyazure-api-management

Api Management sets forward-request for a one way request


I want to log to log the request and the response so I place a one-way-request in the inbound and the outbound section:

<policies>
    <inbound>                       
        <send-one-way-request mode="new">
            <set-url>@("example.com")</set-url>
            <set-method>POST</set-method>               
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body>@(context.Request.Body.As<string>(preserveContent: true))</set-body>
        </send-one-way-request>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>          
        <send-one-way-request mode="new">
            <set-url>@("example.com")</set-url>
            <set-method>POST</set-method>               
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body>@(context.Response.Body.As<string>(preserveContent: true))</set-body>
        </send-one-way-request>
    </outbound>
</policies>

identical call, except the body.

When I check the trace I see this in the inbound section:

send-one-way-request (0 ms)

"One way request was successfully send to https://...."

forward-request (9690 ms)

{
    "response": {
        "status": {
            "code": 200,
            "reason": "OK"
        },
        "headers": [
            {
                "name": "Pragma",
                "value": "no-cache"
            },
            {
                "name": "Content-Length",
                "value": "2"
            },
            {
                "name": "Cache-Control",
                "value": "no-cache"
            },
            {
                "name": "Content-Type",
                "value": "application/json; charset=utf-8"
            },
            {
                "name": "Date",
                "value": "Wed, 05 Jul 2017 07:56:14 GMT"
            },
            {
                "name": "Expires",
                "value": "-1"
            },
            {
                "name": "Server",
                "value": "Microsoft-IIS/8.0"
            },
            {
                "name": "X-AspNet-Version",
                "value": "4.0.30319"
            },
            {
                "name": "X-Powered-By",
                "value": "ASP.NET"
            }
        ]
    }
}

but in the outbound I only get:

send-one-way-request (0 ms)

"One way request was successfully send to https://...."

and no forward request. Because I use a one way request I don't expect a response from the calls and I can't remember to have the forward-request in the inbound part (didn't found them in a saved traced call with a one way request in the inbound).

Is there maybe a configuration anything else that triggers a forward-request?

Edit:

I use the azure function to handle this. When I make a typo in the subdomain the forward-request disappears, but when I make a typo in the function name it is still there... Both requests are directed to the same azure function.

Edit2:

This is getting more confuse: when I send the default body from the swagger file the request-forward is not there. If I repeat the request or if i modify the default body it appears...


Solution

  • Since send-one-way request policy is completely asynchronous in regards to request processing itself, there is no guarantee that reply from such request will be logged, because by the time it is received the request itself may be long processed, response returned to client along with tracing information. So it works as a best effort, if by the time when response to send-one-way-request is received the main request is still being processed response will be logged, otherwise not.

    In the first example reply to one-way request in inbound is logged because there is still a lot processing to be done on the main request - send request to backend, process outbound section. But when one-way request is placed as the last statement in outbound, right before response to the client is sent - response to one-way request will come too late to be placed into trace.

    Typo in subdomain may trigger longer connection time, if such domain not actively refuses connections, thus will stall response, thus it will disappear from trace.

    It's all a question of timing. If you want to make sure that main request processing is stalled until you get response from these side requests use send-request policy instead.