Skip to content

Commit 178a9f5

Browse files
committed
CLOUDSTACK-8581: S3, make connection TTL and TCP KeepAlive configureable
Signed-off-by: Wido den Hollander <wido@widodh.nl>
1 parent b1e5906 commit 178a9f5

5 files changed

Lines changed: 84 additions & 4 deletions

File tree

api/src/com/cloud/agent/api/to/S3TO.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
3434
private String endPoint;
3535
private String bucketName;
3636
private Boolean httpsFlag;
37+
private Boolean useTCPKeepAlive;
3738
private Integer connectionTimeout;
3839
private Integer maxErrorRetry;
3940
private Integer socketTimeout;
41+
private Integer connectionTtl;
4042
private Date created;
4143
private boolean enableRRS;
4244
private long maxSingleUploadSizeInBytes;
@@ -50,7 +52,7 @@ public S3TO() {
5052

5153
public S3TO(final Long id, final String uuid, final String accessKey, final String secretKey, final String endPoint, final String bucketName,
5254
final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, final Integer socketTimeout, final Date created,
53-
final boolean enableRRS, final long maxUploadSize) {
55+
final boolean enableRRS, final long maxUploadSize, final Integer connectionTtl, final Boolean useTCPKeepAlive) {
5456

5557
super();
5658

@@ -67,6 +69,8 @@ public S3TO(final Long id, final String uuid, final String accessKey, final Stri
6769
this.created = created;
6870
this.enableRRS = enableRRS;
6971
this.maxSingleUploadSizeInBytes = maxUploadSize;
72+
this.connectionTtl = connectionTtl;
73+
this.useTCPKeepAlive = useTCPKeepAlive;
7074

7175
}
7276

@@ -118,6 +122,14 @@ public boolean equals(final Object thatObject) {
118122
return false;
119123
}
120124

125+
if (connectionTtl != null ? !connectionTtl.equals(thatS3TO.connectionTtl) : thatS3TO.connectionTtl != null) {
126+
return false;
127+
}
128+
129+
if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatS3TO.useTCPKeepAlive) : thatS3TO.useTCPKeepAlive != null) {
130+
return false;
131+
}
132+
121133
if (bucketName != null ? !bucketName.equals(thatS3TO.bucketName) : thatS3TO.bucketName != null) {
122134
return false;
123135
}
@@ -147,6 +159,8 @@ public int hashCode() {
147159
result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
148160
result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
149161
result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
162+
result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
163+
result = 31 * result + (useTCPKeepAlive ? 1 : 0);
150164

151165
return result;
152166

@@ -245,6 +259,24 @@ public void setSocketTimeout(final Integer socketTimeout) {
245259
this.socketTimeout = socketTimeout;
246260
}
247261

262+
@Override
263+
public Integer getConnectionTtl() {
264+
return this.connectionTtl;
265+
}
266+
267+
public void setConnectionTtl(final Integer connectionTtl) {
268+
this.connectionTtl = connectionTtl;
269+
}
270+
271+
@Override
272+
public Boolean getUseTCPKeepAlive() {
273+
return this.useTCPKeepAlive;
274+
}
275+
276+
public void setUseTCPKeepAlive(final Boolean useTCPKeepAlive) {
277+
this.useTCPKeepAlive = useTCPKeepAlive;
278+
}
279+
248280
public Date getCreated() {
249281
return this.created;
250282
}

api/src/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,8 +502,10 @@ public class ApiConstants {
502502
public static final String S3_BUCKET_NAME = "bucket";
503503
public static final String S3_HTTPS_FLAG = "usehttps";
504504
public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
505+
public static final String S3_CONNECTION_TTL = "connectionttl";
505506
public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
506507
public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
508+
public static final String S3_USE_TCP_KEEPALIVE = "usetcpkeepalive";
507509
public static final String INCL_ZONES = "includezones";
508510
public static final String EXCL_ZONES = "excludezones";
509511
public static final String SOURCE = "source";

api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
import static org.apache.cloudstack.api.ApiConstants.S3_ACCESS_KEY;
2323
import static org.apache.cloudstack.api.ApiConstants.S3_BUCKET_NAME;
2424
import static org.apache.cloudstack.api.ApiConstants.S3_CONNECTION_TIMEOUT;
25+
import static org.apache.cloudstack.api.ApiConstants.S3_CONNECTION_TTL;
2526
import static org.apache.cloudstack.api.ApiConstants.S3_END_POINT;
2627
import static org.apache.cloudstack.api.ApiConstants.S3_HTTPS_FLAG;
2728
import static org.apache.cloudstack.api.ApiConstants.S3_MAX_ERROR_RETRY;
2829
import static org.apache.cloudstack.api.ApiConstants.S3_SECRET_KEY;
2930
import static org.apache.cloudstack.api.ApiConstants.S3_SOCKET_TIMEOUT;
31+
import static org.apache.cloudstack.api.ApiConstants.S3_USE_TCP_KEEPALIVE;
3032
import static org.apache.cloudstack.api.BaseCmd.CommandType.BOOLEAN;
3133
import static org.apache.cloudstack.api.BaseCmd.CommandType.INTEGER;
3234
import static org.apache.cloudstack.api.BaseCmd.CommandType.STRING;
@@ -83,6 +85,12 @@ public final class AddS3Cmd extends BaseCmd {
8385
@Parameter(name = S3_SOCKET_TIMEOUT, type = INTEGER, required = false, description = "socket timeout (milliseconds)")
8486
private final Integer socketTimeout = null;
8587

88+
@Parameter(name = S3_CONNECTION_TTL, type = INTEGER, required = false, description = "connection ttl (milliseconds)")
89+
private final Integer connectionTtl = null;
90+
91+
@Parameter(name = S3_USE_TCP_KEEPALIVE, type = BOOLEAN, required = false, description = "whether tcp keepalive is used")
92+
private final Boolean useTCPKeepAlive = null;
93+
8694
@Override
8795
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
8896
ResourceAllocationException, NetworkRuleConflictException {
@@ -104,6 +112,12 @@ public void execute() throws ResourceUnavailableException, InsufficientCapacityE
104112
if (getSocketTimeout() != null) {
105113
dm.put(ApiConstants.S3_SOCKET_TIMEOUT, getSocketTimeout().toString());
106114
}
115+
if (getConnectionTtl() != null) {
116+
dm.put(ApiConstants.S3_CONNECTION_TTL, getConnectionTtl().toString());
117+
}
118+
if (getUseTCPKeepAlive() != null) {
119+
dm.put(ApiConstants.S3_USE_TCP_KEEPALIVE, getUseTCPKeepAlive().toString());
120+
}
107121

108122

109123
try{
@@ -168,6 +182,14 @@ public boolean equals(final Object thatObject) {
168182
return false;
169183
}
170184

185+
if (connectionTtl != null ? !connectionTtl.equals(thatAddS3Cmd.connectionTtl) : thatAddS3Cmd.connectionTtl != null) {
186+
return false;
187+
}
188+
189+
if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatAddS3Cmd.useTCPKeepAlive) : thatAddS3Cmd.useTCPKeepAlive != null) {
190+
return false;
191+
}
192+
171193
return true;
172194

173195
}
@@ -183,6 +205,8 @@ public int hashCode() {
183205
result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
184206
result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
185207
result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
208+
result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
209+
result = 31 * result + (useTCPKeepAlive != null && useTCPKeepAlive == true ? 1 : 0);
186210

187211
return result;
188212

@@ -230,4 +254,11 @@ public Integer getSocketTimeout() {
230254
return socketTimeout;
231255
}
232256

257+
public Integer getConnectionTtl() {
258+
return connectionTtl;
259+
}
260+
261+
public Boolean getUseTCPKeepAlive() {
262+
return useTCPKeepAlive;
263+
}
233264
}

plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ public DataStoreTO getStoreTO(DataStore store) {
6060
: Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null
6161
: Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null
6262
: Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated(), _configDao.getValue(Config.S3EnableRRS.toString()) == null ? false
63-
: Boolean.parseBoolean(_configDao.getValue(Config.S3EnableRRS.toString())), getMaxSingleUploadSizeInBytes());
63+
: Boolean.parseBoolean(_configDao.getValue(Config.S3EnableRRS.toString())), getMaxSingleUploadSizeInBytes(),
64+
details.get(ApiConstants.S3_CONNECTION_TTL) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TTL)),
65+
details.get(ApiConstants.S3_USE_TCP_KEEPALIVE) == null ? null : Boolean.parseBoolean(details.get(ApiConstants.S3_USE_TCP_KEEPALIVE)));
6466

