Skip to content

Commit c4a62d7

Browse files
committed
Verify bucket exists on startup, create it if not
1 parent 48525cc commit c4a62d7

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ of these changes a reindex of Elasticsearch is required. This can be started by
1414
- API add tags endpoint now returns the added tags.
1515
[CATS-1053](https://opensource.ncsa.illinois.edu/jira/browse/CATS-1053)
1616
- Ability to search by creator name and email address for all resources.
17+
- S3ByteStorageService should verify bucket existence on startup and create if it does not exist.
18+
[CATS-1057](https://opensource.ncsa.illinois.edu/jira/browse/CATS-1057)
1719

1820
### Fixed
1921
- Ability to delete tags on file page.

app/services/s3/S3ByteStorageService.scala

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import models.UUID
66
import com.amazonaws.auth.{AWSStaticCredentialsProvider, BasicAWSCredentials}
77
import com.amazonaws.client.builder.AwsClientBuilder
88
import com.amazonaws.regions.Regions
9-
import com.amazonaws.services.s3.model.{GetObjectRequest, ObjectMetadata}
9+
import com.amazonaws.services.s3.model.{HeadBucketRequest, CreateBucketRequest, GetObjectRequest, ObjectMetadata}
1010
import com.amazonaws.services.s3.{AmazonS3, AmazonS3ClientBuilder}
1111
import com.amazonaws.{AmazonClientException, ClientConfiguration}
1212
import com.google.inject.Inject
@@ -46,6 +46,41 @@ object S3ByteStorageService {
4646
*/
4747
class S3ByteStorageService @Inject()() extends ByteStorageService {
4848

49+
50+
// Only run a single thread at a time when verifying bucket existence
51+
synchronized {
52+
Play.current.configuration.getString(S3ByteStorageService.BucketName) match {
53+
case Some(bucketName) => {
54+
try {
55+
// Validate configuration by checking for bucket existence on startup
56+
this.s3Bucket.headBucket(new HeadBucketRequest(bucketName))
57+
} catch {
58+
case sdke @ (_: AmazonClientException | _: AmazonServiceException) => {
59+
if (sdke.getMessage.contains("Status Code: 404")) {
60+
try {
61+
// Bucket does not exist - create the bucket
62+
this.s3Bucket.createBucket(new CreateBucketRequest(bucketName))
63+
} catch {
64+
// Bucket could not be created - abort
65+
case _: Throwable => throw new RuntimeException("Bad S3 configuration: Bucket does not exist and could not be created.")
66+
}
67+
} else if (sdke.getMessage.contains("Status Code: 403")) {
68+
// Bucket exists, but you do not have permission to access it
69+
throw new RuntimeException("Bad S3 configuration: You do not have access to the configured bucket.")
70+
} else {
71+
// Unknown error - print status code for further investigation
72+
val errMsg = sdke.getLocalizedMessage
73+
Logger.error(errMsg)
74+
throw new RuntimeException("Bad S3 configuration: an unknown error has occurred - " + errMsg)
75+
}
76+
}
77+
case _: Throwable => handleUnknownError(_)
78+
}
79+
}
80+
case _ => throw new RuntimeException("Bad S3 configuration: verify that you have set all configuration options.")
81+
}
82+
}
83+
4984
/**
5085
* Grabs config parameters from Clowder to return a
5186
* AmazonS3 pointing at the configured service endpoint.

0 commit comments

Comments
 (0)