diff --git a/CHANGELOG.md b/CHANGELOG.md index 8743503..f639fcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to the library will be documented in this file. The format of the file is based on [Keep a Changelog](http://keepachangelog.com/) and this library adheres to [Semantic Versioning](http://semver.org/) as mentioned in [README.md][readme] file. +## [ [6.1.1](https://github.com/infobip/infobip-api-java-client/releases/tag/6.1.1) ] - 2025-06-20 + +### Added +* Most recent feature set for [Infobip SMS API](https://www.infobip.com/docs/api/channels/sms). + * Cursor-based pagination support in `getOutboundSmsMessageLogs` function with `useCursor` and `cursor` parameters. + +### Changed +* `SmsLogsResponse` now includes cursor field to support cursor-based pagination. +* Updated Javadoc documentation for `SmsMessageDeliveryReporting`. + ## [ [6.1.0](https://github.com/infobip/infobip-api-java-client/releases/tag/6.1.0) ] - 2025-04-09 ⚠️ **IMPORTANT NOTE:** This release contains compile time breaking changes. diff --git a/README.md b/README.md index bcf0585..5ba5d4b 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Simply add the following in your project's POM file under `dependencies` tag: com.infobip infobip-api-java-client - 6.1.0 + 6.1.1 ``` diff --git a/pom.xml b/pom.xml index 7f79522..77a6490 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.infobip infobip-api-java-client - 6.1.0 + 6.1.1 jar infobip-api-java-client diff --git a/src/main/java/com/infobip/RequestFactory.java b/src/main/java/com/infobip/RequestFactory.java index 081ddbe..5dbe2a8 100644 --- a/src/main/java/com/infobip/RequestFactory.java +++ b/src/main/java/com/infobip/RequestFactory.java @@ -26,7 +26,7 @@ */ final class RequestFactory { - private static final String USER_AGENT_HEADER_VALUE = "infobip-api-client-java/6.1.0"; + private static final String USER_AGENT_HEADER_VALUE = "infobip-api-client-java/6.1.1"; private final ApiKey apiKey; private final BaseUrl baseUrl; diff --git a/src/main/java/com/infobip/api/SmsApi.java b/src/main/java/com/infobip/api/SmsApi.java index fdb7413..5a7d33d 100644 --- a/src/main/java/com/infobip/api/SmsApi.java +++ b/src/main/java/com/infobip/api/SmsApi.java @@ -331,7 +331,9 @@ private RequestDefinition getOutboundSmsMessageLogsDefinition( Integer limit, String entityId, String applicationId, - List campaignReferenceId) { + List campaignReferenceId, + Boolean useCursor, + String cursor) { RequestDefinition.Builder builder = RequestDefinition.builder("GET", "/sms/3/logs") .requiresAuthentication(true) .accept("application/json"); @@ -381,6 +383,12 @@ private RequestDefinition getOutboundSmsMessageLogsDefinition( builder.addQueryParameter(new Parameter("campaignReferenceId", parameterItem)); } } + if (useCursor != null) { + builder.addQueryParameter(new Parameter("useCursor", useCursor)); + } + if (cursor != null) { + builder.addQueryParameter(new Parameter("cursor", cursor)); + } return builder.build(); } @@ -401,6 +409,8 @@ public class GetOutboundSmsMessageLogsRequest { private String entityId; private String applicationId; private List campaignReferenceId; + private Boolean useCursor; + private String cursor; private GetOutboundSmsMessageLogsRequest() {} @@ -547,6 +557,28 @@ public GetOutboundSmsMessageLogsRequest campaignReferenceId(List campaig return this; } + /** + * Sets useCursor. + * + * @param useCursor Flag used to enable cursor-based pagination. When set to true, the system will use the cursor to fetch the next set of logs. (optional) + * @return GetOutboundSmsMessageLogsRequest + */ + public GetOutboundSmsMessageLogsRequest useCursor(Boolean useCursor) { + this.useCursor = useCursor; + return this; + } + + /** + * Sets cursor. + * + * @param cursor Value which represents the current position in the data set. For the first request, this field shouldn't be defined. In subsequent requests, use the `nextCursor` value returned from the previous response to continue fetching data. (optional) + * @return GetOutboundSmsMessageLogsRequest + */ + public GetOutboundSmsMessageLogsRequest cursor(String cursor) { + this.cursor = cursor; + return this; + } + /** * Executes the getOutboundSmsMessageLogs request. * @@ -567,7 +599,9 @@ public SmsLogsResponse execute() throws ApiException { limit, entityId, applicationId, - campaignReferenceId); + campaignReferenceId, + useCursor, + cursor); return apiClient.execute( getOutboundSmsMessageLogsDefinition, new TypeReference() {}.getType()); } @@ -592,7 +626,9 @@ public okhttp3.Call executeAsync(ApiCallback callback) { limit, entityId, applicationId, - campaignReferenceId); + campaignReferenceId, + useCursor, + cursor); return apiClient.executeAsync( getOutboundSmsMessageLogsDefinition, new TypeReference() {}.getType(), callback); } @@ -659,7 +695,7 @@ public okhttp3.Call executeAsync(ApiCallback callback) { /** * Get scheduled SMS messages. *

- * See all scheduled messages and their scheduled date and time. To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). + * See all [scheduled messages](https://www.infobip.com/docs/sms/sms-over-api#schedule-sms) and their scheduled date and time. To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). * * @param bulkId (required) * @return GetScheduledSmsMessagesRequest @@ -720,7 +756,7 @@ public okhttp3.Call executeAsync(ApiCallback callback) { /** * Get scheduled SMS messages status. *

- * See the status of scheduled messages. To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). + * See the status of [scheduled messages](https://www.infobip.com/docs/sms/sms-over-api#schedule-sms). To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). * * @param bulkId (required) * @return GetScheduledSmsMessagesStatusRequest @@ -842,7 +878,7 @@ public okhttp3.Call executeAsync(ApiCallback callback) { /** * Reschedule SMS messages. *

- * Change the date and time of already scheduled messages. To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). + * Change the date and time of already [scheduled messages](https://www.infobip.com/docs/sms/sms-over-api#schedule-sms). To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). * * @param bulkId (required) * @param smsBulkRequest (required) @@ -970,7 +1006,7 @@ public okhttp3.Call executeAsync(ApiCallback callback) { /** * Update scheduled SMS messages status. *

- * Change the status or completely cancel sending of scheduled messages. To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). + * Change the status or completely cancel sending of [scheduled messages](https://www.infobip.com/docs/sms/sms-over-api#schedule-sms). To schedule a message, use the `sendAt` field when [sending a message](https://www.infobip.com/docs/api/channels/sms/sms-messaging/outbound-sms/send-sms-message). * * @param bulkId (required) * @param smsUpdateStatusRequest (required) diff --git a/src/main/java/com/infobip/model/SmsCursorPageInfo.java b/src/main/java/com/infobip/model/SmsCursorPageInfo.java new file mode 100644 index 0000000..b198cbd --- /dev/null +++ b/src/main/java/com/infobip/model/SmsCursorPageInfo.java @@ -0,0 +1,146 @@ +/* + * This class is auto generated from the Infobip OpenAPI specification + * through the OpenAPI Specification Client API libraries (Re)Generator (OSCAR), + * powered by the OpenAPI Generator (https://openapi-generator.tech). + * + * Do not edit manually. To learn how to raise an issue, see the CONTRIBUTING guide + * or contact us @ support@infobip.com. + */ + +package com.infobip.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Objects; + +/** + * Cursor information. + */ +public class SmsCursorPageInfo { + + private Integer limit; + + private String nextCursor; + + /** + * Sets limit. + *

+ * Field description: + * Requested limit. + * + * @param limit + * @return This {@link SmsCursorPageInfo instance}. + */ + public SmsCursorPageInfo limit(Integer limit) { + this.limit = limit; + return this; + } + + /** + * Returns limit. + *

+ * Field description: + * Requested limit. + * + * @return limit + */ + @JsonProperty("limit") + public Integer getLimit() { + return limit; + } + + /** + * Sets limit. + *

+ * Field description: + * Requested limit. + * + * @param limit + */ + @JsonProperty("limit") + public void setLimit(Integer limit) { + this.limit = limit; + } + + /** + * Sets nextCursor. + *

+ * Field description: + * The `cursor` value you will use in your next request to fetch the subsequent set of results. + * + * @param nextCursor + * @return This {@link SmsCursorPageInfo instance}. + */ + public SmsCursorPageInfo nextCursor(String nextCursor) { + this.nextCursor = nextCursor; + return this; + } + + /** + * Returns nextCursor. + *

+ * Field description: + * The `cursor` value you will use in your next request to fetch the subsequent set of results. + * + * @return nextCursor + */ + @JsonProperty("nextCursor") + public String getNextCursor() { + return nextCursor; + } + + /** + * Sets nextCursor. + *

+ * Field description: + * The `cursor` value you will use in your next request to fetch the subsequent set of results. + * + * @param nextCursor + */ + @JsonProperty("nextCursor") + public void setNextCursor(String nextCursor) { + this.nextCursor = nextCursor; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SmsCursorPageInfo smsCursorPageInfo = (SmsCursorPageInfo) o; + return Objects.equals(this.limit, smsCursorPageInfo.limit) + && Objects.equals(this.nextCursor, smsCursorPageInfo.nextCursor); + } + + @Override + public int hashCode() { + return Objects.hash(limit, nextCursor); + } + + @Override + public String toString() { + String newLine = System.lineSeparator(); + return new StringBuilder() + .append("class SmsCursorPageInfo {") + .append(newLine) + .append(" limit: ") + .append(toIndentedString(limit)) + .append(newLine) + .append(" nextCursor: ") + .append(toIndentedString(nextCursor)) + .append(newLine) + .append("}") + .toString(); + } + + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + String lineSeparator = System.lineSeparator(); + String lineSeparatorFollowedByIndentation = lineSeparator + " "; + return o.toString().replace(lineSeparator, lineSeparatorFollowedByIndentation); + } +} diff --git a/src/main/java/com/infobip/model/SmsLogsResponse.java b/src/main/java/com/infobip/model/SmsLogsResponse.java index 3236f90..99f8f83 100644 --- a/src/main/java/com/infobip/model/SmsLogsResponse.java +++ b/src/main/java/com/infobip/model/SmsLogsResponse.java @@ -21,6 +21,8 @@ public class SmsLogsResponse { private List results = null; + private SmsCursorPageInfo cursor; + /** * Sets results. *

@@ -78,6 +80,37 @@ public void setResults(List results) { this.results = results; } + /** + * Sets cursor. + * + * @param cursor + * @return This {@link SmsLogsResponse instance}. + */ + public SmsLogsResponse cursor(SmsCursorPageInfo cursor) { + this.cursor = cursor; + return this; + } + + /** + * Returns cursor. + * + * @return cursor + */ + @JsonProperty("cursor") + public SmsCursorPageInfo getCursor() { + return cursor; + } + + /** + * Sets cursor. + * + * @param cursor + */ + @JsonProperty("cursor") + public void setCursor(SmsCursorPageInfo cursor) { + this.cursor = cursor; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -87,12 +120,13 @@ public boolean equals(Object o) { return false; } SmsLogsResponse smsLogsResponse = (SmsLogsResponse) o; - return Objects.equals(this.results, smsLogsResponse.results); + return Objects.equals(this.results, smsLogsResponse.results) + && Objects.equals(this.cursor, smsLogsResponse.cursor); } @Override public int hashCode() { - return Objects.hash(results); + return Objects.hash(results, cursor); } @Override @@ -104,6 +138,9 @@ public String toString() { .append(" results: ") .append(toIndentedString(results)) .append(newLine) + .append(" cursor: ") + .append(toIndentedString(cursor)) + .append(newLine) .append("}") .toString(); } diff --git a/src/main/java/com/infobip/model/SmsMessageDeliveryReporting.java b/src/main/java/com/infobip/model/SmsMessageDeliveryReporting.java index 0b43a8c..a226dea 100644 --- a/src/main/java/com/infobip/model/SmsMessageDeliveryReporting.java +++ b/src/main/java/com/infobip/model/SmsMessageDeliveryReporting.java @@ -27,7 +27,7 @@ public class SmsMessageDeliveryReporting { * Sets url. *

* Field description: - * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/api#notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. + * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/sms-over-api#push-retry-cycle-notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. * * @param url * @return This {@link SmsMessageDeliveryReporting instance}. @@ -41,7 +41,7 @@ public SmsMessageDeliveryReporting url(String url) { * Returns url. *

* Field description: - * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/api#notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. + * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/sms-over-api#push-retry-cycle-notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. * * @return url */ @@ -54,7 +54,7 @@ public String getUrl() { * Sets url. *

* Field description: - * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/api#notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. + * The URL on your call back server where a delivery report will be sent. If your URL becomes unavailable then the [retry cycle](https://www.infobip.com/docs/sms/sms-over-api#push-retry-cycle-notify-url) uses the following formula: `1min + (1min * retryNumber * retryNumber)`. * * @param url */ diff --git a/src/test/java/com/infobip/RequestFactoryTest.java b/src/test/java/com/infobip/RequestFactoryTest.java index 61d229a..1aee096 100644 --- a/src/test/java/com/infobip/RequestFactoryTest.java +++ b/src/test/java/com/infobip/RequestFactoryTest.java @@ -38,7 +38,7 @@ class RequestFactoryTest { private static final String GIVEN_API_KEY_VALUE = "apiKeyValue"; private static final ApiKey GIVEN_API_KEY = ApiKey.from(GIVEN_API_KEY_VALUE); - private static final String EXPECTED_USER_AGENT_HEADER_VALUE = "infobip-api-client-java/6.1.0"; + private static final String EXPECTED_USER_AGENT_HEADER_VALUE = "infobip-api-client-java/6.1.1"; private final OkHttpClient client = new OkHttpClient(); private final JSON json = new JSON(); diff --git a/src/test/java/com/infobip/api/SmsApiTest.java b/src/test/java/com/infobip/api/SmsApiTest.java index f3b69cd..345f480 100644 --- a/src/test/java/com/infobip/api/SmsApiTest.java +++ b/src/test/java/com/infobip/api/SmsApiTest.java @@ -977,6 +977,10 @@ void shouldGetSmsLogs() { var givenTextContent = "hello"; var givenContent = new SmsTextContent().text(givenTextContent); + var givenNextCursor = "next-cursor-id"; + var givenCursorLimit = 10; + var givenUseCursor = true; + String givenResponse = String.format( "{" + " \"results\": [" + " {" @@ -1040,7 +1044,11 @@ void shouldGetSmsLogs() { + " \"permanent\": %b" + " }" + " }" - + " ]" + + " ]," + + " \"cursor\": {" + + " \"limit\": %d," + + " \"nextCursor\": \"%s\"" + + " }" + "}", givenBulkId, givenApplicationId, @@ -1082,13 +1090,17 @@ void shouldGetSmsLogs() { NO_ERROR_ID, NO_ERROR_NAME, NO_ERROR_DESCRIPTION, - NO_ERROR_IS_PERMANENT); + NO_ERROR_IS_PERMANENT, + givenCursorLimit, + givenNextCursor); setUpSuccessGetRequest( LOGS, Map.of( "bulkId", givenBulkId, - "sentSince", givenSentSinceString), + "sentSince", givenSentSinceString, + "useCursor", Boolean.toString(givenUseCursor), + "cursor", givenNextCursor), givenResponse); SmsApi sendSmsApi = new SmsApi(getApiClient()); @@ -1141,12 +1153,19 @@ void shouldGetSmsLogs() { thenPriceIsEqualTo(anotherLog.getPrice(), givenPricePerMessageMessage2, givenCurrencyMessage2); thenStatusIsDelivered(anotherLog.getStatus()); thenNoError(anotherLog.getError()); + + SmsCursorPageInfo cursorPageInfo = smsLogsResponse.getCursor(); + then(cursorPageInfo).isNotNull(); + then(cursorPageInfo.getNextCursor()).isEqualTo(givenNextCursor); + then(cursorPageInfo.getLimit()).isEqualTo(givenCursorLimit); }; var call = sendSmsApi .getOutboundSmsMessageLogs() .bulkId(List.of(givenBulkId)) - .sentSince(givenSentSinceDateTime); + .sentSince(givenSentSinceDateTime) + .useCursor(givenUseCursor) + .cursor(givenNextCursor); testSuccessfulCall(call::execute, assertions); testSuccessfulAsyncCall(call::executeAsync, assertions); }