Azure / azure-sdk-for-java

This repository is for active development of the Azure SDK for Java. For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/java/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-java.
MIT License
2.25k stars 1.93k forks source link

[BUG] ApiManagement - apiExports().get() returning null on all fields except 'id' #36332

Open SimonasTumsys opened 11 months ago

SimonasTumsys commented 11 months ago

Describe the bug I have been using ApiManagementManager for simple API CRUD operations and it works as intended. However, I faced a major issue when trying to export the API specs. Using manager().apiExports().get() goes through, but only returns the 'id' field. That field is correct, however, I need the link for the specfile, which is always 'null', as 'value' is returned null. Interestingly, the 'format' field is always null as well.

getWithResponse() returns 200 on the same request, but the 'format' and 'value' fields are null, same as the get().

Exception or Stack Trace No exception, as the request goes through.

To Reproduce Steps to reproduce the behavior: Perform manager().apiExports().get() request.

Code Snippet Client:

public ApiManagementManager authenticatedApiManager() throws Exception {

        final ClientSecretCredential credential = new ClientSecretCredentialBuilder()
                .clientId(getClientId())
                .clientSecret(getClientSecret())
                .tenantId(getTenantId())
                .build();

        final AzureProfile profile = new AzureProfile(getTenantId(), getSubscriptionId(), AzureEnvironment.AZURE);

        return ApiManagementManager.authenticate(credential, profile);
    }

Service method:

 public ApiExportResult exportApi(final String id) {
        return getManager()
                .apiExports()
                .get(resourceGroupName, serviceName, id, ExportFormat.SWAGGER_LINK, ExportApi.TRUE);
    }

Expected behavior All three fields should be non-null:

{
    "id": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.ApiManagement/service/<serviceName>/apis/<apiId>",
    "format": null,
    "value": null
}

^ This is an object simply mapped from ApiExportResult:

    public ExportRes(ApiExportResult exportResult) {
        this.id = exportResult.id();
        this.format = exportResult.exportResultFormat();
        this.value = exportResult.value();
    }

Setup (please complete the following information):

Additional context As I said before, other operations work as expected, such as apis().get(), apis().listByService(), etc.

When getting the specfile through a simple GET request directly to Azure (with a token of a user with the same permissions), everything works as intended - a link is returned. It's just the request through the SDK that returns nulls.

joshfree commented 10 months ago

@weidongxu-microsoft could you please assist @SimonasTumsys with this issue

weidongxu-microsoft commented 10 months ago

@v-hongli1 Please take a look.

@SimonasTumsys If possible, would you enable logging and take a look on the JSON of the server response? It would help our diagnosing the issue. We would like to know whether server did not return these properties, or SDK having problem converting JSON to Java class.

SimonasTumsys commented 10 months ago

Here's the full request and response logged:

2023-08-15T12:34:48.185+03:00  INFO 11323 --- [onPool-worker-1] c.a.r.a.i.A.get                          : {"az.sdk.message":"HTTP request","method":"GET","url":"https://management.azure.com/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.ApiManagement/service/<serviceName>/apis/<apiId>?format=REDACTED&export=REDACTED&api-version=2021-08-01","tryCount":"1","contentLength":0}
2023-08-15T12:34:49.146+03:00  INFO 11323 --- [ctor-http-nio-3] c.a.r.a.i.A.get                          : {"az.sdk.message":"HTTP response","contentLength":"545","statusCode":200,"url":"https://management.azure.com/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.ApiManagement/service/<serviceName>/apis/<apiId>?format=REDACTED&export=REDACTED&api-version=2021-08-01","durationMs":946,"body":"{\r\n  \"id\": \"/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.ApiManagement/service/<serviceName>/apis/<apiId>\",\r\n  \"type\": \"Microsoft.ApiManagement/service/apis\",\r\n  \"name\": \"<apiId>\",\r\n  \"properties\": {\r\n    \"format\": \"swagger-link-json\",\r\n    \"value\": {\r\n      \"link\": \"https://apimgmtstmue7q69djuqydci.blob.core.windows.net/api-export/<apiName>.json?sv=2017-04-17&sr=b&sig=G0eWFX7Ohen5wqSOjAvbu%3F2MMzxBmvQqqrSftfv6IOQ%3D&se=2023-08-15T09:39:49Z&sp=r\"\r\n    }\r\n  }\r\n}"}

Seems that the link is being returned by the server.

weidongxu-microsoft commented 10 months ago

@SimonasTumsys

It appears to be incorrect with backend response and their OpenAPI spec https://github.com/Azure/azure-rest-api-specs/blob/main/specification/apimanagement/resource-manager/Microsoft.ApiManagement/stable/2022-08-01/definitions.json#L652-L693

In spec, "id", "format", "value" is in same level (SDK follow the spec). But in response, "format" and "value" is under "properties".

We will include apimanagement backend to see when they can fix that.

github-actions[bot] commented 10 months ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @miaojiang.

SimonasTumsys commented 10 months ago

I'm sorry if this is not the right place to raise another issue, but to circumvent the export issue I raised in the first post, I do my export requests through a simple HttpClient. While testing, I noticed that every export format works fine, except "openapi+json-link". Calling the export endpoint with this format doesn't return a link, but the specfile itself, as String.

GET https://management.azure.com/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.ApiManagement/service/<serviceName/apis/<apiId>?format=openapi+json-link&export=true&api-version=2022-08-01

I assume this is not the expected behavior, as per docs. An object containing a link to the specfile in blob storage should be returned.

Again, I'm sorry for the off-topic. Where should I raise the issue for this?

weidongxu-microsoft commented 10 months ago

For circumvent, maybe manager.serviceClient().getHttpPipeline() would be a little bit easier, as it has authentication and retry logic configured (basically SDK API uses this to send REST request).

We can also take a look on "openapi+json-link" first. If this is backend problem, usually it is on https://github.com/Azure/azure-rest-api-specs/issues

If it affects your production, IcM would also work (probably better than issue :-)) But let's double check it first. Current 1.0.0-beta.3 SDK is on 2021-08-01 api-version. There is a newer 2022-08-01 we can take a look.

SimonasTumsys commented 10 months ago

Well it's not a life or death situation. Ofc would be great if this could be resolved this year.

Thank you for fast and informative responses! Will check it out.

weidongxu-microsoft commented 10 months ago
GET https://management.azure.com/subscriptions/<subId>/resourceGroups/<rgName>/providers/Microsoft.ApiManagement/service/<serviceName/apis/<apiId>?format=openapi+json-link&export=true&api-version=2022-08-01

@SimonasTumsys Here in format=openapi+json-link, should the + get percentage encoded to %2B? (I am not sure if this is logging, or indeed not encoded)

SimonasTumsys commented 10 months ago

This is my mistake. Thank you for your input. It works correctly now.

And using httpPipeline is definitely easier and faster. Thank you!

weidongxu-microsoft commented 10 months ago

@SimonasTumsys

It appears to be incorrect with backend response and their OpenAPI spec https://github.com/Azure/azure-rest-api-specs/blob/main/specification/apimanagement/resource-manager/Microsoft.ApiManagement/stable/2022-08-01/definitions.json#L652-L693

In spec, "id", "format", "value" is in same level (SDK follow the spec). But in response, "format" and "value" is under "properties".

We will include apimanagement backend to see when they can fix that.

@miaojiang Please help check this in backend.

heller-tobias commented 5 months ago

We face the same issue, and would appreciate it if it gets fixed!

bedadiggelmann commented 5 months ago

Same issue here, are there any updates on the progress of fixing this bug?

weidongxu-microsoft commented 5 months ago

I am pinging service member to prioritize the fix.