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:
+ *
+ * - Supports basic authentication and token-based authentication strategies.
+ * - Allows configuration of custom HTTP clients and ObjectMapper for JSON processing.
+ * - Handles request retries for specific HTTP status codes (e.g., 401 Unauthorized).
+ * - Logs detailed request and response information for debugging purposes.
+ *
+ *
+ * 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());