diff --git a/src/main/java/com/twilio/http/TwilioRestClient.java b/src/main/java/com/twilio/http/TwilioRestClient.java index d956d5b49d..a902f0fee6 100644 --- a/src/main/java/com/twilio/http/TwilioRestClient.java +++ b/src/main/java/com/twilio/http/TwilioRestClient.java @@ -3,20 +3,46 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.twilio.auth_strategy.AuthStrategy; -import com.twilio.auth_strategy.BasicAuthStrategy; -import com.twilio.auth_strategy.TokenAuthStrategy; import com.twilio.constant.EnumConstants; -import com.twilio.credential.ClientCredentialProvider; -import lombok.Getter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.Predicate; +import lombok.Getter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; - +/** + * The `TwilioRestClient` class is responsible for making HTTP requests to the Twilio API. + * It provides methods to configure authentication, region, edge, and other settings + * required to interact with Twilio's services. + * + *

Features:

+ * + * + *

Usage Example:

+ *
+ * {@code
+ * TwilioRestClient client = new TwilioRestClient.Builder(ACCOUNT_SID, AUTH_TOKEN)
+ *           .objectMapper(customMapper)
+ *           .build();
+ *
+ * Message message = Message
+ *           .creator(
+ *               new PhoneNumber("+1xxxxxxxxxx"),
+ *               new PhoneNumber("+1xxxxxxxxxx"),
+ *               "This is the ship that made the Kessel Run in fourteen parsecs?"
+ *           ).create(client);
+ * }
+ * 
+ * + *

Note: This class is designed to be thread-safe and reusable.

+ */ public class TwilioRestClient { public static final int HTTP_STATUS_CODE_CREATED = 201; @@ -51,14 +77,8 @@ protected TwilioRestClient(Builder b) { this.region = b.region; this.edge = b.edge; this.httpClient = b.httpClient; - this.objectMapper = new ObjectMapper(); + this.objectMapper = b.objectMapper; this.userAgentExtensions = b.userAgentExtensions; - - // This module configures the ObjectMapper to use - // public API methods for manipulating java.time.* - // classes. The alternative is to use reflection which - // generates warnings from the module system on Java 9+ - objectMapper.registerModule(new JavaTimeModule()); } /** @@ -71,7 +91,7 @@ public Response request(final Request request) { if (username != null && password != null) { request.setAuth(username, password); } else if (authStrategy != null) { - request.setAuth(authStrategy); + request.setAuth(authStrategy); } if (region != null) @@ -106,6 +126,13 @@ public Response request(final Request request) { } public static class Builder { + // This module configures the ObjectMapper to use + // public API methods for manipulating java.time.* + // classes. The alternative is to use reflection which + // generates warnings from the module system on Java 9+ + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper() + .registerModule(new JavaTimeModule()); + private String username; private String password; private AuthStrategy authStrategy; @@ -114,6 +141,7 @@ public static class Builder { private String edge; private HttpClient httpClient; private List userAgentExtensions; + private ObjectMapper objectMapper = DEFAULT_OBJECT_MAPPER; /** * Create a new Twilio Rest Client. @@ -163,6 +191,11 @@ public Builder userAgentExtensions(final List userAgentExtensions) { return this; } + public Builder objectMapper(final ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + return this; + } + /** * Build new TwilioRestClient. * diff --git a/src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java b/src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java index 0562c72534..f3ba9fac59 100644 --- a/src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java +++ b/src/main/java/com/twilio/http/bearertoken/BearerTokenTwilioRestClient.java @@ -44,23 +44,25 @@ private BearerTokenTwilioRestClient(BearerTokenTwilioRestClient.Builder b) { this.region = b.region; this.edge = b.edge; this.httpClient = b.httpClient; - this.objectMapper = new ObjectMapper(); + this.objectMapper = b.objectMapper; this.userAgentExtensions = b.userAgentExtensions; this.tokenManager = b.tokenManager; + } + public static class Builder { // This module configures the ObjectMapper to use // public API methods for manipulating java.time.* // classes. The alternative is to use reflection which // generates warnings from the module system on Java 9+ - objectMapper.registerModule(new JavaTimeModule()); - } - - public static class Builder { + private static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper() + .registerModule(new JavaTimeModule()); + private String region; private String edge; private BearerTokenHttpClient httpClient; private List userAgentExtensions; private TokenManager tokenManager; + private ObjectMapper objectMapper = DEFAULT_OBJECT_MAPPER; public Builder() { this.region = System.getenv("TWILIO_REGION"); @@ -95,6 +97,11 @@ public BearerTokenTwilioRestClient.Builder userAgentExtensions(final List userAgentExtensions; + private ObjectMapper objectMapper = DEFAULT_OBJECT_MAPPER; public Builder() { this.region = System.getenv("TWILIO_REGION"); @@ -82,6 +84,11 @@ public NoAuthTwilioRestClient.Builder userAgentExtensions(final List use return this; } + public NoAuthTwilioRestClient.Builder objectMapper(final ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + return this; + } + public NoAuthTwilioRestClient build() { if (this.httpClient == null) { this.httpClient = new NoAuthNetworkHttpClient(); diff --git a/src/test/java/com/twilio/http/TwilioRestClientTest.java b/src/test/java/com/twilio/http/TwilioRestClientTest.java index 862d72add2..f2bdfc466d 100644 --- a/src/test/java/com/twilio/http/TwilioRestClientTest.java +++ b/src/test/java/com/twilio/http/TwilioRestClientTest.java @@ -1,19 +1,22 @@ package com.twilio.http; -import com.twilio.rest.Domains; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.twilio.rest.Domains; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + public class TwilioRestClientTest { private TwilioRestClient twilioRestClient; @Mock @@ -48,6 +51,34 @@ public void testRequest() { assertNotNull(resp); } + @Test + public void testRequestWithCustomObjectMapper() { + Request request = new Request( + HttpMethod.GET, + Domains.API.toString(), + URI + ); + TwilioRestClient client = new TwilioRestClient.Builder(USER_NAME, TOKEN) + .objectMapper(new ObjectMapper().registerModule(new JavaTimeModule())) + .httpClient(httpClient) + .build(); + + when(httpClient.reliableRequest(request)).thenReturn(new Response("", 200)); + + Response resp = client.request(request); + assertNotNull(resp); + } + + @Test + public void testUsesSingletonDefaultObjectMapper() { + TwilioRestClient client1 = new TwilioRestClient.Builder(USER_NAME, TOKEN) + .build(); + TwilioRestClient client2 = new TwilioRestClient.Builder(USER_NAME, TOKEN) + .build(); + + assertTrue(client1.getObjectMapper() == client2.getObjectMapper()); + } + @Test public void testRequestWithExtension() { Request request = new Request( @@ -57,6 +88,7 @@ public void testRequestWithExtension() { ); twilioRestClientExtension = new TwilioRestClient.Builder(USER_NAME, TOKEN) .userAgentExtensions(userAgentStringExtensions) + .httpClient(httpClient) .build(); twilioRestClientExtension.request(request); assertEquals(userAgentStringExtensions, request.getUserAgentExtensions()); @@ -71,6 +103,7 @@ public void testRequestWithExtensionEmpty() { ); twilioRestClientExtension = new TwilioRestClient.Builder(USER_NAME, TOKEN) .userAgentExtensions(Collections.emptyList()) + .httpClient(httpClient) .build(); twilioRestClientExtension.request(request); assertNull(request.getUserAgentExtensions()); @@ -85,6 +118,7 @@ public void testRequestWithExtensionNull() { ); twilioRestClientExtension = new TwilioRestClient.Builder(USER_NAME, TOKEN) .userAgentExtensions(null) + .httpClient(httpClient) .build(); twilioRestClientExtension.request(request); assertNull(request.getUserAgentExtensions());