azure-sdk-for-net icon indicating copy to clipboard operation
azure-sdk-for-net copied to clipboard

[BUG] Getting SlotConfigResource results in exception

Open dumonjorne opened this issue 2 years ago • 1 comments
trafficstars

Library name and version

Azure.ResourceManager.AppService

Describe the bug

I am trying to get the list SlotConfigNames (the appsettings with the tick next to "slotsetting") to be able to update them later on. When trying to get them, you get an exception that the resource id cannot be null.

await resource.GetSlotConfigNamesResource().GetAsync(); Where resource is a WebSiteResource.

When looking into this, I noticed that the REST API returns null for the id. Which makes sense, because it is not really a resource in itself.

Expected behavior

The method returns the SlotConfigResource as expected and doesn't throw exceptions.

Any idea about a workaround? Currently the only thing I see is to call the REST Api myself.

Actual behavior

An ArgumentNullException with stacktrace:

at Azure.Core.Argument.AssertNotNullOrEmpty(String value, String name) at Azure.Core.ResourceIdentifier..ctor(String resourceId) at Azure.ResourceManager.AppService.SlotConfigNamesResourceData.DeserializeSlotConfigNamesResourceData(JsonElement element) at Azure.ResourceManager.AppService.WebAppsRestOperations.<ListSlotConfigurationNamesAsync>d__138.MoveNext() at Azure.ResourceManager.AppService.SlotConfigNamesResource.<GetAsync>d__14.MoveNext()

Reproduction Steps

Run following code on a WebSiteResource: await resource.GetSlotConfigNamesResource().GetAsync();

Environment

No response

dumonjorne avatar Jan 10 '23 07:01 dumonjorne

Thank you for your feedback. Tagging and routing to the team member best able to assist.

jsquire avatar Jan 10 '23 15:01 jsquire

Hi @dumonjorne, I'm trying to reproduce this issue, and unfortunately currently there is no good workaround for this issue.

And one more thing about this issue is that it is more like a service-side problem. In the REST API spec definition, this is marked as resource, which means a valid ID should be returned by the backend service.

Yao725 avatar Jan 11 '23 08:01 Yao725

@Yao725 I agree that this is an error in the REST API spec definition. There is already a bug ticket submitted for this, however I don't really see much response to it. Is there anyway we can bump this to a higher priority, since it actually breaks the sdk?

https://github.com/Azure/azure-rest-api-specs/issues/19132

dumonjorne avatar Jan 24 '23 14:01 dumonjorne

Sorry for the delayed response, we don't have good ways to accelerate the fix of this bug. Could you please try this workaround?

  • Define the policy that will assign a valid value to the id property.
	public class InvalidPropertyFilterPolicy : HttpPipelineSynchronousPolicy
	{
	    public override void OnReceivedResponse(HttpMessage message)
	    {
	        if (message.Request.Method != RequestMethod.Put || message.Response.ContentStream == null) // Change here to get the expected response
	        {
	            return;
	        }
	 
	        var reader = new StreamReader(message.Response.ContentStream);
	        var content = reader.ReadToEnd().Replace("", ""); // Assign a valid value to the property id
	        var jsonDocument = JsonDocument.Parse(content);
	        var stream = new MemoryStream();
	        var writer = new Utf8JsonWriter(stream);
	        jsonDocument.WriteTo(writer);
	        writer.Flush();
	        message.Response.ContentStream = stream;
	        message.Response.ContentStream.Position = 0;
	    }
	}
  • Register the policy in the ArmClientOptions
	options.AddPolicy(new InvalidPropertyFilterPolicy(), HttpPipelinePosition.PerRetry);

Yao725 avatar Feb 08 '23 05:02 Yao725

Hi,

Thanks for the response. I will try this approach. I had worked around it using a custom REST client, but with this approach I would be able to use the SDK, so that would have my preference.

dumonjorne avatar Feb 13 '23 10:02 dumonjorne

Hi,

Based on the above proposed workaround I was able to get slot config names and update them using the SDK.

class SlotConfigNamesEndpointFilter : HttpPipelineSynchronousPolicy
    {
        public override void OnReceivedResponse(HttpMessage message)
        {
            if (!message.Request.Uri.Path.EndsWith("slotconfignames", StringComparison.OrdinalIgnoreCase) || message.Response.ContentStream == null) // Change here to get the expected response
            {
                return;
            }
            var reader = new StreamReader(message.Response.ContentStream);
            var content = reader.ReadToEnd().Replace("\"id\":null", $"\"id\":\"{message.Request.Uri.Path}\""); // Assign a valid value to the property id
            var jsonDocument = JsonDocument.Parse(content);
            var stream = new MemoryStream();
            var writer = new Utf8JsonWriter(stream);
            jsonDocument.WriteTo(writer);
            writer.Flush();
            message.Response.ContentStream = stream;
            message.Response.ContentStream.Position = 0;
        }
    }

dumonjorne avatar Feb 13 '23 14:02 dumonjorne

Close this issue as it is resolved.

If you have any other feedback to our Azure SDK, feel free to let us know in this survey.

Yao725 avatar Feb 14 '23 01:02 Yao725