From 6af764f4422a0f79d5b28eeaee2f14af1bf3833b Mon Sep 17 00:00:00 2001 From: "AD\\thofor" Date: Tue, 17 Sep 2024 11:32:49 +0200 Subject: [PATCH 1/5] Remove double encoding of the service plan id for requests. Add parsing for generic bad request responses which are not covered by regular ApiErrors. --- pom.xml | 2 +- .../java/com/sinch/xms/ApiConnection.java | 8 +- .../xms/BadRequestResponseException.java | 84 +++ .../com/sinch/xms/EmptyAsyncConsumer.java | 11 +- .../com/sinch/xms/JsonApiAsyncConsumer.java | 11 +- src/main/java/com/sinch/xms/Utils.java | 9 +- .../com/sinch/xms/api/BadRequestError.java | 78 +++ .../java/com/sinch/xms/ApiConnectionIT.java | 637 ++++++------------ 8 files changed, 401 insertions(+), 439 deletions(-) create mode 100644 src/main/java/com/sinch/xms/BadRequestResponseException.java create mode 100644 src/main/java/com/sinch/xms/api/BadRequestError.java diff --git a/pom.xml b/pom.xml index 543a194..8041bf8 100644 --- a/pom.xml +++ b/pom.xml @@ -314,7 +314,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.12.0 + 2.43.0 diff --git a/src/main/java/com/sinch/xms/ApiConnection.java b/src/main/java/com/sinch/xms/ApiConnection.java index 6d9e12f..e8fbb41 100644 --- a/src/main/java/com/sinch/xms/ApiConnection.java +++ b/src/main/java/com/sinch/xms/ApiConnection.java @@ -51,10 +51,8 @@ import com.sinch.xms.api.TagsUpdate; import java.io.Closeable; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -313,19 +311,15 @@ protected void check() { @Nonnull private URI endpoint(@Nonnull String subPath, @Nonnull List params) { try { - String spid = URLEncoder.encode(servicePlanId(), "UTF-8"); - String path = endpoint().getPath() + "/v1/" + spid + subPath; + String path = endpoint().getPath() + "/v1/" + servicePlanId() + subPath; URIBuilder uriBuilder = new URIBuilder(endpoint()).setPath(path); if (!params.isEmpty()) { uriBuilder.setParameters(params); } - return uriBuilder.build(); } catch (URISyntaxException e) { throw new IllegalArgumentException(e); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); } } diff --git a/src/main/java/com/sinch/xms/BadRequestResponseException.java b/src/main/java/com/sinch/xms/BadRequestResponseException.java new file mode 100644 index 0000000..d5f763b --- /dev/null +++ b/src/main/java/com/sinch/xms/BadRequestResponseException.java @@ -0,0 +1,84 @@ +/*- + * #%L + * SDK for Sinch SMS + * %% + * Copyright (C) 2016 Sinch + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.sinch.xms; + +import com.sinch.xms.api.BadRequestError; + +/** + * Exception representing a non api error response from XMS. This exception is thrown when some fundamental + * contract of the XMS API has been broken. + * + *

For information about specific errors please refer to the XMS API documentation. + */ +public class BadRequestResponseException extends ApiException { + + private static final long serialVersionUID = 1L; + + private final Integer status; + private final String path; + private final String timestamp; + private final String error; + + BadRequestResponseException(BadRequestError error) { + super(error.path()); + + this.status = error.status(); + this.path = error.path(); + this.timestamp = error.timestamp(); + this.error = error.error(); + } + + /** + * The machine readable HTTP status code. + * + * @return the status code. + */ + public Integer getStatus() { + return status; + } + + /** + * The path of the request. + * + * @return the path text + */ + public String getPath() { + return path; + } + + /** + * The timestamp of the error. + * + * @return the timestamp as a string. + */ + public String getTimestamp() { + return timestamp; + } + + /** + * The human readable HTTP error text for the status. + * + * @return the error text + */ + public String getError() { + return error; + } +} diff --git a/src/main/java/com/sinch/xms/EmptyAsyncConsumer.java b/src/main/java/com/sinch/xms/EmptyAsyncConsumer.java index 553da5a..16b424b 100644 --- a/src/main/java/com/sinch/xms/EmptyAsyncConsumer.java +++ b/src/main/java/com/sinch/xms/EmptyAsyncConsumer.java @@ -20,7 +20,9 @@ package com.sinch.xms; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.ValueInstantiationException; import com.sinch.xms.api.ApiError; +import com.sinch.xms.api.BadRequestError; import java.io.IOException; import java.nio.CharBuffer; import org.apache.http.HttpException; @@ -82,8 +84,13 @@ protected Void buildResult(HttpContext context) throws Exception { return null; case HttpStatus.SC_BAD_REQUEST: case HttpStatus.SC_FORBIDDEN: - ApiError error = json.readValue(content, ApiError.class); - throw new ErrorResponseException(error); + try { + ApiError error = json.readValue(content, ApiError.class); + throw new ErrorResponseException(error); + } catch (ValueInstantiationException e) { + BadRequestError error = json.readValue(content, BadRequestError.class); + throw new BadRequestResponseException(error); + } case HttpStatus.SC_NOT_FOUND: HttpCoreContext coreContext = HttpCoreContext.adapt(context); RequestLine rl = coreContext.getRequest().getRequestLine(); diff --git a/src/main/java/com/sinch/xms/JsonApiAsyncConsumer.java b/src/main/java/com/sinch/xms/JsonApiAsyncConsumer.java index 673ca7b..35ad443 100644 --- a/src/main/java/com/sinch/xms/JsonApiAsyncConsumer.java +++ b/src/main/java/com/sinch/xms/JsonApiAsyncConsumer.java @@ -20,7 +20,9 @@ package com.sinch.xms; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.ValueInstantiationException; import com.sinch.xms.api.ApiError; +import com.sinch.xms.api.BadRequestError; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; @@ -87,8 +89,13 @@ protected T buildResult(HttpContext context) throws Exception { return null; case HttpStatus.SC_BAD_REQUEST: case HttpStatus.SC_FORBIDDEN: - ApiError error = json.readValue(inputStream, ApiError.class); - throw new ErrorResponseException(error); + try { + ApiError error = json.readValue(inputStream, ApiError.class); + throw new ErrorResponseException(error); + } catch (ValueInstantiationException e) { + BadRequestError error = json.readValue(bios.toInputStream(), BadRequestError.class); + throw new BadRequestResponseException(error); + } case HttpStatus.SC_NOT_FOUND: HttpCoreContext coreContext = HttpCoreContext.adapt(context); RequestLine rl = coreContext.getRequest().getRequestLine(); diff --git a/src/main/java/com/sinch/xms/Utils.java b/src/main/java/com/sinch/xms/Utils.java index 540a8e5..1d31bca 100644 --- a/src/main/java/com/sinch/xms/Utils.java +++ b/src/main/java/com/sinch/xms/Utils.java @@ -106,14 +106,19 @@ static T requireNonNull(T o, String name) { * @throws NotFoundException if the desired resource was not found */ static ConcurrentException unwrapExecutionException(ExecutionException e) - throws ErrorResponseException, UnexpectedResponseException, UnauthorizedException, - NotFoundException { + throws ErrorResponseException, + UnexpectedResponseException, + UnauthorizedException, + NotFoundException, + BadRequestResponseException { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } else if (e.getCause() instanceof Error) { throw (Error) e.getCause(); } else if (e.getCause() instanceof ErrorResponseException) { throw (ErrorResponseException) e.getCause(); + } else if (e.getCause() instanceof BadRequestResponseException) { + throw (BadRequestResponseException) e.getCause(); } else if (e.getCause() instanceof NotFoundException) { throw (NotFoundException) e.getCause(); } else if (e.getCause() instanceof UnexpectedResponseException) { diff --git a/src/main/java/com/sinch/xms/api/BadRequestError.java b/src/main/java/com/sinch/xms/api/BadRequestError.java new file mode 100644 index 0000000..16ebfd9 --- /dev/null +++ b/src/main/java/com/sinch/xms/api/BadRequestError.java @@ -0,0 +1,78 @@ +/*- + * #%L + * SDK for Sinch SMS + * %% + * Copyright (C) 2016 Sinch + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.sinch.xms.api; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.sinch.xms.BadRequestResponseException; +import javax.annotation.Nonnull; +import org.immutables.value.Value; + +/** + * API object containing an error response. + * + * @see BadRequestResponseException + */ +@Value.Immutable +@ValueStylePackageDirect +@JsonDeserialize(as = BadRequestErrorImpl.class) +public abstract class BadRequestError { + + /** + * The timestamp of the error. + * + * @return a non-null string + */ + public abstract String timestamp(); + + /** + * The machine readable HTTP status code. + * + * @return a non-null integer + */ + public abstract Integer status(); + + /** + * The human readable HTTP error text for the status. + * + * @return a non-null string + */ + public abstract String error(); + + /** + * The path of the request. + * + * @return a non-null string + */ + public abstract String path(); + + /** + * Creates a new bad request error object from the given timestamp, status, error and path. + * + * @param timestamp the timestamp of the error + * @param status the status code + * @param error the error message + * @param path the path + * @return a non-null Bad request error object + */ + @Nonnull + public static BadRequestError of(String timestamp, Integer status, String error, String path) { + return BadRequestErrorImpl.of(timestamp, status, error, path); + } +} diff --git a/src/test/java/com/sinch/xms/ApiConnectionIT.java b/src/test/java/com/sinch/xms/ApiConnectionIT.java index c9db4b0..aed2637 100644 --- a/src/test/java/com/sinch/xms/ApiConnectionIT.java +++ b/src/test/java/com/sinch/xms/ApiConnectionIT.java @@ -94,7 +94,6 @@ import java.util.List; import java.util.Queue; import java.util.Set; -import java.util.TreeSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -174,18 +173,14 @@ public void canCreateBinaryBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchBinarySmsResult actual = conn.createBatch(request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -223,18 +218,14 @@ public void canCreateTextBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchTextSmsResult actual = conn.createBatch(request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -279,18 +270,14 @@ public void canCreateTextBatchWithSubstitutions() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchTextSmsResult actual = conn.createBatch(request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -327,18 +314,14 @@ public void canCreateMmsBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchMmsResult actual = conn.createBatch(request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -363,21 +346,17 @@ public void canHandleBatchCreateWithError() throws Exception { stubPostResponse(apiError, path, 400); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.createBatch(request); fail("Expected exception, got none"); } catch (ErrorResponseException e) { assertThat(e.getCode(), is(apiError.code())); assertThat(e.getText(), is(apiError.text())); - } finally { - conn.close(); } } @@ -422,20 +401,63 @@ public void canHandleBatchCreateWithInvalidJson() throws Exception { .withHeader("Content-Type", "application/json; charset=UTF-8") .withBody(response))); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.createBatch(request); fail("Expected exception, got none"); } catch (ConcurrentException e) { assertThat(e.getCause(), is(instanceOf(JsonParseException.class))); - } finally { - conn.close(); + } + } + + @Test + public void canHandleBatchCreateWithInvalidServicePlanId() throws Exception { + String spid = "%&! #$"; + + MtBatchTextSmsCreate request = + SinchSMSApi.batchTextSms() + .sender("12345") + .addRecipient("123456789") + .addRecipient("987654321") + .body("Hello, world!") + .build(); + + String response = + String.join( + "\n", + "{", + " 'timestamp': '2024-09-13T09:10:58Z',", + " 'status': 400,", + " 'error': 'Bad Request',", + " 'path': '/xms/v1/%25%26%21%20%23%24'", + "}") + .replace('\'', '"'); + + String path = "/v1/%25&!%20%23$/batches"; + + wm.stubFor( + post(urlEqualTo(path)) + .willReturn( + aResponse() + .withStatus(400) + .withHeader("Content-Type", "application/json; charset=UTF-8") + .withBody(response))); + + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("toktok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { + conn.createBatch(request); + fail("Expected exception, got none"); + } catch (BadRequestResponseException e) { + assertThat(e.getPath(), is("/xms/v1/%25%26%21%20%23%24")); + assertThat(e.getStatus(), is(400)); } } @@ -480,13 +502,6 @@ public void canHandleAsyncBatchCreateWithInvalidJson() throws Exception { .withHeader("Content-Type", "application/json; charset=UTF-8") .withBody(response))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("toktok") - .endpoint("http://localhost:" + wm.port()) - .start(); - FutureCallback callback = new TestCallback() { @@ -496,13 +511,16 @@ public void failed(Exception e) { } }; - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("toktok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { conn.createBatchAsync(request, callback).get(); fail("Expected exception, got none"); } catch (ExecutionException e) { assertThat(e.getCause(), is(instanceOf(JsonParseException.class))); - } finally { - conn.close(); } } @@ -522,18 +540,14 @@ public void canHandleBatchCreateWithUnauthorized() throws Exception { stubPostResponse("", path, HttpStatus.SC_UNAUTHORIZED); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.createBatch(request); fail("Expected exception, got none"); - } finally { - conn.close(); } } @@ -553,13 +567,6 @@ public void canHandleAsyncBatchCreateWithUnauthorized() throws Exception { stubPostResponse("", path, HttpStatus.SC_UNAUTHORIZED); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("toktok") - .endpoint("http://localhost:" + wm.port()) - .start(); - FutureCallback callback = new TestCallback() { @@ -569,13 +576,16 @@ public void failed(Exception e) { } }; - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("toktok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { conn.createBatchAsync(request, callback).get(); fail("Expected exception, got none"); } catch (ExecutionException e) { assertThat(e.getCause(), is(instanceOf(UnauthorizedException.class))); - } finally { - conn.close(); } } @@ -613,18 +623,14 @@ public void canReplaceBinaryBatch() throws Exception { stubPutResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchBinarySmsResult actual = conn.replaceBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -662,18 +668,14 @@ public void canReplaceTextBatch() throws Exception { stubPutResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchTextSmsResult actual = conn.replaceBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -710,18 +712,14 @@ public void canReplaceMmsBatch() throws Exception { stubPutResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchMmsResult actual = conn.replaceBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -759,18 +757,14 @@ public void canUpdateSimpleTextBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchTextSmsResult actual = conn.updateBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -782,10 +776,6 @@ public void canUpdateSimpleBinaryBatch() throws Exception { BatchId batchId = TestUtils.freshBatchId(); OffsetDateTime time = OffsetDateTime.of(2016, 10, 2, 9, 34, 28, 542000000, ZoneOffset.UTC); - Set tags = new TreeSet(); - tags.add("tag1"); - tags.add("tag2"); - MtBatchBinarySmsUpdate request = SinchSMSApi.batchBinarySmsUpdate() .sender("12345") @@ -812,18 +802,14 @@ public void canUpdateSimpleBinaryBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchBinarySmsResult actual = conn.updateBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -860,18 +846,14 @@ public void canUpdateSimpleMmsBatch() throws Exception { stubPostResponse(expected, path, 201); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchMmsResult actual = conn.updateBatch(batchId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -901,18 +883,14 @@ public void canFetchTextBatch() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchResult actual = conn.fetchBatch(batchId); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -942,14 +920,12 @@ public void canFetchTextBatchAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -961,8 +937,6 @@ public void completed(MtBatchResult result) { MtBatchResult actual = conn.fetchBatchAsync(batchId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -993,14 +967,12 @@ public void canFetchBinaryBatch() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -1012,8 +984,6 @@ public void completed(MtBatchResult result) { MtBatchResult actual = conn.fetchBatchAsync(batchId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1034,20 +1004,16 @@ public void canHandle404WhenFetchingBatchSync() throws Exception { .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()) .withBody("BAD"))); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.fetchBatch(batchId); fail("Expected exception, got none"); } catch (NotFoundException e) { assertThat(e.getPath(), is(path)); - } finally { - conn.close(); } } @@ -1066,13 +1032,6 @@ public void canHandle404WhenFetchingBatchAsync() throws Exception { .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()) .withBody("BAD"))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("toktok") - .endpoint("http://localhost:" + wm.port()) - .start(); - FutureCallback callback = new TestCallback() { @@ -1084,13 +1043,16 @@ public void failed(Exception e) { } }; - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("toktok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { conn.fetchBatchAsync(batchId, callback).get(); fail("Expected exception, got none"); } catch (ExecutionException e) { assertThat(e.getCause(), is(instanceOf(NotFoundException.class))); - } finally { - conn.close(); } } @@ -1109,20 +1071,18 @@ public void canHandle500WhenFetchingBatch() throws Exception { .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()) .withBody("BAD"))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("tok") - .endpoint("http://localhost:" + wm.port()) - .start(); - /* * The exception we'll receive in the callback. Need to store it to * verify that it is the same exception as received from #get(). */ final AtomicReference failException = new AtomicReference(); - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("tok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { /* * Used to make sure callback and test thread are agreeing about the * failException variable. @@ -1186,8 +1146,6 @@ public void failed(Exception exception) { assertThat(read, is(3)); assertThat(Arrays.copyOf(buf, 3), is(new byte[] {'B', 'A', 'D'})); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1216,18 +1174,14 @@ public void canCancelBatch() throws Exception { stubDeleteResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchResult result = conn.cancelBatch(batchId); assertThat(result, is(expected)); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -1289,14 +1243,12 @@ public void canCancelBatchConcurrently() throws Exception { stubDeleteResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { final Queue results = new ConcurrentArrayQueue(); final CountDownLatch latch = new CountDownLatch(2); @@ -1321,8 +1273,6 @@ public void completed(MtBatchResult result) { assertThat(results.size(), is(2)); assertThat(results.poll(), is(expected2)); assertThat(results.poll(), is(expected1)); - } finally { - conn.close(); } verifyDeleteRequest(path1); @@ -1340,14 +1290,12 @@ public void canListBatchesWithEmpty() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -1361,8 +1309,6 @@ public void completed(Page result) { Page actual = fetcher.fetchAsync(0, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1389,14 +1335,12 @@ public void canListBatchesWithTwoPages() throws Exception { stubGetResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -1422,8 +1366,6 @@ public void completed(Page result) { Page actual2 = fetcher.fetchAsync(1, testCallback).get(); assertThat(actual2, is(expected2)); - } finally { - conn.close(); } verifyGetRequest(path1); @@ -1487,14 +1429,12 @@ public void canIterateOverPages() throws Exception { stubGetResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { PagedFetcher fetcher = conn.fetchBatches(filter); List> actuals = new ArrayList<>(); @@ -1508,8 +1448,6 @@ public void canIterateOverPages() throws Exception { expecteds.add(expected2); assertThat(actuals, is(expecteds)); - } finally { - conn.close(); } verifyGetRequest(path1); @@ -1573,14 +1511,12 @@ public void canIterateOverBatchesWithTwoPages() throws Exception { stubGetResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { PagedFetcher fetcher = conn.fetchBatches(filter); List actuals = new ArrayList<>(); @@ -1594,8 +1530,6 @@ public void canIterateOverBatchesWithTwoPages() throws Exception { expecteds.addAll(expected2.content()); assertThat(actuals, is(expecteds)); - } finally { - conn.close(); } verifyGetRequest(path1); @@ -1637,13 +1571,6 @@ public void canFetchDeliveryReportSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("tok") - .endpoint("http://localhost:" + wm.port()) - .start(); - BatchDeliveryReportParams filter = SinchSMSApi.batchDeliveryReportParams() .summaryReport() @@ -1651,11 +1578,14 @@ public void canFetchDeliveryReportSync() throws Exception { .addCode(200, 300) .build(); - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("tok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { BatchDeliveryReport actual = conn.fetchDeliveryReport(batchId, filter); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1690,16 +1620,14 @@ public void canFetchDeliveryReportAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + BatchDeliveryReportParams filter = SinchSMSApi.batchDeliveryReportParams().fullReport().build(); + + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - BatchDeliveryReportParams filter = SinchSMSApi.batchDeliveryReportParams().fullReport().build(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -1712,8 +1640,6 @@ public void completed(BatchDeliveryReport result) { BatchDeliveryReport actual = conn.fetchDeliveryReportAsync(batchId, filter, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1741,18 +1667,14 @@ public void canFetchRecipientDeliveryReportSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { RecipientDeliveryReport actual = conn.fetchDeliveryReport(batchId, recipient); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1763,9 +1685,10 @@ public void canFetchDeliveryReports() throws Exception { String spid = TestUtils.freshServicePlanId(); BatchId batchId = TestUtils.freshBatchId(); String recipient = "987654321"; - DeliveryReportFilter filter = SinchSMSApi.deliveryReportFilter().build(); + DeliveryReportFilter filter = + SinchSMSApi.deliveryReportFilter().clientReference("%&! #$").build(); - String path = "/v1/" + spid + "/delivery_reports?page=0"; + String path = "/v1/" + spid + "/delivery_reports?page=0&client_reference=%25%26%21+%23%24"; final RecipientDeliveryReportSms expected1 = RecipientDeliveryReportSms.builder() @@ -1789,19 +1712,15 @@ public void canFetchDeliveryReports() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { PagedFetcher fetcher = conn.fetchDeliveryReports(filter); Page actual = fetcher.fetch(0); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1829,14 +1748,12 @@ public void canFetchRecipientDeliveryReportAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -1849,8 +1766,6 @@ public void completed(RecipientDeliveryReport result) { RecipientDeliveryReport actual = conn.fetchDeliveryReportAsync(batchId, recipient, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -1932,18 +1847,14 @@ public void canCreateBatchDryRunSync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MtBatchDryRunResult actual = conn.createBatchDryRun(request, null, null); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -1967,14 +1878,12 @@ public void canCreateBatchDryRunAsync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -1987,8 +1896,6 @@ public void completed(MtBatchDryRunResult result) { MtBatchDryRunResult actual = conn.createBatchDryRunAsync(request, true, 5, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -2032,18 +1939,14 @@ public void canCreateGroupSync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { GroupResult actual = conn.createGroup(request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -2087,14 +1990,12 @@ public void canCreateGroupAsync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -2106,8 +2007,6 @@ public void completed(GroupResult result) { GroupResult actual = conn.createGroupAsync(request, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -2137,18 +2036,14 @@ public void canFetchGroupSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { GroupResult actual = conn.fetchGroup(groupId); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -2178,14 +2073,12 @@ public void canFetchGroupAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -2197,8 +2090,6 @@ public void completed(GroupResult result) { GroupResult actual = conn.fetchGroupAsync(groupId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -2215,18 +2106,14 @@ public void canFetchGroupMembersSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { Set actual = conn.fetchGroupMembers(groupId); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -2243,14 +2130,12 @@ public void canFetchGroupMembersAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -2262,8 +2147,6 @@ public void completed(Set result) { Set actual = conn.fetchGroupMembersAsync(groupId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -2280,14 +2163,12 @@ public void canListGroupsWithEmpty() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -2301,8 +2182,6 @@ public void completed(Page result) { Page actual = fetcher.fetchAsync(0, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -2329,14 +2208,12 @@ public void canListGroupsWithTwoPages() throws Exception { stubGetResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -2362,8 +2239,6 @@ public void completed(Page result) { Page actual2 = fetcher.fetchAsync(1, testCallback).get(); assertThat(actual2, is(expected2)); - } finally { - conn.close(); } verifyGetRequest(path1); @@ -2394,18 +2269,14 @@ public void canUpdateGroupSync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { GroupResult actual = conn.updateGroup(groupId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -2435,14 +2306,12 @@ public void canUpdateGroupAsync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -2454,8 +2323,6 @@ public void completed(GroupResult result) { GroupResult actual = conn.updateGroupAsync(groupId, request, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -2499,18 +2366,14 @@ public void canReplaceGroupSync() throws Exception { stubPutResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { GroupResult actual = conn.replaceGroup(groupId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -2554,14 +2417,12 @@ public void canReplaceGroupAsync() throws Exception { stubPutResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -2573,8 +2434,6 @@ public void completed(GroupResult result) { GroupResult actual = conn.replaceGroupAsync(groupId, request, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -2604,17 +2463,13 @@ public void canDeleteGroupSync() throws Exception { stubDeleteResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.deleteGroup(groupId); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2644,14 +2499,12 @@ public void canDeleteGroupAsync() throws Exception { stubDeleteResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -2662,8 +2515,6 @@ public void completed(Void result) { }; conn.deleteGroupAsync(groupId, testCallback).get(); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2686,21 +2537,17 @@ public void canHandle400WhenDeletingGroupSync() throws Exception { .withHeader("Content-Type", "application/json") .withBody(json.writeValueAsBytes(apiError)))); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.deleteGroup(groupId); fail("Expected exception, got none"); } catch (ErrorResponseException e) { assertThat(e.getCode(), is(apiError.code())); assertThat(e.getText(), is(apiError.text())); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2719,20 +2566,16 @@ public void canHandle401WhenDeletingGroupSync() throws Exception { .withStatus(401) .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()))); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.deleteGroup(groupId); fail("Expected exception, got none"); } catch (UnauthorizedException e) { // This exception is expected. - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2752,13 +2595,6 @@ public void canHandle401WhenDeletingGroupAsync() throws Exception { .withStatus(401) .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("tok") - .endpoint("http://localhost:" + wm.port()) - .start(); - FutureCallback callback = new TestCallback() { @@ -2768,13 +2604,16 @@ public void failed(Exception e) { } }; - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("tok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { conn.deleteGroupAsync(groupId, callback).get(); fail("Expected exception, got none"); } catch (ExecutionException e) { assertThat(e.getCause(), is(instanceOf(UnauthorizedException.class))); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2793,20 +2632,16 @@ public void canHandle404WhenDeletingGroupSync() throws Exception { .withStatus(404) .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()))); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { conn.deleteGroup(groupId); fail("Expected exception, got none"); } catch (NotFoundException e) { assertThat(e.getPath(), is(path)); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2826,13 +2661,6 @@ public void canHandle404WhenDeletingGroupAsync() throws Exception { .withStatus(404) .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("tok") - .endpoint("http://localhost:" + wm.port()) - .start(); - FutureCallback callback = new TestCallback() { @@ -2844,13 +2672,16 @@ public void failed(Exception e) { } }; - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("tok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { conn.deleteGroupAsync(groupId, callback).get(); fail("Expected exception, got none"); } catch (ExecutionException e) { assertThat(e.getCause(), is(instanceOf(NotFoundException.class))); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2871,20 +2702,18 @@ public void canHandle500WhenDeletingGroup() throws Exception { .withHeader("Content-Type", ContentType.TEXT_PLAIN.toString()) .withBody("BAD"))); - ApiConnection conn = - ApiConnection.builder() - .servicePlanId(spid) - .token("tok") - .endpoint("http://localhost:" + wm.port()) - .start(); - /* * The exception we'll receive in the callback. Need to store it to * verify that it is the same exception as received from #get(). */ final AtomicReference failException = new AtomicReference(); - try { + try (ApiConnection conn = + ApiConnection.builder() + .servicePlanId(spid) + .token("tok") + .endpoint("http://localhost:" + wm.port()) + .start(); ) { /* * Used to make sure callback and test thread are agreeing about the * failException variable. @@ -2948,8 +2777,6 @@ public void failed(Exception exception) { assertThat(read, is(3)); assertThat(Arrays.copyOf(buf, 3), is(new byte[] {'B', 'A', 'D'})); - } finally { - conn.close(); } verifyDeleteRequest(path); @@ -2972,18 +2799,14 @@ public void canUpdateGroupTagsSync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { Tags actual = conn.updateTags(groupId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -3006,14 +2829,12 @@ public void canUpdateGroupTagsAsync() throws Exception { stubPostResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -3025,8 +2846,6 @@ public void completed(Tags result) { Tags actual = conn.updateTagsAsync(groupId, request, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPostRequest(path, request); @@ -3045,18 +2864,14 @@ public void canReplaceGroupTagsSync() throws Exception { stubPutResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { Tags actual = conn.replaceTags(groupId, request); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -3075,14 +2890,12 @@ public void canReplaceGroupTagsAsync() throws Exception { stubPutResponse(expected, path, 200); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("toktok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -3094,8 +2907,6 @@ public void completed(Tags result) { Tags actual = conn.replaceTagsAsync(groupId, request, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyPutRequest(path, request); @@ -3112,18 +2923,14 @@ public void canFetchGroupTagsSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { Tags actual = conn.fetchTags(groupId); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -3140,14 +2947,12 @@ public void canFetchGroupTagsAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -3159,8 +2964,6 @@ public void completed(Tags result) { Tags actual = conn.fetchTagsAsync(groupId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -3176,14 +2979,12 @@ public void canListInboundsWithEmpty() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -3197,8 +2998,6 @@ public void completed(Page result) { Page actual = fetcher.fetchAsync(0, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -3256,14 +3055,12 @@ public void canListInboundsWithTwoPages() throws Exception { stubGetResponse(expected2, path2); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback> testCallback = new TestCallback>() { @@ -3289,8 +3086,6 @@ public void completed(Page result) { Page actual2 = fetcher.fetchAsync(1, testCallback).get(); assertThat(actual2, is(expected2)); - } finally { - conn.close(); } verifyGetRequest(path1); @@ -3320,18 +3115,14 @@ public void canFetchInboundSync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { MoSms actual = conn.fetchInbound(smsId); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); @@ -3360,14 +3151,12 @@ public void canFetchInboundAsync() throws Exception { stubGetResponse(expected, path); - ApiConnection conn = + try (ApiConnection conn = ApiConnection.builder() .servicePlanId(spid) .token("tok") .endpoint("http://localhost:" + wm.port()) - .start(); - - try { + .start(); ) { FutureCallback testCallback = new TestCallback() { @@ -3379,8 +3168,6 @@ public void completed(MoSms result) { MoSms actual = conn.fetchInboundAsync(smsId, testCallback).get(); assertThat(actual, is(expected)); - } finally { - conn.close(); } verifyGetRequest(path); From 639bcc6ec3379fbd9aa346df99027126e1e65b53 Mon Sep 17 00:00:00 2001 From: "AD\\thofor" Date: Tue, 17 Sep 2024 11:35:00 +0200 Subject: [PATCH 2/5] Spotless fix --- src/main/java/com/sinch/xms/BadRequestResponseException.java | 4 ++-- src/main/java/com/sinch/xms/api/MoMmsBody.java | 2 ++ src/main/java/com/sinch/xms/api/MoMmsMedia.java | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sinch/xms/BadRequestResponseException.java b/src/main/java/com/sinch/xms/BadRequestResponseException.java index d5f763b..addf9c5 100644 --- a/src/main/java/com/sinch/xms/BadRequestResponseException.java +++ b/src/main/java/com/sinch/xms/BadRequestResponseException.java @@ -22,8 +22,8 @@ import com.sinch.xms.api.BadRequestError; /** - * Exception representing a non api error response from XMS. This exception is thrown when some fundamental - * contract of the XMS API has been broken. + * Exception representing a non api error response from XMS. This exception is thrown when some + * fundamental contract of the XMS API has been broken. * *

For information about specific errors please refer to the XMS API documentation. diff --git a/src/main/java/com/sinch/xms/api/MoMmsBody.java b/src/main/java/com/sinch/xms/api/MoMmsBody.java index 19391ef..b885383 100644 --- a/src/main/java/com/sinch/xms/api/MoMmsBody.java +++ b/src/main/java/com/sinch/xms/api/MoMmsBody.java @@ -56,6 +56,7 @@ public static final MoMmsBody.Builder builder() { */ @Nullable public abstract String subject(); + /** * The textual message body, if available. * @@ -63,6 +64,7 @@ public static final MoMmsBody.Builder builder() { */ @Nullable public abstract String message(); + /** * The list of attached media. * diff --git a/src/main/java/com/sinch/xms/api/MoMmsMedia.java b/src/main/java/com/sinch/xms/api/MoMmsMedia.java index 13ff28c..522ef2f 100644 --- a/src/main/java/com/sinch/xms/api/MoMmsMedia.java +++ b/src/main/java/com/sinch/xms/api/MoMmsMedia.java @@ -56,6 +56,7 @@ public static final MoMmsMedia.Builder builder() { */ @Nullable public abstract String url(); + /** * The content type of provided media. For example, 'image/jpeg' * @@ -67,6 +68,7 @@ public static final MoMmsMedia.Builder builder() { @Nonnull @JsonProperty("content_type") public abstract String contentType(); + /** * The status received while media upload to storage. Possible values are: Uploaded or Failed. * @@ -74,6 +76,7 @@ public static final MoMmsMedia.Builder builder() { */ @Nonnull public abstract MediaStatus status(); + /** * Error code in case of failure or 0 for success. * From 287c7f542298e5e57ff08ce1c69b29b8e006ff16 Mon Sep 17 00:00:00 2001 From: thomasf147 <70749161+thomasf147@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:39:18 +0200 Subject: [PATCH 3/5] Update pr.yaml Updating workflow actions/upload-artifact@v2 to v4 --- .github/workflows/pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index f118579..03e08a9 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -16,7 +16,7 @@ jobs: - name: Build with Maven run: mvn --batch-mode --update-snapshots verify -Dgpg.skip - run: mkdir snapshots && cp target/*.jar snapshots - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: Package path: snapshots From 3be8332fbaf92a567b62c801a876a0e1c5f5ee40 Mon Sep 17 00:00:00 2001 From: "AD\\thofor" Date: Tue, 17 Sep 2024 11:44:07 +0200 Subject: [PATCH 4/5] Revert spotless update --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8041bf8..543a194 100644 --- a/pom.xml +++ b/pom.xml @@ -314,7 +314,7 @@ com.diffplug.spotless spotless-maven-plugin - 2.43.0 + 2.12.0 From c399b2b0d369d0ab7f59162a6562418633b77e83 Mon Sep 17 00:00:00 2001 From: "AD\\thofor" Date: Tue, 17 Sep 2024 16:17:33 +0200 Subject: [PATCH 5/5] Fix spotless --- src/main/java/com/sinch/xms/Utils.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/sinch/xms/Utils.java b/src/main/java/com/sinch/xms/Utils.java index 1d31bca..fbdff08 100644 --- a/src/main/java/com/sinch/xms/Utils.java +++ b/src/main/java/com/sinch/xms/Utils.java @@ -106,11 +106,8 @@ static T requireNonNull(T o, String name) { * @throws NotFoundException if the desired resource was not found */ static ConcurrentException unwrapExecutionException(ExecutionException e) - throws ErrorResponseException, - UnexpectedResponseException, - UnauthorizedException, - NotFoundException, - BadRequestResponseException { + throws ErrorResponseException, UnexpectedResponseException, UnauthorizedException, + NotFoundException, BadRequestResponseException { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } else if (e.getCause() instanceof Error) {