{
+
+ private final Integer currentPage;
+ private final Integer pageSize;
+
+ public SMSCursorPageNavigator(Integer currentPage, Integer pageSize) {
+ super(null);
+ this.currentPage = currentPage;
+ this.pageSize = pageSize;
+ }
+
+ private Integer computeNextPageCursor() {
+ return null == pageSize || pageSize == 0 ? null : currentPage + 1;
+ }
+
+ @Override
+ public Integer getToken() {
+ return computeNextPageCursor();
+ }
+
+ @Override
+ public String toString() {
+ return "SMSCursorPageNavigator{"
+ + "currentPage="
+ + currentPage
+ + ", pageSize="
+ + pageSize
+ + "} "
+ + super.toString();
+ }
+}
diff --git a/client/src/main/com/sinch/sdk/domains/sms/models/v1/package-info.java b/client/src/main/com/sinch/sdk/domains/sms/models/v1/package-info.java
new file mode 100644
index 000000000..a31fb92a3
--- /dev/null
+++ b/client/src/main/com/sinch/sdk/domains/sms/models/v1/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * SMS API related models
+ *
+ * @since 1.5
+ */
+package com.sinch.sdk.domains.sms.models.v1;
diff --git a/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/SmsEvent.java b/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/SmsEvent.java
new file mode 100644
index 000000000..6257897ec
--- /dev/null
+++ b/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/SmsEvent.java
@@ -0,0 +1,13 @@
+package com.sinch.sdk.domains.sms.models.v1.webhooks;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.sinch.sdk.domains.sms.models.v1.webhooks.internal.WebhookEventOneOfImpl;
+
+/**
+ * Base class for all WebHook event's class
+ *
+ * @see com.sinch.sdk.domains.sms.api.v1.WebHooksService#parseEvent(String)
+ * @since 1.5
+ */
+@JsonDeserialize(using = WebhookEventOneOfImpl.Deserializer.class)
+public interface SmsEvent {}
diff --git a/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/package-info.java b/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/package-info.java
new file mode 100644
index 000000000..f1aa66b4d
--- /dev/null
+++ b/client/src/main/com/sinch/sdk/domains/sms/models/v1/webhooks/package-info.java
@@ -0,0 +1,57 @@
+/**
+ * SMS API webhooks related models
+ *
+ * Incoming SMS WebHook
+ *
+ * An inbound message is a message sent to one of your short codes or long numbers from a mobile
+ * phone. To receive inbound message callbacks, a URL needs to be added to your REST API.
+ *
+ *
This URL can be specified in your Dashboard .
+ *
+ *
See https://developers.sinch.com/docs/sms/api-reference/sms/tag/Webhooks/#tag/Webhooks/operation/incomingSMS
+ *
+ *
Delivery Report WebHook
+ *
+ * A delivery report contains the status and status code for each recipient of a batch. To get a
+ * delivery report callback for a message or batch of messages, set the delivery_report
+ *
field accordingly when creating a batch.
+ *
+ *
The following is provided so you can better understand our webhooks/callbacks. Configuration
+ * of both webhooks and the type of delivery report requested happens when sending a batch.
+ *
+ *
Callback URL
+ *
+ *
The callback URL can either be provided for each batch or provisioned globally for your
+ * account in your Sinch Customer Dashboard .
+ * Learn how to configure a webhook/callback here
+ *
+ *
Type
+ *
+ *
The type
is the type of delivery report webhook. The response will vary depending
+ * on the webhook delivery report you selected when the batch was sent, so choose the appropriate
+ * selection under "One of".
+ *
+ *
+ * The delivery_report_sms
and delivery_report_mms
types are
+ * documented under Delivery report .
+ * These are reports containing either
+ * a full report or summary report , depending on your selection at the time the batch was
+ * sent.
+ *
The recipient_delivery_report_sms
and recipient_delivery_report_mms
+ *
delivery report types are documented under Recipient delivery report .
+ * These are delivery reports for recipient phone numbers. If you set per_recipient
+ *
for the delivery_report
parameter when sending the batch, a recipient
+ * report gets sent to you for each status change for each recipient in your batch. If you set
+ * per_recipient_final
, a recipient report gets sent to you for the final status
+ * of each recipient in your batch.
+ *
+ *
+ * See https://developers.sinch.com/docs/sms/api-reference/sms/tag/Webhooks/#tag/Webhooks/operation/deliveryReport
+ *
+ * @since 1.5
+ */
+package com.sinch.sdk.domains.sms.models.v1.webhooks;
diff --git a/client/src/main/com/sinch/sdk/package-info.java b/client/src/main/com/sinch/sdk/package-info.java
index d930893d6..2e4779f4f 100644
--- a/client/src/main/com/sinch/sdk/package-info.java
+++ b/client/src/main/com/sinch/sdk/package-info.java
@@ -1,5 +1,5 @@
/**
- * Sinch Java SDK for Numbers, SMS & Verification
+ * Sinch Java SDK for Conversation, Numbers, SMS, Verification & Voice
*
* Provides the client necessary to interface with Sinch APIS
*
diff --git a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/ConversationWebhooksAuthenticationValidationTest.java b/client/src/test/java/com/sinch/sdk/auth/HmacAuthenticationValidationTest.java
similarity index 71%
rename from client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/ConversationWebhooksAuthenticationValidationTest.java
rename to client/src/test/java/com/sinch/sdk/auth/HmacAuthenticationValidationTest.java
index 6851a88f4..7d7e09273 100644
--- a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/ConversationWebhooksAuthenticationValidationTest.java
+++ b/client/src/test/java/com/sinch/sdk/auth/HmacAuthenticationValidationTest.java
@@ -1,4 +1,4 @@
-package com.sinch.sdk.domains.conversation.api.v1.adapters;
+package com.sinch.sdk.auth;
import static org.junit.jupiter.api.Assertions.*;
@@ -9,23 +9,21 @@
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
-class ConversationWebhooksAuthenticationValidationTest {
+class HmacAuthenticationValidationTest {
- ConversationWebhooksAuthenticationValidation webhooksService =
- new ConversationWebhooksAuthenticationValidation();
+ HmacAuthenticationValidation webhooksService = new HmacAuthenticationValidation();
Map headers =
Stream.of(
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.SIGNATURE_HEADER,
+ HmacAuthenticationValidation.SIGNATURE_HEADER,
"6bpJoRmFoXVjfJIVglMoJzYXxnoxRujzR4k2GOXewOE="),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.ALGORITHM_HEADER, "HmacSHA256"),
+ HmacAuthenticationValidation.ALGORITHM_HEADER, "HmacSHA256"),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.NONCE_HEADER,
- "01FJA8B4A7BM43YGWSG9GBV067"),
+ HmacAuthenticationValidation.NONCE_HEADER, "01FJA8B4A7BM43YGWSG9GBV067"),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.TIMESTAMP_HEADER, "1634579353"))
+ HmacAuthenticationValidation.TIMESTAMP_HEADER, "1634579353"))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
String secret = "foo_secret1234";
@@ -66,11 +64,7 @@ void checkValidateAuthenticatedRequestMissingSignature() {
Map headerSet =
headers.entrySet().stream()
- .filter(
- entry ->
- !entry
- .getKey()
- .equals(ConversationWebhooksAuthenticationValidation.SIGNATURE_HEADER))
+ .filter(entry -> !entry.getKey().equals(HmacAuthenticationValidation.SIGNATURE_HEADER))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
boolean authenticationResult =
@@ -84,11 +78,7 @@ void checkValidateAuthenticatedRequestMissingAlgorithm() {
Map headerSet =
headers.entrySet().stream()
- .filter(
- entry ->
- !entry
- .getKey()
- .equals(ConversationWebhooksAuthenticationValidation.ALGORITHM_HEADER))
+ .filter(entry -> !entry.getKey().equals(HmacAuthenticationValidation.ALGORITHM_HEADER))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
boolean authenticationResult =
@@ -102,11 +92,7 @@ void checkValidateAuthenticatedMissingNonce() {
Map headerSet =
headers.entrySet().stream()
- .filter(
- entry ->
- !entry
- .getKey()
- .equals(ConversationWebhooksAuthenticationValidation.NONCE_HEADER))
+ .filter(entry -> !entry.getKey().equals(HmacAuthenticationValidation.NONCE_HEADER))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
boolean authenticationResult =
@@ -120,11 +106,7 @@ void checkValidateAuthenticatedMissingTimeStamp() {
Map headerSet =
headers.entrySet().stream()
- .filter(
- entry ->
- !entry
- .getKey()
- .equals(ConversationWebhooksAuthenticationValidation.TIMESTAMP_HEADER))
+ .filter(entry -> !entry.getKey().equals(HmacAuthenticationValidation.TIMESTAMP_HEADER))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
boolean authenticationResult =
diff --git a/client/src/test/java/com/sinch/sdk/domains/PaginationFillerHelper.java b/client/src/test/java/com/sinch/sdk/domains/PaginationFillerHelper.java
new file mode 100644
index 000000000..aec8749f6
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/PaginationFillerHelper.java
@@ -0,0 +1,29 @@
+package com.sinch.sdk.domains;
+
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class PaginationFillerHelper {
+
+ public static Collection parametersFiller(
+ String name, Object value, STYLE style, boolean explode, List> values) {
+
+ List parameters = new ArrayList<>();
+
+ URLParameter parameter = new URLParameter(name, value, style, explode);
+ parameters.add(parameter);
+ for (int i = 0; i < values.size(); ) {
+ parameter =
+ new URLParameter(
+ (String) values.get(i++),
+ values.get(i++),
+ (STYLE) values.get(i++),
+ (boolean) values.get(i++));
+ parameters.add(parameter);
+ }
+ return parameters;
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksClientServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksClientServiceTest.java
index 24fb82e75..f4430de81 100644
--- a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksClientServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksClientServiceTest.java
@@ -8,6 +8,7 @@
import static org.mockito.Mockito.when;
import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.auth.HmacAuthenticationValidation;
import com.sinch.sdk.core.TestHelpers;
import com.sinch.sdk.core.exceptions.ApiException;
import com.sinch.sdk.core.http.AuthManager;
@@ -40,7 +41,7 @@ public class WebHooksClientServiceTest extends ConversationBaseTest {
@Mock WebhooksApi api;
@Mock HttpClient httpClient;
@Mock Map authManagers;
- @Mock ConversationWebhooksAuthenticationValidation authenticationValidation;
+ @Mock HmacAuthenticationValidation authenticationValidation;
@Captor ArgumentCaptor uriPartIDCaptor;
@Captor ArgumentCaptor idCaptor;
diff --git a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksServiceTest.java
index d9feab74d..136dbd3ce 100644
--- a/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/conversation/api/v1/adapters/WebHooksServiceTest.java
@@ -5,6 +5,7 @@
import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
import com.adelean.inject.resources.junit.jupiter.TestWithResources;
import com.sinch.sdk.SinchClient;
+import com.sinch.sdk.auth.HmacAuthenticationValidation;
import com.sinch.sdk.core.exceptions.ApiException;
import com.sinch.sdk.domains.conversation.models.v1.webhooks.events.capability.CapabilityEvent;
import com.sinch.sdk.domains.conversation.models.v1.webhooks.events.channel.ChannelEvent;
@@ -119,15 +120,14 @@ void checkApplicationAuthentication() throws ApiException {
Map headers =
Stream.of(
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.SIGNATURE_HEADER,
+ HmacAuthenticationValidation.SIGNATURE_HEADER,
"6bpJoRmFoXVjfJIVglMoJzYXxnoxRujzR4k2GOXewOE="),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.ALGORITHM_HEADER, "HmacSHA256"),
+ HmacAuthenticationValidation.ALGORITHM_HEADER, "HmacSHA256"),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.NONCE_HEADER,
- "01FJA8B4A7BM43YGWSG9GBV067"),
+ HmacAuthenticationValidation.NONCE_HEADER, "01FJA8B4A7BM43YGWSG9GBV067"),
new AbstractMap.SimpleEntry<>(
- ConversationWebhooksAuthenticationValidation.TIMESTAMP_HEADER, "1634579353"))
+ HmacAuthenticationValidation.TIMESTAMP_HEADER, "1634579353"))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
boolean authenticationResult =
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/BatchesServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/BatchesServiceTest.java
index c1f461e02..e2b2b1ad2 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/BatchesServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/BatchesServiceTest.java
@@ -246,25 +246,25 @@ public class BatchesServiceTest extends BaseTest {
.setUdh(udh)
.build();
- @GivenJsonResource("/domains/sms/v1/BinaryResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/BinaryResponseDto.json")
public SendSMS201ResponseDto binaryResponseDto;
- @GivenJsonResource("/domains/sms/v1/MediaResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/MediaResponseDto.json")
SendSMS201ResponseDto mediaResponseDto;
- @GivenJsonResource("/domains/sms/v1/TextResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/TextResponseDto.json")
SendSMS201ResponseDto textResponseDto;
- @GivenJsonResource("/domains/sms/v1/DryRunResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/DryRunResponseDto.json")
DryRun200ResponseDto dryRunResponseDto;
- @GivenJsonResource("/domains/sms/v1/ListBatchesResponseDtoPage0.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage0.json")
ApiBatchListDto listBatchesResponseDtoPage0;
- @GivenJsonResource("/domains/sms/v1/ListBatchesResponseDtoPage1.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage1.json")
ApiBatchListDto listBatchesResponseDtoPage1;
- @GivenJsonResource("/domains/sms/v1/ListBatchesResponseDtoPage2.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage2.json")
ApiBatchListDto listBatchesResponseDtoPage2;
@Mock SmsContext context;
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/DeliveryReportsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/DeliveryReportsServiceTest.java
index dde863784..b82028ca0 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/DeliveryReportsServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/DeliveryReportsServiceTest.java
@@ -50,25 +50,28 @@ class DeliveryReportsServiceTest extends BaseTest {
DeliveryReportsService service;
String uriPartID = "foovalue";
- @GivenJsonResource("/domains/sms/v1/DeliveryReportBatchSMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
DeliveryReportDto deliveryReportBatchSMSDto;
- @GivenJsonResource("/domains/sms/v1/DeliveryReportBatchMMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportMMSDto.json")
DeliveryReportDto deliveryReportBatchMMSDto;
- @GivenJsonResource("/domains/sms/v1/DeliveryReportRecipientSMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportSMSDto.json")
RecipientDeliveryReportDto deliveryReportRecipientSMSDto;
- @GivenJsonResource("/domains/sms/v1/DeliveryReportRecipientMMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportMMSDto.json")
RecipientDeliveryReportDto deliveryReportRecipientMMSDto;
- @GivenJsonResource("/domains/sms/v1/ListDeliveryReportResponseDtoPage0.json")
+ @GivenJsonResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage0.json")
DeliveryReportListDto listDeliveryReportResponseDtoPage0;
- @GivenJsonResource("/domains/sms/v1/ListDeliveryReportResponseDtoPage1.json")
+ @GivenJsonResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage1.json")
DeliveryReportListDto listDeliveryReportResponseDtoPage1;
- @GivenJsonResource("/domains/sms/v1/ListDeliveryReportResponseDtoPage2.json")
+ @GivenJsonResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage2.json")
DeliveryReportListDto listDeliveryReportResponseDtoPage2;
@BeforeEach
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/GroupsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/GroupsServiceTest.java
index 9bc1bfe99..41ed9aac2 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/GroupsServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/GroupsServiceTest.java
@@ -51,16 +51,16 @@ class GroupsServiceTest extends BaseTest {
@Captor ArgumentCaptor groupIdCaptor;
- @GivenJsonResource("/domains/sms/v1/GroupResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/groups/GroupDto.json")
CreateGroupResponseDto createGroupResponseDto;
- @GivenJsonResource("/domains/sms/v1/GroupsListResponseDtoPage0.json")
+ @GivenJsonResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage0.json")
ApiGroupListDto groupsListResponseDtoPage0;
- @GivenJsonResource("/domains/sms/v1/GroupsListResponseDtoPage1.json")
+ @GivenJsonResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage1.json")
ApiGroupListDto groupsListResponseDtoPage1;
- @GivenJsonResource("/domains/sms/v1/GroupsListResponseDtoPage2.json")
+ @GivenJsonResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage2.json")
ApiGroupListDto groupsListResponseDtoPage2;
@BeforeEach
@@ -121,14 +121,11 @@ void list() throws ApiException {
.setAutoUpdate(
GroupAutoUpdate.builder()
.setTo("15551231234")
- .setAdd(
- GroupAutoUpdateKeyword.builder()
- .setFirstWord("Add 1st keyword")
- .build())
+ .setAdd(GroupAutoUpdateKeyword.builder().setFirstWord("1stKeyword").build())
.setRemove(
GroupAutoUpdateKeyword.builder()
- .setFirstWord("remove 1st keyword")
- .setSecondWord("remove 2nd keyword")
+ .setFirstWord("1stKeyword")
+ .setSecondWord("2ndKeyword")
.build())
.build())
.build());
@@ -155,14 +152,11 @@ void list() throws ApiException {
.setAutoUpdate(
GroupAutoUpdate.builder()
.setTo("15551231234")
- .setAdd(
- GroupAutoUpdateKeyword.builder()
- .setFirstWord("Add 1st keyword")
- .build())
+ .setAdd(GroupAutoUpdateKeyword.builder().setFirstWord("1stKeyword").build())
.setRemove(
GroupAutoUpdateKeyword.builder()
- .setFirstWord("remove 1st keyword")
- .setSecondWord("remove 2nd keyword")
+ .setFirstWord("1stKeyword")
+ .setSecondWord("2ndKeyword")
.build())
.build())
.build());
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/InboundsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/InboundsServiceTest.java
index f75637c62..bc3816cd3 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/InboundsServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/InboundsServiceTest.java
@@ -40,19 +40,19 @@ class InboundsServiceTest extends BaseTest {
String uriPartID = "foovalue";
- @GivenJsonResource("/domains/sms/v1/MOBinaryDto.json")
+ @GivenJsonResource("/domains/sms/v1/inbounds/InboundBinaryDto.json")
InboundDto binary;
- @GivenJsonResource("/domains/sms/v1/MOTextDto.json")
+ @GivenJsonResource("/domains/sms/v1/inbounds/InboundTextDto.json")
InboundDto text;
- @GivenJsonResource("/domains/sms/v1/InboundsListResponseDtoPage0.json")
+ @GivenJsonResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage0.json")
ApiInboundListDto inboundsLisResponseDtoPage0;
- @GivenJsonResource("/domains/sms/v1/InboundsListResponseDtoPage1.json")
+ @GivenJsonResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage1.json")
ApiInboundListDto inboundsLisResponseDtoPage1;
- @GivenJsonResource("/domains/sms/v1/InboundsListResponseDtoPage2.json")
+ @GivenJsonResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage2.json")
ApiInboundListDto inboundsLisResponseDtoPage2;
@BeforeEach
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/WebHooksServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/WebHooksServiceTest.java
index afe604226..5a3fbcb0f 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/WebHooksServiceTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/WebHooksServiceTest.java
@@ -28,22 +28,22 @@
@TestWithResources
public class WebHooksServiceTest extends BaseTest {
- @GivenTextResource("/domains/sms/v1/MOBinaryDto.json")
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundBinaryDto.json")
String incomingSMSBinaryJsonString;
- @GivenTextResource("/domains/sms/v1/MOTextDto.json")
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundTextDto.json")
String incomingSMSTextJsonString;
- @GivenTextResource("/domains/sms/v1/DeliveryReportRecipientSMSDto.json")
+ @GivenTextResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportSMSDto.json")
String deliveryReportRecipientSMSJsonString;
- @GivenTextResource("/domains/sms/v1/DeliveryReportRecipientMMSDto.json")
+ @GivenTextResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportMMSDto.json")
String deliveryReportRecipientMMSJsonString;
- @GivenTextResource("/domains/sms/v1/DeliveryReportBatchSMSDto.json")
+ @GivenTextResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
String deliveryReportBatchSMSJsonString;
- @GivenTextResource("/domains/sms/v1/DeliveryReportBatchMMSDto.json")
+ @GivenTextResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportMMSDto.json")
String deliveryReportBatchMMSJsonString;
@InjectMocks WebHooksService service;
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/BatchDtoConverterTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/BatchDtoConverterTest.java
index b5428ace0..22ea01b7e 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/BatchDtoConverterTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/BatchDtoConverterTest.java
@@ -27,22 +27,22 @@
@TestWithResources
class BatchDtoConverterTest extends BaseTest {
- @GivenJsonResource("/domains/sms/v1/BinaryResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/BinaryResponseDto.json")
public SendSMS201ResponseDto binaryResponseDto;
- @GivenJsonResource("/domains/sms/v1/TextResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/TextResponseDto.json")
public SendSMS201ResponseDto textResponseDto;
- @GivenJsonResource("/domains/sms/v1/MediaResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/MediaResponseDto.json")
public SendSMS201ResponseDto mediaResponseDto;
- @GivenJsonResource("/domains/sms/v1/SendSMSBinaryRequestDto.json")
+ @GivenJsonResource("/domains/sms/v1/BinaryRequestDto.json")
public SendSMSRequestDto sendBinaryRequestDto;
- @GivenJsonResource("/domains/sms/v1/SendSMSTextRequestDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/request/TextRequestDto.json")
public SendSMSRequestDto sendTextRequestDto;
- @GivenJsonResource("/domains/sms/v1/SendSMSMediaRequestDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/request/MediaRequestDto.json")
public SendSMSRequestDto sendMediaRequestDto;
@GivenJsonResource("/domains/sms/v1/UpdateSMSTextRequestDto.json")
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DeliveryReportBatchDtoConverterTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DeliveryReportBatchDtoConverterTest.java
index 789d6416d..cbfd8a515 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DeliveryReportBatchDtoConverterTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DeliveryReportBatchDtoConverterTest.java
@@ -22,10 +22,10 @@
@TestWithResources
class DeliveryReportBatchDtoConverterTest extends BaseTest {
- @GivenJsonResource("/domains/sms/v1/DeliveryReportBatchSMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
DeliveryReportDto deliveryReportSMSClientDto;
- @GivenJsonResource("/domains/sms/v1/DeliveryReportBatchMMSDto.json")
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportMMSDto.json")
DeliveryReportDto deliveryReportMMSClientDto;
public static void compareWithDto(
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DryRunDtoConverterTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DryRunDtoConverterTest.java
index 4f53ccaa1..7b262f973 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DryRunDtoConverterTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/DryRunDtoConverterTest.java
@@ -13,7 +13,7 @@
@TestWithResources
public class DryRunDtoConverterTest extends BaseTest {
- @GivenJsonResource("/domains/sms/v1/DryRunResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/batches/response/DryRunResponseDto.json")
DryRun200ResponseDto loadedDto;
public static DryRun dryRunClient =
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/GroupsDtoConverterTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/GroupsDtoConverterTest.java
index dba3a52ee..047c233f6 100644
--- a/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/GroupsDtoConverterTest.java
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/adapters/converters/GroupsDtoConverterTest.java
@@ -27,16 +27,16 @@
@TestWithResources
class GroupsDtoConverterTest extends BaseTest {
- @GivenJsonResource("/domains/sms/v1/GroupResponseDto.json")
+ @GivenJsonResource("/domains/sms/v1/groups/GroupDto.json")
CreateGroupResponseDto createGroupResponseDto;
- @GivenJsonResource("/domains/sms/v1/GroupCreateRequestParametersDto.json")
+ @GivenJsonResource("/domains/sms/v1/CreateGroupRequestDto.json")
GroupObjectDto createGroupRequestParametersDto;
- @GivenJsonResource("/domains/sms/v1/GroupUpdateRequestParametersDto.json")
+ @GivenJsonResource("/domains/sms/v1/groups/request/GroupUpdateRequestDto.json")
UpdateGroupRequestDto groupUpdateRequestParametersDto;
- @GivenJsonResource("/domains/sms/v1/GroupReplaceRequestParametersDto.json")
+ @GivenJsonResource("/domains/sms/v1/ReplaceGroupRequestDto.json")
ReplaceGroupRequestDto groupReplaceRequestParametersDto;
static void compareWithDto(Group client, CreateGroupResponseDto dto) {
@@ -105,16 +105,17 @@ void convertUpdateRequestParameters() throws UnexpectedException {
GroupUpdateRequestParameters client =
GroupUpdateRequestParameters.builder()
.setName("My new customers")
- .setAdd(Collections.singletonList("foo"))
- .setRemove(Arrays.asList("01FC66621XXXXX119Z8PMV1AHY", "01FC66621XXXXX119Z8PMV1A00"))
- .setAddFromGroup("add from group string")
- .setRemoveFromGroup("remove from group string")
+ .setAdd(Collections.singletonList("+12345674890"))
+ .setRemove(Arrays.asList("+0987654321", "+3456789123"))
+ .setAddFromGroup("01FC66621XXXXX119Z8PMV1AHY")
+ .setRemoveFromGroup("01FC66621XXXXX119Z8PMV1A00")
.setAutoUpdate(
GroupAutoUpdateRequestParameters.builder()
.setTo("15551231234")
.setAdd(
GroupAutoUpdateKeywordRequestParameters.builder()
.setFirstWord("Add 1st keyword")
+ .setSecondWord("Add 2nd keyword")
.build())
.setRemove(
GroupAutoUpdateKeywordRequestParameters.builder()
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java
new file mode 100644
index 000000000..c13c7b9fa
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceTest.java
@@ -0,0 +1,505 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import com.adelean.inject.resources.junit.jupiter.GivenJsonResource;
+import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
+import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.BaseTest;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpContentType;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpRequestTest.HttpRequestMatcher;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.domains.PaginationFillerHelper;
+import com.sinch.sdk.domains.sms.api.v1.BatchesService;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.DryRunQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.ListBatchesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateTextRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.internal.ApiBatchList;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+
+@TestWithResources
+public class BatchesServiceTest extends BaseTest {
+
+ static final String SMS_AUTH_NAMES = "BearerAuth";
+
+ static final String SERVICE_PLAN_ID = "foo value";
+ static final String BATCH_ID = "foo batchID";
+
+ @GivenJsonResource("/domains/sms/v1/batches/request/TextRequestDto.json")
+ TextRequest textRequestDto;
+
+ @GivenTextResource("/domains/sms/v1/batches/response/TextResponseDto.json")
+ String jsonTextResponseDto;
+
+ @GivenJsonResource("/domains/sms/v1/batches/response/TextResponseDto.json")
+ BatchResponse textResponseDto;
+
+ @GivenTextResource("/domains/sms/v1/batches/response/DryRunResponseDto.json")
+ String jsonDryRunResponseDto;
+
+ @GivenJsonResource("/domains/sms/v1/batches/response/DryRunResponseDto.json")
+ DryRunResponse dryRunResponseDto;
+
+ @GivenTextResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage0.json")
+ String jsonBatchesResponseDtoPage0;
+
+ @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage0.json")
+ ApiBatchList listBatchesResponseDtoPage0;
+
+ @GivenTextResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage1.json")
+ String jsonBatchesResponseDtoPage1;
+
+ @GivenJsonResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage1.json")
+ ApiBatchList listBatchesResponseDtoPage1;
+
+ @GivenTextResource("/domains/sms/v1/batches/response/ListBatchesResponseDtoPage2.json")
+ String jsonBatchesResponseDtoPage2;
+
+ @GivenJsonResource("/domains/sms/v1/batches/request/UpdateTextRequestDto.json")
+ UpdateTextRequest updateTextRequestDto;
+
+ @GivenJsonResource("/domains/sms/v1/batches/request/SendDeliveryFeedbackRequestDto.json")
+ SendDeliveryFeedbackRequest sendDeliveryFeedbackRequestDto;
+
+ @Mock HttpClient httpClient;
+ @Mock ServerConfiguration serverConfiguration;
+ @Mock Map authManagers;
+
+ BatchesService service;
+
+ @BeforeEach
+ public void initMocks() {
+ service =
+ new BatchesServiceImpl(
+ httpClient,
+ serverConfiguration,
+ authManagers,
+ HttpMapper.getInstance(),
+ SERVICE_PLAN_ID);
+ }
+
+ @Test
+ void get() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID),
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchResponse response = service.get(BATCH_ID);
+
+ TestHelpers.recursiveEquals(response, textResponseDto);
+ }
+
+ @Test
+ void send() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches",
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON), textRequestDto),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchResponse response = service.send(textRequestDto);
+
+ TestHelpers.recursiveEquals(response, textResponseDto);
+ }
+
+ @Test
+ void dryRunDefault() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches/dry_run",
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON), textRequestDto),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonDryRunResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ DryRunResponse response = service.dryRun(textRequestDto);
+
+ TestHelpers.recursiveEquals(response, dryRunResponseDto);
+ }
+
+ @Test
+ void dryRun() throws ApiException {
+
+ DryRunQueryParameters queryParameters =
+ DryRunQueryParameters.builder().setPerRecipient(true).setNumberOfRecipients(456).build();
+
+ Collection urlParameters =
+ Arrays.asList(
+ new URLParameter("per_recipient", true, STYLE.FORM, true),
+ new URLParameter("number_of_recipients", 456, STYLE.FORM, true));
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches/dry_run",
+ HttpMethod.POST,
+ urlParameters,
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON), textRequestDto),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonDryRunResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ DryRunResponse response = service.dryRun(queryParameters, textRequestDto);
+
+ TestHelpers.recursiveEquals(response, dryRunResponseDto);
+ }
+
+ @Test
+ void listDefault() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonBatchesResponseDtoPage0.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ ListBatchesResponse response = service.list();
+
+ TestHelpers.recursiveEquals(response.getContent(), listBatchesResponseDtoPage0.getItems());
+ }
+
+ @Test
+ void list() throws ApiException {
+
+ List commonParameters =
+ Arrays.asList(
+ "page_size",
+ 2,
+ STYLE.FORM,
+ true,
+ "from",
+ "+1234567890",
+ STYLE.FORM,
+ true,
+ "start_date",
+ "2023-11-03T15:21:21.113Z",
+ STYLE.FORM,
+ true,
+ "end_date",
+ "2023-12-12T15:54:21.321Z",
+ STYLE.FORM,
+ true,
+ "client_reference",
+ "client reference",
+ STYLE.FORM,
+ true);
+
+ Collection urlParametersPage0 =
+ PaginationFillerHelper.parametersFiller("page", 0, STYLE.FORM, true, commonParameters);
+ Collection urlParametersPage1 =
+ PaginationFillerHelper.parametersFiller("page", 1, STYLE.FORM, true, commonParameters);
+ Collection urlParametersPage2 =
+ PaginationFillerHelper.parametersFiller("page", 2, STYLE.FORM, true, commonParameters);
+
+ HttpRequest httpRequest0 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches",
+ HttpMethod.GET,
+ urlParametersPage0,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+
+ HttpRequest httpRequest1 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches",
+ HttpMethod.GET,
+ urlParametersPage1,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+
+ HttpRequest httpRequest2 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/batches",
+ HttpMethod.GET,
+ urlParametersPage2,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+
+ HttpResponse httpResponse0 =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonBatchesResponseDtoPage0.getBytes());
+ HttpResponse httpResponse1 =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonBatchesResponseDtoPage1.getBytes());
+ HttpResponse httpResponse2 =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonBatchesResponseDtoPage2.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest0))))
+ .thenReturn(httpResponse0);
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest1))))
+ .thenReturn(httpResponse1);
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest2))))
+ .thenReturn(httpResponse2);
+
+ ListBatchesQueryParameters initialRequest =
+ ListBatchesQueryParameters.builder()
+ .setPage(0)
+ .setPageSize(2)
+ .setFrom("+1234567890")
+ .setClientReference("client reference")
+ .setStartDate(Instant.parse("2023-11-03T15:21:21.113Z"))
+ .setEndDate(Instant.parse("2023-12-12T15:54:21.321Z"))
+ .build();
+
+ ListBatchesResponse response = service.list(initialRequest);
+
+ Iterator iterator = response.iterator();
+
+ BatchResponse item = iterator.next();
+ TestHelpers.recursiveEquals(item, listBatchesResponseDtoPage0.getItems().get(0));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listBatchesResponseDtoPage0.getItems().get(1));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listBatchesResponseDtoPage1.getItems().get(0));
+
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(false);
+ }
+
+ @Test
+ void update() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID),
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ updateTextRequestDto),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchResponse response = service.update(BATCH_ID, updateTextRequestDto);
+
+ TestHelpers.recursiveEquals(response, textResponseDto);
+ }
+
+ @Test
+ void replace() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID),
+ HttpMethod.PUT,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON), textRequestDto),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchResponse response = service.replace(BATCH_ID, textRequestDto);
+
+ TestHelpers.recursiveEquals(response, textResponseDto);
+ }
+
+ @Test
+ void cancel() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID),
+ HttpMethod.DELETE,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextResponseDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchResponse response = service.cancel(BATCH_ID);
+
+ TestHelpers.recursiveEquals(response, textResponseDto);
+ }
+
+ @Test
+ void sendDeliveryFeedback() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID)
+ + "/delivery_feedback",
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ sendDeliveryFeedbackRequestDto),
+ Collections.emptyMap(),
+ Collections.emptyList(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse = new HttpResponse(200, null, Collections.emptyMap(), null);
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ service.sendDeliveryFeedback(BATCH_ID, sendDeliveryFeedbackRequestDto);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceTest.java
new file mode 100644
index 000000000..1b4ef291b
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceTest.java
@@ -0,0 +1,318 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import com.adelean.inject.resources.junit.jupiter.GivenJsonResource;
+import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
+import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.BaseTest;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpContentType;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpRequestTest.HttpRequestMatcher;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.domains.PaginationFillerHelper;
+import com.sinch.sdk.domains.sms.api.v1.DeliveryReportsService;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryReceiptErrorCode;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryStatus;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.ListDeliveryReportsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.ListDeliveryReportsResponse;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.internal.DeliveryReportList;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+
+@TestWithResources
+class DeliveryReportsServiceTest extends BaseTest {
+ static final String SMS_AUTH_NAMES = "BearerAuth";
+ static final String SERVICE_PLAN_ID = "foo value";
+ static final String BATCH_ID = "foo batchID";
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
+ String jsonBatchDeliveryReportSMSDto;
+
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
+ BatchDeliveryReport batchDeliveryReportSMSDto;
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportMMSDto.json")
+ String jsonRecipientDeliveryReportMMSDto;
+
+ @GivenJsonResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportMMSDto.json")
+ RecipientDeliveryReport recipientDeliveryReportMMSDto;
+
+ @GivenTextResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage0.json")
+ String jsonListDeliveryReportResponseDtoPage0;
+
+ @GivenJsonResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage0.json")
+ DeliveryReportList listDeliveryReportResponseDtoPage0;
+
+ @GivenTextResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage1.json")
+ String jsonListDeliveryReportResponseDtoPage1;
+
+ @GivenJsonResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage1.json")
+ DeliveryReportList listDeliveryReportResponseDtoPage1;
+
+ @GivenTextResource(
+ "/domains/sms/v1/deliveryreports/response/ListDeliveryReportResponseDtoPage2.json")
+ String jsonListDeliveryReportResponseDtoPage2;
+
+ @Mock ServerConfiguration serverConfiguration;
+ @Mock HttpClient httpClient;
+ @Mock Map authManagers;
+
+ DeliveryReportsService service;
+
+ @BeforeEach
+ public void initMocks() {
+ service =
+ new DeliveryReportsServiceImpl(
+ httpClient,
+ serverConfiguration,
+ authManagers,
+ HttpMapper.getInstance(),
+ SERVICE_PLAN_ID);
+ }
+
+ @Test
+ void getBatchDeliveryReport() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID)
+ + "/delivery_report",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonBatchDeliveryReportSMSDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ BatchDeliveryReport response = service.get(BATCH_ID);
+
+ TestHelpers.recursiveEquals(response, batchDeliveryReportSMSDto);
+ }
+
+ @Test
+ void getRecipientDeliveryReport() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/batches/"
+ + URLPathUtils.encodePathSegment(BATCH_ID)
+ + "/delivery_report/"
+ + URLPathUtils.encodePathSegment("+1234567890"),
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonRecipientDeliveryReportMMSDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ RecipientDeliveryReport response = service.getForNumber(BATCH_ID, "+1234567890");
+
+ TestHelpers.recursiveEquals(response, recipientDeliveryReportMMSDto);
+ }
+
+ @Test
+ void listDefault() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/delivery_reports",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListDeliveryReportResponseDtoPage0.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ ListDeliveryReportsResponse response = service.list();
+ TestHelpers.recursiveEquals(
+ response.getContent(), listDeliveryReportResponseDtoPage0.getItems());
+ }
+
+ @Test
+ void list() throws ApiException {
+
+ List commonParameters =
+ Arrays.asList(
+ "page_size",
+ 2,
+ STYLE.FORM,
+ true,
+ "start_date",
+ "2023-11-03T15:21:21.113Z",
+ STYLE.FORM,
+ true,
+ "end_date",
+ "2023-12-12T15:54:21.321Z",
+ STYLE.FORM,
+ true,
+ "status",
+ Arrays.asList(DeliveryStatus.QUEUED, DeliveryStatus.DISPATCHED),
+ STYLE.FORM,
+ false,
+ "code",
+ Arrays.asList(
+ DeliveryReceiptErrorCode.DISPATCHED, DeliveryReceiptErrorCode.UNPROVISIONED_REGION),
+ STYLE.FORM,
+ false,
+ "client_reference",
+ "client reference",
+ STYLE.FORM,
+ true);
+
+ Collection urlParameters0 =
+ PaginationFillerHelper.parametersFiller("page", 0, STYLE.FORM, true, commonParameters);
+ Collection urlParameters1 =
+ PaginationFillerHelper.parametersFiller("page", 1, STYLE.FORM, true, commonParameters);
+ Collection urlParameters2 =
+ PaginationFillerHelper.parametersFiller("page", 2, STYLE.FORM, true, commonParameters);
+
+ HttpRequest httpRequest0 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/delivery_reports",
+ HttpMethod.GET,
+ urlParameters0,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest1 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/delivery_reports",
+ HttpMethod.GET,
+ urlParameters1,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest2 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/delivery_reports",
+ HttpMethod.GET,
+ urlParameters2,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse0 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListDeliveryReportResponseDtoPage0.getBytes());
+ HttpResponse httpResponse1 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListDeliveryReportResponseDtoPage1.getBytes());
+ HttpResponse httpResponse2 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListDeliveryReportResponseDtoPage2.getBytes());
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest0))))
+ .thenReturn(httpResponse0);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest1))))
+ .thenReturn(httpResponse1);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest2))))
+ .thenReturn(httpResponse2);
+
+ ListDeliveryReportsQueryParameters initialRequest =
+ ListDeliveryReportsQueryParameters.builder()
+ .setPage(0)
+ .setPageSize(2)
+ .setStartDate(Instant.parse("2023-11-03T15:21:21.113Z"))
+ .setEndDate(Instant.parse("2023-12-12T15:54:21.321Z"))
+ .setStatus(Arrays.asList(DeliveryStatus.QUEUED, DeliveryStatus.DISPATCHED))
+ .setCode(
+ Arrays.asList(
+ DeliveryReceiptErrorCode.DISPATCHED,
+ DeliveryReceiptErrorCode.UNPROVISIONED_REGION))
+ .setClientReference("client reference")
+ .build();
+
+ ListDeliveryReportsResponse response = service.list(initialRequest);
+
+ Iterator iterator = response.iterator();
+
+ RecipientDeliveryReport item = iterator.next();
+ TestHelpers.recursiveEquals(item, listDeliveryReportResponseDtoPage0.getItems().get(0));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listDeliveryReportResponseDtoPage0.getItems().get(1));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listDeliveryReportResponseDtoPage1.getItems().get(0));
+
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(false);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceTest.java
new file mode 100644
index 000000000..35e49e913
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceTest.java
@@ -0,0 +1,388 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import com.adelean.inject.resources.junit.jupiter.GivenJsonResource;
+import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
+import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.BaseTest;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpContentType;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpRequestTest.HttpRequestMatcher;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.domains.PaginationFillerHelper;
+import com.sinch.sdk.domains.sms.api.v1.GroupsService;
+import com.sinch.sdk.domains.sms.models.v1.groups.Group;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupUpdateRequestDtoTest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.ListGroupsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.ListGroupsResponse;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.internal.ApiGroupList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+
+@TestWithResources
+class GroupsServiceTest extends BaseTest {
+
+ static final String SMS_AUTH_NAMES = "BearerAuth";
+
+ static final String SERVICE_PLAN_ID = "foo value";
+ static final String GROUP_ID = "foo groupID";
+
+ @GivenTextResource("/domains/sms/v1/groups/GroupDto.json")
+ String jsonGroupDto;
+
+ @GivenJsonResource("/domains/sms/v1/groups/GroupDto.json")
+ Group groupDto;
+
+ @GivenTextResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage0.json")
+ String jsonListGroupsResponseDtoPage0;
+
+ @GivenJsonResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage0.json")
+ ApiGroupList listGroupsResponseDtoPage0;
+
+ @GivenTextResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage1.json")
+ String jsonListGroupsResponseDtoPage1;
+
+ @GivenJsonResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage1.json")
+ ApiGroupList listGroupsResponseDtoPage1;
+
+ @GivenTextResource("/domains/sms/v1/groups/response/ListGroupsResponseDtoPage2.json")
+ String jsonListGroupsResponseDtoPage2;
+
+ @Mock ServerConfiguration serverConfiguration;
+ @Mock HttpClient httpClient;
+ @Mock Map authManagers;
+ GroupsService service;
+
+ @BeforeEach
+ public void initMocks() {
+ service =
+ new GroupsServiceImpl(
+ httpClient,
+ serverConfiguration,
+ authManagers,
+ HttpMapper.getInstance(),
+ SERVICE_PLAN_ID);
+ }
+
+ @Test
+ void get() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/groups/"
+ + URLPathUtils.encodePathSegment(GROUP_ID),
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonGroupDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ Group response = service.get(GROUP_ID);
+
+ TestHelpers.recursiveEquals(response, groupDto);
+ }
+
+ @Test
+ void create() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/groups",
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ GroupRequest.builder().setName("foo").build()),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonGroupDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ Group response = service.create(GroupRequest.builder().setName("foo").build());
+
+ TestHelpers.recursiveEquals(response, groupDto);
+ }
+
+ @Test
+ void listDefault() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/groups",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListGroupsResponseDtoPage0.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ ListGroupsResponse response = service.list();
+ TestHelpers.recursiveEquals(response.getContent(), listGroupsResponseDtoPage0.getItems());
+ }
+
+ @Test
+ void list() throws ApiException {
+
+ List commonParameters = Arrays.asList("page_size", 2, STYLE.FORM, true);
+
+ Collection urlParameters0 =
+ PaginationFillerHelper.parametersFiller("page", 0, STYLE.FORM, true, commonParameters);
+ Collection urlParameters1 =
+ PaginationFillerHelper.parametersFiller("page", 1, STYLE.FORM, true, commonParameters);
+ Collection urlParameters2 =
+ PaginationFillerHelper.parametersFiller("page", 2, STYLE.FORM, true, commonParameters);
+
+ HttpRequest httpRequest0 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/groups",
+ HttpMethod.GET,
+ urlParameters0,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest1 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/groups",
+ HttpMethod.GET,
+ urlParameters1,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest2 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/groups",
+ HttpMethod.GET,
+ urlParameters2,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse0 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListGroupsResponseDtoPage0.getBytes());
+ HttpResponse httpResponse1 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListGroupsResponseDtoPage1.getBytes());
+ HttpResponse httpResponse2 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonListGroupsResponseDtoPage2.getBytes());
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest0))))
+ .thenReturn(httpResponse0);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest1))))
+ .thenReturn(httpResponse1);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest2))))
+ .thenReturn(httpResponse2);
+
+ ListGroupsQueryParameters initialRequest =
+ ListGroupsQueryParameters.builder().setPage(0).setPageSize(2).build();
+
+ ListGroupsResponse response = service.list(initialRequest);
+
+ Iterator iterator = response.iterator();
+
+ Group item = iterator.next();
+ TestHelpers.recursiveEquals(item, listGroupsResponseDtoPage0.getItems().get(0));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listGroupsResponseDtoPage0.getItems().get(1));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listGroupsResponseDtoPage1.getItems().get(0));
+
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(false);
+ }
+
+ @Test
+ void replace() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/groups/"
+ + URLPathUtils.encodePathSegment(GROUP_ID),
+ HttpMethod.PUT,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ GroupRequest.builder().setName("foo").build()),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonGroupDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ Group response = service.replace(GROUP_ID, GroupRequest.builder().setName("foo").build());
+
+ TestHelpers.recursiveEquals(response, groupDto);
+ }
+
+ @Test
+ void update() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/groups/"
+ + URLPathUtils.encodePathSegment(GROUP_ID),
+ HttpMethod.POST,
+ Collections.emptyList(),
+ HttpMapper.getInstance()
+ .serialize(
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ GroupUpdateRequestDtoTest.requestDTO),
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonGroupDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ Group response = service.update(GROUP_ID, GroupUpdateRequestDtoTest.requestDTO);
+
+ TestHelpers.recursiveEquals(response, groupDto);
+ }
+
+ @Test
+ void delete() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/groups/"
+ + URLPathUtils.encodePathSegment(GROUP_ID),
+ HttpMethod.DELETE,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse = new HttpResponse(200, null, Collections.emptyMap(), null);
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ service.delete(GROUP_ID);
+ }
+
+ @Test
+ void listMembers() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/groups/"
+ + URLPathUtils.encodePathSegment(GROUP_ID)
+ + "/members",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), "[\"entry 1\", \"entry 2\"]".getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ Collection members = service.listMembers(GROUP_ID);
+ TestHelpers.recursiveEquals(members, new ArrayList<>(Arrays.asList("entry 1", "entry 2")));
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceTest.java
new file mode 100644
index 000000000..053d9dcc0
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceTest.java
@@ -0,0 +1,261 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import com.adelean.inject.resources.junit.jupiter.GivenJsonResource;
+import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
+import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.BaseTest;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpContentType;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpRequestTest.HttpRequestMatcher;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.domains.PaginationFillerHelper;
+import com.sinch.sdk.domains.sms.api.v1.InboundsService;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.request.ListInboundMessagesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.ListInboundsResponse;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.internal.ApiInboundList;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+
+@TestWithResources
+public class InboundsServiceTest extends BaseTest {
+
+ static final String SMS_AUTH_NAMES = "BearerAuth";
+ static final String SERVICE_PLAN_ID = "foo value";
+ static final String BATCH_ID = "foo batchID";
+
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundTextDto.json")
+ String jsonTextMessageDto;
+
+ @GivenJsonResource("/domains/sms/v1/inbounds/InboundTextDto.json")
+ TextMessage textMessageDto;
+
+ @GivenTextResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage0.json")
+ String jsonInboundsListResponseDto0;
+
+ @GivenJsonResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage0.json")
+ ApiInboundList listInboundsListResponseDto0;
+
+ @GivenTextResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage1.json")
+ String jsonInboundsListResponseDto1;
+
+ @GivenJsonResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage1.json")
+ ApiInboundList listInboundsListResponseDto1;
+
+ @GivenTextResource("/domains/sms/v1/inbounds/response/internal/InboundsListResponseDtoPage2.json")
+ String jsonInboundsListResponseDto2;
+
+ @Mock HttpClient httpClient;
+ @Mock ServerConfiguration serverConfiguration;
+ @Mock Map authManagers;
+
+ InboundsService service;
+
+ @BeforeEach
+ public void initMocks() {
+ service =
+ new InboundsServiceImpl(
+ httpClient,
+ serverConfiguration,
+ authManagers,
+ HttpMapper.getInstance(),
+ SERVICE_PLAN_ID);
+ }
+
+ @Test
+ void get() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/"
+ + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID)
+ + "/inbounds/"
+ + URLPathUtils.encodePathSegment(BATCH_ID),
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(200, null, Collections.emptyMap(), jsonTextMessageDto.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ InboundMessage response = service.get(BATCH_ID);
+
+ TestHelpers.recursiveEquals(response, textMessageDto);
+ }
+
+ @Test
+ void listDefault() throws ApiException {
+
+ HttpRequest httpRequest =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/inbounds",
+ HttpMethod.GET,
+ Collections.emptyList(),
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonInboundsListResponseDto0.getBytes());
+
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest))))
+ .thenReturn(httpResponse);
+
+ ListInboundsResponse response = service.list();
+ TestHelpers.recursiveEquals(response.getContent(), listInboundsListResponseDto0.getItems());
+ }
+
+ @Test
+ void list() throws ApiException {
+
+ List commonParameters =
+ Arrays.asList(
+ "page_size",
+ 2,
+ STYLE.FORM,
+ true,
+ "to",
+ "+1234567890",
+ STYLE.FORM,
+ true,
+ "start_date",
+ "2023-11-03T15:21:21.113Z",
+ STYLE.FORM,
+ true,
+ "end_date",
+ "2023-12-12T15:54:21.321Z",
+ STYLE.FORM,
+ true,
+ "client_reference",
+ "client reference",
+ STYLE.FORM,
+ true);
+
+ Collection urlParameters0 =
+ PaginationFillerHelper.parametersFiller("page", 0, STYLE.FORM, true, commonParameters);
+ Collection urlParameters1 =
+ PaginationFillerHelper.parametersFiller("page", 1, STYLE.FORM, true, commonParameters);
+ Collection urlParameters2 =
+ PaginationFillerHelper.parametersFiller("page", 2, STYLE.FORM, true, commonParameters);
+
+ HttpRequest httpRequest0 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/inbounds",
+ HttpMethod.GET,
+ urlParameters0,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest1 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/inbounds",
+ HttpMethod.GET,
+ urlParameters1,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpRequest httpRequest2 =
+ new HttpRequest(
+ "/xms/v1/" + URLPathUtils.encodePathSegment(SERVICE_PLAN_ID) + "/inbounds",
+ HttpMethod.GET,
+ urlParameters2,
+ (String) null,
+ Collections.emptyMap(),
+ Collections.singletonList(HttpContentType.APPLICATION_JSON),
+ Collections.emptyList(),
+ Collections.singletonList(SMS_AUTH_NAMES));
+ HttpResponse httpResponse0 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonInboundsListResponseDto0.getBytes());
+ HttpResponse httpResponse1 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonInboundsListResponseDto1.getBytes());
+ HttpResponse httpResponse2 =
+ new HttpResponse(
+ 200, null, Collections.emptyMap(), jsonInboundsListResponseDto2.getBytes());
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest0))))
+ .thenReturn(httpResponse0);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest1))))
+ .thenReturn(httpResponse1);
+ when(httpClient.invokeAPI(
+ eq(serverConfiguration),
+ eq(authManagers),
+ argThat(new HttpRequestMatcher(httpRequest2))))
+ .thenReturn(httpResponse2);
+
+ ListInboundMessagesQueryParameters initialRequest =
+ ListInboundMessagesQueryParameters.builder()
+ .setPage(0)
+ .setPageSize(2)
+ .setTo(Arrays.asList("+1234567890"))
+ .setClientReference("client reference")
+ .setStartDate(Instant.parse("2023-11-03T15:21:21.113Z"))
+ .setEndDate(Instant.parse("2023-12-12T15:54:21.321Z"))
+ .build();
+
+ ListInboundsResponse response = service.list(initialRequest);
+
+ Iterator iterator = response.iterator();
+
+ InboundMessage item = iterator.next();
+ TestHelpers.recursiveEquals(item, listInboundsListResponseDto0.getItems().get(0));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listInboundsListResponseDto0.getItems().get(1));
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(true);
+
+ item = iterator.next();
+ TestHelpers.recursiveEquals(item, listInboundsListResponseDto1.getItems().get(0));
+
+ Assertions.assertThat(iterator.hasNext()).isEqualTo(false);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java
new file mode 100644
index 000000000..c520d8d4b
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/SMSServiceTest.java
@@ -0,0 +1,189 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.models.SmsContext;
+import com.sinch.sdk.models.SmsServicePlanCredentials;
+import com.sinch.sdk.models.UnifiedCredentials;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+
+class SMSServiceTest {
+
+ @Mock HttpClient httpClient;
+
+ @Test
+ void projectIdDoNotAcceptNullKey() {
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder().setKeyId(null).setKeySecret("foo").setProjectId("foo").build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new SMSService(credentials, context, server, httpClient));
+ assertTrue(exception.getMessage().contains("keyId"));
+ }
+
+ @Test
+ void projectIdDoNotAcceptNullKeySecret() {
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder().setKeyId("foo").setKeySecret(null).setProjectId("foo").build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new SMSService(credentials, context, server, httpClient));
+ assertTrue(exception.getMessage().contains("keySecret"));
+ }
+
+ @Test
+ void projectIdDoNotAcceptNullProject() {
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder().setKeyId("foo").setKeySecret("foo").setProjectId(null).build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new SMSService(credentials, context, server, httpClient));
+ assertTrue(exception.getMessage().contains("projectId"));
+ }
+
+ @Test
+ void projectIdDoNotAcceptNullCredentials() {
+
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+ Exception exception =
+ assertThrows(
+ NullPointerException.class, () -> new SMSService(null, context, server, httpClient));
+ assertTrue(exception.getMessage().contains("Credentials must be defined"));
+ }
+
+ @Test
+ void projectIdDoNotAcceptNullContext() {
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder()
+ .setKeyId("foo")
+ .setKeySecret("foo")
+ .setProjectId("foo")
+ .build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+ Exception exception =
+ assertThrows(
+ NullPointerException.class,
+ () -> new SMSService(credentials, null, server, httpClient));
+ assertTrue(exception.getMessage().contains("Context must be defined"));
+ }
+
+ @Test
+ void projectIdDoNotAcceptNullSmsUrl() {
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder()
+ .setKeyId("foo")
+ .setKeySecret("foo")
+ .setProjectId("foo")
+ .build();
+ SmsContext context = SmsContext.builder().setSmsUrl(null).build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new SMSService(credentials, context, server, httpClient));
+ assertTrue(exception.getMessage().contains("smsUrl"));
+ }
+
+ @Test
+ void projectIdUsagePassed() {
+
+ UnifiedCredentials credentials =
+ UnifiedCredentials.builder()
+ .setKeyId("foo key ")
+ .setKeySecret("foo secret")
+ .setProjectId("foo project")
+ .build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ ServerConfiguration server = new ServerConfiguration("https://oauth.foo.url");
+
+ assertDoesNotThrow(
+ () -> new SMSService(credentials, context, server, httpClient), "Init passed");
+ }
+
+ @Test
+ void servicePlanIdDoNotAcceptNullApiToken() {
+ SmsServicePlanCredentials credentials =
+ SmsServicePlanCredentials.builder().setApiToken(null).setServicePlanId("foo plan").build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new SMSService(credentials, context, httpClient));
+ assertTrue(exception.getMessage().contains("apiToken"));
+ }
+
+ @Test
+ void servicePlanIdDoNotAcceptNullServicePlanId() {
+ SmsServicePlanCredentials credentials =
+ SmsServicePlanCredentials.builder().setApiToken("foo token").setServicePlanId(null).build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new SMSService(credentials, context, httpClient));
+ assertTrue(exception.getMessage().contains("servicePlanId"));
+ }
+
+ @Test
+ void servicePlanIdDoNotAcceptNullCredentials() {
+
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+ Exception exception =
+ assertThrows(NullPointerException.class, () -> new SMSService(null, context, httpClient));
+ assertTrue(exception.getMessage().contains("Credentials must be defined"));
+ }
+
+ @Test
+ void servicePlanIdDoNotAcceptNullContext() {
+ SmsServicePlanCredentials credentials =
+ SmsServicePlanCredentials.builder()
+ .setApiToken("foo token")
+ .setServicePlanId("foo plan")
+ .build();
+ Exception exception =
+ assertThrows(
+ NullPointerException.class, () -> new SMSService(credentials, null, httpClient));
+ assertTrue(exception.getMessage().contains("Context must be defined"));
+ }
+
+ @Test
+ void servicePlanIdDoNotAcceptNullSmsUrl() {
+ SmsServicePlanCredentials credentials =
+ SmsServicePlanCredentials.builder()
+ .setApiToken("foo token")
+ .setServicePlanId("foo plan")
+ .build();
+ SmsContext context = SmsContext.builder().setSmsUrl(null).build();
+ Exception exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new SMSService(credentials, context, httpClient));
+ assertTrue(exception.getMessage().contains("smsUrl"));
+ }
+
+ @Test
+ void servicePlanIdUsagePassed() {
+
+ SmsServicePlanCredentials credentials =
+ SmsServicePlanCredentials.builder()
+ .setApiToken("foo token")
+ .setServicePlanId("foo plan")
+ .build();
+ SmsContext context = SmsContext.builder().setSmsUrl("https://sms.foo.url").build();
+
+ assertDoesNotThrow(() -> new SMSService(credentials, context, httpClient), "Init passed");
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/WebHooksServiceTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/WebHooksServiceTest.java
new file mode 100644
index 000000000..d9838badc
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/api/v1/adapters/WebHooksServiceTest.java
@@ -0,0 +1,147 @@
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.adelean.inject.resources.junit.jupiter.GivenTextResource;
+import com.adelean.inject.resources.junit.jupiter.TestWithResources;
+import com.sinch.sdk.BaseTest;
+import com.sinch.sdk.SinchClient;
+import com.sinch.sdk.auth.HmacAuthenticationValidation;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.domains.sms.api.v1.WebHooksService;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReportDtoTest;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReportDtoTest;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessageDtoTest;
+import com.sinch.sdk.domains.sms.models.v1.webhooks.SmsEvent;
+import com.sinch.sdk.models.Configuration;
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+@TestWithResources
+public class WebHooksServiceTest extends BaseTest {
+
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundBinaryDto.json")
+ String loadedInboundBinaryEvent;
+
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundTextDto.json")
+ String loadedInboundTextEvent;
+
+ @GivenTextResource("/domains/sms/v1/inbounds/InboundMediaDto.json")
+ String loadedInboundMediaEvent;
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportSMSDto.json")
+ String loadedBatchDeliveryReportSMSEvent;
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/BatchDeliveryReportMMSDto.json")
+ String loadedBatchDeliveryReportMMSEvent;
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportSMSDto.json")
+ String loadedRecipientDeliveryReportSMSEvent;
+
+ @GivenTextResource("/domains/sms/v1/deliveryreports/RecipientDeliveryReportMMSDto.json")
+ String loadedRecipientDeliveryReportMMSEvent;
+
+ WebHooksService service;
+
+ @BeforeEach
+ public void setUp() {
+
+ Configuration configuration =
+ Configuration.builder()
+ .setProjectId("unused")
+ .setKeyId("unused")
+ .setKeySecret("unused")
+ .build();
+ service = new SinchClient(configuration).sms().v1().webhooks();
+ }
+
+ @Test
+ void checkApplicationAuthentication() throws ApiException {
+
+ Map headers =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>(
+ HmacAuthenticationValidation.SIGNATURE_HEADER,
+ "ZoHei66PPN/kZjw7hFVfGhJOnml3iGNCMWoyQVcE5o0="),
+ new AbstractMap.SimpleEntry<>(
+ HmacAuthenticationValidation.ALGORITHM_HEADER, "HmacSHA256"),
+ new AbstractMap.SimpleEntry<>(
+ HmacAuthenticationValidation.NONCE_HEADER, "01JHFFHWYY7HSS4FWTMDTQEK8V"),
+ new AbstractMap.SimpleEntry<>(
+ HmacAuthenticationValidation.TIMESTAMP_HEADER, "1736760161"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ boolean authenticationResult =
+ service.validateAuthenticationHeader(
+ "SMSWebhooksSecret",
+ headers,
+ "{\"at\":\"2025-01-13T09:22:40.914Z\",\"batch_id\":\"01JHFFHQ0P99JPPNQPJDV7JTBP\",\"client_reference\":\"a"
+ + " client"
+ + " reference\",\"code\":0,\"operator_status_at\":\"2025-01-13T09:22:00Z\",\"recipient\":\"33662162466\",\"status\":\"Delivered\",\"type\":\"recipient_delivery_report_sms\"}");
+
+ assertTrue(authenticationResult);
+ }
+
+ @Test
+ void incomingSMSBinary() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedInboundBinaryEvent);
+
+ TestHelpers.recursiveEquals(InboundMessageDtoTest.binaryDTO, response);
+ }
+
+ @Test
+ void incomingSMSText() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedInboundTextEvent);
+
+ TestHelpers.recursiveEquals(InboundMessageDtoTest.textDTO, response);
+ }
+
+ @Test
+ void incomingSMSMedia() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedInboundMediaEvent);
+
+ TestHelpers.recursiveEquals(InboundMessageDtoTest.mediaDTO, response);
+ }
+
+ @Test
+ void deliveryReportRecipientDeliveryReportSms() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedRecipientDeliveryReportSMSEvent);
+
+ TestHelpers.recursiveEquals(
+ RecipientDeliveryReportDtoTest.deliveryReportRecipientSMS, response);
+ }
+
+ @Test
+ void deliveryReportRecipientDeliveryReportMms() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedRecipientDeliveryReportMMSEvent);
+
+ TestHelpers.recursiveEquals(
+ RecipientDeliveryReportDtoTest.deliveryReportRecipientMMS, response);
+ }
+
+ @Test
+ void deliveryReportBatchDeliveryReportSms() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedBatchDeliveryReportSMSEvent);
+
+ TestHelpers.recursiveEquals(BatchDeliveryReportDtoTest.deliveryReportBatchSMS, response);
+ }
+
+ @Test
+ void deliveryReportBatchDeliveryReportMms() throws ApiException {
+
+ SmsEvent response = service.parseEvent(loadedBatchDeliveryReportMMSEvent);
+
+ TestHelpers.recursiveEquals(BatchDeliveryReportDtoTest.deliveryReportBatchMMS, response);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/domains/sms/models/v1/internal/SMSCursorPageNavigatorTest.java b/client/src/test/java/com/sinch/sdk/domains/sms/models/v1/internal/SMSCursorPageNavigatorTest.java
new file mode 100644
index 000000000..521cd1453
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/domains/sms/models/v1/internal/SMSCursorPageNavigatorTest.java
@@ -0,0 +1,25 @@
+package com.sinch.sdk.domains.sms.models.v1.internal;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class SMSCursorPageNavigatorTest {
+
+ @Test
+ void getTokenNullPageSize() {
+ SMSCursorPageNavigator cursorNavigator = new SMSCursorPageNavigator(45, null);
+ Assertions.assertThat(cursorNavigator.getToken()).isEqualTo(null);
+ }
+
+ @Test
+ void getTokenZeroPageSize() {
+ SMSCursorPageNavigator cursorNavigator = new SMSCursorPageNavigator(45, 0);
+ Assertions.assertThat(cursorNavigator.getToken()).isEqualTo(null);
+ }
+
+ @Test
+ void getToken() {
+ SMSCursorPageNavigator cursorNavigator = new SMSCursorPageNavigator(0, 15);
+ Assertions.assertThat(cursorNavigator.getToken()).isEqualTo(1);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/Config.java b/client/src/test/java/com/sinch/sdk/e2e/Config.java
index e0eec03ab..515741888 100644
--- a/client/src/test/java/com/sinch/sdk/e2e/Config.java
+++ b/client/src/test/java/com/sinch/sdk/e2e/Config.java
@@ -5,6 +5,7 @@
import com.sinch.sdk.models.ConversationContext;
import com.sinch.sdk.models.ConversationRegion;
import com.sinch.sdk.models.MailgunContext;
+import com.sinch.sdk.models.SmsContext;
import com.sinch.sdk.models.VoiceContext;
import java.util.Arrays;
@@ -27,6 +28,8 @@ public class Config {
public static final String MAILGUN_API_KEY = "apiKey";
public static final String MAILGUN_STORAGE = "http://localhost:3021";
+ public static final String SMS_HOST_NAME = "http://localhost:3017";
+
private final SinchClient client;
private Config() {
@@ -54,6 +57,7 @@ private Config() {
MailgunContext.builder().setStorageUrls(Arrays.asList(MAILGUN_STORAGE)).build())
.setMailgunApiKey(MAILGUN_API_KEY)
.setMailgunUrl(MAILGUN_HOST_NAME)
+ .setSmsContext(SmsContext.builder().setSmsUrl(SMS_HOST_NAME).build())
.build();
client = new SinchClient(configuration);
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/BatchesSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/BatchesSteps.java
new file mode 100644
index 000000000..ca7d7053b
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/BatchesSteps.java
@@ -0,0 +1,367 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.utils.Pair;
+import com.sinch.sdk.domains.sms.BatchesService;
+import com.sinch.sdk.domains.sms.models.BatchText;
+import com.sinch.sdk.domains.sms.models.DeliveryReportType;
+import com.sinch.sdk.domains.sms.models.DryRun;
+import com.sinch.sdk.domains.sms.models.DryRunPerRecipientDetails;
+import com.sinch.sdk.domains.sms.models.Parameters;
+import com.sinch.sdk.domains.sms.models.requests.BatchesListRequestParameters;
+import com.sinch.sdk.domains.sms.models.requests.SendSmsBatchTextRequest;
+import com.sinch.sdk.domains.sms.models.requests.UpdateSmsBatchTextRequest;
+import com.sinch.sdk.domains.sms.models.responses.BatchesListResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class BatchesSteps {
+
+ BatchesService service;
+
+ BatchText sendTextResponse;
+ BatchText sendTextWithParametersResponse;
+ DryRun dryRunResponse;
+ BatchesListResponse listOnePageResponse;
+ BatchesListResponse listAllResponse;
+ BatchesListResponse listAllByPageResponse;
+ BatchText getBatchResponse;
+ BatchText updateResponse;
+ BatchText replaceResponse;
+ BatchText cancelResponse;
+ Boolean sendDeliveryFeedbackPassed;
+
+ @Given("^the SMS service \"Batches\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().batches();
+ }
+
+ @When("^I send a request to send a text message$")
+ public void send() {
+ SendSmsBatchTextRequest request =
+ SendSmsBatchTextRequest.builder()
+ .setBody("SMS body message")
+ .setTo(Collections.singletonList("+12017777777"))
+ .setFrom("+12015555555")
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setFeedbackEnabled(true)
+ .build();
+
+ sendTextResponse = service.send(request);
+ }
+
+ @When("^I send a request to send a text message with multiple parameters$")
+ public void sendWithParameters() {
+ SendSmsBatchTextRequest request =
+ SendSmsBatchTextRequest.builder()
+ .setBody("Hello ${name}! Get 20% off with this discount code ${code}")
+ .setTo(Arrays.asList("+12017777777", "+12018888888"))
+ .setFrom("+12015555555")
+ .setParameters(
+ new Parameters(
+ Arrays.asList(
+ new Parameters.Entry("name", new Pair<>("+12017777777", "John"), "there"),
+ new Parameters.Entry("name", new Pair<>("+12018888888", "Paul")),
+ new Parameters.Entry(
+ "code", new Pair<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83")))))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .build();
+
+ sendTextWithParametersResponse = service.send(request);
+ }
+
+ @When("^I send a request to perform a dry run of a batch$")
+ public void dryRun() {
+ SendSmsBatchTextRequest request =
+ SendSmsBatchTextRequest.builder()
+ .setBody("Hello ${name}!")
+ .setTo(Arrays.asList("+12017777777", "+12018888888", "+12019999999"))
+ .setFrom("+12015555555")
+ .setParameters(
+ new Parameters(
+ Arrays.asList(
+ new Parameters.Entry("name", new Pair<>("+12017777777", "John"), "there"))))
+ .setDeliveryReport(DeliveryReportType.NONE)
+ .build();
+
+ dryRunResponse = service.dryRun(true, 3, request);
+ }
+
+ @When("^I send a request to list the SMS batches$")
+ public void listOnePage() {
+ BatchesListRequestParameters request =
+ BatchesListRequestParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS batches$")
+ public void listAll() {
+ BatchesListRequestParameters request =
+ BatchesListRequestParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS batches pages$")
+ public void listAllByPage() {
+ BatchesListRequestParameters request =
+ BatchesListRequestParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @When("^I send a request to retrieve an SMS batch$")
+ public void get() {
+
+ getBatchResponse = service.get("foo");
+ }
+
+ @When("^I send a request to update an SMS batch$")
+ public void update() {
+
+ UpdateSmsBatchTextRequest request =
+ UpdateSmsBatchTextRequest.builder()
+ .setFrom("+12016666666")
+ .setToAdd(Collections.singletonList("01W4FFL35P4NC4K35SMSGROUP1"))
+ .setDeliveryReport(DeliveryReportType.SUMMARY)
+ .build();
+ updateResponse = service.update("foo", request);
+ }
+
+ @When("^I send a request to replace an SMS batch$")
+ public void replace() {
+
+ SendSmsBatchTextRequest request =
+ SendSmsBatchTextRequest.builder()
+ .setFrom("+12016666666")
+ .setTo(Collections.singletonList("+12018888888"))
+ .setBody("This is the replacement batch")
+ .setSendAt(Instant.parse("2024-06-06T09:35:00Z"))
+ .build();
+ replaceResponse = service.replace("foo", request);
+ }
+
+ @When("^I send a request to cancel an SMS batch$")
+ public void cancel() {
+
+ cancelResponse = service.cancel("foo");
+ }
+
+ @When("^I send a request to send delivery feedbacks$")
+ public void sendDeliveryFeedback() {
+
+ service.sendDeliveryFeedback("foo", Arrays.asList("+12017777777"));
+ sendDeliveryFeedbackPassed = true;
+ }
+
+ @Then("the response contains the text SMS details")
+ public void sendResult() {
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Collections.singletonList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(sendTextResponse, expected);
+ }
+
+ @Then("the response contains the text SMS details with multiple parameters")
+ public void sendWithParametersResult() {
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH2")
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setParameters(
+ new Parameters(
+ Arrays.asList(
+ new Parameters.Entry("name", new Pair<>("+12017777777", "John"), "there"),
+ new Parameters.Entry("name", new Pair<>("+12018888888", "Paul")),
+ new Parameters.Entry(
+ "code", new Pair<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83")))))
+ .setBody("Hello ${name}! Get 20% off with this discount code ${code}")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setExpireAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(sendTextWithParametersResponse, expected);
+ }
+
+ @Then(
+ "the response contains the calculated bodies and number of parts for all messages in the"
+ + " batch")
+ public void dryRunResult() {
+ DryRun expected =
+ DryRun.builder()
+ .setNumberOfRecipients(3)
+ .setNumberOfMessages(3)
+ .setPerRecipient(
+ Arrays.asList(
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12017777777")
+ .setNumberOfParts(1)
+ .setBody("Hello John!")
+ .setEncoding("text")
+ .build(),
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12019999999")
+ .setNumberOfParts(1)
+ .setBody("Hello there!")
+ .setEncoding("text")
+ .build(),
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12018888888")
+ .setNumberOfParts(1)
+ .setBody("Hello there!")
+ .setEncoding("text")
+ .build()))
+ .build();
+
+ TestHelpers.recursiveEquals(dryRunResponse, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS batches")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS batches list contains \"{int}\" SMS batches")
+ public void listAllResult(int expected) {
+
+ BatchesListResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS batches iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+
+ @Then("the response contains the SMS batch details")
+ public void getResult() {
+
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Collections.singletonList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(getBatchResponse, expected);
+ }
+
+ @Then("the response contains the SMS batch details with updated data")
+ public void updateResult() {
+
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12017777777", "01W4FFL35P4NC4K35SMSGROUP1"))
+ .setFrom("12016666666")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:48.054Z"))
+ .setDeliveryReport(DeliveryReportType.SUMMARY)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(updateResponse, expected);
+ }
+
+ @Then("the response contains the new SMS batch details with the provided data for replacement")
+ public void replaceResult() {
+
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12018888888"))
+ .setFrom("12016666666")
+ .setCanceled(false)
+ .setBody("This is the replacement batch")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:23:32.504Z"))
+ .setDeliveryReport(DeliveryReportType.NONE)
+ .setSendAt(Instant.parse("2024-06-06T09:35:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:35:00Z"))
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(replaceResponse, expected);
+ }
+
+ @Then("the response contains the SMS batch details with a cancelled status")
+ public void cancelResult() {
+
+ BatchText expected =
+ BatchText.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(true)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:29.978Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(cancelResponse, expected);
+ }
+
+ @Then("the delivery feedback response contains no data")
+ public void setSendDeliveryFeedbackResult() {
+ Assertions.assertTrue(sendDeliveryFeedbackPassed);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/DeliveryReportsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/DeliveryReportsSteps.java
new file mode 100644
index 000000000..74ec37136
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/DeliveryReportsSteps.java
@@ -0,0 +1,184 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.DeliveryReportsService;
+import com.sinch.sdk.domains.sms.models.DeliveryReportBatch;
+import com.sinch.sdk.domains.sms.models.DeliveryReportBatchSMS;
+import com.sinch.sdk.domains.sms.models.DeliveryReportErrorCode;
+import com.sinch.sdk.domains.sms.models.DeliveryReportRecipient;
+import com.sinch.sdk.domains.sms.models.DeliveryReportRecipientSMS;
+import com.sinch.sdk.domains.sms.models.DeliveryReportStatus;
+import com.sinch.sdk.domains.sms.models.DeliveryReportStatusDetails;
+import com.sinch.sdk.domains.sms.models.DeliveryReportType;
+import com.sinch.sdk.domains.sms.models.requests.DeliveryReportBatchGetRequestParameters;
+import com.sinch.sdk.domains.sms.models.requests.DeliveryReportListRequestParameters;
+import com.sinch.sdk.domains.sms.models.responses.DeliveryReportsListResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class DeliveryReportsSteps {
+
+ DeliveryReportsService service;
+
+ DeliveryReportBatch summaryReport;
+ DeliveryReportBatch fullReport;
+ DeliveryReportRecipient recipientReport;
+ DeliveryReportsListResponse listOnePageResponse;
+ DeliveryReportsListResponse listAllResponse;
+ DeliveryReportsListResponse listAllByPageResponse;
+
+ @Given("^the SMS service \"Delivery Reports\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().deliveryReports();
+ }
+
+ @When("^I send a request to retrieve a summary SMS delivery report$")
+ public void getSummary() {
+ DeliveryReportBatchGetRequestParameters request =
+ DeliveryReportBatchGetRequestParameters.builder()
+ .setType(DeliveryReportType.SUMMARY)
+ .setStatuses(Arrays.asList(DeliveryReportStatus.DELIVERED, DeliveryReportStatus.FAILED))
+ .setCodes(Arrays.asList(15, 0))
+ .build();
+
+ summaryReport = service.get("foo", request);
+ }
+
+ @When("^I send a request to retrieve a full SMS delivery report$")
+ public void getFull() {
+ DeliveryReportBatchGetRequestParameters request =
+ DeliveryReportBatchGetRequestParameters.builder().setType(DeliveryReportType.FULL).build();
+
+ fullReport = service.get("foo", request);
+ }
+
+ @When("^I send a request to retrieve a recipient's delivery report$")
+ public void getRecipient() {
+
+ recipientReport = service.getForNumber("foo", "+12345678");
+ }
+
+ @When("^I send a request to list the SMS delivery reports$")
+ public void listOnePage() {
+ DeliveryReportListRequestParameters request =
+ DeliveryReportListRequestParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS delivery reports$")
+ public void listAll() {
+ DeliveryReportListRequestParameters request =
+ DeliveryReportListRequestParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS delivery reports pages$")
+ public void listAllByPage() {
+ DeliveryReportListRequestParameters request =
+ DeliveryReportListRequestParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @Then("the response contains a summary SMS delivery report")
+ public void getSummaryResult() {
+ DeliveryReportBatch expected =
+ DeliveryReportBatchSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setStatuses(
+ Arrays.asList(
+ DeliveryReportStatusDetails.builder()
+ .setCode(15)
+ .setCount(1)
+ .setStatus(DeliveryReportStatus.FAILED)
+ .build(),
+ DeliveryReportStatusDetails.builder()
+ .setCode(0)
+ .setCount(1)
+ .setStatus(DeliveryReportStatus.DELIVERED)
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+ TestHelpers.recursiveEquals(summaryReport, expected);
+ }
+
+ @Then("the response contains a full SMS delivery report")
+ public void getFullResult() {
+ DeliveryReportBatch expected =
+ DeliveryReportBatchSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setStatuses(
+ Arrays.asList(
+ DeliveryReportStatusDetails.builder()
+ .setCode(0)
+ .setCount(1)
+ .setStatus(DeliveryReportStatus.DELIVERED)
+ .setRecipients(Collections.singletonList("12017777777"))
+ .build(),
+ DeliveryReportStatusDetails.builder()
+ .setCode(15)
+ .setCount(1)
+ .setStatus(DeliveryReportStatus.FAILED)
+ .setRecipients(Collections.singletonList("12018888888"))
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+ TestHelpers.recursiveEquals(fullReport, expected);
+ }
+
+ @Then("the response contains the recipient's delivery report details")
+ public void getRecipientResult() {
+ DeliveryReportRecipient expected =
+ DeliveryReportRecipientSMS.builder()
+ .setAt(Instant.parse("2024-06-06T13:06:27.833Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setCode(DeliveryReportErrorCode.from(0))
+ .setOperatorStatusAt(Instant.parse("2024-06-06T13:06:00Z"))
+ .setRecipient("12017777777")
+ .setStatus(DeliveryReportStatus.DELIVERED)
+ .build();
+
+ TestHelpers.recursiveEquals(recipientReport, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS delivery reports")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS delivery reports list contains \"{int}\" SMS delivery reports")
+ public void listAllResult(int expected) {
+ DeliveryReportsListResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS delivery reports iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/GroupsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/GroupsSteps.java
new file mode 100644
index 000000000..41edc12d1
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/GroupsSteps.java
@@ -0,0 +1,227 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.GroupsService;
+import com.sinch.sdk.domains.sms.models.Group;
+import com.sinch.sdk.domains.sms.models.requests.GroupCreateRequestParameters;
+import com.sinch.sdk.domains.sms.models.requests.GroupReplaceRequestParameters;
+import com.sinch.sdk.domains.sms.models.requests.GroupUpdateRequestParameters;
+import com.sinch.sdk.domains.sms.models.requests.GroupsListRequestParameters;
+import com.sinch.sdk.domains.sms.models.responses.GroupsListResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class GroupsSteps {
+
+ GroupsService service;
+ Group createResponse;
+ Group getResponse;
+ GroupsListResponse listOnePageResponse;
+ GroupsListResponse listAllResponse;
+ GroupsListResponse listAllByPageResponse;
+ Group updateResponse;
+ Group updateRemoveNameResponse;
+ Group replaceResponse;
+ Boolean deletePassed;
+ Collection lisMembersResponse;
+
+ @Given("^the SMS service \"Groups\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().groups();
+ }
+
+ @When("^I send a request to create an SMS group$")
+ public void create() {
+ GroupCreateRequestParameters request =
+ GroupCreateRequestParameters.builder()
+ .setName("Group master")
+ .setMembers(Arrays.asList("+12017778888", "+12018887777"))
+ .setChildGroupIds(Collections.singletonList("01W4FFL35P4NC4K35SUBGROUP1"))
+ .build();
+
+ createResponse = service.create(request);
+ }
+
+ @When("^I send a request to retrieve an SMS group$")
+ public void get() {
+
+ getResponse = service.get("01W4FFL35P4NC4K35SMSGROUP1");
+ }
+
+ @When("^I send a request to list the existing SMS groups$")
+ public void listOnePage() {
+ GroupsListRequestParameters request =
+ GroupsListRequestParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS groups$")
+ public void listAll() {
+ GroupsListRequestParameters request =
+ GroupsListRequestParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS groups pages$")
+ public void listAllByPage() {
+ GroupsListRequestParameters request =
+ GroupsListRequestParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @When("^I send a request to update an SMS group$")
+ public void update() {
+
+ GroupUpdateRequestParameters parameters =
+ GroupUpdateRequestParameters.builder()
+ .setName("Updated group name")
+ .setAdd(Arrays.asList("+12017771111", "+12017772222"))
+ .setRemove(Arrays.asList("+12017773333", "+12017774444"))
+ .setAddFromGroup("01W4FFL35P4NC4K35SMSGROUP2")
+ .setRemoveFromGroup("01W4FFL35P4NC4K35SMSGROUP3")
+ .build();
+ updateResponse = service.update("groupid", parameters);
+ }
+
+ @When("^I send a request to update an SMS group to remove its name$")
+ public void updateRemoveName() {
+
+ GroupUpdateRequestParameters parameters =
+ GroupUpdateRequestParameters.builder().setName(null).build();
+ updateRemoveNameResponse = service.update("groupid", parameters);
+ }
+
+ @When("^I send a request to replace an SMS group$")
+ public void replace() {
+
+ GroupReplaceRequestParameters parameters =
+ GroupReplaceRequestParameters.builder()
+ .setName("Replacement group")
+ .setMembers(Arrays.asList("+12018881111", "+12018882222", "+12018883333"))
+ .build();
+ replaceResponse = service.replace("groupid", parameters);
+ }
+
+ @When("^I send a request to delete an SMS group$")
+ public void delete() {
+
+ service.delete("groupid");
+ deletePassed = true;
+ }
+
+ @When("^I send a request to list the members of an SMS group$")
+ public void listMembers() {
+
+ lisMembersResponse = service.listMembers("groupid");
+ }
+
+ @Then("the response contains the SMS group details")
+ public void createOrGetResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Group master")
+ .setSize(2)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setChildGroupIds(Collections.singletonList("01W4FFL35P4NC4K35SUBGROUP1"))
+ .build();
+
+ Group current = null != createResponse ? createResponse : getResponse;
+
+ TestHelpers.recursiveEquals(current, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS groups")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS groups list contains \"{int}\" SMS groups")
+ public void listAllResult(int expected) {
+ GroupsListResponse response = null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS groups iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+
+ @Then("the response contains the updated SMS group details")
+ public void updateResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Updated group name")
+ .setSize(6)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:19:58.147Z"))
+ .setChildGroupIds(Arrays.asList("01W4FFL35P4NC4K35SUBGROUP1"))
+ .build();
+ TestHelpers.recursiveEquals(updateResponse, expected);
+ }
+
+ @Then("the response contains the updated SMS group details where the name has been removed")
+ public void updateRemoveNameResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP2")
+ .setSize(5)
+ .setCreatedAt(Instant.parse("2024-06-06T12:45:18.761Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T13:12:05.137Z"))
+ .setChildGroupIds(Collections.emptyList())
+ .build();
+ TestHelpers.recursiveEquals(updateRemoveNameResponse, expected);
+ }
+
+ @Then("the response contains the replaced SMS group details")
+ public void replaceResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Replacement group")
+ .setSize(3)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-08-21T09:39:36.679Z"))
+ .setChildGroupIds(Collections.singletonList("01W4FFL35P4NC4K35SUBGROUP1"))
+ .build();
+ TestHelpers.recursiveEquals(replaceResponse, expected);
+ }
+
+ @Then("the delete SMS group response contains no data")
+ public void deleteResult() {
+ Assertions.assertTrue(deletePassed);
+ }
+
+ @Then("the response contains the phone numbers of the SMS group")
+ public void lisMembersResult() {
+ Collection expected =
+ new ArrayList<>(Arrays.asList("12018881111", "12018882222", "12018883333"));
+ TestHelpers.recursiveEquals(lisMembersResponse, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/InboundsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/InboundsSteps.java
new file mode 100644
index 000000000..85f323bbe
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/InboundsSteps.java
@@ -0,0 +1,112 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.InboundsService;
+import com.sinch.sdk.domains.sms.models.InboundText;
+import com.sinch.sdk.domains.sms.models.requests.InboundsListRequestParameters;
+import com.sinch.sdk.domains.sms.models.responses.InboundsListResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class InboundsSteps {
+
+ InboundsService service;
+ InboundText getResponse;
+ InboundsListResponse listOnePageResponse;
+ InboundsListResponse listAllResponse;
+ InboundsListResponse listAllByPageResponse;
+
+ @Given("^the SMS service \"Inbounds\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().inbounds();
+ }
+
+ @When("^I send a request to retrieve an inbound message")
+ public void get() {
+
+ getResponse = (InboundText) service.get("inboundid");
+ }
+
+ @When("^I send a request to list the inbound messages$")
+ public void listOnePage() {
+ InboundsListRequestParameters request =
+ InboundsListRequestParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the inbound messages$")
+ public void listAll() {
+ InboundsListRequestParameters request =
+ InboundsListRequestParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the inbound messages pages$")
+ public void listAllByPage() {
+ InboundsListRequestParameters request =
+ InboundsListRequestParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @Then("the response contains the inbound message details")
+ public void getResult() {
+ InboundText expected =
+ InboundText.builder()
+ .setBody("Hello John!")
+ .setFrom("12015555555")
+ .setId("01W4FFL35P4NC4K35INBOUND01")
+ .setOperatorId("311071")
+ .setReceivedAt(Instant.parse("2024-06-06T14:16:54.777Z"))
+ .setTo("12017777777")
+ .build();
+
+ TestHelpers.recursiveEquals(getResponse, expected);
+ }
+
+ @Then("the response contains \"{int}\" inbound messages")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the inbound messages list contains \"{int}\" inbound messages")
+ public void listAllResult(int expected) {
+ InboundsListResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the inbound messages iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/SmsIT.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/SmsIT.java
new file mode 100644
index 000000000..0361145fe
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/SmsIT.java
@@ -0,0 +1,16 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
+
+import org.junit.platform.suite.api.ConfigurationParameter;
+import org.junit.platform.suite.api.IncludeEngines;
+import org.junit.platform.suite.api.SelectClasspathResource;
+import org.junit.platform.suite.api.Suite;
+import org.junit.platform.suite.api.SuiteDisplayName;
+
+@Suite
+@SuiteDisplayName("SMS V0")
+@IncludeEngines("cucumber")
+@SelectClasspathResource("features/sms")
+@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.sinch.sdk.e2e.domains.sms.v0")
+public class SmsIT {}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/WebhooksSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/WebhooksSteps.java
new file mode 100644
index 000000000..390644936
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v0/WebhooksSteps.java
@@ -0,0 +1,151 @@
+package com.sinch.sdk.e2e.domains.sms.v0;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.WebHooksService;
+import com.sinch.sdk.domains.sms.models.DeliveryReportBatchSMS;
+import com.sinch.sdk.domains.sms.models.DeliveryReportErrorCode;
+import com.sinch.sdk.domains.sms.models.DeliveryReportRecipient;
+import com.sinch.sdk.domains.sms.models.DeliveryReportRecipientSMS;
+import com.sinch.sdk.domains.sms.models.DeliveryReportStatus;
+import com.sinch.sdk.domains.sms.models.DeliveryReportStatusDetails;
+import com.sinch.sdk.domains.sms.models.InboundText;
+import com.sinch.sdk.domains.sms.models.webhooks.WebhooksEvent;
+import com.sinch.sdk.e2e.Config;
+import com.sinch.sdk.e2e.domains.WebhooksHelper;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.io.IOException;
+import java.net.URL;
+import java.time.Instant;
+import java.util.Arrays;
+
+public class WebhooksSteps {
+
+ static final String WEBHOOKS_PATH_PREFIX = "/webhooks/sms";
+ static final String WEBHOOKS_URL = Config.SMS_HOST_NAME + WEBHOOKS_PATH_PREFIX;
+
+ WebHooksService service;
+ WebhooksHelper.Response incoming;
+ WebhooksHelper.Response deliveryReport;
+ WebhooksHelper.Response deliveryReportRecipientDelivered;
+ WebhooksHelper.Response deliveryReportRecipientAborted;
+
+ @Given("^the SMS Webhooks handler is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().webHooks();
+ }
+
+ @When("^I send a request to trigger an \"incoming SMS\" event")
+ public void incoming() throws IOException {
+
+ incoming = WebhooksHelper.callURL(new URL(WEBHOOKS_URL + "/incoming-sms"), service::parse);
+ }
+
+ @When("^I send a request to trigger an \"SMS delivery report\" event")
+ public void deliveryReport() throws IOException {
+
+ deliveryReport =
+ WebhooksHelper.callURL(new URL(WEBHOOKS_URL + "/delivery-report-sms"), service::parse);
+ }
+
+ @When(
+ "^I send a request to trigger an \"SMS recipient delivery report\" event with the status"
+ + " \"Delivered\"")
+ public void deliveryReportRecipientDelivered() throws IOException {
+
+ deliveryReportRecipientDelivered =
+ WebhooksHelper.callURL(
+ new URL(WEBHOOKS_URL + "/recipient-delivery-report-sms-delivered"), service::parse);
+ }
+
+ @When(
+ "^I send a request to trigger an \"SMS recipient delivery report\" event with the status"
+ + " \"Aborted\"")
+ public void deliveryReportRecipientAborted() throws IOException {
+
+ deliveryReportRecipientAborted =
+ WebhooksHelper.callURL(
+ new URL(WEBHOOKS_URL + "/recipient-delivery-report-sms-aborted"), service::parse);
+ }
+
+ @Then("the SMS event describes an \"incoming SMS\" event")
+ public void incomingResult() {
+ InboundText expected =
+ InboundText.builder()
+ .setBody("Hello John! 👋")
+ .setFrom("12015555555")
+ .setId("01W4FFL35P4NC4K35SMSBATCH8")
+ .setOperatorId("311071")
+ .setReceivedAt(Instant.parse("2024-06-06T07:52:37.386Z"))
+ .setTo("12017777777")
+ .build();
+
+ TestHelpers.recursiveEquals(incoming.event, expected);
+ }
+
+ @Then("the SMS event describes an \"SMS delivery report\" event")
+ public void deliveryReportResult() {
+ DeliveryReportBatchSMS expected =
+ DeliveryReportBatchSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH8")
+ .setClientReference("client-ref")
+ .setStatuses(
+ Arrays.asList(
+ DeliveryReportStatusDetails.builder()
+ .setCode(0)
+ .setCount(2)
+ .setRecipients(Arrays.asList("12017777777", "33612345678"))
+ .setStatus(DeliveryReportStatus.DELIVERED)
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReport.event, expected);
+ }
+
+ @Then(
+ "the SMS event describes an SMS recipient delivery report event with the status"
+ + " \"Delivered\"")
+ public void deliveryReportRecipientDeliveredResult() {
+ DeliveryReportRecipient expected =
+ DeliveryReportRecipientSMS.builder()
+ .setAt(Instant.parse("2024-06-06T08:17:19.210Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH9")
+ .setClientReference("client-ref")
+ .setCode(DeliveryReportErrorCode.from(0))
+ .setOperatorStatusAt(Instant.parse("2024-06-06T08:17:00Z"))
+ .setRecipient("12017777777")
+ .setStatus(DeliveryReportStatus.DELIVERED)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReportRecipientDelivered.event, expected);
+ }
+
+ @Then(
+ "the SMS event describes an SMS recipient delivery report event with the status \"Aborted\"")
+ public void deliveryReportRecipientAbortedResult() {
+ DeliveryReportRecipient expected =
+ DeliveryReportRecipientSMS.builder()
+ .setAt(Instant.parse("2024-06-06T08:17:15.603Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH9")
+ .setClientReference("client-ref")
+ .setCode(DeliveryReportErrorCode.UNPROVISIONED_REGION)
+ .setRecipient("12010000000")
+ .setStatus(DeliveryReportStatus.ABORTED)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReportRecipientAborted.event, expected);
+ }
+
+ @Then("the header of the event {string} contains a valid signature")
+ public void validateHeader(String _unused) {
+ // dummy empty validation: V0 do not support authentication
+ }
+
+ @Then("the header of the event {string} with the status {string} contains a valid signature")
+ public void validateHeader(String _unused, String status) {
+ // dummy empty validation: V0 do not support authentication
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java
new file mode 100644
index 000000000..a73724315
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/BatchesSteps.java
@@ -0,0 +1,410 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.api.v1.BatchesService;
+import com.sinch.sdk.domains.sms.models.v1.batches.DeliveryReportType;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.DryRunQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.ListBatchesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateTextRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunPerRecipientDetails;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.TextResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.Assertions;
+
+public class BatchesSteps {
+
+ BatchesService service;
+
+ BatchResponse sendTextResponse;
+ BatchResponse sendTextWithParametersResponse;
+ DryRunResponse dryRunResponse;
+ ListBatchesResponse listOnePageResponse;
+ ListBatchesResponse listAllResponse;
+ ListBatchesResponse listAllByPageResponse;
+ BatchResponse getBatchResponse;
+ BatchResponse updateResponse;
+ BatchResponse replaceResponse;
+ BatchResponse cancelResponse;
+ Boolean sendDeliveryFeedbackPassed;
+
+ @Given("^the SMS service \"Batches\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().v1().batches();
+ }
+
+ @When("^I send a request to send a text message$")
+ public void send() {
+ TextRequest request =
+ TextRequest.builder()
+ .setBody("SMS body message")
+ .setTo(Collections.singletonList("+12017777777"))
+ .setFrom("+12015555555")
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setFeedbackEnabled(true)
+ .build();
+
+ sendTextResponse = service.send(request);
+ }
+
+ @When("^I send a request to send a text message with multiple parameters$")
+ public void sendWithParameters() {
+
+ Map nameParameters =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>("+12017777777", "John"),
+ new AbstractMap.SimpleEntry<>("+12018888888", "Paul"),
+ new AbstractMap.SimpleEntry<>("default", "there"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Map codeParameters =
+ Stream.of(new AbstractMap.SimpleEntry<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Map> parameters =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>("name", nameParameters),
+ new AbstractMap.SimpleEntry<>("code", codeParameters))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ TextRequest request =
+ TextRequest.builder()
+ .setBody("Hello ${name}! Get 20% off with this discount code ${code}")
+ .setTo(Arrays.asList("+12017777777", "+12018888888"))
+ .setFrom("+12015555555")
+ .setParameters(parameters)
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .build();
+
+ sendTextWithParametersResponse = service.send(request);
+ }
+
+ @When("^I send a request to perform a dry run of a batch$")
+ public void dryRun() {
+
+ Map nameParameters =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>("+12017777777", "John"),
+ new AbstractMap.SimpleEntry<>("default", "there"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Map> parameters =
+ Stream.of(new AbstractMap.SimpleEntry<>("name", nameParameters))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ TextRequest request =
+ TextRequest.builder()
+ .setBody("Hello ${name}!")
+ .setTo(Arrays.asList("+12017777777", "+12018888888", "+12019999999"))
+ .setFrom("+12015555555")
+ .setParameters(parameters)
+ .setDeliveryReport(DeliveryReportType.NONE)
+ .build();
+
+ DryRunQueryParameters queryParameters =
+ DryRunQueryParameters.builder().setPerRecipient(true).setNumberOfRecipients(3).build();
+ dryRunResponse = service.dryRun(queryParameters, request);
+ }
+
+ @When("^I send a request to list the SMS batches$")
+ public void listOnePage() {
+ ListBatchesQueryParameters request =
+ ListBatchesQueryParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS batches$")
+ public void listAll() {
+ ListBatchesQueryParameters request =
+ ListBatchesQueryParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS batches pages$")
+ public void listAllByPage() {
+ ListBatchesQueryParameters request =
+ ListBatchesQueryParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @When("^I send a request to retrieve an SMS batch$")
+ public void get() {
+
+ getBatchResponse = service.get("foo");
+ }
+
+ @When("^I send a request to update an SMS batch$")
+ public void update() {
+
+ UpdateTextRequest request =
+ UpdateTextRequest.builder()
+ .setFrom("+12016666666")
+ .setToAdd(Collections.singletonList("01W4FFL35P4NC4K35SMSGROUP1"))
+ .setDeliveryReport(DeliveryReportType.SUMMARY)
+ .build();
+ updateResponse = service.update("foo", request);
+ }
+
+ @When("^I send a request to replace an SMS batch$")
+ public void replace() {
+
+ TextRequest request =
+ TextRequest.builder()
+ .setFrom("+12016666666")
+ .setTo(Collections.singletonList("+12018888888"))
+ .setBody("This is the replacement batch")
+ .setSendAt(Instant.parse("2024-06-06T09:35:00Z"))
+ .build();
+ replaceResponse = service.replace("foo", request);
+ }
+
+ @When("^I send a request to cancel an SMS batch$")
+ public void cancel() {
+
+ cancelResponse = service.cancel("foo");
+ }
+
+ @When("^I send a request to send delivery feedbacks$")
+ public void sendDeliveryFeedback() {
+
+ SendDeliveryFeedbackRequest request =
+ SendDeliveryFeedbackRequest.builder()
+ .setRecipients(Collections.singletonList("+12017777777"))
+ .build();
+ service.sendDeliveryFeedback("foo", request);
+ sendDeliveryFeedbackPassed = true;
+ }
+
+ @Then("the response contains the text SMS details")
+ public void sendResult() {
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Collections.singletonList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(sendTextResponse, expected);
+ }
+
+ @Then("the response contains the text SMS details with multiple parameters")
+ public void sendWithParametersResult() {
+
+ Map nameParameters =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>("+12017777777", "John"),
+ new AbstractMap.SimpleEntry<>("+12018888888", "Paul"),
+ new AbstractMap.SimpleEntry<>("default", "there"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Map codeParameters =
+ Stream.of(new AbstractMap.SimpleEntry<>("+12017777777", "HALLOWEEN20 \uD83C\uDF83"))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ Map> parameters =
+ Stream.of(
+ new AbstractMap.SimpleEntry<>("name", nameParameters),
+ new AbstractMap.SimpleEntry<>("code", codeParameters))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH2")
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setParameters(parameters)
+ .setBody("Hello ${name}! Get 20% off with this discount code ${code}")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setExpireAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(sendTextWithParametersResponse, expected);
+ }
+
+ @Then(
+ "the response contains the calculated bodies and number of parts for all messages in the"
+ + " batch")
+ public void dryRunResult() {
+ DryRunResponse expected =
+ DryRunResponse.builder()
+ .setNumberOfRecipients(3)
+ .setNumberOfMessages(3)
+ .setPerRecipient(
+ Arrays.asList(
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12017777777")
+ .setNumberOfParts(1)
+ .setBody("Hello John!")
+ .setEncoding("text")
+ .build(),
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12019999999")
+ .setNumberOfParts(1)
+ .setBody("Hello there!")
+ .setEncoding("text")
+ .build(),
+ DryRunPerRecipientDetails.builder()
+ .setRecipient("12018888888")
+ .setNumberOfParts(1)
+ .setBody("Hello there!")
+ .setEncoding("text")
+ .build()))
+ .build();
+
+ TestHelpers.recursiveEquals(dryRunResponse, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS batches")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS batches list contains \"{int}\" SMS batches")
+ public void listAllResult(int expected) {
+
+ ListBatchesResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS batches iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+
+ @Then("the response contains the SMS batch details")
+ public void getResult() {
+
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Collections.singletonList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(getBatchResponse, expected);
+ }
+
+ @Then("the response contains the SMS batch details with updated data")
+ public void updateResult() {
+
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12017777777", "01W4FFL35P4NC4K35SMSGROUP1"))
+ .setFrom("12016666666")
+ .setCanceled(false)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:48.054Z"))
+ .setDeliveryReport(DeliveryReportType.SUMMARY)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(updateResponse, expected);
+ }
+
+ @Then("the response contains the new SMS batch details with the provided data for replacement")
+ public void replaceResult() {
+
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12018888888"))
+ .setFrom("12016666666")
+ .setCanceled(false)
+ .setBody("This is the replacement batch")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:23:32.504Z"))
+ .setDeliveryReport(DeliveryReportType.NONE)
+ .setSendAt(Instant.parse("2024-06-06T09:35:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:35:00Z"))
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(replaceResponse, expected);
+ }
+
+ @Then("the response contains the SMS batch details with a cancelled status")
+ public void cancelResult() {
+
+ TextResponse expected =
+ TextResponse.builder()
+ .setId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setTo(Arrays.asList("12017777777"))
+ .setFrom("12015555555")
+ .setCanceled(true)
+ .setBody("SMS body message")
+ .setCreatedAt(Instant.parse("2024-06-06T09:22:14.304Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:22:29.978Z"))
+ .setDeliveryReport(DeliveryReportType.FULL)
+ .setSendAt(Instant.parse("2024-06-06T09:25:00Z"))
+ .setExpireAt(Instant.parse("2024-06-09T09:25:00Z"))
+ .setFeedbackEnabled(true)
+ .setFlashMessage(false)
+ .build();
+
+ TestHelpers.recursiveEquals(cancelResponse, expected);
+ }
+
+ @Then("the delivery feedback response contains no data")
+ public void setSendDeliveryFeedbackResult() {
+ Assertions.assertTrue(sendDeliveryFeedbackPassed);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/DeliveryReportsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/DeliveryReportsSteps.java
new file mode 100644
index 000000000..a7dfb1ca7
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/DeliveryReportsSteps.java
@@ -0,0 +1,186 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.api.v1.DeliveryReportsService;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReportSMS;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryReceiptErrorCode;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryStatus;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.MessageDeliveryStatus;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReportSMS;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.BatchDeliveryReportQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.ListDeliveryReportsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.QueryReportType;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.ListDeliveryReportsResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class DeliveryReportsSteps {
+
+ DeliveryReportsService service;
+
+ BatchDeliveryReport summaryReport;
+ BatchDeliveryReport fullReport;
+ RecipientDeliveryReport recipientReport;
+ ListDeliveryReportsResponse listOnePageResponse;
+ ListDeliveryReportsResponse listAllResponse;
+ ListDeliveryReportsResponse listAllByPageResponse;
+
+ @Given("^the SMS service \"Delivery Reports\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().v1().deliveryReports();
+ }
+
+ @When("^I send a request to retrieve a summary SMS delivery report$")
+ public void getSummary() {
+ BatchDeliveryReportQueryParameters request =
+ BatchDeliveryReportQueryParameters.builder()
+ .setType(QueryReportType.SUMMARY)
+ .setStatus(Arrays.asList(DeliveryStatus.DELIVERED, DeliveryStatus.FAILED))
+ .setCode(
+ Arrays.asList(DeliveryReceiptErrorCode.from(15), DeliveryReceiptErrorCode.from(0)))
+ .build();
+
+ summaryReport = service.get("foo", request);
+ }
+
+ @When("^I send a request to retrieve a full SMS delivery report$")
+ public void getFull() {
+ BatchDeliveryReportQueryParameters request =
+ BatchDeliveryReportQueryParameters.builder().setType(QueryReportType.FULL).build();
+
+ fullReport = service.get("foo", request);
+ }
+
+ @When("^I send a request to retrieve a recipient's delivery report$")
+ public void getRecipient() {
+
+ recipientReport = service.getForNumber("foo", "+12345678");
+ }
+
+ @When("^I send a request to list the SMS delivery reports$")
+ public void listOnePage() {
+ ListDeliveryReportsQueryParameters request =
+ ListDeliveryReportsQueryParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS delivery reports$")
+ public void listAll() {
+ ListDeliveryReportsQueryParameters request =
+ ListDeliveryReportsQueryParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS delivery reports pages$")
+ public void listAllByPage() {
+ ListDeliveryReportsQueryParameters request =
+ ListDeliveryReportsQueryParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @Then("the response contains a summary SMS delivery report")
+ public void getSummaryResult() {
+ BatchDeliveryReport expected =
+ BatchDeliveryReportSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setStatuses(
+ Arrays.asList(
+ MessageDeliveryStatus.builder()
+ .setCode(DeliveryReceiptErrorCode.from(15))
+ .setCount(1)
+ .setStatus(DeliveryStatus.FAILED)
+ .build(),
+ MessageDeliveryStatus.builder()
+ .setCode(DeliveryReceiptErrorCode.from(0))
+ .setCount(1)
+ .setStatus(DeliveryStatus.DELIVERED)
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+ TestHelpers.recursiveEquals(summaryReport, expected);
+ }
+
+ @Then("the response contains a full SMS delivery report")
+ public void getFullResult() {
+ BatchDeliveryReport expected =
+ BatchDeliveryReportSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setStatuses(
+ Arrays.asList(
+ MessageDeliveryStatus.builder()
+ .setCode(DeliveryReceiptErrorCode.from(0))
+ .setCount(1)
+ .setStatus(DeliveryStatus.DELIVERED)
+ .setRecipients(new HashSet<>(Collections.singletonList("12017777777")))
+ .build(),
+ MessageDeliveryStatus.builder()
+ .setCode(DeliveryReceiptErrorCode.from(15))
+ .setCount(1)
+ .setStatus(DeliveryStatus.FAILED)
+ .setRecipients(new HashSet<>(Collections.singletonList("12018888888")))
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+ TestHelpers.recursiveEquals(fullReport, expected);
+ }
+
+ @Then("the response contains the recipient's delivery report details")
+ public void getRecipientResult() {
+ RecipientDeliveryReport expected =
+ RecipientDeliveryReportSMS.builder()
+ .setCreatedAt(Instant.parse("2024-06-06T13:06:27.833Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH1")
+ .setClientReference("reference_e2e")
+ .setCode(DeliveryReceiptErrorCode.from(0))
+ .setOperatorStatusAt(Instant.parse("2024-06-06T13:06:00Z"))
+ .setRecipient("12017777777")
+ .setStatus(DeliveryStatus.DELIVERED)
+ .build();
+
+ TestHelpers.recursiveEquals(recipientReport, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS delivery reports")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS delivery reports list contains \"{int}\" SMS delivery reports")
+ public void listAllResult(int expected) {
+ ListDeliveryReportsResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS delivery reports iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/GroupsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/GroupsSteps.java
new file mode 100644
index 000000000..2c303a00b
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/GroupsSteps.java
@@ -0,0 +1,224 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.api.v1.GroupsService;
+import com.sinch.sdk.domains.sms.models.v1.groups.Group;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupUpdateRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.ListGroupsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.ListGroupsResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class GroupsSteps {
+
+ GroupsService service;
+ Group createResponse;
+ Group getResponse;
+ ListGroupsResponse listOnePageResponse;
+ ListGroupsResponse listAllResponse;
+ ListGroupsResponse listAllByPageResponse;
+ Group updateResponse;
+ Group updateRemoveNameResponse;
+ Group replaceResponse;
+ Boolean deletePassed;
+ Collection lisMembersResponse;
+
+ @Given("^the SMS service \"Groups\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().v1().groups();
+ }
+
+ @When("^I send a request to create an SMS group$")
+ public void create() {
+ GroupRequest request =
+ GroupRequest.builder()
+ .setName("Group master")
+ .setMembers(new HashSet<>(Arrays.asList("+12017778888", "+12018887777")))
+ .setChildGroups(new HashSet<>(Arrays.asList("01W4FFL35P4NC4K35SUBGROUP1")))
+ .build();
+
+ createResponse = service.create(request);
+ }
+
+ @When("^I send a request to retrieve an SMS group$")
+ public void get() {
+
+ getResponse = service.get("01W4FFL35P4NC4K35SMSGROUP1");
+ }
+
+ @When("^I send a request to list the existing SMS groups$")
+ public void listOnePage() {
+ ListGroupsQueryParameters request = ListGroupsQueryParameters.builder().setPageSize(2).build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the SMS groups$")
+ public void listAll() {
+ ListGroupsQueryParameters request = ListGroupsQueryParameters.builder().setPageSize(2).build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the SMS groups pages$")
+ public void listAllByPage() {
+ ListGroupsQueryParameters request = ListGroupsQueryParameters.builder().setPageSize(2).build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @When("^I send a request to update an SMS group$")
+ public void update() {
+
+ GroupUpdateRequest parameters =
+ GroupUpdateRequest.builder()
+ .setName("Updated group name")
+ .setAdd(Arrays.asList("+12017771111", "+12017772222"))
+ .setRemove(Arrays.asList("+12017773333", "+12017774444"))
+ .setAddFromGroup("01W4FFL35P4NC4K35SMSGROUP2")
+ .setRemoveFromGroup("01W4FFL35P4NC4K35SMSGROUP3")
+ .build();
+ updateResponse = service.update("groupid", parameters);
+ }
+
+ @When("^I send a request to update an SMS group to remove its name$")
+ public void updateRemoveName() {
+
+ GroupUpdateRequest parameters = GroupUpdateRequest.builder().setName(null).build();
+ updateRemoveNameResponse = service.update("groupid", parameters);
+ }
+
+ @When("^I send a request to replace an SMS group$")
+ public void replace() {
+
+ GroupRequest parameters =
+ GroupRequest.builder()
+ .setName("Replacement group")
+ .setMembers(
+ new HashSet<>(Arrays.asList("+12018881111", "+12018882222", "+12018883333")))
+ .build();
+ replaceResponse = service.replace("groupid", parameters);
+ }
+
+ @When("^I send a request to delete an SMS group$")
+ public void delete() {
+
+ service.delete("groupid");
+ deletePassed = true;
+ }
+
+ @When("^I send a request to list the members of an SMS group$")
+ public void listMembers() {
+
+ lisMembersResponse = service.listMembers("groupid");
+ }
+
+ @Then("the response contains the SMS group details")
+ public void createOrGetResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Group master")
+ .setSize(2)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setChildGroups(new HashSet<>(Collections.singleton("01W4FFL35P4NC4K35SUBGROUP1")))
+ .build();
+
+ Group current = null != createResponse ? createResponse : getResponse;
+
+ TestHelpers.recursiveEquals(current, expected);
+ }
+
+ @Then("the response contains \"{int}\" SMS groups")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the SMS groups list contains \"{int}\" SMS groups")
+ public void listAllResult(int expected) {
+ ListGroupsResponse response = null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the SMS groups iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+
+ @Then("the response contains the updated SMS group details")
+ public void updateResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Updated group name")
+ .setSize(6)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T09:19:58.147Z"))
+ .setChildGroups(new HashSet<>(Collections.singleton("01W4FFL35P4NC4K35SUBGROUP1")))
+ .build();
+ TestHelpers.recursiveEquals(updateResponse, expected);
+ }
+
+ @Then("the response contains the updated SMS group details where the name has been removed")
+ public void updateRemoveNameResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP2")
+ .setSize(5)
+ .setCreatedAt(Instant.parse("2024-06-06T12:45:18.761Z"))
+ .setModifiedAt(Instant.parse("2024-06-06T13:12:05.137Z"))
+ .setChildGroups(new HashSet<>())
+ .build();
+ TestHelpers.recursiveEquals(updateRemoveNameResponse, expected);
+ }
+
+ @Then("the response contains the replaced SMS group details")
+ public void replaceResult() {
+ Group expected =
+ Group.builder()
+ .setId("01W4FFL35P4NC4K35SMSGROUP1")
+ .setName("Replacement group")
+ .setSize(3)
+ .setCreatedAt(Instant.parse("2024-06-06T08:59:22.156Z"))
+ .setModifiedAt(Instant.parse("2024-08-21T09:39:36.679Z"))
+ .setChildGroups(new HashSet<>(Collections.singleton("01W4FFL35P4NC4K35SUBGROUP1")))
+ .build();
+ TestHelpers.recursiveEquals(replaceResponse, expected);
+ }
+
+ @Then("the delete SMS group response contains no data")
+ public void deleteResult() {
+ Assertions.assertTrue(deletePassed);
+ }
+
+ @Then("the response contains the phone numbers of the SMS group")
+ public void lisMembersResult() {
+ Collection expected =
+ new ArrayList<>(Arrays.asList("12018881111", "12018882222", "12018883333"));
+ TestHelpers.recursiveEquals(lisMembersResponse, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/InboundsSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/InboundsSteps.java
new file mode 100644
index 000000000..0a0311438
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/InboundsSteps.java
@@ -0,0 +1,113 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.api.v1.InboundsService;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.request.ListInboundMessagesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.ListInboundsResponse;
+import com.sinch.sdk.e2e.Config;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.jupiter.api.Assertions;
+
+public class InboundsSteps {
+
+ InboundsService service;
+ InboundMessage getResponse;
+ ListInboundsResponse listOnePageResponse;
+ ListInboundsResponse listAllResponse;
+ ListInboundsResponse listAllByPageResponse;
+
+ @Given("^the SMS service \"Inbounds\" is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().v1().inbounds();
+ }
+
+ @When("^I send a request to retrieve an inbound message")
+ public void get() {
+
+ getResponse = service.get("inboundid");
+ }
+
+ @When("^I send a request to list the inbound messages$")
+ public void listOnePage() {
+ ListInboundMessagesQueryParameters request =
+ ListInboundMessagesQueryParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listOnePageResponse = service.list(request);
+ }
+
+ @When("^I send a request to list all the inbound messages$")
+ public void listAll() {
+ ListInboundMessagesQueryParameters request =
+ ListInboundMessagesQueryParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listAllResponse = service.list(request);
+ }
+
+ @When("^I iterate manually over the inbound messages pages$")
+ public void listAllByPage() {
+ ListInboundMessagesQueryParameters request =
+ ListInboundMessagesQueryParameters.builder()
+ .setTo(Arrays.asList("12017777777", "12018888888"))
+ .setPageSize(2)
+ .build();
+
+ listAllByPageResponse = service.list(request);
+ }
+
+ @Then("the response contains the inbound message details")
+ public void getResult() {
+ TextMessage expected =
+ TextMessage.builder()
+ .setBody("Hello John!")
+ .setFrom("12015555555")
+ .setId("01W4FFL35P4NC4K35INBOUND01")
+ .setOperatorId("311071")
+ .setReceivedAt(Instant.parse("2024-06-06T14:16:54.777Z"))
+ .setTo("12017777777")
+ .build();
+
+ TestHelpers.recursiveEquals(getResponse, expected);
+ }
+
+ @Then("the response contains \"{int}\" inbound messages")
+ public void onePageResult(int expected) {
+
+ Assertions.assertEquals(listOnePageResponse.getContent().size(), expected);
+ }
+
+ @Then("the inbound messages list contains \"{int}\" inbound messages")
+ public void listAllResult(int expected) {
+ ListInboundsResponse response =
+ null != listAllResponse ? listAllResponse : listAllByPageResponse;
+
+ AtomicInteger count = new AtomicInteger();
+ response.iterator().forEachRemaining(_unused -> count.getAndIncrement());
+
+ Assertions.assertEquals(count.get(), expected);
+ }
+
+ @Then("the inbound messages iteration result contains the data from \"{int}\" pages")
+ public void listAllByPageResult(int expected) {
+
+ int count = listAllByPageResponse.getContent().isEmpty() ? 0 : 1;
+ while (listAllByPageResponse.hasNextPage()) {
+ count++;
+ listAllByPageResponse = listAllByPageResponse.nextPage();
+ }
+ Assertions.assertEquals(count, expected);
+ }
+}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java
new file mode 100644
index 000000000..42139b9be
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/SmsIT.java
@@ -0,0 +1,16 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
+
+import org.junit.platform.suite.api.ConfigurationParameter;
+import org.junit.platform.suite.api.IncludeEngines;
+import org.junit.platform.suite.api.SelectClasspathResource;
+import org.junit.platform.suite.api.Suite;
+import org.junit.platform.suite.api.SuiteDisplayName;
+
+@Suite
+@SuiteDisplayName("SMS V1")
+@IncludeEngines("cucumber")
+@SelectClasspathResource("features/sms")
+@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.sinch.sdk.e2e.domains.sms.v1")
+public class SmsIT {}
diff --git a/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/WebhooksSteps.java b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/WebhooksSteps.java
new file mode 100644
index 000000000..8334f1bda
--- /dev/null
+++ b/client/src/test/java/com/sinch/sdk/e2e/domains/sms/v1/WebhooksSteps.java
@@ -0,0 +1,175 @@
+package com.sinch.sdk.e2e.domains.sms.v1;
+
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.domains.sms.api.v1.WebHooksService;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReportSMS;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryReceiptErrorCode;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryStatus;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.MessageDeliveryStatus;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReportSMS;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage;
+import com.sinch.sdk.domains.sms.models.v1.webhooks.SmsEvent;
+import com.sinch.sdk.e2e.Config;
+import com.sinch.sdk.e2e.domains.WebhooksHelper;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import java.io.IOException;
+import java.net.URL;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.HashSet;
+import org.junit.jupiter.api.Assertions;
+
+public class WebhooksSteps {
+
+ static final String WEBHOOKS_PATH_PREFIX = "/webhooks/sms";
+ static final String WEBHOOKS_URL = Config.SMS_HOST_NAME + WEBHOOKS_PATH_PREFIX;
+
+ static final String SECRET = "KayakingTheSwell";
+
+ WebHooksService service;
+ WebhooksHelper.Response incoming;
+ WebhooksHelper.Response deliveryReport;
+ WebhooksHelper.Response deliveryReportRecipientDelivered;
+ WebhooksHelper.Response deliveryReportRecipientAborted;
+
+ @Given("^the SMS Webhooks handler is available")
+ public void serviceAvailable() {
+
+ service = Config.getSinchClient().sms().v1().webhooks();
+ }
+
+ @When("^I send a request to trigger an \"incoming SMS\" event")
+ public void incoming() throws IOException {
+
+ incoming = WebhooksHelper.callURL(new URL(WEBHOOKS_URL + "/incoming-sms"), service::parseEvent);
+ }
+
+ @When("^I send a request to trigger an \"SMS delivery report\" event")
+ public void deliveryReport() throws IOException {
+
+ deliveryReport =
+ WebhooksHelper.callURL(new URL(WEBHOOKS_URL + "/delivery-report-sms"), service::parseEvent);
+ }
+
+ @When(
+ "^I send a request to trigger an \"SMS recipient delivery report\" event with the status"
+ + " \"Delivered\"")
+ public void deliveryReportRecipientDelivered() throws IOException {
+
+ deliveryReportRecipientDelivered =
+ WebhooksHelper.callURL(
+ new URL(WEBHOOKS_URL + "/recipient-delivery-report-sms-delivered"),
+ service::parseEvent);
+ }
+
+ @When(
+ "^I send a request to trigger an \"SMS recipient delivery report\" event with the status"
+ + " \"Aborted\"")
+ public void deliveryReportRecipientAborted() throws IOException {
+
+ deliveryReportRecipientAborted =
+ WebhooksHelper.callURL(
+ new URL(WEBHOOKS_URL + "/recipient-delivery-report-sms-aborted"), service::parseEvent);
+ }
+
+ @Then("the SMS event describes an \"incoming SMS\" event")
+ public void incomingResult() {
+ SmsEvent expected =
+ TextMessage.builder()
+ .setBody("Hello John! 👋")
+ .setFrom("12015555555")
+ .setId("01W4FFL35P4NC4K35SMSBATCH8")
+ .setOperatorId("311071")
+ .setReceivedAt(Instant.parse("2024-06-06T07:52:37.386Z"))
+ .setTo("12017777777")
+ .build();
+
+ TestHelpers.recursiveEquals(incoming.event, expected);
+ }
+
+ @Then("the SMS event describes an \"SMS delivery report\" event")
+ public void deliveryReportResult() {
+ SmsEvent expected =
+ BatchDeliveryReportSMS.builder()
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH8")
+ .setClientReference("client-ref")
+ .setStatuses(
+ Arrays.asList(
+ MessageDeliveryStatus.builder()
+ .setCode(DeliveryReceiptErrorCode.from(0))
+ .setCount(2)
+ .setRecipients(new HashSet<>(Arrays.asList("12017777777", "33612345678")))
+ .setStatus(DeliveryStatus.DELIVERED)
+ .build()))
+ .setTotalMessageCount(2)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReport.event, expected);
+ }
+
+ @Then(
+ "the SMS event describes an SMS recipient delivery report event with the status"
+ + " \"Delivered\"")
+ public void deliveryReportRecipientDeliveredResult() {
+ SmsEvent expected =
+ RecipientDeliveryReportSMS.builder()
+ .setCreatedAt(Instant.parse("2024-06-06T08:17:19.210Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH9")
+ .setClientReference("client-ref")
+ .setCode(DeliveryReceiptErrorCode.from(0))
+ .setOperatorStatusAt(Instant.parse("2024-06-06T08:17:00Z"))
+ .setRecipient("12017777777")
+ .setStatus(DeliveryStatus.DELIVERED)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReportRecipientDelivered.event, expected);
+ }
+
+ @Then(
+ "the SMS event describes an SMS recipient delivery report event with the status \"Aborted\"")
+ public void deliveryReportRecipientAbortedResult() {
+ SmsEvent expected =
+ RecipientDeliveryReportSMS.builder()
+ .setCreatedAt(Instant.parse("2024-06-06T08:17:15.603Z"))
+ .setBatchId("01W4FFL35P4NC4K35SMSBATCH9")
+ .setClientReference("client-ref")
+ .setCode(DeliveryReceiptErrorCode.UNPROVISIONED_REGION)
+ .setRecipient("12010000000")
+ .setStatus(DeliveryStatus.ABORTED)
+ .build();
+
+ TestHelpers.recursiveEquals(deliveryReportRecipientAborted.event, expected);
+ }
+
+ @Then("the header of the event {string} contains a valid signature")
+ public void validateHeader(String event) {
+
+ WebhooksHelper.Response response = null;
+ if (event.equals("IncomingSMS")) {
+ response = incoming;
+ } else if (event.equals("DeliveryReport")) {
+ response = deliveryReport;
+ }
+
+ boolean validated =
+ service.validateAuthenticationHeader(SECRET, response.headers, response.rawPayload);
+ Assertions.assertTrue(validated);
+ }
+
+ @Then("the header of the event {string} with the status {string} contains a valid signature")
+ public void validateHeader(String _unused, String status) {
+
+ WebhooksHelper.Response response = null;
+ if (status.equals("Delivered")) {
+ response = deliveryReportRecipientDelivered;
+ } else if (status.equals("Aborted")) {
+ response = deliveryReportRecipientAborted;
+ }
+
+ boolean validated =
+ service.validateAuthenticationHeader(SECRET, response.headers, response.rawPayload);
+ Assertions.assertTrue(validated);
+ }
+}
diff --git a/core/src/main/com/sinch/sdk/core/databind/QueryParameterSerializer.java b/core/src/main/com/sinch/sdk/core/databind/QueryParameterSerializer.java
new file mode 100644
index 000000000..9b049d1f6
--- /dev/null
+++ b/core/src/main/com/sinch/sdk/core/databind/QueryParameterSerializer.java
@@ -0,0 +1,5 @@
+package com.sinch.sdk.core.databind;
+
+import java.util.function.Function;
+
+public interface QueryParameterSerializer extends Function {}
diff --git a/core/src/main/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializer.java b/core/src/main/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializer.java
new file mode 100644
index 000000000..3255642b2
--- /dev/null
+++ b/core/src/main/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializer.java
@@ -0,0 +1,27 @@
+package com.sinch.sdk.core.databind.query_parameter;
+
+import com.sinch.sdk.core.databind.QueryParameterSerializer;
+import java.util.Collection;
+
+public class CollectionStringToCommaSerializer
+ implements QueryParameterSerializer, String> {
+
+ public static CollectionStringToCommaSerializer getInstance() {
+ return CollectionStringToCommaSerializer.LazyHolder.INSTANCE;
+ }
+
+ @Override
+ public String apply(Collection collection) {
+ if (null == collection) {
+ return null;
+ }
+ return String.join(",", collection);
+ }
+
+ private static class LazyHolder {
+ private static final CollectionStringToCommaSerializer INSTANCE =
+ new CollectionStringToCommaSerializer();
+ }
+
+ private CollectionStringToCommaSerializer() {}
+}
diff --git a/core/src/main/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601Serializer.java b/core/src/main/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601Serializer.java
new file mode 100644
index 000000000..b41c9fd92
--- /dev/null
+++ b/core/src/main/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601Serializer.java
@@ -0,0 +1,25 @@
+package com.sinch.sdk.core.databind.query_parameter;
+
+import com.sinch.sdk.core.databind.QueryParameterSerializer;
+import java.time.Instant;
+
+public class InstantToIso8601Serializer implements QueryParameterSerializer {
+
+ public static InstantToIso8601Serializer getInstance() {
+ return LazyHolder.INSTANCE;
+ }
+
+ @Override
+ public String apply(Instant instant) {
+ if (null == instant) {
+ return null;
+ }
+ return instant.toString();
+ }
+
+ private static class LazyHolder {
+ private static final InstantToIso8601Serializer INSTANCE = new InstantToIso8601Serializer();
+ }
+
+ private InstantToIso8601Serializer() {}
+}
diff --git a/core/src/main/com/sinch/sdk/core/http/URLParameter.java b/core/src/main/com/sinch/sdk/core/http/URLParameter.java
index 82a54171f..dd44c9546 100644
--- a/core/src/main/com/sinch/sdk/core/http/URLParameter.java
+++ b/core/src/main/com/sinch/sdk/core/http/URLParameter.java
@@ -1,5 +1,7 @@
package com.sinch.sdk.core.http;
+import java.util.Objects;
+
public class URLParameter {
private final String name;
private final Object value;
@@ -62,6 +64,26 @@ public String toString() {
+ '}';
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof URLParameter)) {
+ return false;
+ }
+ URLParameter that = (URLParameter) o;
+ return isExplode() == that.isExplode()
+ && Objects.equals(getName(), that.getName())
+ && Objects.equals(getValue(), that.getValue())
+ && getStyle() == that.getStyle();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getName(), getValue(), getStyle(), isExplode());
+ }
+
public enum STYLE {
MATRIX,
LABEL,
@@ -69,6 +91,17 @@ public enum STYLE {
SIMPLE,
SPACE_DELIMITED,
PIPE_DELIMITED,
- DEEP_OBJECT
+ DEEP_OBJECT;
}
+
+ // the following constants do not follow java standard by purpose
+ // Aim is to have direct access to OpenApi Spec authorized values as constant without overhead
+ // ref: https://spec.openapis.org/oas/latest.html#style-values
+ public static final STYLE matrix = STYLE.MATRIX;
+ public static final STYLE label = STYLE.LABEL;
+ public static final STYLE form = STYLE.FORM;
+ public static final STYLE simple = STYLE.SIMPLE;
+ public static final STYLE spaceDelimited = STYLE.SPACE_DELIMITED;
+ public static final STYLE pipeDelimited = STYLE.PIPE_DELIMITED;
+ public static final STYLE deepObject = STYLE.DEEP_OBJECT;
}
diff --git a/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java b/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java
index 7ced9d8b9..6def5f845 100644
--- a/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java
+++ b/core/src/main/com/sinch/sdk/core/http/URLParameterUtils.java
@@ -1,6 +1,9 @@
package com.sinch.sdk.core.http;
+import com.sinch.sdk.core.databind.QueryParameterSerializer;
import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.models.OptionalValue;
import com.sinch.sdk.core.utils.EnumDynamic;
import com.sinch.sdk.core.utils.StringUtil;
import java.io.UnsupportedEncodingException;
@@ -8,6 +11,7 @@
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -26,7 +30,7 @@ public static String encodeParametersAsString(Collection parameter
.collect(Collectors.joining("&"));
}
- public static Optional encode(URLParameter parameter) {
+ protected static Optional encode(URLParameter parameter) {
if (null == parameter
|| StringUtil.isEmpty(parameter.getName())
@@ -195,7 +199,7 @@ private static Optional encodeObject(URLParameter parameter) {
throw new ApiException("Not yet implemented '" + parameter + "'");
}
- public static String encodeParameterValue(String value) {
+ private static String encodeParameterValue(String value) {
try {
return URLEncoder.encode(value, "UTF-8").replaceAll("\\.", "%2E");
@@ -203,4 +207,21 @@ public static String encodeParameterValue(String value) {
return value;
}
}
+
+ public static void addQueryParam(
+ OptionalValue optionalValue,
+ String paramName,
+ STYLE paramStyle,
+ QueryParameterSerializer serializer,
+ List queryParametersList,
+ boolean explode) {
+ optionalValue.ifPresent(
+ value ->
+ queryParametersList.add(
+ new URLParameter(
+ paramName,
+ null == serializer ? value : serializer.apply(value),
+ paramStyle,
+ explode)));
+ }
}
diff --git a/core/src/test/java/com/sinch/sdk/core/TestHelpers.java b/core/src/test/java/com/sinch/sdk/core/TestHelpers.java
index 0b965fe0b..e74f7db49 100644
--- a/core/src/test/java/com/sinch/sdk/core/TestHelpers.java
+++ b/core/src/test/java/com/sinch/sdk/core/TestHelpers.java
@@ -8,11 +8,11 @@ public class TestHelpers {
private static final RecursiveComparisonConfiguration recursiveComparisonConfiguration =
RecursiveComparisonConfiguration.builder().withStrictTypeChecking(true).build();
- public static void recursiveEquals(Object o1, Object o2) {
+ public static void recursiveEquals(Object actual, Object expected) {
- Assertions.assertThat(o1.getClass()).isEqualTo(o2.getClass());
- Assertions.assertThat(o1)
+ Assertions.assertThat(actual.getClass()).isEqualTo(expected.getClass());
+ Assertions.assertThat(actual)
.usingRecursiveComparison(recursiveComparisonConfiguration)
- .isEqualTo(o2);
+ .isEqualTo(expected);
}
}
diff --git a/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializerTest.java b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializerTest.java
new file mode 100644
index 000000000..d90add527
--- /dev/null
+++ b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/CollectionStringToCommaSerializerTest.java
@@ -0,0 +1,49 @@
+package com.sinch.sdk.core.databind.query_parameter;
+
+import com.sinch.sdk.core.TestHelpers;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class CollectionStringToCommaSerializerTest {
+
+ CollectionStringToCommaSerializer serializer = CollectionStringToCommaSerializer.getInstance();
+
+ @Test
+ void serialize() {
+
+ List list = Arrays.asList("foo1", "foo2");
+
+ String serialized = serializer.apply(list);
+
+ TestHelpers.recursiveEquals("foo1,foo2", serialized);
+ }
+
+ @Test
+ void serializeSingle() {
+
+ List list = Collections.singletonList("foo1");
+
+ String serialized = serializer.apply(list);
+
+ TestHelpers.recursiveEquals("foo1", serialized);
+ }
+
+ @Test
+ void serializeEmpty() {
+
+ String serialized = serializer.apply(Collections.emptyList());
+
+ Assertions.assertEquals("", serialized);
+ }
+
+ @Test
+ void serializeNull() {
+
+ String serialized = serializer.apply(null);
+
+ Assertions.assertNull(serialized);
+ }
+}
diff --git a/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java
new file mode 100644
index 000000000..2806c58a1
--- /dev/null
+++ b/core/src/test/java/com/sinch/sdk/core/databind/query_parameter/InstantToIso8601SerializerTest.java
@@ -0,0 +1,29 @@
+package com.sinch.sdk.core.databind.query_parameter;
+
+import com.sinch.sdk.core.TestHelpers;
+import java.time.Instant;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class InstantToIso8601SerializerTest {
+
+ InstantToIso8601Serializer serializer = InstantToIso8601Serializer.getInstance();
+
+ @Test
+ void serialize() {
+
+ Instant instant = Instant.parse("2024-05-04T10:00:00.123Z");
+
+ String serialized = serializer.apply(instant);
+
+ TestHelpers.recursiveEquals("2024-05-04T10:00:00.123Z", serialized);
+ }
+
+ @Test
+ void serializeNull() {
+
+ String serialized = serializer.apply(null);
+
+ Assertions.assertNull(serialized);
+ }
+}
diff --git a/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java b/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java
new file mode 100644
index 000000000..f39bcf295
--- /dev/null
+++ b/core/src/test/java/com/sinch/sdk/core/http/URLParameterTest.java
@@ -0,0 +1,44 @@
+package com.sinch.sdk.core.http;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import org.junit.jupiter.api.Test;
+
+class URLParameterTest {
+
+ @Test
+ void matrix() {
+ assertEquals(STYLE.MATRIX, URLParameter.matrix);
+ }
+
+ @Test
+ void label() {
+ assertEquals(STYLE.LABEL, URLParameter.label);
+ }
+
+ @Test
+ void form() {
+ assertEquals(STYLE.FORM, URLParameter.form);
+ }
+
+ @Test
+ void simple() {
+ assertEquals(STYLE.SIMPLE, URLParameter.simple);
+ }
+
+ @Test
+ void spaceDelimited() {
+ assertEquals(STYLE.SPACE_DELIMITED, URLParameter.spaceDelimited);
+ }
+
+ @Test
+ void pipeDelimited() {
+ assertEquals(STYLE.PIPE_DELIMITED, URLParameter.pipeDelimited);
+ }
+
+ @Test
+ void deepObject() {
+ assertEquals(STYLE.DEEP_OBJECT, URLParameter.deepObject);
+ }
+}
diff --git a/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java b/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java
index 35b582384..0d977de46 100644
--- a/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java
+++ b/core/src/test/java/com/sinch/sdk/core/http/URLParameterUtilsTest.java
@@ -1,10 +1,18 @@
package com.sinch.sdk.core.http;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import com.sinch.sdk.core.TestHelpers;
+import com.sinch.sdk.core.databind.query_parameter.InstantToIso8601Serializer;
import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.http.URLParameter.STYLE;
+import com.sinch.sdk.core.models.OptionalValue;
+import java.time.Instant;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -374,4 +382,51 @@ void encodePipeDelimitedArrayExplode() {
URLParameter.STYLE.PIPE_DELIMITED,
true)));
}
+
+ @Test
+ void addQueryParamNotPresent() {
+
+ // Collections.emptyList() is not modifiable and will throw an exception if trying to add an
+ // entry
+ assertDoesNotThrow(
+ () ->
+ URLParameterUtils.addQueryParam(
+ OptionalValue.empty(),
+ "foo name",
+ STYLE.DEEP_OBJECT,
+ null,
+ Collections.emptyList(),
+ false),
+ "Ignored empty value");
+ }
+
+ @Test
+ void addQueryParamInteger() {
+ ArrayList list = new ArrayList<>();
+
+ URLParameterUtils.addQueryParam(
+ OptionalValue.of(15), "foo name", STYLE.DEEP_OBJECT, null, list, true);
+ assertEquals(1, list.size());
+
+ TestHelpers.recursiveEquals(
+ list.get(0), new URLParameter("foo name", 15, STYLE.DEEP_OBJECT, true));
+ }
+
+ @Test
+ void addQueryParamInstant() {
+ ArrayList list = new ArrayList<>();
+
+ URLParameterUtils.addQueryParam(
+ OptionalValue.of(Instant.parse("2024-05-04T10:00:00.123Z")),
+ "foo name",
+ STYLE.DEEP_OBJECT,
+ InstantToIso8601Serializer.getInstance(),
+ list,
+ true);
+ assertEquals(1, list.size());
+
+ TestHelpers.recursiveEquals(
+ list.get(0),
+ new URLParameter("foo name", "2024-05-04T10:00:00.123Z", STYLE.DEEP_OBJECT, true));
+ }
}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/AppApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/AppApi.java
index 87bdb3b32..20e980aa5 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/AppApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/AppApi.java
@@ -427,6 +427,7 @@ private HttpRequest appUpdateAppRequestBuilder(
.replaceAll("\\{" + "app_id" + "\\}", URLPathUtils.encodePathSegment(appId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != updateMask) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ContactApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ContactApi.java
index 8daf06e90..70753721e 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ContactApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ContactApi.java
@@ -483,26 +483,31 @@ private HttpRequest contactListContactsRequestBuilder(
"\\{" + "project_id" + "\\}", URLPathUtils.encodePathSegment(projectId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != pageSize) {
localVarQueryParams.add(
new URLParameter(
"page_size", pageSize, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageToken) {
localVarQueryParams.add(
new URLParameter(
"page_token", pageToken, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != externalId) {
localVarQueryParams.add(
new URLParameter(
"external_id", externalId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != channel) {
localVarQueryParams.add(
new URLParameter(
"channel", channel, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != identity) {
localVarQueryParams.add(
new URLParameter(
@@ -708,6 +713,7 @@ private HttpRequest contactUpdateContactRequestBuilder(
"\\{" + "contact_id" + "\\}", URLPathUtils.encodePathSegment(contactId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != updateMask) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ConversationApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ConversationApi.java
index e817c65f3..dd39f4f8e 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ConversationApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/ConversationApi.java
@@ -515,31 +515,37 @@ private HttpRequest conversationListConversationsRequestBuilder(
"\\{" + "project_id" + "\\}", URLPathUtils.encodePathSegment(projectId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != appId) {
localVarQueryParams.add(
new URLParameter(
"app_id", appId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != contactId) {
localVarQueryParams.add(
new URLParameter(
"contact_id", contactId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != onlyActive) {
localVarQueryParams.add(
new URLParameter(
"only_active", onlyActive, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageSize) {
localVarQueryParams.add(
new URLParameter(
"page_size", pageSize, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageToken) {
localVarQueryParams.add(
new URLParameter(
"page_token", pageToken, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != activeChannel) {
localVarQueryParams.add(
new URLParameter(
@@ -668,26 +674,31 @@ private HttpRequest conversationListRecentConversationsRequestBuilder(
"\\{" + "project_id" + "\\}", URLPathUtils.encodePathSegment(projectId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != appId) {
localVarQueryParams.add(
new URLParameter(
"app_id", appId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != onlyActive) {
localVarQueryParams.add(
new URLParameter(
"only_active", onlyActive, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageSize) {
localVarQueryParams.add(
new URLParameter(
"page_size", pageSize, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageToken) {
localVarQueryParams.add(
new URLParameter(
"page_token", pageToken, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != order) {
localVarQueryParams.add(
new URLParameter("order", order, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
@@ -899,11 +910,13 @@ private HttpRequest conversationUpdateConversationRequestBuilder(
URLPathUtils.encodePathSegment(conversationId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != updateMask) {
localVarQueryParams.add(
new URLParameter(
"update_mask", updateMask, URLParameter.STYLE.valueOf("form".toUpperCase()), false));
}
+
if (null != metadataUpdateStrategy) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/EventsApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/EventsApi.java
index bfffc668e..b8e16e461 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/EventsApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/EventsApi.java
@@ -275,6 +275,7 @@ private HttpRequest eventsListEventsRequestBuilder(
"\\{" + "project_id" + "\\}", URLPathUtils.encodePathSegment(projectId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != conversationId) {
localVarQueryParams.add(
new URLParameter(
@@ -283,16 +284,19 @@ private HttpRequest eventsListEventsRequestBuilder(
URLParameter.STYLE.valueOf("form".toUpperCase()),
true));
}
+
if (null != contactId) {
localVarQueryParams.add(
new URLParameter(
"contact_id", contactId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageSize) {
localVarQueryParams.add(
new URLParameter(
"page_size", pageSize, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageToken) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/MessagesApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/MessagesApi.java
index 538ff4beb..ed79a3bda 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/MessagesApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/MessagesApi.java
@@ -125,6 +125,7 @@ private HttpRequest messagesDeleteMessageRequestBuilder(
"\\{" + "message_id" + "\\}", URLPathUtils.encodePathSegment(messageId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != messagesSource) {
localVarQueryParams.add(
new URLParameter(
@@ -223,6 +224,7 @@ private HttpRequest messagesGetMessageRequestBuilder(
"\\{" + "message_id" + "\\}", URLPathUtils.encodePathSegment(messageId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != messagesSource) {
localVarQueryParams.add(
new URLParameter(
@@ -410,6 +412,7 @@ private HttpRequest messagesListMessagesRequestBuilder(
"\\{" + "project_id" + "\\}", URLPathUtils.encodePathSegment(projectId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != conversationId) {
localVarQueryParams.add(
new URLParameter(
@@ -418,16 +421,19 @@ private HttpRequest messagesListMessagesRequestBuilder(
URLParameter.STYLE.valueOf("form".toUpperCase()),
true));
}
+
if (null != contactId) {
localVarQueryParams.add(
new URLParameter(
"contact_id", contactId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != appId) {
localVarQueryParams.add(
new URLParameter(
"app_id", appId, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != channelIdentity) {
localVarQueryParams.add(
new URLParameter(
@@ -436,30 +442,36 @@ private HttpRequest messagesListMessagesRequestBuilder(
URLParameter.STYLE.valueOf("form".toUpperCase()),
true));
}
+
if (null != startTime) {
localVarQueryParams.add(
new URLParameter(
"start_time", startTime, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != endTime) {
localVarQueryParams.add(
new URLParameter(
"end_time", endTime, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageSize) {
localVarQueryParams.add(
new URLParameter(
"page_size", pageSize, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != pageToken) {
localVarQueryParams.add(
new URLParameter(
"page_token", pageToken, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != view) {
localVarQueryParams.add(
new URLParameter("view", view, URLParameter.STYLE.valueOf("form".toUpperCase()), true));
}
+
if (null != messagesSource) {
localVarQueryParams.add(
new URLParameter(
@@ -468,6 +480,7 @@ private HttpRequest messagesListMessagesRequestBuilder(
URLParameter.STYLE.valueOf("form".toUpperCase()),
true));
}
+
if (null != onlyRecipientOriginated) {
localVarQueryParams.add(
new URLParameter(
@@ -476,6 +489,7 @@ private HttpRequest messagesListMessagesRequestBuilder(
URLParameter.STYLE.valueOf("form".toUpperCase()),
true));
}
+
if (null != channel) {
localVarQueryParams.add(
new URLParameter(
@@ -680,6 +694,7 @@ private HttpRequest messagesUpdateMessageMetadataRequestBuilder(
"\\{" + "message_id" + "\\}", URLPathUtils.encodePathSegment(messageId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != messagesSource) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/WebhooksApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/WebhooksApi.java
index 2409a57ff..7072d87b9 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/WebhooksApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/api/v1/internal/WebhooksApi.java
@@ -449,6 +449,7 @@ private HttpRequest webhooksUpdateWebhookRequestBuilder(
"\\{" + "webhook_id" + "\\}", URLPathUtils.encodePathSegment(webhookId.toString()));
List localVarQueryParams = new ArrayList<>();
+
if (null != updateMask) {
localVarQueryParams.add(
new URLParameter(
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/request/QueryCapabilityRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/request/QueryCapabilityRequest.java
index e24c3ac6e..52401c7d7 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/request/QueryCapabilityRequest.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/request/QueryCapabilityRequest.java
@@ -25,7 +25,7 @@ public interface QueryCapabilityRequest {
String getAppId();
/**
- * Get recipient
+ * Identifies the recipient.
*
* @return recipient
*/
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/response/QueryCapabilityResponse.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/response/QueryCapabilityResponse.java
index b8934c16c..7866542f6 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/response/QueryCapabilityResponse.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/capability/response/QueryCapabilityResponse.java
@@ -28,7 +28,7 @@ public interface QueryCapabilityResponse {
String getAppId();
/**
- * Get recipient
+ * Identifies the recipient.
*
* @return recipient
*/
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/contact/request/GetChannelProfileRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/contact/request/GetChannelProfileRequest.java
index 67173b22b..cb2765809 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/contact/request/GetChannelProfileRequest.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/contact/request/GetChannelProfileRequest.java
@@ -25,7 +25,7 @@ public interface GetChannelProfileRequest {
String getAppId();
/**
- * Get recipient
+ * Identifies the recipient.
*
* @return recipient
*/
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/events/request/SendEventRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/events/request/SendEventRequest.java
index 7bd59335c..76b53c41c 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/events/request/SendEventRequest.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/events/request/SendEventRequest.java
@@ -67,7 +67,9 @@ public interface SendEventRequest {
MessageQueue getQueue();
/**
- * Get recipient
+ * Identifies the recipient. If Dispatch Mode is
+ * used, you must use the identified_by
field.
*
* @return recipient
*/
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternal.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternal.java
index 7a90796dc..5bb8819ab 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternal.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternal.java
@@ -13,7 +13,6 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.sinch.sdk.core.utils.EnumDynamic;
import com.sinch.sdk.core.utils.EnumSupportDynamic;
-import com.sinch.sdk.domains.conversation.models.v1.messages.types.channelspecific.ChannelSpecificMessage;
import java.util.Arrays;
import java.util.stream.Stream;
@@ -57,7 +56,7 @@ public static String valueOf(MessageTypeEnum e) {
*
* @return message
*/
- ChannelSpecificMessage getMessage();
+ ChannelSpecificMessageMessageInternal getMessage();
/**
* Getting builder
@@ -87,7 +86,7 @@ interface Builder {
* @return Current builder
* @see #getMessage
*/
- Builder setMessage(ChannelSpecificMessage message);
+ Builder setMessage(ChannelSpecificMessageMessageInternal message);
/**
* Create instance
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternalImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternalImpl.java
index 42e87c7c7..e835b115e 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternalImpl.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/internal/ChannelSpecificMessageInternalImpl.java
@@ -7,7 +7,6 @@
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import com.sinch.sdk.core.models.OptionalValue;
-import com.sinch.sdk.domains.conversation.models.v1.messages.types.channelspecific.ChannelSpecificMessage;
import java.util.Objects;
@JsonPropertyOrder({
@@ -25,12 +24,13 @@ public class ChannelSpecificMessageInternalImpl implements ChannelSpecificMessag
public static final String JSON_PROPERTY_MESSAGE = "message";
- private OptionalValue message;
+ private OptionalValue message;
public ChannelSpecificMessageInternalImpl() {}
protected ChannelSpecificMessageInternalImpl(
- OptionalValue messageType, OptionalValue message) {
+ OptionalValue messageType,
+ OptionalValue message) {
this.messageType = messageType;
this.message = message;
}
@@ -47,13 +47,13 @@ public OptionalValue messageType() {
}
@JsonIgnore
- public ChannelSpecificMessage getMessage() {
+ public ChannelSpecificMessageMessageInternal getMessage() {
return message.orElse(null);
}
@JsonProperty(JSON_PROPERTY_MESSAGE)
@JsonInclude(value = JsonInclude.Include.ALWAYS)
- public OptionalValue message() {
+ public OptionalValue message() {
return message;
}
@@ -100,7 +100,7 @@ private String toIndentedString(Object o) {
@JsonPOJOBuilder(withPrefix = "set")
static class Builder implements ChannelSpecificMessageInternal.Builder {
OptionalValue messageType = OptionalValue.empty();
- OptionalValue message = OptionalValue.empty();
+ OptionalValue message = OptionalValue.empty();
@JsonProperty(JSON_PROPERTY_MESSAGE_TYPE)
public Builder setMessageType(MessageTypeEnum messageType) {
@@ -109,7 +109,7 @@ public Builder setMessageType(MessageTypeEnum messageType) {
}
@JsonProperty(JSON_PROPERTY_MESSAGE)
- public Builder setMessage(ChannelSpecificMessage message) {
+ public Builder setMessage(ChannelSpecificMessageMessageInternal message) {
this.message = OptionalValue.of(message);
return this;
}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/request/SendMessageRequest.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/request/SendMessageRequest.java
index 842f04343..a56b19b40 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/request/SendMessageRequest.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/messages/request/SendMessageRequest.java
@@ -109,7 +109,9 @@ public interface SendMessageRequest {
MessageQueue getQueue();
/**
- * Get recipient
+ * Identifies the recipient. If Dispatch Mode is
+ * used, you must use the identified_by
field.
*
* @return recipient
*/
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/webhooks/internal/CreateWebhookRequestInternal.java b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/webhooks/internal/CreateWebhookRequestInternal.java
index eeac1e3b5..310932923 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/webhooks/internal/CreateWebhookRequestInternal.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/conversation/models/v1/webhooks/internal/CreateWebhookRequestInternal.java
@@ -105,16 +105,6 @@ interface Builder {
*/
Builder setClientCredentials(ClientCredentials clientCredentials);
- /**
- * see getter
- *
- * @param id see getter
- * @return Current builder
- * @see #getId
- * @readOnly This field is returned by the server and cannot be modified
- */
- Builder setId(String id);
-
/**
* see getter
*
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/adapters/api/v1/BatchesApi.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/adapters/api/v1/BatchesApi.java
index bd4b53145..50ee62f98 100644
--- a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/adapters/api/v1/BatchesApi.java
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/adapters/api/v1/BatchesApi.java
@@ -761,8 +761,8 @@ private HttpRequest sendSMSRequestBuilder(
}
/**
- * Update a Batch message This operation updates all specified parameters of a batch that matches
- * the provided batch ID.
+ * Update a BatchResponse message This operation updates all specified parameters of a batch that
+ * matches the provided batch ID.
*
* @param servicePlanId Your service plan ID. You can find this on your
* [Dashboard](https://dashboard.sinch.com/sms/api/rest). (required)
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/BatchesService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/BatchesService.java
new file mode 100644
index 000000000..1b979d7e0
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/BatchesService.java
@@ -0,0 +1,143 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1;
+
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.BatchRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.DryRunQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.ListBatchesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateBatchRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse;
+
+/** Batches Service */
+public interface BatchesService {
+
+ /**
+ * Cancel a batch message A batch can be canceled at any point. If a batch is canceled while
+ * it's currently being delivered some messages currently being processed might still be
+ * delivered. The delivery report will indicate which messages were canceled and which
+ * weren't. Canceling a batch scheduled in the future will result in an empty delivery report
+ * while canceling an already sent batch would result in no change to the completed delivery
+ * report.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @return BatchResponse
+ * @throws ApiException if fails to make API call
+ */
+ BatchResponse cancel(String batchId) throws ApiException;
+
+ /**
+ * Dry run (using default parameters) This operation will perform a dry run of a batch which
+ * calculates the bodies and number of parts for all messages in the batch without actually
+ * sending any messages.
+ *
+ * @param sendRequest (optional)
+ * @return DryRunResponse
+ * @throws ApiException if fails to make API call
+ */
+ DryRunResponse dryRun(BatchRequest sendRequest) throws ApiException;
+
+ /**
+ * Dry run This operation will perform a dry run of a batch which calculates the bodies and number
+ * of parts for all messages in the batch without actually sending any messages.
+ *
+ * @param queryParameter (optional)
+ * @param sendRequest (optional)
+ * @return DryRunResponse
+ * @throws ApiException if fails to make API call
+ */
+ DryRunResponse dryRun(DryRunQueryParameters queryParameter, BatchRequest sendRequest)
+ throws ApiException;
+
+ /**
+ * Get a batch message This operation returns a specific batch that matches the provided batch ID.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @return BatchResponse
+ * @throws ApiException if fails to make API call
+ */
+ BatchResponse get(String batchId) throws ApiException;
+
+ /**
+ * List Batches (using default parameters) With the list operation you can list batch messages
+ * created in the last 14 days that you have created. This operation supports pagination.
+ *
+ * @return ListBatchesResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListBatchesResponse list() throws ApiException;
+
+ /**
+ * List Batches With the list operation you can list batch messages created in the last 14 days
+ * that you have created. This operation supports pagination.
+ *
+ * @param queryParameter (optional)
+ * @return ListBatchesResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListBatchesResponse list(ListBatchesQueryParameters queryParameter) throws ApiException;
+
+ /**
+ * Replace a batch This operation will replace all the parameters of a batch with the provided
+ * values. It is the same as cancelling a batch and sending a new one instead.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @param sendRequest (optional)
+ * @return BatchResponse
+ * @throws ApiException if fails to make API call
+ */
+ BatchResponse replace(String batchId, BatchRequest sendRequest) throws ApiException;
+
+ /**
+ * Send delivery feedback for a message Send feedback if your system can confirm successful
+ * message delivery. Feedback can only be provided if `feedback_enabled` was set when
+ * batch was submitted. **Batches**: It is possible to submit feedback multiple times for the same
+ * batch for different recipients. Feedback without specified recipients is treated as successful
+ * message delivery to all recipients referenced in the batch. Note that the
+ * `recipients` key is still required even if the value is empty. **Groups**: If the
+ * batch message was creating using a group ID, at least one recipient is required. Excluding
+ * recipients (an empty recipient list) does not work and will result in a failed request.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @param sendDeliveryFeedbackRequest A list of phone numbers (MSISDNs) that successfully received
+ * the message. (required)
+ * @throws ApiException if fails to make API call
+ */
+ void sendDeliveryFeedback(String batchId, SendDeliveryFeedbackRequest sendDeliveryFeedbackRequest)
+ throws ApiException;
+
+ /**
+ * Send Send a message or a batch of messages. Depending on the length of the body, one message
+ * might be split into multiple parts and charged accordingly. Any groups targeted in a scheduled
+ * batch will be evaluated at the time of sending. If a group is deleted between batch creation
+ * and scheduled date, it will be considered empty. Be sure to use the correct
+ * [region](/docs/sms/api-reference/#base-url) in the server URL.
+ *
+ * @param sendRequest Default schema is Text if type is not specified. (optional)
+ * @return BatchResponse
+ * @throws ApiException if fails to make API call
+ */
+ BatchResponse send(BatchRequest sendRequest) throws ApiException;
+
+ /**
+ * Update a Batch message This operation updates all specified parameters of a batch that matches
+ * the provided batch ID.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @param updateBatchRequest (optional)
+ * @return BatchResponse
+ * @throws ApiException if fails to make API call
+ */
+ BatchResponse update(String batchId, UpdateBatchRequest updateBatchRequest) throws ApiException;
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/DeliveryReportsService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/DeliveryReportsService.java
new file mode 100644
index 000000000..363b85efb
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/DeliveryReportsService.java
@@ -0,0 +1,79 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1;
+
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.BatchDeliveryReportQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.ListDeliveryReportsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.ListDeliveryReportsResponse;
+
+/** Delivery reports Service */
+public interface DeliveryReportsService {
+
+ /**
+ * Retrieve a delivery report (using default parameters) Delivery reports can be retrieved even if
+ * no callback was requested. The difference between a summary and a full report is only that the
+ * full report contains the phone numbers in
+ * [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format for each status code.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @return BatchDeliveryReport
+ * @throws ApiException if fails to make API call
+ */
+ BatchDeliveryReport get(String batchId) throws ApiException;
+
+ /**
+ * Retrieve a delivery report Delivery reports can be retrieved even if no callback was requested.
+ * The difference between a summary and a full report is only that the full report contains the
+ * phone numbers in [E.164](https://community.sinch.com/t5/Glossary/E-164/ta-p/7537) format for
+ * each status code.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @param queryParameter (optional)
+ * @return BatchDeliveryReport
+ * @throws ApiException if fails to make API call
+ */
+ BatchDeliveryReport get(String batchId, BatchDeliveryReportQueryParameters queryParameter)
+ throws ApiException;
+
+ /**
+ * Retrieve a recipient delivery report A recipient delivery report contains the message status
+ * for a single recipient phone number.
+ *
+ * @param batchId The batch ID you received from sending a message. (required)
+ * @param recipientMsisdn Phone number for which you to want to search. (required)
+ * @return RecipientDeliveryReport
+ * @throws ApiException if fails to make API call
+ */
+ RecipientDeliveryReport getForNumber(String batchId, String recipientMsisdn) throws ApiException;
+
+ /**
+ * Retrieve a list of delivery reports (using default parameters) Get a list of finished delivery
+ * reports. This operation supports pagination.
+ *
+ * @return ListDeliveryReportsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListDeliveryReportsResponse list() throws ApiException;
+
+ /**
+ * Retrieve a list of delivery reports Get a list of finished delivery reports. This operation
+ * supports pagination.
+ *
+ * @param queryParameter (optional)
+ * @return ListDeliveryReportsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListDeliveryReportsResponse list(ListDeliveryReportsQueryParameters queryParameter)
+ throws ApiException;
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/GroupsService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/GroupsService.java
new file mode 100644
index 000000000..f40560e1e
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/GroupsService.java
@@ -0,0 +1,118 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1;
+
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.domains.sms.models.v1.groups.Group;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupUpdateRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.ListGroupsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.ListGroupsResponse;
+import java.util.List;
+
+/** Groups Service */
+public interface GroupsService {
+
+ /**
+ * Create a group This endpoint allows you to create a group of recipients. A new group must be
+ * created with a group name. This is represented by the `name` field which can be up to
+ * 20 charecters. In addition, there are a number of optional fields: - `members` field
+ * enables groups to be created with an initial list of contacts - `auto_update` allows
+ * customers to auto subscribe to a new group. This contains three fields. The `to`
+ * field contains the group creator's number. (This number **must be provisioned by contacting
+ * your account manager**.) The `add` and `remove` fields are objects
+ * containing the keywords that customers need to text to join or leave a group.
+ *
+ * @param groupRequest (optional)
+ * @return Group
+ * @throws ApiException if fails to make API call
+ */
+ Group create(GroupRequest groupRequest) throws ApiException;
+
+ /**
+ * Delete a group This operation deletes the group with the provided group ID.
+ *
+ * @param groupId ID of a group that you are interested in getting. (required)
+ * @throws ApiException if fails to make API call
+ */
+ void delete(String groupId) throws ApiException;
+
+ /**
+ * Get phone numbers for a group This operation retrieves the members of the group with the
+ * provided group ID.
+ *
+ * @param groupId ID of a group that you are interested in getting. (required)
+ * @return List<String>
+ * @throws ApiException if fails to make API call
+ */
+ List listMembers(String groupId) throws ApiException;
+
+ /**
+ * List Groups (using default parameters) With the list operation you can list all groups that you
+ * have created. This operation supports pagination. Groups are returned in reverse chronological
+ * order.
+ *
+ * @return ListGroupsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListGroupsResponse list() throws ApiException;
+
+ /**
+ * List Groups With the list operation you can list all groups that you have created. This
+ * operation supports pagination. Groups are returned in reverse chronological order.
+ *
+ * @param queryParameter (optional)
+ * @return ListGroupsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListGroupsResponse list(ListGroupsQueryParameters queryParameter) throws ApiException;
+
+ /**
+ * Replace a group The replace operation will replace all parameters, including members, of an
+ * existing group with new values. Replacing a group targeted by a batch message scheduled in the
+ * future is allowed and changes will be reflected when the batch is sent.
+ *
+ * @param groupId ID of a group that you are interested in getting. (required)
+ * @param groupRequest (optional)
+ * @return Group
+ * @throws ApiException if fails to make API call
+ */
+ Group replace(String groupId, GroupRequest groupRequest) throws ApiException;
+
+ /**
+ * Retrieve a group This operation retrieves a specific group with the provided group ID.
+ *
+ * @param groupId ID of a group that you are interested in getting. (required)
+ * @return Group
+ * @throws ApiException if fails to make API call
+ */
+ Group get(String groupId) throws ApiException;
+
+ /**
+ * Update a group With the update group operation, you can add and remove members in an existing
+ * group as well as rename the group. This method encompasses a few ways to update a group: 1. By
+ * using `add` and `remove` arrays containing phone numbers, you control the
+ * group movements. Any list of valid numbers in E.164 format can be added. 2. By using the
+ * `auto_update` object, your customer can add or remove themselves from groups. 3. You
+ * can also add or remove other groups into this group with `add_from_group` and
+ * `remove_from_group`. #### Other group update info - The request will not be rejected
+ * for duplicate adds or unknown removes. - The additions will be done before the deletions. If an
+ * phone number is on both lists, it will not be apart of the resulting group. - Updating a group
+ * targeted by a batch message scheduled in the future is allowed. Changes will be reflected when
+ * the batch is sent.
+ *
+ * @param groupId ID of a group that you are interested in getting. (required)
+ * @param groupUpdateRequest (optional)
+ * @return Group
+ * @throws ApiException if fails to make API call
+ */
+ Group update(String groupId, GroupUpdateRequest groupUpdateRequest) throws ApiException;
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/InboundsService.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/InboundsService.java
new file mode 100644
index 000000000..d53c5d1e9
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/InboundsService.java
@@ -0,0 +1,51 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1;
+
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.request.ListInboundMessagesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.ListInboundsResponse;
+
+/** Inbounds Service */
+public interface InboundsService {
+
+ /**
+ * List incoming messages (using default parameters) With the list operation, you can list all
+ * inbound messages that you have received. This operation supports pagination. Inbounds are
+ * returned in reverse chronological order.
+ *
+ * @return ListInboundsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListInboundsResponse list() throws ApiException;
+
+ /**
+ * List incoming messages With the list operation, you can list all inbound messages that you have
+ * received. This operation supports pagination. Inbounds are returned in reverse chronological
+ * order.
+ *
+ * @param queryParameter (optional)
+ * @return ListInboundsResponse
+ * @throws ApiException if fails to make API call
+ */
+ ListInboundsResponse list(ListInboundMessagesQueryParameters queryParameter) throws ApiException;
+
+ /**
+ * Retrieve inbound message This operation retrieves a specific inbound message with the provided
+ * inbound ID.
+ *
+ * @param inboundId The inbound ID found when listing inbound messages. (required)
+ * @return InboundMessage
+ * @throws ApiException if fails to make API call
+ */
+ InboundMessage get(String inboundId) throws ApiException;
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceImpl.java
new file mode 100644
index 000000000..3cd18a999
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/BatchesServiceImpl.java
@@ -0,0 +1,664 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.sinch.sdk.core.databind.query_parameter.InstantToIso8601Serializer;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.exceptions.ApiExceptionBuilder;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.HttpStatus;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameterUtils;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.core.models.pagination.Page;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.BatchRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.DryRunQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.ListBatchesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.SendDeliveryFeedbackRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.request.UpdateBatchRequest;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.DryRunResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.ListBatchesResponse;
+import com.sinch.sdk.domains.sms.models.v1.batches.response.internal.ApiBatchList;
+import com.sinch.sdk.domains.sms.models.v1.internal.SMSCursorPageNavigator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class BatchesServiceImpl implements com.sinch.sdk.domains.sms.api.v1.BatchesService {
+
+ private static final Logger LOGGER = Logger.getLogger(BatchesServiceImpl.class.getName());
+ private final HttpClient httpClient;
+ private final ServerConfiguration serverConfiguration;
+ private final Map authManagersByOasSecuritySchemes;
+ private final HttpMapper mapper;
+
+ private final String servicePlanId;
+
+ public BatchesServiceImpl(
+ HttpClient httpClient,
+ ServerConfiguration serverConfiguration,
+ Map authManagersByOasSecuritySchemes,
+ HttpMapper mapper,
+ String servicePlanId) {
+ this.httpClient = httpClient;
+ this.serverConfiguration = serverConfiguration;
+ this.authManagersByOasSecuritySchemes = authManagersByOasSecuritySchemes;
+ this.mapper = mapper;
+ this.servicePlanId = servicePlanId;
+ }
+
+ public BatchResponse cancel(String batchId) throws ApiException {
+
+ LOGGER.finest("[cancel]" + " " + "batchId: " + batchId);
+
+ HttpRequest httpRequest = cancelRequestBuilder(batchId);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest cancelRequestBuilder(String batchId) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling cancel");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(400, "Missing the required parameter 'batchId' when calling cancel");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.DELETE,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public DryRunResponse dryRun(BatchRequest sendRequest) throws ApiException {
+
+ return dryRun(null, sendRequest);
+ }
+
+ public DryRunResponse dryRun(DryRunQueryParameters queryParameter, BatchRequest sendRequest)
+ throws ApiException {
+
+ LOGGER.finest(
+ "[dryRun]"
+ + " "
+ + "queryParameter: "
+ + queryParameter
+ + ", "
+ + "sendRequest: "
+ + sendRequest);
+
+ HttpRequest httpRequest = dryRunRequestBuilder(queryParameter, sendRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest dryRunRequestBuilder(
+ DryRunQueryParameters queryParameter, BatchRequest sendRequest) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling dryRun");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/dry_run"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+ if (null != queryParameter) {
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPerRecipient(),
+ "per_recipient",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getNumberOfRecipients(),
+ "number_of_recipients",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+ }
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, sendRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public BatchResponse get(String batchId) throws ApiException {
+
+ LOGGER.finest("[get]" + " " + "batchId: " + batchId);
+
+ HttpRequest httpRequest = getRequestBuilder(batchId);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest getRequestBuilder(String batchId) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling get");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(400, "Missing the required parameter 'batchId' when calling get");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public ListBatchesResponse list() throws ApiException {
+
+ return list(null);
+ }
+
+ public ListBatchesResponse list(ListBatchesQueryParameters queryParameter) throws ApiException {
+
+ LOGGER.finest("[list]" + " " + "queryParameter: " + queryParameter);
+
+ HttpRequest httpRequest = listRequestBuilder(queryParameter);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+
+ ApiBatchList deserialized =
+ mapper.deserialize(response, new TypeReference() {});
+
+ return new ListBatchesResponse(
+ this,
+ new Page<>(
+ queryParameter,
+ deserialized.getItems(),
+ new SMSCursorPageNavigator(deserialized.getPage(), deserialized.getPageSize())));
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest listRequestBuilder(ListBatchesQueryParameters queryParameter)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling list");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+ if (null != queryParameter) {
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPage(), "page", URLParameter.form, null, localVarQueryParams, true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPageSize(),
+ "page_size",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getFrom(), "from", URLParameter.form, null, localVarQueryParams, true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getStartDate(),
+ "start_date",
+ URLParameter.form,
+ InstantToIso8601Serializer.getInstance(),
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getEndDate(),
+ "end_date",
+ URLParameter.form,
+ InstantToIso8601Serializer.getInstance(),
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getClientReference(),
+ "client_reference",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+ }
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public BatchResponse replace(String batchId, BatchRequest sendRequest) throws ApiException {
+
+ LOGGER.finest("[replace]" + " " + "batchId: " + batchId + ", " + "sendRequest: " + sendRequest);
+
+ HttpRequest httpRequest = replaceRequestBuilder(batchId, sendRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest replaceRequestBuilder(String batchId, BatchRequest sendRequest)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling replace");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(400, "Missing the required parameter 'batchId' when calling replace");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, sendRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.PUT,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public void sendDeliveryFeedback(
+ String batchId, SendDeliveryFeedbackRequest sendDeliveryFeedbackRequest) throws ApiException {
+
+ LOGGER.finest(
+ "[sendDeliveryFeedback]"
+ + " "
+ + "batchId: "
+ + batchId
+ + ", "
+ + "sendDeliveryFeedbackRequest: "
+ + sendDeliveryFeedbackRequest);
+
+ HttpRequest httpRequest =
+ sendDeliveryFeedbackRequestBuilder(batchId, sendDeliveryFeedbackRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return;
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest sendDeliveryFeedbackRequestBuilder(
+ String batchId, SendDeliveryFeedbackRequest sendDeliveryFeedbackRequest) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400,
+ "Missing the required parameter 'this.servicePlanId' when calling sendDeliveryFeedback");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'batchId' when calling sendDeliveryFeedback");
+ }
+ // verify the required parameter 'sendDeliveryFeedbackRequest' is set
+ if (sendDeliveryFeedbackRequest == null) {
+ throw new ApiException(
+ 400,
+ "Missing the required parameter 'sendDeliveryFeedbackRequest' when calling"
+ + " sendDeliveryFeedback");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}/delivery_feedback"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList();
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody =
+ mapper.serialize(localVarContentTypes, sendDeliveryFeedbackRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public BatchResponse send(BatchRequest sendRequest) throws ApiException {
+
+ LOGGER.finest("[send]" + " " + "sendRequest: " + sendRequest);
+
+ HttpRequest httpRequest = sendRequestBuilder(sendRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest sendRequestBuilder(BatchRequest sendRequest) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling send");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, sendRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public BatchResponse update(String batchId, UpdateBatchRequest updateBatchRequest)
+ throws ApiException {
+
+ LOGGER.finest(
+ "[update]"
+ + " "
+ + "batchId: "
+ + batchId
+ + ", "
+ + "updateBatchRequest: "
+ + updateBatchRequest);
+
+ HttpRequest httpRequest = updateRequestBuilder(batchId, updateBatchRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest updateRequestBuilder(String batchId, UpdateBatchRequest updateBatchRequest)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling update");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(400, "Missing the required parameter 'batchId' when calling update");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, updateBatchRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceImpl.java
new file mode 100644
index 000000000..44613b688
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/DeliveryReportsServiceImpl.java
@@ -0,0 +1,353 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.sinch.sdk.core.databind.query_parameter.InstantToIso8601Serializer;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.exceptions.ApiExceptionBuilder;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.HttpStatus;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameterUtils;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.core.models.pagination.Page;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.BatchDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.RecipientDeliveryReport;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.BatchDeliveryReportQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.request.ListDeliveryReportsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.ListDeliveryReportsResponse;
+import com.sinch.sdk.domains.sms.models.v1.deliveryreports.response.internal.DeliveryReportList;
+import com.sinch.sdk.domains.sms.models.v1.internal.SMSCursorPageNavigator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class DeliveryReportsServiceImpl
+ implements com.sinch.sdk.domains.sms.api.v1.DeliveryReportsService {
+
+ private static final Logger LOGGER = Logger.getLogger(DeliveryReportsServiceImpl.class.getName());
+ private final HttpClient httpClient;
+ private final ServerConfiguration serverConfiguration;
+ private final Map authManagersByOasSecuritySchemes;
+ private final HttpMapper mapper;
+
+ private final String servicePlanId;
+
+ public DeliveryReportsServiceImpl(
+ HttpClient httpClient,
+ ServerConfiguration serverConfiguration,
+ Map authManagersByOasSecuritySchemes,
+ HttpMapper mapper,
+ String servicePlanId) {
+ this.httpClient = httpClient;
+ this.serverConfiguration = serverConfiguration;
+ this.authManagersByOasSecuritySchemes = authManagersByOasSecuritySchemes;
+ this.mapper = mapper;
+ this.servicePlanId = servicePlanId;
+ }
+
+ public BatchDeliveryReport get(String batchId) throws ApiException {
+
+ return get(batchId, null);
+ }
+
+ public BatchDeliveryReport get(String batchId, BatchDeliveryReportQueryParameters queryParameter)
+ throws ApiException {
+
+ LOGGER.finest(
+ "[get]" + " " + "batchId: " + batchId + ", " + "queryParameter: " + queryParameter);
+
+ HttpRequest httpRequest = getRequestBuilder(batchId, queryParameter);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest getRequestBuilder(
+ String batchId, BatchDeliveryReportQueryParameters queryParameter) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling get");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(400, "Missing the required parameter 'batchId' when calling get");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}/delivery_report"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+ if (null != queryParameter) {
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getType(), "type", URLParameter.form, null, localVarQueryParams, true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getStatus(),
+ "status",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ false);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getCode(), "code", URLParameter.form, null, localVarQueryParams, false);
+ }
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public RecipientDeliveryReport getForNumber(String batchId, String recipientMsisdn)
+ throws ApiException {
+
+ LOGGER.finest(
+ "[getForNumber]"
+ + " "
+ + "batchId: "
+ + batchId
+ + ", "
+ + "recipientMsisdn: "
+ + recipientMsisdn);
+
+ HttpRequest httpRequest = getForNumberRequestBuilder(batchId, recipientMsisdn);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest getForNumberRequestBuilder(String batchId, String recipientMsisdn)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling getForNumber");
+ }
+ // verify the required parameter 'batchId' is set
+ if (batchId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'batchId' when calling getForNumber");
+ }
+ // verify the required parameter 'recipientMsisdn' is set
+ if (recipientMsisdn == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'recipientMsisdn' when calling getForNumber");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/batches/{batch_id}/delivery_report/{recipient_msisdn}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "batch_id" + "\\}", URLPathUtils.encodePathSegment(batchId.toString()))
+ .replaceAll(
+ "\\{" + "recipient_msisdn" + "\\}",
+ URLPathUtils.encodePathSegment(recipientMsisdn.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public ListDeliveryReportsResponse list() throws ApiException {
+
+ return list(null);
+ }
+
+ public ListDeliveryReportsResponse list(ListDeliveryReportsQueryParameters queryParameter)
+ throws ApiException {
+
+ LOGGER.finest("[list]" + " " + "queryParameter: " + queryParameter);
+
+ HttpRequest httpRequest = listRequestBuilder(queryParameter);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+
+ DeliveryReportList deserialized =
+ mapper.deserialize(response, new TypeReference() {});
+
+ return new ListDeliveryReportsResponse(
+ this,
+ new Page<>(
+ queryParameter,
+ deserialized.getItems(),
+ new SMSCursorPageNavigator(deserialized.getPage(), deserialized.getPageSize())));
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest listRequestBuilder(ListDeliveryReportsQueryParameters queryParameter)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling list");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/delivery_reports"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+ if (null != queryParameter) {
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPage(), "page", URLParameter.form, null, localVarQueryParams, true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPageSize(),
+ "page_size",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getStartDate(),
+ "start_date",
+ URLParameter.form,
+ InstantToIso8601Serializer.getInstance(),
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getEndDate(),
+ "end_date",
+ URLParameter.form,
+ InstantToIso8601Serializer.getInstance(),
+ localVarQueryParams,
+ true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getStatus(),
+ "status",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ false);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getCode(), "code", URLParameter.form, null, localVarQueryParams, false);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getClientReference(),
+ "client_reference",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+ }
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceImpl.java
new file mode 100644
index 000000000..3c2f2107d
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/GroupsServiceImpl.java
@@ -0,0 +1,526 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.exceptions.ApiExceptionBuilder;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.HttpStatus;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameterUtils;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.core.models.pagination.Page;
+import com.sinch.sdk.domains.sms.models.v1.groups.Group;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupUpdateRequest;
+import com.sinch.sdk.domains.sms.models.v1.groups.request.ListGroupsQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.ListGroupsResponse;
+import com.sinch.sdk.domains.sms.models.v1.groups.response.internal.ApiGroupList;
+import com.sinch.sdk.domains.sms.models.v1.internal.SMSCursorPageNavigator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class GroupsServiceImpl implements com.sinch.sdk.domains.sms.api.v1.GroupsService {
+
+ private static final Logger LOGGER = Logger.getLogger(GroupsServiceImpl.class.getName());
+ private final HttpClient httpClient;
+ private final ServerConfiguration serverConfiguration;
+ private final Map authManagersByOasSecuritySchemes;
+ private final HttpMapper mapper;
+
+ private final String servicePlanId;
+
+ public GroupsServiceImpl(
+ HttpClient httpClient,
+ ServerConfiguration serverConfiguration,
+ Map authManagersByOasSecuritySchemes,
+ HttpMapper mapper,
+ String servicePlanId) {
+ this.httpClient = httpClient;
+ this.serverConfiguration = serverConfiguration;
+ this.authManagersByOasSecuritySchemes = authManagersByOasSecuritySchemes;
+ this.mapper = mapper;
+ this.servicePlanId = servicePlanId;
+ }
+
+ public Group create(GroupRequest groupRequest) throws ApiException {
+
+ LOGGER.finest("[create]" + " " + "groupRequest: " + groupRequest);
+
+ HttpRequest httpRequest = createRequestBuilder(groupRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest createRequestBuilder(GroupRequest groupRequest) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling create");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, groupRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public void delete(String groupId) throws ApiException {
+
+ LOGGER.finest("[delete]" + " " + "groupId: " + groupId);
+
+ HttpRequest httpRequest = deleteRequestBuilder(groupId);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return;
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest deleteRequestBuilder(String groupId) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling delete");
+ }
+ // verify the required parameter 'groupId' is set
+ if (groupId == null) {
+ throw new ApiException(400, "Missing the required parameter 'groupId' when calling delete");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups/{group_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "group_id" + "\\}", URLPathUtils.encodePathSegment(groupId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList();
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.DELETE,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public List listMembers(String groupId) throws ApiException {
+
+ LOGGER.finest("[listMembers]" + " " + "groupId: " + groupId);
+
+ HttpRequest httpRequest = listMembersRequestBuilder(groupId);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference>() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest listMembersRequestBuilder(String groupId) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling listMembers");
+ }
+ // verify the required parameter 'groupId' is set
+ if (groupId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'groupId' when calling listMembers");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups/{group_id}/members"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "group_id" + "\\}", URLPathUtils.encodePathSegment(groupId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public ListGroupsResponse list() throws ApiException {
+
+ return list(null);
+ }
+
+ public ListGroupsResponse list(ListGroupsQueryParameters queryParameter) throws ApiException {
+
+ LOGGER.finest("[list]" + " " + "queryParameter: " + queryParameter);
+
+ HttpRequest httpRequest = listRequestBuilder(queryParameter);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+
+ ApiGroupList deserialized =
+ mapper.deserialize(response, new TypeReference() {});
+
+ return new ListGroupsResponse(
+ this,
+ new Page<>(
+ queryParameter,
+ deserialized.getItems(),
+ new SMSCursorPageNavigator(deserialized.getPage(), deserialized.getPageSize())));
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest listRequestBuilder(ListGroupsQueryParameters queryParameter)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling list");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+ if (null != queryParameter) {
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPage(), "page", URLParameter.form, null, localVarQueryParams, true);
+
+ URLParameterUtils.addQueryParam(
+ queryParameter.getPageSize(),
+ "page_size",
+ URLParameter.form,
+ null,
+ localVarQueryParams,
+ true);
+ }
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public Group replace(String groupId, GroupRequest groupRequest) throws ApiException {
+
+ LOGGER.finest(
+ "[replace]" + " " + "groupId: " + groupId + ", " + "groupRequest: " + groupRequest);
+
+ HttpRequest httpRequest = replaceRequestBuilder(groupId, groupRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest replaceRequestBuilder(String groupId, GroupRequest groupRequest)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling replace");
+ }
+ // verify the required parameter 'groupId' is set
+ if (groupId == null) {
+ throw new ApiException(400, "Missing the required parameter 'groupId' when calling replace");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups/{group_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "group_id" + "\\}", URLPathUtils.encodePathSegment(groupId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, groupRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.PUT,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public Group get(String groupId) throws ApiException {
+
+ LOGGER.finest("[get]" + " " + "groupId: " + groupId);
+
+ HttpRequest httpRequest = getRequestBuilder(groupId);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest getRequestBuilder(String groupId) throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling get");
+ }
+ // verify the required parameter 'groupId' is set
+ if (groupId == null) {
+ throw new ApiException(400, "Missing the required parameter 'groupId' when calling get");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups/{group_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "group_id" + "\\}", URLPathUtils.encodePathSegment(groupId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList();
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = null;
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.GET,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+
+ public Group update(String groupId, GroupUpdateRequest groupUpdateRequest) throws ApiException {
+
+ LOGGER.finest(
+ "[update]"
+ + " "
+ + "groupId: "
+ + groupId
+ + ", "
+ + "groupUpdateRequest: "
+ + groupUpdateRequest);
+
+ HttpRequest httpRequest = updateRequestBuilder(groupId, groupUpdateRequest);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+ return mapper.deserialize(response, new TypeReference() {});
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference>() {}));
+ }
+
+ private HttpRequest updateRequestBuilder(String groupId, GroupUpdateRequest groupUpdateRequest)
+ throws ApiException {
+ // verify the required parameter 'this.servicePlanId' is set
+ if (this.servicePlanId == null) {
+ throw new ApiException(
+ 400, "Missing the required parameter 'this.servicePlanId' when calling update");
+ }
+ // verify the required parameter 'groupId' is set
+ if (groupId == null) {
+ throw new ApiException(400, "Missing the required parameter 'groupId' when calling update");
+ }
+
+ String localVarPath =
+ "/xms/v1/{service_plan_id}/groups/{group_id}"
+ .replaceAll(
+ "\\{" + "service_plan_id" + "\\}",
+ URLPathUtils.encodePathSegment(this.servicePlanId.toString()))
+ .replaceAll(
+ "\\{" + "group_id" + "\\}", URLPathUtils.encodePathSegment(groupId.toString()));
+
+ List localVarQueryParams = new ArrayList<>();
+
+ Map localVarHeaderParams = new HashMap<>();
+
+ final Collection localVarAccepts = Arrays.asList("application/json");
+
+ final Collection localVarContentTypes = Arrays.asList("application/json");
+
+ final Collection localVarAuthNames = Arrays.asList("BearerAuth");
+ final String serializedBody = mapper.serialize(localVarContentTypes, groupUpdateRequest);
+
+ return new HttpRequest(
+ localVarPath,
+ HttpMethod.POST,
+ localVarQueryParams,
+ serializedBody,
+ localVarHeaderParams,
+ localVarAccepts,
+ localVarContentTypes,
+ localVarAuthNames);
+ }
+}
diff --git a/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceImpl.java b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceImpl.java
new file mode 100644
index 000000000..af85db19f
--- /dev/null
+++ b/openapi-contracts/src/main/com/sinch/sdk/domains/sms/api/v1/adapters/InboundsServiceImpl.java
@@ -0,0 +1,244 @@
+/*
+ * API Overview | Sinch
+ *
+ * OpenAPI document version: v1
+ * Contact: Support@sinch.com
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * Do not edit the class manually.
+ */
+
+package com.sinch.sdk.domains.sms.api.v1.adapters;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.sinch.sdk.core.databind.query_parameter.CollectionStringToCommaSerializer;
+import com.sinch.sdk.core.databind.query_parameter.InstantToIso8601Serializer;
+import com.sinch.sdk.core.exceptions.ApiException;
+import com.sinch.sdk.core.exceptions.ApiExceptionBuilder;
+import com.sinch.sdk.core.http.AuthManager;
+import com.sinch.sdk.core.http.HttpClient;
+import com.sinch.sdk.core.http.HttpMapper;
+import com.sinch.sdk.core.http.HttpMethod;
+import com.sinch.sdk.core.http.HttpRequest;
+import com.sinch.sdk.core.http.HttpResponse;
+import com.sinch.sdk.core.http.HttpStatus;
+import com.sinch.sdk.core.http.URLParameter;
+import com.sinch.sdk.core.http.URLParameterUtils;
+import com.sinch.sdk.core.http.URLPathUtils;
+import com.sinch.sdk.core.models.ServerConfiguration;
+import com.sinch.sdk.core.models.pagination.Page;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.request.ListInboundMessagesQueryParameters;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.ListInboundsResponse;
+import com.sinch.sdk.domains.sms.models.v1.inbounds.response.internal.ApiInboundList;
+import com.sinch.sdk.domains.sms.models.v1.internal.SMSCursorPageNavigator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+public class InboundsServiceImpl implements com.sinch.sdk.domains.sms.api.v1.InboundsService {
+
+ private static final Logger LOGGER = Logger.getLogger(InboundsServiceImpl.class.getName());
+ private final HttpClient httpClient;
+ private final ServerConfiguration serverConfiguration;
+ private final Map authManagersByOasSecuritySchemes;
+ private final HttpMapper mapper;
+
+ private final String servicePlanId;
+
+ public InboundsServiceImpl(
+ HttpClient httpClient,
+ ServerConfiguration serverConfiguration,
+ Map authManagersByOasSecuritySchemes,
+ HttpMapper mapper,
+ String servicePlanId) {
+ this.httpClient = httpClient;
+ this.serverConfiguration = serverConfiguration;
+ this.authManagersByOasSecuritySchemes = authManagersByOasSecuritySchemes;
+ this.mapper = mapper;
+ this.servicePlanId = servicePlanId;
+ }
+
+ public ListInboundsResponse list() throws ApiException {
+
+ return list(null);
+ }
+
+ public ListInboundsResponse list(ListInboundMessagesQueryParameters queryParameter)
+ throws ApiException {
+
+ LOGGER.finest("[list]" + " " + "queryParameter: " + queryParameter);
+
+ HttpRequest httpRequest = listRequestBuilder(queryParameter);
+ HttpResponse response =
+ httpClient.invokeAPI(
+ this.serverConfiguration, this.authManagersByOasSecuritySchemes, httpRequest);
+
+ if (HttpStatus.isSuccessfulStatus(response.getCode())) {
+
+ ApiInboundList deserialized =
+ mapper.deserialize(response, new TypeReference() {});
+
+ return new ListInboundsResponse(
+ this,
+ new Page<>(
+ queryParameter,
+ deserialized.getItems(),
+ new SMSCursorPageNavigator(deserialized.getPage(), deserialized.getPageSize())));
+ }
+ // fallback to default errors handling:
+ // all error cases definition are not required from specs: will try some "hardcoded" content
+ // parsing
+ throw ApiExceptionBuilder.build(
+ response.getMessage(),
+ response.getCode(),
+ mapper.deserialize(response, new TypeReference