Skip to content

Commit 783c420

Browse files
authored
Merge pull request #30 from Bandwidth/SWI-6678
SWI-6678
2 parents 383ccb5 + fb50030 commit 783c420

File tree

7 files changed

+257
-4
lines changed

7 files changed

+257
-4
lines changed

src/main/java/com/bandwidth/sdk/numbers/NumbersClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.bandwidth.sdk.numbers.models.orders.Order;
55
import com.bandwidth.sdk.numbers.models.orders.OrderResponse;
66
import com.bandwidth.sdk.numbers.models.AvailableNumberSearchRequest;
7+
import com.bandwidth.sdk.numbers.models.orders.OrdersResponse;
78

89
public interface NumbersClient extends AutoCloseable {
910

@@ -34,4 +35,12 @@ public interface NumbersClient extends AutoCloseable {
3435
* @return {@link OrderResponse} with the details of the results of placing the order
3536
*/
3637
OrderResponse getOrderStatus(String orderId);
38+
39+
/**
40+
* Fetch the details of all orders.
41+
*
42+
* @param customerOrderId The customerOrderId of the order to search on
43+
* @return {@link OrdersResponse} with the details of all orders
44+
*/
45+
OrdersResponse getOrdersByCustomerOrderId(String customerOrderId);
3746
}

src/main/java/com/bandwidth/sdk/numbers/NumbersClientImpl.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.bandwidth.sdk.numbers;
22

33
import com.bandwidth.sdk.numbers.exception.ExceptionUtils;
4+
import com.bandwidth.sdk.numbers.exception.NumbersApiException;
45
import com.bandwidth.sdk.numbers.helpers.RetryableRequest;
56
import com.bandwidth.sdk.numbers.helpers.SleepRetryPolicy;
67
import com.bandwidth.sdk.numbers.models.AvailableNumberSearchRequest;
78
import com.bandwidth.sdk.numbers.models.SearchResult;
89
import com.bandwidth.sdk.numbers.models.orders.Order;
910
import com.bandwidth.sdk.numbers.models.orders.OrderResponse;
11+
import com.bandwidth.sdk.numbers.models.orders.OrdersResponse;
1012
import com.bandwidth.sdk.numbers.serde.NumbersSerde;
1113
import com.google.common.base.Preconditions;
1214
import io.netty.handler.codec.http.HttpHeaderNames;
@@ -105,6 +107,41 @@ public OrderResponse getOrderStatus(String orderId) {
105107
});
106108
}
107109

