Skip to content

Commit

Permalink
Communication - Added Phone Number Administration Create Search LRO (A…
Browse files Browse the repository at this point in the history
…zure#15998)

* Added create search LRO

* Addressed PR comments

* Addressed Ankit's comments

* Cleaned poll operation

* Removed SUCCESS as a terminal state

* Test redone to use async responses
  • Loading branch information
jbeauregardb authored Oct 8, 2020
1 parent 5cb484c commit 97c9e9b
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,12 +37,19 @@
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.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.azure.core.util.FluxUtil.monoError;
Expand All @@ -53,7 +61,6 @@
@ServiceClient(builder = PhoneNumberClientBuilder.class, isAsync = true)
public final class PhoneNumberAsyncClient {
private final ClientLogger logger = new ClientLogger(PhoneNumberAsyncClient.class);

private final PhoneNumberAdministrationsImpl phoneNumberAdministrations;

PhoneNumberAsyncClient(PhoneNumberAdminClientImpl phoneNumberAdminClient) {
Expand Down Expand Up @@ -757,4 +764,74 @@ Mono<Response<Void>> 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 pollInterval 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
*/
@ServiceMethod(returns = ReturnType.COLLECTION)
public PollerFlux<PhoneNumberSearch, PhoneNumberSearch> beginCreateSearch(
CreateSearchOptions options, Duration pollInterval) {
Objects.requireNonNull(options, "'options' cannot be null.");
Objects.requireNonNull(pollInterval, "'pollInterval' cannot be null.");
return new PollerFlux<PhoneNumberSearch, PhoneNumberSearch>(pollInterval,
createSearchActivationOperation(options),
createSearchPollOperation(),
cancelSearchOperation(),
createSearchFetchResultOperation());
}

private Function<PollingContext<PhoneNumberSearch>, Mono<PhoneNumberSearch>>
createSearchActivationOperation(CreateSearchOptions options) {
return (pollingContext) -> {
Mono<PhoneNumberSearch> response = createSearch(options).flatMap(createSearchResponse -> {
String searchId = createSearchResponse.getSearchId();
Mono<PhoneNumberSearch> phoneNumberSearch = getSearchById(searchId);
return phoneNumberSearch;
});
return response;
};
}

private Function<PollingContext<PhoneNumberSearch>, Mono<PollResponse<PhoneNumberSearch>>>
createSearchPollOperation() {
return pollingContext ->
getSearchById(pollingContext.getLatestResponse().getValue().getSearchId())
.flatMap(getSearchResponse -> {
SearchStatus status = getSearchResponse.getStatus();
if (status.equals(SearchStatus.EXPIRED)
|| status.equals(SearchStatus.CANCELLED)
|| status.equals(SearchStatus.RESERVED)) {
return Mono.just(new PollResponse<>(
LongRunningOperationStatus.SUCCESSFULLY_COMPLETED, getSearchResponse));
}
if (status.equals(SearchStatus.ERROR)) {
return Mono.just(new PollResponse<>(
LongRunningOperationStatus.FAILED, getSearchResponse));
}
return Mono.just(new PollResponse<>(LongRunningOperationStatus.IN_PROGRESS, getSearchResponse));
});
}

private BiFunction<PollingContext<PhoneNumberSearch>,
PollResponse<PhoneNumberSearch>, Mono<PhoneNumberSearch>>
cancelSearchOperation() {
return (pollingContext, firstResponse) -> {
cancelSearch(pollingContext.getLatestResponse().getValue().getSearchId());
return Mono.just(pollingContext.getLatestResponse().getValue());
};
}

private Function<PollingContext<PhoneNumberSearch>,
Mono<PhoneNumberSearch>> createSearchFetchResultOperation() {
return pollingContext -> {
return Mono.just(pollingContext.getLatestResponse().getValue());
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -521,4 +524,19 @@ public void purchaseSearch(String searchId) {
public Response<Void> 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 pollInterval 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.COLLECTION)
public SyncPoller<PhoneNumberSearch, PhoneNumberSearch> beginCreateSearch(
CreateSearchOptions options, Duration pollInterval) {
return phoneNumberAsyncClient.beginCreateSearch(options, pollInterval).getSyncPoller();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@
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.AsyncPollResponse;
import com.azure.core.util.polling.LongRunningOperationStatus;
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;
Expand Down Expand Up @@ -463,6 +467,31 @@ public void releasePhoneNumbersWithResponse() {
.verifyComplete();
}

@Test()
public void beginCreateSearch() {
List<String> phonePlanIds = new ArrayList<>();
phonePlanIds.add(PHONE_PLAN_ID);

CreateSearchOptions createSearchOptions = new CreateSearchOptions();
createSearchOptions
.setAreaCode(AREA_CODE_FOR_SEARCH)
.setDescription(SEARCH_OPTIONS_DESCRIPTION)
.setDisplayName(SEARCH_OPTIONS_NAME)
.setPhonePlanIds(phonePlanIds)
.setQuantity(2);

Duration duration = Duration.ofSeconds(1);
PhoneNumberAsyncClient client = this.getClient();
PollerFlux<PhoneNumberSearch, PhoneNumberSearch> poller =
client.beginCreateSearch(createSearchOptions, duration);
AsyncPollResponse<PhoneNumberSearch, PhoneNumberSearch> asyncRes =
poller.takeUntil(apr -> apr.getStatus() == LongRunningOperationStatus.SUCCESSFULLY_COMPLETED)
.blockLast();
PhoneNumberSearch testResult = asyncRes.getValue();
assertEquals(testResult.getPhoneNumbers().size(), 2);
assertNotNull(testResult.getSearchId());
}

private PhoneNumberAsyncClient getClient() {
return super.getClientBuilder().buildAsyncClient();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public class PhoneNumberIntegrationTestBase extends TestBase {
Configuration.getGlobalConfiguration().get("LOCATION_OPTION_STATE", "CA");
protected static final String LOCATION_OPTION_CITY =
Configuration.getGlobalConfiguration().get("LOCATION_OPTION_CITY", "NOAM-US-CA-LA");
protected static final String SEARCH_OPTIONS_DESCRIPTION =
Configuration.getGlobalConfiguration().get("SEARCH_OPTIONS_DESCRIPTION", "testsearch20200014");
protected static final String SEARCH_OPTIONS_NAME =
Configuration.getGlobalConfiguration().get("SEARCH_OPTIONS_NAME", "testsearch20200014");

protected PhoneNumberClientBuilder getClientBuilder() {
HttpClient httpClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -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" : [ ]
}

0 comments on commit 97c9e9b

Please sign in to comment.