Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable defaultAwsCredentialChain when botoCfgPath is neglected #627

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/server_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ Example server configuration

* - botoCfgPath
- str
- Path to AWS credentials (if using S3 for remote storage)
- `<DEFAULT_USER_DIR> <https://github.com/Yelp/nrtsearch/blob/f612f5d3e14e468ab8c9b45dd4be0ab84231b9de/src/main/java/com/yelp/nrtsearch/server/config/LuceneServerConfiguration.java#L35>`_/boto.cfg
- Path to AWS credentials (if using S3 for remote storage); Will use the DefaultAWSCredentialsProviderChain if omitted.
- null

* - archiveDirectory
- str
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ public class LuceneServerConfiguration {
Paths.get(System.getProperty("user.home"), "lucene", "server");
public static final Path DEFAULT_ARCHIVER_DIR =
Paths.get(DEFAULT_USER_DIR.toString(), "archiver");
public static final Path DEFAULT_BOTO_CFG_PATH =
Paths.get(DEFAULT_USER_DIR.toString(), "boto.cfg");
public static final Path DEFAULT_STATE_DIR =
Paths.get(DEFAULT_USER_DIR.toString(), "default_state");
public static final Path DEFAULT_INDEX_DIR =
Expand Down Expand Up @@ -137,7 +135,7 @@ public LuceneServerConfiguration(InputStream yamlStream) {
stateDir = configReader.getString("stateDir", DEFAULT_STATE_DIR.toString());
indexDir = configReader.getString("indexDir", DEFAULT_INDEX_DIR.toString());
archiveDirectory = configReader.getString("archiveDirectory", DEFAULT_ARCHIVER_DIR.toString());
botoCfgPath = configReader.getString("botoCfgPath", DEFAULT_BOTO_CFG_PATH.toString());
botoCfgPath = configReader.getString("botoCfgPath", null);
bucketName = configReader.getString("bucketName", DEFAULT_BUCKET_NAME);
maxS3ClientRetries =
configReader.getInteger("maxS3ClientRetries", DEFAULT_MAX_S3_CLIENT_RETRIES);
Expand Down
77 changes: 45 additions & 32 deletions src/main/java/com/yelp/nrtsearch/server/module/S3Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package com.yelp.nrtsearch.server.module;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.AnonymousAWSCredentials;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.auth.profile.ProfilesConfigFile;
import com.amazonaws.client.builder.AwsClientBuilder;
Expand All @@ -44,21 +46,26 @@ public class S3Module extends AbstractModule {
@Singleton
@Provides
protected AmazonS3 providesAmazonS3(LuceneServerConfiguration luceneServerConfiguration) {
if (luceneServerConfiguration
.getBotoCfgPath()
.equals(LuceneServerConfiguration.DEFAULT_BOTO_CFG_PATH.toString())) {
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("dummyService", "dummyRegion"))
.build();
AWSCredentialsProvider awsCredentialsProvider;
if (luceneServerConfiguration.getBotoCfgPath() == null) {
awsCredentialsProvider = new DefaultAWSCredentialsProviderChain();
} else {
Path botoCfgPath = Paths.get(luceneServerConfiguration.getBotoCfgPath());
final ProfilesConfigFile profilesConfigFile = new ProfilesConfigFile(botoCfgPath.toFile());
final AWSCredentialsProvider awsCredentialsProvider =
new ProfileCredentialsProvider(profilesConfigFile, "default");
awsCredentialsProvider = new ProfileCredentialsProvider(profilesConfigFile, "default");
}
final boolean globalBucketAccess = luceneServerConfiguration.getEnableGlobalBucketAccess();

AmazonS3ClientBuilder clientBuilder =
AmazonS3ClientBuilder.standard()
.withCredentials(awsCredentialsProvider)
.withForceGlobalBucketAccessEnabled(globalBucketAccess);
try {
AmazonS3 s3ClientInterim =
AmazonS3ClientBuilder.standard().withCredentials(awsCredentialsProvider).build();
AmazonS3ClientBuilder.standard()
.withCredentials(awsCredentialsProvider)
.withForceGlobalBucketAccessEnabled(globalBucketAccess)
.build();
String region = s3ClientInterim.getBucketLocation(luceneServerConfiguration.getBucketName());
// In useast-1, the region is returned as "US" which is an equivalent to "us-east-1"
// https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/model/Region.html#US_Standard
Expand All @@ -68,28 +75,34 @@ protected AmazonS3 providesAmazonS3(LuceneServerConfiguration luceneServerConfig
}
String serviceEndpoint = String.format("s3.%s.amazonaws.com", region);
logger.info(String.format("S3 ServiceEndpoint: %s", serviceEndpoint));
AmazonS3ClientBuilder clientBuilder =
AmazonS3ClientBuilder.standard()
.withCredentials(awsCredentialsProvider)
.withEndpointConfiguration(new EndpointConfiguration(serviceEndpoint, region));

int maxRetries = luceneServerConfiguration.getMaxS3ClientRetries();
if (maxRetries > 0) {
RetryPolicy retryPolicy =
new RetryPolicy(
PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION,
PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY,
maxRetries,
true);
ClientConfiguration clientConfiguration =
new ClientConfiguration().withRetryPolicy(retryPolicy);
clientBuilder.setClientConfiguration(clientConfiguration);
}
clientBuilder.withEndpointConfiguration(new EndpointConfiguration(serviceEndpoint, region));
} catch (SdkClientException sdkClientException) {
logger.warn(
"failed to get the location of S3 bucket: "
+ luceneServerConfiguration.getBucketName()
+ ". This could be caused by missing credentials and/or regions, or wrong bucket name.",
sdkClientException);
logger.info("return a dummy AmazonS3.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the trade off of using a dummy Amazon S3 client here?

Copy link
Contributor Author

@waziqi89 waziqi89 Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used to keep the consistency after making the changes. This is essential for some existing tests where the s3 settings is invalid.
https://github.com/Yelp/nrtsearch/pull/627/files#diff-37db6e5b57c28cce4fd4b60b04b1e1c8308668c90a4d5ec9d1ee6bac6becfe1aL53

return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
.withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration("dummyService", "dummyRegion"))
.build();
}

if (luceneServerConfiguration.getEnableGlobalBucketAccess()) {
clientBuilder.enableForceGlobalBucketAccess();
}
return clientBuilder.build();
int maxRetries = luceneServerConfiguration.getMaxS3ClientRetries();
if (maxRetries > 0) {
RetryPolicy retryPolicy =
new RetryPolicy(
PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION,
PredefinedRetryPolicies.DEFAULT_BACKOFF_STRATEGY,
maxRetries,
true);
ClientConfiguration clientConfiguration =
new ClientConfiguration().withRetryPolicy(retryPolicy);
clientBuilder.setClientConfiguration(clientConfiguration);
}

return clientBuilder.build();
}
}
Loading