110+
/**
111+
* This queries the /orders API with a required parameter of customerOrderId
112+
* If we need to extend this for any reason, we should implement a getOrders method with a builder for the possible query parameters
113+
* The HTTP client will need to be investigated to see how it will support adding multiple query parameters
114+
*
115+
* @param customerOrderId The customerOrderId of the order to search on
116+
* @return The orders response
117+
*/
118+
@Override
119+
public OrdersResponse getOrdersByCustomerOrderId(String customerOrderId){
120+
return getOrdersByCustomerOrderIdAsync(customerOrderId).join();
121+
}
122+
123+
private CompletableFuture<OrdersResponse> getOrdersByCustomerOrderIdAsync(String customerOrderId) throws NumbersApiException {
124+
// arbitrary
125+
String pageSize = "100";
126+
127+
return catchAsyncClientExceptions(() -> {
128+
String url = MessageFormat.format("{0}/accounts/{1}/orders?customerOrderId={2}&page=1&size={3}", baseUrl, account, customerOrderId, pageSize);
129+
return httpClient.prepareGet(url)
130+
.execute()
131+
.toCompletableFuture()
132+
.thenApply(resp -> {
133+
String responseBodyString = resp.getResponseBody(StandardCharsets.UTF_8);
134+
if (resp.getStatusCode() != 200) {
135+
if (resp.getStatusCode() == 204) {
136+
throw new NumbersApiException("No orders found");
137+
}
138+
throw new NumbersApiException("Error fetching orders. Response body: " + responseBodyString + "; Status code: " + resp.getStatusCode());
139+
}
140+
return NumbersSerde.deserialize(responseBodyString, OrdersResponse.class);
141+
});
142+
});
143+
}
144+
108145
@Override
109146
public void close() {
110147
try {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.bandwidth.sdk.numbers.models.orders;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
8+
import org.immutables.value.Value;
9+
10+
import javax.annotation.Nullable;
11+
12+
@Value.Immutable
13+
@JsonSerialize(as = ImmutableOrdersResponse.class)
14+
@JsonDeserialize(as = ImmutableOrdersResponse.class)
15+
@JacksonXmlRootElement(localName = "ResponseSelectWrapper")
16+
@JsonIgnoreProperties(ignoreUnknown = true)
17+
public abstract class OrdersResponse {
18+
@Value.Redacted
19+
@Nullable
20+
@JacksonXmlProperty(localName = "ListOrderIdUserIdDate")
21+
public abstract OrdersResponseWrapper getOrdersResponseData();
22+
23+
public static ImmutableOrdersResponse.Builder builder() {
24+
return ImmutableOrdersResponse.builder();
25+
}
26+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.bandwidth.sdk.numbers.models.orders;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
8+
import org.immutables.value.Value;
9+
10+
import javax.annotation.Nullable;
11+
import java.util.Date;
12+
13+
@Value.Immutable
14+
@JsonSerialize(as = ImmutableOrdersResponseData.class)
15+
@JsonDeserialize(as = ImmutableOrdersResponseData.class)
16+
@JacksonXmlRootElement(localName = "OrderIdUserIdDate")
17+
@JsonIgnoreProperties(ignoreUnknown = true)
18+
public abstract class OrdersResponseData {
19+
@Nullable
20+
@JacksonXmlProperty(localName = "accountId")
21+
public abstract String getAccountId();
22+
23+
@Nullable
24+
@JacksonXmlProperty(localName = "CountOfTNs")
25+
public abstract Integer getCountOfTns();
26+
27+
@Nullable
28+
@JacksonXmlProperty(localName = "CustomerOrderId")
29+
public abstract String getCustomerOrderId();
30+
31+
@Nullable
32+
@JacksonXmlProperty(localName = "userId")
33+
public abstract String getUserId();
34+
35+
@Nullable
36+
@JacksonXmlProperty(localName = "lastModifiedDate")
37+
public abstract Date getLastModifiedDate();
38+
39+
@Nullable
40+
@JacksonXmlProperty(localName = "OrderDate")
41+
public abstract Date getOrderDate();
42+
43+
@Nullable
44+
@JacksonXmlProperty(localName = "OrderType")
45+
public abstract String getOrderType();
46+
47+
@Nullable
48+
@JacksonXmlProperty(localName = "orderId")
49+
public abstract String getOrderId();
50+
51+
@Nullable
52+
@JacksonXmlProperty(localName = "OrderStatus")
53+
public abstract OrderResponse.OrderStatus getOrderStatus();
54+
55+
@Nullable
56+
@JacksonXmlProperty(localName = "Summary")
57+
public abstract String getSummary();
58+
59+
public static ImmutableOrdersResponseData.Builder builder() {
60+
return ImmutableOrdersResponseData.builder();
61+
}
62+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.bandwidth.sdk.numbers.models.orders;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
8+
import org.immutables.value.Value;
9+
10+
import javax.annotation.Nullable;
11+
12+
@Value.Immutable
13+
@JsonSerialize(as = ImmutableOrdersResponseLinks.class)
14+
@JsonDeserialize(as = ImmutableOrdersResponseLinks.class)
15+
@JacksonXmlRootElement(localName = "Links")
16+
@JsonIgnoreProperties(ignoreUnknown = true)
17+
public abstract class OrdersResponseLinks {
18+
@Nullable
19+
@JacksonXmlProperty(localName = "first")
20+
public abstract String getFirst();
21+
22+
@Nullable
23+
@JacksonXmlProperty(localName = "next")
24+
public abstract String getNext();
25+
26+
public static ImmutableOrdersResponseLinks.Builder builder() {
27+
return ImmutableOrdersResponseLinks.builder();
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.bandwidth.sdk.numbers.models.orders;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
5+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
6+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
7+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
8+
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
9+
import org.immutables.value.Value;
10+
11+
import javax.annotation.Nullable;
12+
import java.util.List;
13+
14+
@Value.Immutable
15+
@JsonSerialize(as = ImmutableOrdersResponseWrapper.class)
16+
@JsonDeserialize(as = ImmutableOrdersResponseWrapper.class)
17+
@JacksonXmlRootElement(localName = "ListOrderIdUserIdDate")
18+
@JsonIgnoreProperties(ignoreUnknown = true)
19+
public abstract class OrdersResponseWrapper {
20+
@Nullable
21+
@JacksonXmlProperty(localName = "TotalCount")
22+
public abstract Integer getTotalCount();
23+
24+
@Nullable
25+
@JacksonXmlElementWrapper(localName = "Links")
26+
public abstract OrdersResponseLinks getLinks();
27+
28+
@Nullable
29+
@JacksonXmlElementWrapper(useWrapping = false)
30+
@JacksonXmlProperty(localName = "OrderIdUserIdDate")
31+
public abstract List<OrdersResponseData> getOrders();
32+
33+
public static ImmutableOrdersResponseWrapper.Builder builder() {
34+
return ImmutableOrdersResponseWrapper.builder();
35+
}
36+
}

src/test/java/com/bandwidth/sdk/numbers/NumbersClientImplTest.java

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
import com.bandwidth.sdk.numbers.models.ImmutableErrorResponse;
77
import com.bandwidth.sdk.numbers.models.ImmutableSearchResult;
88
import com.bandwidth.sdk.numbers.models.SearchResult;
9-
import com.bandwidth.sdk.numbers.models.orders.ExistingTelephoneNumberOrderType;
10-
import com.bandwidth.sdk.numbers.models.orders.ImmutableOrderResponse;
11-
import com.bandwidth.sdk.numbers.models.orders.Order;
12-
import com.bandwidth.sdk.numbers.models.orders.OrderResponse;
9+
import com.bandwidth.sdk.numbers.models.orders.*;
1310
import com.bandwidth.sdk.numbers.serde.NumbersSerde;
1411
import org.assertj.core.api.Assertions;
1512
import org.asynchttpclient.AsyncHttpClient;
@@ -23,6 +20,7 @@
2320
import org.mockito.junit.MockitoJUnitRunner;
2421

2522
import java.nio.charset.StandardCharsets;
23+
import java.util.List;
2624
import java.util.concurrent.CompletableFuture;
2725
import java.util.concurrent.CompletionException;
2826

@@ -80,6 +78,23 @@ public class NumbersClientImplTest {
8078
.order(order)
8179
.build();
8280

81+
private final OrdersResponse ordersResponse = ImmutableOrdersResponse.builder()
82+
.ordersResponseData(OrdersResponseWrapper.builder()
83+
.addOrders(ImmutableOrdersResponseData.builder()
84+
.accountId("1")
85+
.countOfTns(1)
86+
.customerOrderId("foo")
87+
.userId("1")
88+
.lastModifiedDate(null)
89+
.orderDate(null)
90+
.orderType("1")
91+
.orderId("1")
92+
.orderStatus(OrderResponse.OrderStatus.COMPLETE)
93+
.summary("1")
94+
.build())
95+
.build())
96+
.build();
97+
8398
@Mock
8499
private AsyncHttpClient asyncHttpClient;
85100
@Mock
@@ -179,4 +194,43 @@ public void orderNumbersWithError() {
179194
assertThat(thrown).isInstanceOf(NumbersApiException.class);
180195
}
181196

197+
@Test
198+
public void searchForNumberByCustomerOrderId() {
199+
when(asyncHttpClient.prepareGet(anyString())).thenReturn(boundRequestBuilder);
200+
when(boundRequestBuilder.execute()).thenReturn(listenableFuture);
201+
when(listenableFuture.toCompletableFuture()).thenReturn(CompletableFuture.completedFuture(response));
202+
when(response.getStatusCode()).thenReturn(200);
203+
when(response.getResponseBody(StandardCharsets.UTF_8)).thenReturn(NumbersSerde.serialize(ordersResponse));
204+
205+
assertThat(ordersResponse).isEqualTo(numbersClient.getOrdersByCustomerOrderId("foo"));
206+
List<OrdersResponseData> orders = ordersResponse.getOrdersResponseData().getOrders();
207+
assertThat(orders).hasSize(1);
208+
assertThat(orders.get(0).getCustomerOrderId()).isEqualTo("foo");
209+
assertThat(orders.get(0).getOrderId()).isEqualTo("1");
210+
211+
verify(asyncHttpClient, times(1)).prepareGet(anyString());
212+
}
213+
214+
@Test
215+
public void searchForNumberByCustomerOrderIdNoOrdersFound() {
216+
when(asyncHttpClient.prepareGet(anyString())).thenReturn(boundRequestBuilder);
217+
when(boundRequestBuilder.execute()).thenReturn(listenableFuture);
218+
when(listenableFuture.toCompletableFuture()).thenReturn(CompletableFuture.completedFuture(response));
219+
when(response.getStatusCode()).thenReturn(204);
220+
221+
Throwable thrown = Assertions.catchThrowable(() -> numbersClient.getOrdersByCustomerOrderId("foo"));
222+
assertThat(thrown).isInstanceOf(CompletionException.class).hasCauseInstanceOf(NumbersApiException.class);
223+
}
224+
225+
@Test
226+
public void searchForNumberByCustomerOrderIdRequestError() {
227+
when(asyncHttpClient.prepareGet(anyString())).thenReturn(boundRequestBuilder);
228+
when(boundRequestBuilder.execute()).thenReturn(listenableFuture);
229+
when(listenableFuture.toCompletableFuture()).thenReturn(CompletableFuture.completedFuture(response));
230+
when(response.getStatusCode()).thenReturn(400);
231+
232+
Throwable thrown = Assertions.catchThrowable(() -> numbersClient.getOrdersByCustomerOrderId("foo"));
233+
assertThat(thrown).isInstanceOf(CompletionException.class).hasCauseInstanceOf(NumbersApiException.class);
234+
}
235+
182236
}

0 commit comments

Comments
 (0)