diff --git a/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberAsyncClient.java b/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberAsyncClient.java index 61ac69041c37d..d291f63fe66a8 100644 --- a/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberAsyncClient.java +++ b/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberAsyncClient.java @@ -25,6 +25,7 @@ import com.azure.communication.administration.models.UpdateNumberCapabilitiesResponse; import com.azure.communication.administration.models.NumberConfiguration; import com.azure.communication.administration.models.PhoneNumberSearch; +import com.azure.communication.administration.models.SearchStatus; import com.azure.communication.administration.models.UpdateNumberCapabilitiesRequest; import com.azure.communication.administration.models.UpdatePhoneNumberCapabilitiesResponse; import com.azure.communication.common.PhoneNumber; @@ -36,12 +37,18 @@ import com.azure.core.util.Context; import com.azure.core.util.FluxUtil; import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.polling.LongRunningOperationStatus; +import com.azure.core.util.polling.PollResponse; +import com.azure.core.util.polling.PollerFlux; +import com.azure.core.util.polling.PollingContext; import reactor.core.publisher.Mono; +import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; import static com.azure.core.util.FluxUtil.monoError; @@ -53,6 +60,7 @@ @ServiceClient(builder = PhoneNumberClientBuilder.class, isAsync = true) public final class PhoneNumberAsyncClient { private final ClientLogger logger = new ClientLogger(PhoneNumberAsyncClient.class); + private static final Duration DEFAULT_POLL_INTERVAL = Duration.ofSeconds(60); private final PhoneNumberAdministrationsImpl phoneNumberAdministrations; @@ -757,4 +765,68 @@ Mono> purchaseSearchWithResponse(String searchId, Context context return monoError(logger, ex); } } + + /** + * Initiates a search and returns a {@link PhoneNumberSearch} usable by other functions + * This function returns a Long Running Operation poller that allows you to + * wait indefinitely until the operation is complete. + * + * @param options A {@link CreateSearchOptions} with the search options + * @param lroDuration The time our long running operation will keep on polling + * until it gets a result from the server + * @return A {@link PollerFlux} object with the search result + */ + public PollerFlux beginCreateSearch( + CreateSearchOptions options, Duration lroDuration) { + final Duration interval = lroDuration != null ? lroDuration : DEFAULT_POLL_INTERVAL; + return new PollerFlux(interval, + createSearchActivationOperation(options), + createSearchPollOperation(), + (activationResponse, pollingContext) -> Mono.error(new RuntimeException("Cancellation is not supported")), + createSearchFetchResultOperation()); + } + + private Function, + Mono> createSearchActivationOperation(CreateSearchOptions options) { + return (pollingContext) -> { + Mono response = createSearch(options).flatMap(createSearchResponse -> + { + String searchId = createSearchResponse.getSearchId(); + PhoneNumberSearch phoneNumberSearch = new PhoneNumberSearch().setSearchId(searchId); + return Mono.just(phoneNumberSearch); + }); + return response; + }; + } + + private Function, + Mono>> createSearchPollOperation() { + return pollingContext -> + getSearchById(pollingContext.getActivationResponse().getValue().getSearchId()) + .flatMap(getSearchResponse -> { + if (getSearchResponse.getStatus().equals(SearchStatus.SUCCESS)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, getSearchResponse)); + } + if (getSearchResponse.getStatus().equals(SearchStatus.EXPIRED)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, getSearchResponse)); + } + if (getSearchResponse.getStatus().equals(SearchStatus.CANCELLED)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, getSearchResponse)); + } + if (getSearchResponse.getStatus().equals(SearchStatus.RESERVED)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, getSearchResponse)); + } + if (getSearchResponse.getStatus().equals(SearchStatus.ERROR)) { + return Mono.just(new PollResponse<>(LongRunningOperationStatus.FAILED, getSearchResponse)); + } + return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, getSearchResponse)); + }); + } + + private Function, + Mono> createSearchFetchResultOperation() { + return pollingContext -> { + return Mono.just(pollingContext.getLatestResponse().getValue()); + }; + } } diff --git a/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberClient.java b/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberClient.java index f06a4dcbb5f68..d15facfe211f5 100644 --- a/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberClient.java +++ b/sdk/communication/azure-communication-administration/src/main/java/com/azure/communication/administration/PhoneNumberClient.java @@ -27,6 +27,9 @@ import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.Response; import com.azure.core.util.Context; +import com.azure.core.util.polling.SyncPoller; + +import java.time.Duration; import java.util.List; import java.util.Map; @@ -521,4 +524,19 @@ public void purchaseSearch(String searchId) { public Response purchaseSearchWithResponse(String searchId, Context context) { return phoneNumberAsyncClient.purchaseSearchWithResponse(searchId, context).block(); } + + /** + * Initiates a search and returns a {@link PhoneNumberSearch} usable by other functions + * This function returns a Long Running Operation poller. + * + * @param options A {@link CreateSearchOptions} with the search options + * @param lroDuration The time our long running operation will keep on polling + * until it gets a result from the server + * @return A {@link SyncPoller} object with the search result + */ + @ServiceMethod(returns = ReturnType.SINGLE) + public SyncPoller beginCreateSearch( + CreateSearchOptions options, Duration lroDuration) { + return phoneNumberAsyncClient.beginCreateSearch(options, lroDuration).getSyncPoller(); + } } diff --git a/sdk/communication/azure-communication-administration/src/test/java/com/azure/communication/administration/PhoneNumberAsyncClientIntegrationTest.java b/sdk/communication/azure-communication-administration/src/test/java/com/azure/communication/administration/PhoneNumberAsyncClientIntegrationTest.java index 73e101c2c66c4..5106d69f0a5ff 100644 --- a/sdk/communication/azure-communication-administration/src/test/java/com/azure/communication/administration/PhoneNumberAsyncClientIntegrationTest.java +++ b/sdk/communication/azure-communication-administration/src/test/java/com/azure/communication/administration/PhoneNumberAsyncClientIntegrationTest.java @@ -23,12 +23,15 @@ import com.azure.communication.common.PhoneNumber; import com.azure.core.http.rest.PagedFlux; import com.azure.core.http.rest.Response; +import com.azure.core.util.polling.PollerFlux; +import com.azure.core.util.polling.SyncPoller; import com.azure.core.util.Context; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -449,6 +452,29 @@ public void releasePhoneNumbersWithResponse() { .verifyComplete(); } + @Test() + public void beginCreateSearch() { + List phonePlanIds = new ArrayList<>(); + phonePlanIds.add("27b53eec-8ff4-4070-8900-fbeaabfd158a"); + + CreateSearchOptions createSearchOptions = new CreateSearchOptions(); + createSearchOptions + .setAreaCode(AREA_CODE_FOR_SEARCH) + .setDescription("testsearch20200014") + .setDisplayName("testsearch20200014") + .setPhonePlanIds(phonePlanIds) + .setQuantity(2); + + Duration duration = Duration.ofSeconds(5); + PhoneNumberAsyncClient client = this.getClient(); + PollerFlux res = client.beginCreateSearch(createSearchOptions, duration); + SyncPoller sync = res.getSyncPoller(); + sync.waitForCompletion(); + PhoneNumberSearch testResult = sync.getFinalResult(); + assertEquals(testResult.getPhoneNumbers().size(), 2); + assertNotNull(testResult.getSearchId()); + } + private PhoneNumberAsyncClient getClient() { return super.getClientBuilder().buildAsyncClient(); } diff --git a/sdk/communication/azure-communication-administration/src/test/resources/session-records/beginCreateSearch.json b/sdk/communication/azure-communication-administration/src/test/resources/session-records/beginCreateSearch.json new file mode 100644 index 0000000000000..6ec687b238d06 --- /dev/null +++ b/sdk/communication/azure-communication-administration/src/test/resources/session-records/beginCreateSearch.json @@ -0,0 +1,59 @@ +{ + "networkCallRecords" : [ { + "Method" : "POST", + "Uri" : "https://REDACTED.communication.azure.com/administration/phonenumbers/searches?api-version=2020-07-20-preview1", + "Headers" : { + "User-Agent" : "azsdk-java-azure-communication-administration/1.0.0-beta.1 (11.0.8; Windows 10; 10.0)", + "Content-Type" : "application/json" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "X-Processing-Time" : "2106ms", + "MS-CV" : "AudA+TBsSkC2dy5EORj0jg.0", + "retry-after" : "0", + "X-Azure-Ref" : "0/598XwAAAABNqI5PZ5BrTocglFXesDJDREVOMDJFREdFMDMxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "StatusCode" : "201", + "Body" : "{\"searchId\":\"44b70e2f-6521-454e-a8ea-67ab95927a13\"}", + "Date" : "Tue, 06 Oct 2020 16:49:05 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.communication.azure.com/administration/phonenumbers/searches/44b70e2f-6521-454e-a8ea-67ab95927a13?api-version=2020-07-20-preview1", + "Headers" : { + "User-Agent" : "azsdk-java-azure-communication-administration/1.0.0-beta.1 (11.0.8; Windows 10; 10.0)" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "X-Processing-Time" : "351ms", + "MS-CV" : "UsgvNonyy0W78Wb+YlAR/Q.0", + "retry-after" : "0", + "X-Azure-Ref" : "0B6B8XwAAAABJLU8C50vpQr8eJDv7BnURREVOMDJFREdFMDMxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "StatusCode" : "200", + "Body" : "{\"searchId\":\"44b70e2f-6521-454e-a8ea-67ab95927a13\",\"displayName\":\"testsearch20200014\",\"createdAt\":\"2020-10-06T16:49:05.1044519+00:00\",\"description\":\"testsearch20200014\",\"phonePlanIds\":[\"27b53eec-8ff4-4070-8900-fbeaabfd158a\"],\"areaCode\":\"323\",\"quantity\":2,\"locationOptions\":[],\"status\":\"Pending\",\"phoneNumbers\":[]}", + "Date" : "Tue, 06 Oct 2020 16:49:11 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + }, { + "Method" : "GET", + "Uri" : "https://REDACTED.communication.azure.com/administration/phonenumbers/searches/44b70e2f-6521-454e-a8ea-67ab95927a13?api-version=2020-07-20-preview1", + "Headers" : { + "User-Agent" : "azsdk-java-azure-communication-administration/1.0.0-beta.1 (11.0.8; Windows 10; 10.0)" + }, + "Response" : { + "Transfer-Encoding" : "chunked", + "X-Processing-Time" : "292ms", + "MS-CV" : "rgPQQ3XR50SFtXr68Qefqw.0", + "retry-after" : "0", + "X-Azure-Ref" : "0DaB8XwAAAADdZnkaYhXqS76qjA9LTed8REVOMDJFREdFMDMxNQA5ZmM3YjUxOS1hOGNjLTRmODktOTM1ZS1jOTE0OGFlMDllODE=", + "StatusCode" : "200", + "Body" : "{\"searchId\":\"44b70e2f-6521-454e-a8ea-67ab95927a13\",\"displayName\":\"testsearch20200014\",\"createdAt\":\"2020-10-06T16:49:05.1044519+00:00\",\"description\":\"testsearch20200014\",\"phonePlanIds\":[\"27b53eec-8ff4-4070-8900-fbeaabfd158a\"],\"areaCode\":\"323\",\"quantity\":2,\"locationOptions\":[],\"status\":\"Reserved\",\"phoneNumbers\":[\"+13234866789\",\"+13234866792\"],\"reservationExpiryDate\":\"2020-10-06T17:05:13.5997531+00:00\"}", + "Date" : "Tue, 06 Oct 2020 16:49:16 GMT", + "Content-Type" : "application/json; charset=utf-8" + }, + "Exception" : null + } ], + "variables" : [ ] +} \ No newline at end of file