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

[Question] Implementing Long-Running Operations with SyncPoller #40815

Open danielszaniszlo opened 3 days ago

danielszaniszlo commented 3 days ago

Query/Question Hello Experts, I am reaching out to seek your expertise regarding an implementation challenge I am facing with testing our API, which supports two primary use cases: Real-time and Batch processing. Context:

Issue: My challenge revolves around the implementation of Long-Running Operations (LROs) for job creation. Specifically, I am looking for guidance on how to use the SyncPoller in this context. I am sending my requests to a LIVE environment and my RealTime test cases are passing. Here is my draft PR where you can find the code: https://github.com/Azure/azure-sdk-for-java/pull/40725

My test setup with client configuration

protected void beforeTest() {
        DeidentificationClientBuilder deidentificationClientbuilder = new DeidentificationClientBuilder()
            .endpoint(Configuration.getGlobalConfiguration().get("DEID_SERVICE_ENDPOINT", "endpoint"))
            .httpClient(HttpClient.createDefault())
            .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BASIC));
        if (getTestMode() == TestMode.PLAYBACK) {
            deidentificationClientbuilder.httpClient(interceptorManager.getPlaybackClient())
                .credential(request -> Mono.just(new AccessToken("this_is_a_token", OffsetDateTime.MAX)));
        } else if (getTestMode() == TestMode.RECORD) {
            deidentificationClientbuilder.addPolicy(interceptorManager.getRecordPolicy())
                .credential(new DefaultAzureCredentialBuilder().build());
        } else if (getTestMode() == TestMode.LIVE) {
            deidentificationClientbuilder.credential(new DefaultAzureCredentialBuilder().build());
        }
        deidentificationClient = deidentificationClientbuilder.buildClient();
    }

sdk/healthdataaiservices/azure-health-deidentification/src/test/java/com/azure/health/deidentification/batch/SyncJobOperationsTest.java

SyncPoller<DeidentificationJob, DeidentificationJob> poller = deidentificationClient.beginCreateJob(jobName, job);

When I am doing it I get the followinng error: java.lang.IllegalStateException: Cannot poll with strategy SyncOperationLocationPollingStrategy

Why is this not a Bug or a feature Request? It is probably my lack of knowledge with the Java SDK.

Setup (please complete the following information if applicable):

alzimmermsft commented 2 days ago

Hi @danielszaniszlo, this exception is thrown when all polling strategies return false when calling canPoll. In the generated code only the custom strategy is added and that uses the default canPoll for the super type OperationResourcePollingStrategy which simply checks:

If one, or both, of those fail this exception will be thrown. This is a case where some debugging is needed on the initial response to make sure the above holds true.

danielszaniszlo commented 2 days ago

HI @alzimmermsft, Thanks for the quick reply. The polling endpoint url is valid and the initial response is successful too, but it doesn't have the operation-location Header. image

What URL should be in the operation-location header?

In our case the request PUT https://endpoint/jobs/{name} is the original request which creates a job and with GET https://endpoint/jobs/{name} you can query the created job status

alzimmermsft commented 2 days ago

Pulling in @srnagar and @weidongxu-microsoft as this differs from the expected pattern of OperationResourcePollingStrategy polling. Do we have any design recommendations for the pattern above?