CLOUDSTACK-8581: S3, make connection TTL and TCP KeepAlive configureable

Signed-off-by: Wido den Hollander <wido@widodh.nl>
This commit is contained in:
Wido den Hollander 2015-07-14 08:17:49 +02:00
parent b1e5906923
commit 178a9f555d
5 changed files with 84 additions and 4 deletions

View File

@ -34,9 +34,11 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
private String endPoint;
private String bucketName;
private Boolean httpsFlag;
private Boolean useTCPKeepAlive;
private Integer connectionTimeout;
private Integer maxErrorRetry;
private Integer socketTimeout;
private Integer connectionTtl;
private Date created;
private boolean enableRRS;
private long maxSingleUploadSizeInBytes;
@ -50,7 +52,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
public S3TO(final Long id, final String uuid, final String accessKey, final String secretKey, final String endPoint, final String bucketName,
final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, final Integer socketTimeout, final Date created,
final boolean enableRRS, final long maxUploadSize) {
final boolean enableRRS, final long maxUploadSize, final Integer connectionTtl, final Boolean useTCPKeepAlive) {
super();
@ -67,6 +69,8 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
this.created = created;
this.enableRRS = enableRRS;
this.maxSingleUploadSizeInBytes = maxUploadSize;
this.connectionTtl = connectionTtl;
this.useTCPKeepAlive = useTCPKeepAlive;
}
@ -118,6 +122,14 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
return false;
}
if (connectionTtl != null ? !connectionTtl.equals(thatS3TO.connectionTtl) : thatS3TO.connectionTtl != null) {
return false;
}
if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatS3TO.useTCPKeepAlive) : thatS3TO.useTCPKeepAlive != null) {
return false;
}
if (bucketName != null ? !bucketName.equals(thatS3TO.bucketName) : thatS3TO.bucketName != null) {
return false;
}
@ -147,6 +159,8 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
result = 31 * result + (useTCPKeepAlive ? 1 : 0);
return result;
@ -245,6 +259,24 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO {
this.socketTimeout = socketTimeout;
}
@Override
public Integer getConnectionTtl() {
return this.connectionTtl;
}
public void setConnectionTtl(final Integer connectionTtl) {
this.connectionTtl = connectionTtl;
}
@Override
public Boolean getUseTCPKeepAlive() {
return this.useTCPKeepAlive;
}
public void setUseTCPKeepAlive(final Boolean useTCPKeepAlive) {
this.useTCPKeepAlive = useTCPKeepAlive;
}
public Date getCreated() {
return this.created;
}

View File

