Enabling AWS S3 on GovCloud

I discovered that the standard AmazonS3FileStorage implementation that is bundled with the platform does not work with GovCloud regions. It took some time but I figured out the reason and I thought I’d share.

The issue derives from the URL that is being constructed. From the bundled version:

protected URL getAmazonUrl(FileDescriptor fileDescr) {
    // the region-specific endpoint to the target object expressed in path style
    try {
        return new URL(String.format("https://%s.s3.amazonaws.com/%s",
                amazonS3Config.getBucket(), resolveFileName(fileDescr)));
    } catch (MalformedURLException e) {
        throw new RuntimeException("Unable to parse service endpoint: " + e.getMessage());
    }
}

The constructed URL does not match the endpoints listed here.

To fix this issue:

  1. Extend the AmazonS3FileStorage bean
  2. Override getAmazonURL(FileDescriptor fileDescr) with:

protected URL getAmazonUrl(FileDescriptor fileDescr) {
// the region-specific endpoint to the target object expressed in path style
try {
return new URL(String.format(“https://%s.s3.%s.amazonaws.com/%s”,
amazonS3Config.getBucket(), amazonS3Config.getRegionName(), resolveFileName(fileDescr)));
} catch (MalformedURLException e) {
throw new RuntimeException("Unable to parse service endpoint: " + e.getMessage());
}
}

  1. Update spring.xml to reflect the new FileStorage bean that you created:

<bean name="cuba_FileStorage" class="path.to.youNewBean"/>

This works for me and I hope it works for you too.

5 Likes