diff --git a/changelog.md b/changelog.md
index c98e8d7..80f1373 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,12 @@
# Changelog
+## v1.11.1
+
+### Apr 06, 2026
+
+- Fix: `setTimeout` now applies to OkHttp connect, read, and write timeouts (previously only connect). Optional `setConnectTimeout`, `setReadTimeout`, and `setWriteTimeout` override individual phases.
+- Build: Maven Surefire updated with `surefire-junit-platform` so JUnit 5 tests run when enabled.
+
## v1.11.0
### Feb 09, 2026
diff --git a/pom.xml b/pom.xml
index b978879..a0bbd32 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
cms
jar
contentstack-management-java
- 1.11.0
+ 1.11.1
Contentstack Java Management SDK for Content Management API, Contentstack is a headless CMS with an
API-first approach
@@ -89,11 +89,11 @@
3.0.0
5.2.2
3.1.12
- 2.12.0
- 2.12.0
- 5.1.0
+ 3.0.0
+ 3.0.0
+ 5.3.2
0.8.13
- 1.18.38
+ 1.18.42
5.11.4
5.10.1
2.13.2
@@ -101,6 +101,7 @@
1.5
3.8.0
2.5.3
+ 3.5.2
@@ -242,7 +243,14 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.0.0-M5
+ ${maven-surefire-plugin.version}
+
+
+ org.apache.maven.surefire
+ surefire-junit-platform
+ ${maven-surefire-plugin.version}
+
+
@@ -252,8 +260,9 @@
**/*TestCase.java
**/*TestSuite.java
- ${project.build.directory}/surefire-reports
- true
+ ${project.build.directory}/surefire-reports
+
+ true
true
diff --git a/src/main/java/com/contentstack/cms/Contentstack.java b/src/main/java/com/contentstack/cms/Contentstack.java
index 1bcad23..ebe847b 100644
--- a/src/main/java/com/contentstack/cms/Contentstack.java
+++ b/src/main/java/com/contentstack/cms/Contentstack.java
@@ -599,6 +599,9 @@ public static class Builder {
private String port = Util.PORT; // Default PORT for Contentstack API
private String version = Util.VERSION; // Default Version for Contentstack API
private int timeout = Util.TIMEOUT; // Default timeout 30 seconds
+ private Integer connectTimeoutSeconds;
+ private Integer readTimeoutSeconds;
+ private Integer writeTimeoutSeconds;
private Boolean retry = Util.RETRY_ON_FAILURE;// Default base url for contentstack
private RetryConfig retryConfig = RetryConfig.defaultConfig();
/**
@@ -687,10 +690,37 @@ public Builder setVersion(@NotNull String version) {
* @return Client timeout
*/
public Builder setTimeout(int timeout) {
+ validateTimeoutSeconds(timeout, "timeout");
this.timeout = timeout;
return this;
}
+ public Builder setReadTimeout(int readTimeoutSeconds) {
+ validateTimeoutSeconds(readTimeoutSeconds, "readTimeout");
+ this.readTimeoutSeconds = readTimeoutSeconds;
+ return this;
+ }
+
+ public Builder setWriteTimeout(int writeTimeoutSeconds) {
+ validateTimeoutSeconds(writeTimeoutSeconds, "writeTimeout");
+ this.writeTimeoutSeconds = writeTimeoutSeconds;
+ return this;
+ }
+
+ public Builder setConnectTimeout(int connectTimeoutSeconds) {
+ validateTimeoutSeconds(connectTimeoutSeconds, "connectTimeout");
+ this.connectTimeoutSeconds = connectTimeoutSeconds;
+ return this;
+ }
+
+ private static void validateTimeoutSeconds(int seconds, String name) {
+ if (seconds <= 0) {
+ throw new IllegalArgumentException(name + " must be positive.");
+ }
+ }
+
+
+
/**
* Create a new connection pool with tuning parameters appropriate for a
* single-user application. The tuning parameters in this pool are
@@ -840,11 +870,16 @@ private void validateClient(Contentstack contentstack) {
}
private OkHttpClient httpClient(Contentstack contentstack, Boolean retryOnFailure) {
+ int connectSec = this.connectTimeoutSeconds != null ? this.connectTimeoutSeconds : this.timeout;
+ int readSec = this.readTimeoutSeconds != null ? this.readTimeoutSeconds : this.timeout;
+ int writeSec = this.writeTimeoutSeconds != null ? this.writeTimeoutSeconds : this.timeout;
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectionPool(this.connectionPool)
.addInterceptor(logger())
.proxy(this.proxy)
- .connectTimeout(Duration.ofSeconds(this.timeout))
+ .connectTimeout(Duration.ofSeconds(connectSec))
+ .readTimeout(Duration.ofSeconds(readSec))
+ .writeTimeout(Duration.ofSeconds(writeSec))
.retryOnConnectionFailure(retryOnFailure);
// Add either OAuth or traditional auth interceptor
diff --git a/src/test/java/com/contentstack/cms/ContentstackUnitTest.java b/src/test/java/com/contentstack/cms/ContentstackUnitTest.java
index b2666c4..9e84c9b 100644
--- a/src/test/java/com/contentstack/cms/ContentstackUnitTest.java
+++ b/src/test/java/com/contentstack/cms/ContentstackUnitTest.java
@@ -19,6 +19,7 @@
import java.net.Proxy;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
public class ContentstackUnitTest {
@@ -167,6 +168,68 @@ void setTimeout() {
Assertions.assertEquals(3, contentstack.timeout);
}
+ @Test
+ void setTimeoutZeroThrows() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Contentstack.Builder().setTimeout(0));
+ }
+
+ @Test
+ void setTimeoutNegativeThrows() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Contentstack.Builder().setTimeout(-1));
+ }
+
+ @Test
+ void setReadTimeoutZeroThrows() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Contentstack.Builder().setReadTimeout(0));
+ }
+
+ @Test
+ void setWriteTimeoutNegativeThrows() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Contentstack.Builder().setWriteTimeout(-5));
+ }
+
+ @Test
+ void setConnectTimeoutInvalidThrows() {
+ Assertions.assertThrows(IllegalArgumentException.class,
+ () -> new Contentstack.Builder().setConnectTimeout(-1));
+ }
+
+ @Test
+ void okHttpTimeoutsMatchSetTimeout() {
+ Contentstack client = new Contentstack.Builder().setTimeout(45).build();
+ OkHttpClient ok = (OkHttpClient) client.instance.callFactory();
+ Assertions.assertEquals(45_000, ok.connectTimeoutMillis());
+ Assertions.assertEquals(45_000, ok.readTimeoutMillis());
+ Assertions.assertEquals(45_000, ok.writeTimeoutMillis());
+ }
+
+ @Test
+ void okHttpDefaultTimeoutsUseUtilTimeout() {
+ Contentstack client = new Contentstack.Builder().build();
+ OkHttpClient ok = (OkHttpClient) client.instance.callFactory();
+ int expectedMs = (int) TimeUnit.SECONDS.toMillis(30);
+ Assertions.assertEquals(expectedMs, ok.connectTimeoutMillis());
+ Assertions.assertEquals(expectedMs, ok.readTimeoutMillis());
+ Assertions.assertEquals(expectedMs, ok.writeTimeoutMillis());
+ }
+
+ @Test
+ void okHttpPerLegOverridesFallBackToSetTimeout() {
+ Contentstack client = new Contentstack.Builder()
+ .setTimeout(10)
+ .setReadTimeout(90)
+ .build();
+ OkHttpClient ok = (OkHttpClient) client.instance.callFactory();
+ Assertions.assertEquals(10_000, ok.connectTimeoutMillis());
+ Assertions.assertEquals(90_000, ok.readTimeoutMillis());
+ Assertions.assertEquals(10_000, ok.writeTimeoutMillis());
+ Assertions.assertEquals(10, client.timeout);
+ }
+
@Test
void testSetAuthtoken() {
Contentstack contentstack = new Contentstack.Builder()