6567
}
6668

utils/src/com/cloud/utils/S3Utils.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,18 @@ public static AmazonS3 acquireClient(final ClientOptions clientOptions) {
102102
configuration.setSocketTimeout(clientOptions.getSocketTimeout());
103103
}
104104

105+
if (clientOptions.getUseTCPKeepAlive() != null) {
106+
configuration.setUseTcpKeepAlive(clientOptions.getUseTCPKeepAlive());
107+
}
108+
109+
if (clientOptions.getConnectionTtl() != null) {
110+
configuration.setConnectionTTL(clientOptions.getConnectionTtl());
111+
}
112+
105113
if (LOGGER.isDebugEnabled()) {
106-
LOGGER.debug(format("Creating S3 client with configuration: [protocol: %1$s, connectionTimeOut: " + "%2$s, maxErrorRetry: %3$s, socketTimeout: %4$s]",
107-
configuration.getProtocol(), configuration.getConnectionTimeout(), configuration.getMaxErrorRetry(), configuration.getSocketTimeout()));
114+
LOGGER.debug(format("Creating S3 client with configuration: [protocol: %1$s, connectionTimeOut: " + "%2$s, maxErrorRetry: %3$s, socketTimeout: %4$s, useTCPKeepAlive: %5$s, connectionTtl: %6$s]",
115+
configuration.getProtocol(), configuration.getConnectionTimeout(), configuration.getMaxErrorRetry(), configuration.getSocketTimeout(),
116+
configuration.useTcpKeepAlive(), configuration.getConnectionTTL()));
108117
}
109118

110119
final AmazonS3Client client = new AmazonS3Client(credentials, configuration);
@@ -510,6 +519,7 @@ public static List<String> checkClientOptions(ClientOptions clientOptions) {
510519
errorMessages.addAll(checkOptionalField("connection timeout", clientOptions.getConnectionTimeout()));
511520
errorMessages.addAll(checkOptionalField("socket timeout", clientOptions.getSocketTimeout()));
512521
errorMessages.addAll(checkOptionalField("max error retries", clientOptions.getMaxErrorRetry()));
522+
errorMessages.addAll(checkOptionalField("connection ttl", clientOptions.getConnectionTtl()));
513523

514524
return unmodifiableList(errorMessages);
515525

@@ -566,6 +576,9 @@ public interface ClientOptions {
566576

567577
Integer getSocketTimeout();
568578

579+
Boolean getUseTCPKeepAlive();
580+
581+
Integer getConnectionTtl();
569582
}
570583

571584
public interface ObjectNamingStrategy {

0 commit comments

Comments
 (0)