Add prefix path support for AWS S3 website

This commit is contained in:
Mike Primm 2022-02-20 21:38:50 -06:00
parent ea97296684
commit ef045da32f
13 changed files with 110 additions and 17 deletions

View File

@ -60,7 +60,7 @@ public class AWSS3MapStorage extends MapStorage {
baseURI = map.getPrefix() + var.variantSuffix + "/"+ (x >> 5) + "_" + (y >> 5) + "/" + x + "_" + y; baseURI = map.getPrefix() + var.variantSuffix + "/"+ (x >> 5) + "_" + (y >> 5) + "/" + x + "_" + y;
} }
uri = baseURI + "." + map.getImageFormat().getFileExt(); uri = baseURI + "." + map.getImageFormat().getFileExt();
baseKey = "tiles/" + world.getName() + "/" + uri; baseKey = AWSS3MapStorage.this.prefix + "tiles/" + world.getName() + "/" + uri;
} }
@Override @Override
public boolean exists() { public boolean exists() {
@ -200,6 +200,7 @@ public class AWSS3MapStorage extends MapStorage {
private String access_key_id; private String access_key_id;
private String secret_access_key; private String secret_access_key;
private S3Client s3; private S3Client s3;
private String prefix;
public AWSS3MapStorage() { public AWSS3MapStorage() {
} }
@ -222,6 +223,10 @@ public class AWSS3MapStorage extends MapStorage {
region = core.configuration.getString("storage/region", "us-east-1"); region = core.configuration.getString("storage/region", "us-east-1");
access_key_id = core.configuration.getString("storage/aws_access_key_id", System.getenv("AWS_ACCESS_KEY_ID")); access_key_id = core.configuration.getString("storage/aws_access_key_id", System.getenv("AWS_ACCESS_KEY_ID"));
secret_access_key = core.configuration.getString("storage/aws_secret_access_key", System.getenv("AWS_SECRET_ACCESS_KEY")); secret_access_key = core.configuration.getString("storage/aws_secret_access_key", System.getenv("AWS_SECRET_ACCESS_KEY"));
prefix = core.configuration.getString("storage/prefix", "");
if ((prefix.length() > 0) && (prefix.charAt(prefix.length()-1) != '/')) {
prefix += '/';
}
// Now creste the access client for the S3 service // Now creste the access client for the S3 service
Log.info("Using AWS S3 storage: web site at S3 bucket " + bucketname + " in region " + region); Log.info("Using AWS S3 storage: web site at S3 bucket " + bucketname + " in region " + region);
s3 = new DefaultS3ClientBuilder() s3 = new DefaultS3ClientBuilder()
@ -237,6 +242,7 @@ public class AWSS3MapStorage extends MapStorage {
ListObjectsV2Request listreq = ListObjectsV2Request.builder() ListObjectsV2Request listreq = ListObjectsV2Request.builder()
.bucketName(bucketname) .bucketName(bucketname)
.maxKeys(1) .maxKeys(1)
.prefix(prefix)
.build(); .build();
try { try {
ListObjectsV2Response rslt = s3.listObjectsV2(listreq); ListObjectsV2Response rslt = s3.listObjectsV2(listreq);
@ -245,13 +251,10 @@ public class AWSS3MapStorage extends MapStorage {
return false; return false;
} }
List<S3Object> content = rslt.getContents(); List<S3Object> content = rslt.getContents();
Log.info("content=" + content.size());
} catch (S3Exception s3x) { } catch (S3Exception s3x) {
if (!s3x.getCode().equals("SignatureDoesNotMatch")) { // S3 behavior when no object match.... Log.severe("AWS Exception", s3x);
Log.severe("AWS Exception", s3x); Log.severe("req=" + listreq);
Log.severe("req=" + listreq); return false;
return false;
}
} }
return true; return true;
} }
@ -310,7 +313,7 @@ public class AWSS3MapStorage extends MapStorage {
private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase, private void processEnumMapTiles(DynmapWorld world, MapType map, ImageVariant var, MapStorageTileEnumCB cb, MapStorageBaseTileEnumCB cbBase,
MapStorageTileSearchEndCB cbEnd) { MapStorageTileSearchEndCB cbEnd) {
String basekey = "tiles/" + world.getName() + "/" + map.getPrefix() + var.variantSuffix + "/"; String basekey = prefix + "tiles/" + world.getName() + "/" + map.getPrefix() + var.variantSuffix + "/";
ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(basekey).maxKeys(1000).build(); ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(basekey).maxKeys(1000).build();
boolean done = false; boolean done = false;
try { try {
@ -416,7 +419,7 @@ public class AWSS3MapStorage extends MapStorage {
} }
private void processPurgeMapTiles(DynmapWorld world, MapType map, ImageVariant var) { private void processPurgeMapTiles(DynmapWorld world, MapType map, ImageVariant var) {
String basekey = "tiles/" + world.getName() + "/" + map.getPrefix() + var.variantSuffix + "/"; String basekey = prefix + "tiles/" + world.getName() + "/" + map.getPrefix() + var.variantSuffix + "/";
ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(basekey).delimiter("").maxKeys(1000).encodingType("url").requestPayer("requester").build(); ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(basekey).delimiter("").maxKeys(1000).encodingType("url").requestPayer("requester").build();
try { try {
boolean done = false; boolean done = false;
@ -466,7 +469,7 @@ public class AWSS3MapStorage extends MapStorage {
public boolean setPlayerFaceImage(String playername, FaceType facetype, public boolean setPlayerFaceImage(String playername, FaceType facetype,
BufferOutputStream encImage) { BufferOutputStream encImage) {
boolean done = false; boolean done = false;
String baseKey = "faces/" + facetype.id + "/" + playername + ".png"; String baseKey = prefix + "faces/" + facetype.id + "/" + playername + ".png";
try { try {
if (encImage == null) { // Delete? if (encImage == null) { // Delete?
DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build(); DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build();
@ -491,7 +494,7 @@ public class AWSS3MapStorage extends MapStorage {
@Override @Override
public boolean hasPlayerFaceImage(String playername, FaceType facetype) { public boolean hasPlayerFaceImage(String playername, FaceType facetype) {
String baseKey = "faces/" + facetype.id + "/" + playername + ".png"; String baseKey = prefix + "faces/" + facetype.id + "/" + playername + ".png";
boolean exists = false; boolean exists = false;
try { try {
ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(baseKey).maxKeys(1).build(); ListObjectsV2Request req = ListObjectsV2Request.builder().bucketName(bucketname).prefix(baseKey).maxKeys(1).build();
@ -509,7 +512,7 @@ public class AWSS3MapStorage extends MapStorage {
@Override @Override
public boolean setMarkerImage(String markerid, BufferOutputStream encImage) { public boolean setMarkerImage(String markerid, BufferOutputStream encImage) {
boolean done = false; boolean done = false;
String baseKey = "_markers_/" + markerid + ".png"; String baseKey = prefix + "tiles/_markers_/" + markerid + ".png";
try { try {
if (encImage == null) { // Delete? if (encImage == null) { // Delete?
DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build(); DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build();
@ -534,7 +537,7 @@ public class AWSS3MapStorage extends MapStorage {
@Override @Override
public boolean setMarkerFile(String world, String content) { public boolean setMarkerFile(String world, String content) {
boolean done = false; boolean done = false;
String baseKey = "_markers_/marker_" + world + ".json"; String baseKey = prefix + "tiles/_markers_/marker_" + world + ".json";
try { try {
if (content == null) { // Delete? if (content == null) { // Delete?
DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build(); DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build();
@ -628,6 +631,7 @@ public class AWSS3MapStorage extends MapStorage {
public boolean setStaticWebFile(String fileid, BufferOutputStream content) { public boolean setStaticWebFile(String fileid, BufferOutputStream content) {
boolean done = false; boolean done = false;
String baseKey = prefix + fileid;
try { try {
byte[] cacheval = standalone_cache.get(fileid); byte[] cacheval = standalone_cache.get(fileid);
@ -635,7 +639,7 @@ public class AWSS3MapStorage extends MapStorage {
if ((cacheval != null) && (cacheval.length == 0)) { // Delete cached? if ((cacheval != null) && (cacheval.length == 0)) { // Delete cached?
return true; return true;
} }
DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(fileid).build(); DeleteObjectRequest delreq = DeleteObjectRequest.builder().bucketName(bucketname).key(baseKey).build();
s3.deleteObject(delreq); s3.deleteObject(delreq);
standalone_cache.put(fileid, new byte[0]); // Mark in cache standalone_cache.put(fileid, new byte[0]); // Mark in cache
} }
@ -668,7 +672,7 @@ public class AWSS3MapStorage extends MapStorage {
else if (fileid.endsWith(".js")) { else if (fileid.endsWith(".js")) {
ct = "application/x-javascript"; ct = "application/x-javascript";
} }
PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(fileid).contentType(ct).build(); PutObjectRequest req = PutObjectRequest.builder().bucketName(bucketname).key(baseKey).contentType(ct).build();
s3.putObject(req, RequestBody.fromBytes(content.buf, content.len)); s3.putObject(req, RequestBody.fromBytes(content.buf, content.len));
standalone_cache.put(fileid, digest); standalone_cache.put(fileid, digest);
} }

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -39,6 +39,14 @@ storage:
#userid: dynmap #userid: dynmap
#password: dynmap #password: dynmap
#prefix: "" #prefix: ""
#
# AWS S3 backet web site
#type: aws_s3
#bucketname: "dynmap-bucket-name"
#region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
#prefix: ""
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent

View File

@ -43,9 +43,10 @@ storage:
# #
# AWS S3 backet web site # AWS S3 backet web site
#type: aws_s3 #type: aws_s3
#bucketname: dynmap #bucketname: "dynmap-bucket-name"
#region: us-east-1 #region: us-east-1
#aws_access_key_id: "<aws-access-key-id>"
#aws_secret_access_key: "<aws-secret-access-key>"
components: components:
- class: org.dynmap.ClientConfigurationComponent - class: org.dynmap.ClientConfigurationComponent