@ -502,8 +502,10 @@ public class ApiConstants {
public static final String S3_BUCKET_NAME = "bucket";
public static final String S3_HTTPS_FLAG = "usehttps";
public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
public static final String S3_CONNECTION_TTL = "connectionttl";
public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
public static final String S3_USE_TCP_KEEPALIVE = "usetcpkeepalive";
public static final String INCL_ZONES = "includezones";
public static final String EXCL_ZONES = "excludezones";
public static final String SOURCE = "source";

View File

@ -22,11 +22,13 @@ import static com.cloud.user.Account.ACCOUNT_ID_SYSTEM;
import static org.apache.cloudstack.api.ApiConstants.S3_ACCESS_KEY;
import static org.apache.cloudstack.api.ApiConstants.S3_BUCKET_NAME;
import static org.apache.cloudstack.api.ApiConstants.S3_CONNECTION_TIMEOUT;
import static org.apache.cloudstack.api.ApiConstants.S3_CONNECTION_TTL;
import static org.apache.cloudstack.api.ApiConstants.S3_END_POINT;
import static org.apache.cloudstack.api.ApiConstants.S3_HTTPS_FLAG;
import static org.apache.cloudstack.api.ApiConstants.S3_MAX_ERROR_RETRY;
import static org.apache.cloudstack.api.ApiConstants.S3_SECRET_KEY;
import static org.apache.cloudstack.api.ApiConstants.S3_SOCKET_TIMEOUT;
import static org.apache.cloudstack.api.ApiConstants.S3_USE_TCP_KEEPALIVE;
import static org.apache.cloudstack.api.BaseCmd.CommandType.BOOLEAN;
import static org.apache.cloudstack.api.BaseCmd.CommandType.INTEGER;
import static org.apache.cloudstack.api.BaseCmd.CommandType.STRING;
@ -83,6 +85,12 @@ public final class AddS3Cmd extends BaseCmd {
@Parameter(name = S3_SOCKET_TIMEOUT, type = INTEGER, required = false, description = "socket timeout (milliseconds)")
private final Integer socketTimeout = null;
@Parameter(name = S3_CONNECTION_TTL, type = INTEGER, required = false, description = "connection ttl (milliseconds)")
private final Integer connectionTtl = null;
@Parameter(name = S3_USE_TCP_KEEPALIVE, type = BOOLEAN, required = false, description = "whether tcp keepalive is used")
private final Boolean useTCPKeepAlive = null;
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
ResourceAllocationException, NetworkRuleConflictException {
@ -104,6 +112,12 @@ public final class AddS3Cmd extends BaseCmd {
if (getSocketTimeout() != null) {
dm.put(ApiConstants.S3_SOCKET_TIMEOUT, getSocketTimeout().toString());
}
if (getConnectionTtl() != null) {
dm.put(ApiConstants.S3_CONNECTION_TTL, getConnectionTtl().toString());
}
if (getUseTCPKeepAlive() != null) {
dm.put(ApiConstants.S3_USE_TCP_KEEPALIVE, getUseTCPKeepAlive().toString());
}
try{
@ -168,6 +182,14 @@ public final class AddS3Cmd extends BaseCmd {
return false;
}
if (connectionTtl != null ? !connectionTtl.equals(thatAddS3Cmd.connectionTtl) : thatAddS3Cmd.connectionTtl != null) {
return false;
}
if (useTCPKeepAlive != null ? !useTCPKeepAlive.equals(thatAddS3Cmd.useTCPKeepAlive) : thatAddS3Cmd.useTCPKeepAlive != null) {
return false;
}
return true;
}
@ -183,6 +205,8 @@ public final class AddS3Cmd extends BaseCmd {
result = 31 * result + (connectionTimeout != null ? connectionTimeout.hashCode() : 0);
result = 31 * result + (maxErrorRetry != null ? maxErrorRetry.hashCode() : 0);
result = 31 * result + (socketTimeout != null ? socketTimeout.hashCode() : 0);
result = 31 * result + (connectionTtl != null ? connectionTtl.hashCode() : 0);
result = 31 * result + (useTCPKeepAlive != null && useTCPKeepAlive == true ? 1 : 0);
return result;
@ -230,4 +254,11 @@ public final class AddS3Cmd extends BaseCmd {
return socketTimeout;
}
public Integer getConnectionTtl() {
return connectionTtl;
}
public Boolean getUseTCPKeepAlive() {
return useTCPKeepAlive;
}
}

View File

@ -60,7 +60,9 @@ public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl {
: Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null
: Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null
: Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated(), _configDao.getValue(Config.S3EnableRRS.toString()) == null ? false
: Boolean.parseBoolean(_configDao.getValue(Config.S3EnableRRS.toString())), getMaxSingleUploadSizeInBytes());
: Boolean.parseBoolean(_configDao.getValue(Config.S3EnableRRS.toString())), getMaxSingleUploadSizeInBytes(),
details.get(ApiConstants.S3_CONNECTION_TTL) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TTL)),
details.get(ApiConstants.S3_USE_TCP_KEEPALIVE) == null ? null : Boolean.parseBoolean(details.get(ApiConstants.S3_USE_TCP_KEEPALIVE)));
}

View File

@ -102,9 +102,18 @@ public final class S3Utils {
configuration.setSocketTimeout(clientOptions.getSocketTimeout());
}
if (clientOptions.getUseTCPKeepAlive() != null) {
configuration.setUseTcpKeepAlive(clientOptions.getUseTCPKeepAlive());
}
if (clientOptions.getConnectionTtl() != null) {
configuration.setConnectionTTL(clientOptions.getConnectionTtl());
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(format("Creating S3 client with configuration: [protocol: %1$s, connectionTimeOut: " + "%2$s, maxErrorRetry: %3$s, socketTimeout: %4$s]",
configuration.getProtocol(), configuration.getConnectionTimeout(), configuration.getMaxErrorRetry(), configuration.getSocketTimeout()));
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]",
configuration.getProtocol(), configuration.getConnectionTimeout(), configuration.getMaxErrorRetry(), configuration.getSocketTimeout(),
configuration.useTcpKeepAlive(), configuration.getConnectionTTL()));
}
final AmazonS3Client client = new AmazonS3Client(credentials, configuration);
@ -510,6 +519,7 @@ public final class S3Utils {
errorMessages.addAll(checkOptionalField("connection timeout", clientOptions.getConnectionTimeout()));
errorMessages.addAll(checkOptionalField("socket timeout", clientOptions.getSocketTimeout()));
errorMessages.addAll(checkOptionalField("max error retries", clientOptions.getMaxErrorRetry()));
errorMessages.addAll(checkOptionalField("connection ttl", clientOptions.getConnectionTtl()));
return unmodifiableList(errorMessages);
@ -566,6 +576,9 @@ public final class S3Utils {
Integer getSocketTimeout();
Boolean getUseTCPKeepAlive();
Integer getConnectionTtl();
}
public interface ObjectNamingStrategy {