diff --git a/sdk/client/resourcemanager/poller.go b/sdk/client/resourcemanager/poller.go index 66d04205ca..e97471b9cd 100644 --- a/sdk/client/resourcemanager/poller.go +++ b/sdk/client/resourcemanager/poller.go @@ -40,13 +40,13 @@ func PollerFromResponse(response *client.Response, client *Client) (poller polle contentType = response.Request.Header.Get("Content-Type") } - statusCodesToCheckProvisioningState := response.StatusCode == http.StatusOK || response.StatusCode == http.StatusCreated + statusCodesToCheckProvisioningState := response.StatusCode == http.StatusOK || response.StatusCode == http.StatusCreated || (response.StatusCode == http.StatusAccepted && lroIsSelfReference) contentTypeMatchesForProvisioningStateCheck := strings.Contains(strings.ToLower(contentType), "application/json") methodIsApplicable := strings.EqualFold(response.Request.Method, "PATCH") || strings.EqualFold(response.Request.Method, "POST") || strings.EqualFold(response.Request.Method, "PUT") if statusCodesToCheckProvisioningState && contentTypeMatchesForProvisioningStateCheck && methodIsApplicable { - provisioningState, provisioningStateErr := provisioningStatePollerFromResponse(response, client, DefaultPollingInterval) + provisioningState, provisioningStateErr := provisioningStatePollerFromResponse(response, lroIsSelfReference, client, DefaultPollingInterval) if provisioningStateErr != nil { err = provisioningStateErr return pollers.Poller{}, fmt.Errorf("building provisioningState poller: %+v", provisioningStateErr) diff --git a/sdk/client/resourcemanager/poller_provisioning_state.go b/sdk/client/resourcemanager/poller_provisioning_state.go index 36c14507af..0805d872b6 100644 --- a/sdk/client/resourcemanager/poller_provisioning_state.go +++ b/sdk/client/resourcemanager/poller_provisioning_state.go @@ -29,17 +29,17 @@ type provisioningStatePoller struct { resourcePath string } -func provisioningStatePollerFromResponse(response *client.Response, client *Client, pollingInterval time.Duration) (*provisioningStatePoller, error) { +func provisioningStatePollerFromResponse(response *client.Response, lroIsSelfReference bool, client *Client, pollingInterval time.Duration) (*provisioningStatePoller, error) { // if we've gotten to this point then we're polling against a Resource Manager resource/operation of some kind // we next need to determine if the current URI is a Resource Manager resource, or if we should be polling on the // resource (e.g. `/my/resource`) rather than an operation on the resource (e.g. `/my/resource/start`) if response.Request == nil { return nil, fmt.Errorf("request was nil") } - originalUri := response.Request.URL.RequestURI() if response.Request.URL == nil { return nil, fmt.Errorf("request url was nil") } + originalUri := response.Request.URL.RequestURI() // all Resource Manager operations require the `api-version` querystring apiVersion := response.Request.URL.Query().Get("api-version") @@ -47,9 +47,14 @@ func provisioningStatePollerFromResponse(response *client.Response, client *Clie return nil, fmt.Errorf("unable to determine `api-version` from %q", originalUri) } - resourcePath, err := resourceManagerResourcePathFromUri(originalUri) - if err != nil { - return nil, fmt.Errorf("determining Resource Manager Resource Path from %q: %+v", originalUri, err) + resourcePath := originalUri + if !lroIsSelfReference { + // if it's a self-reference (such as API Management's API/API Schema) + path, err := resourceManagerResourcePathFromUri(originalUri) + if err != nil { + return nil, fmt.Errorf("determining Resource Manager Resource Path from %q: %+v", originalUri, err) + } + resourcePath = *path } return &provisioningStatePoller{ @@ -57,7 +62,7 @@ func provisioningStatePollerFromResponse(response *client.Response, client *Clie client: client, initialRetryDuration: pollingInterval, originalUri: originalUri, - resourcePath: *resourcePath, + resourcePath: resourcePath, }, nil } diff --git a/sdk/client/resourcemanager/poller_test.go b/sdk/client/resourcemanager/poller_test.go index d85ce2456d..043e342147 100644 --- a/sdk/client/resourcemanager/poller_test.go +++ b/sdk/client/resourcemanager/poller_test.go @@ -111,6 +111,26 @@ func TestNewPoller_LongRunningOperationWithSelfReference(t *testing.T) { }, valid: true, }, + { + // Seen in API Management - API and API Schema + response: &client.Response{ + Response: &http.Response{ + StatusCode: http.StatusAccepted, + Header: http.Header{ + http.CanonicalHeaderKey("Content-Type"): []string{"application/json"}, + http.CanonicalHeaderKey("Location"): []string{"https://async-url-test.local/subscriptions/1234/providers/foo/operations/6789?api-version=2020-01-01&asyncId=abc123&asyncCode=201"}, + }, + Request: &http.Request{ + Method: http.MethodPut, + URL: func() *url.URL { + u, _ := url.Parse("https://async-url-test.local/subscriptions/1234/providers/foo/operations/6789?api-version=2020-01-01") + return u + }(), + }, + }, + }, + valid: true, + }, } for _, v := range testData {