>From Wail Alkowaileet <[email protected]>:

Wail Alkowaileet has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17773 )


Change subject: [ASTERIXDB-3260][STO] Expose stored cloud objects for 
diagnostics
......................................................................

[ASTERIXDB-3260][STO] Expose stored cloud objects for diagnostics

- user model changes: no
- storage format changes: no
- interface changes: yes

Details:
Expose the list of objects (as a JSON array) stored in the
cloud object store (S3)

Change-Id: I37900dc4d5401530a25ef66b916e7b6827ca93dd
---
M 
asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
M 
asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
M 
asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
3 files changed, 99 insertions(+), 38 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/73/17773/1

diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
index 6973b7b..d9c248e 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/AbstractCloudIOManager.java
@@ -49,6 +49,9 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;

+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 public abstract class AbstractCloudIOManager extends IOManager implements 
IPartitionBootstrapper {
     private static final Logger LOGGER = LogManager.getLogger();
     private static final String DATAVERSE_PATH =
@@ -260,4 +263,14 @@
         super.close();
         localIoManager.close();
     }
+
+    /**
+     * Returns a list of all stored objects (sorted ASC by path) in the cloud 
and their sizes
+     *
+     * @param objectMapper to create the result {@link JsonNode}
+     * @return {@link JsonNode} with stored objects' information
+     */
+    public final JsonNode listAsJson(ObjectMapper objectMapper) {
+        return cloudClient.listAsJson(objectMapper, bucket);
+    }
 }
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
index ff26915..f2b7ff4 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/ICloudClient.java
@@ -28,6 +28,9 @@
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.api.io.FileReference;

+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 /**
  * Interface containing methods to perform IO operation on the Cloud Storage
  */
@@ -137,6 +140,15 @@
     void syncFiles(String bucket, Map<String, String> 
cloudToLocalStoragePaths) throws HyracksDataException;

     /**
+     * Produces a {@link JsonNode} that contains information about the stored 
objects in the cloud
+     *
+     * @param objectMapper to create the result {@link JsonNode}
+     * @param bucket       bucket name
+     * @return {@link JsonNode} with stored objects' information
+     */
+    JsonNode listAsJson(ObjectMapper objectMapper, String bucket);
+
+    /**
      * Performs any necessary closing and cleaning up
      */
     void close();
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
index 5619fc8..5faf663 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/aws/s3/S3CloudClient.java
@@ -53,6 +53,11 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;

+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
 import software.amazon.awssdk.core.ResponseInputStream;
 import software.amazon.awssdk.core.sync.RequestBody;
 import software.amazon.awssdk.regions.Region;
@@ -100,22 +105,6 @@

     }

-    private S3Client buildClient() {
-        S3ClientBuilder builder = S3Client.builder();
-        builder.credentialsProvider(config.createCredentialsProvider());
-        builder.region(Region.of(config.getRegion()));
-        if (config.getEndpoint() != null && !config.getEndpoint().isEmpty()) {
-            URI uri;
-            try {
-                uri = new URI(config.getEndpoint());
-            } catch (URISyntaxException ex) {
-                throw new IllegalArgumentException(ex);
-            }
-            builder.endpointOverride(uri);
-        }
-        return builder.build();
-    }
-
     @Override
     public ICloudBufferedWriter createBufferedWriter(String bucket, String 
path) {
         return new S3BufferedWriter(s3Client, profiler, bucket, path);
@@ -253,17 +242,6 @@
         }
     }

-    private Set<String> filterAndGet(List<S3Object> contents, FilenameFilter 
filter) {
-        Set<String> files = new HashSet<>();
-        for (S3Object s3Object : contents) {
-            String path = config.isEncodeKeys() ? 
S3Utils.decodeURI(s3Object.key()) : s3Object.key();
-            if (filter.accept(null, IoUtil.getFileNameFromPath(path))) {
-                files.add(path);
-            }
-        }
-        return files;
-    }
-
     @Override
     public void syncFiles(String bucket, Map<String, String> 
cloudToLocalStoragePaths) throws HyracksDataException {
         LOGGER.info("Syncing cloud storage to local storage started");
@@ -311,6 +289,58 @@
         LOGGER.info("Syncing cloud storage to local storage successful");
     }

+    @Override
+    public JsonNode listAsJson(ObjectMapper objectMapper, String bucket) {
+        List<S3Object> objects = listS3Objects(s3Client, bucket, "/");
+        ArrayNode objectsInfo = objectMapper.createArrayNode();
+
+        objects.sort((x, y) -> String.CASE_INSENSITIVE_ORDER.compare(x.key(), 
y.key()));
+        for (S3Object object : objects) {
+            ObjectNode objectInfo = objectsInfo.addObject();
+            objectInfo.put("path", object.key());
+            objectInfo.put("size", object.size());
+        }
+        return objectsInfo;
+    }
+
+    @Override
+    public void close() {
+        if (s3Client != null) {
+            s3Client.close();
+        }
+
+        if (s3TransferManager != null) {
+            s3TransferManager.close();
+        }
+    }
+
+    private S3Client buildClient() {
+        S3ClientBuilder builder = S3Client.builder();
+        builder.credentialsProvider(config.createCredentialsProvider());
+        builder.region(Region.of(config.getRegion()));
+        if (config.getEndpoint() != null && !config.getEndpoint().isEmpty()) {
+            URI uri;
+            try {
+                uri = new URI(config.getEndpoint());
+            } catch (URISyntaxException ex) {
+                throw new IllegalArgumentException(ex);
+            }
+            builder.endpointOverride(uri);
+        }
+        return builder.build();
+    }
+
+    private Set<String> filterAndGet(List<S3Object> contents, FilenameFilter 
filter) {
+        Set<String> files = new HashSet<>();
+        for (S3Object s3Object : contents) {
+            String path = config.isEncodeKeys() ? 
S3Utils.decodeURI(s3Object.key()) : s3Object.key();
+            if (filter.accept(null, IoUtil.getFileNameFromPath(path))) {
+                files.add(path);
+            }
+        }
+        return files;
+    }
+
     private void downloadFiles(String bucket, Map<String, String> 
cloudToLocalStoragePaths)
             throws HyracksDataException {
         byte[] buffer = new byte[8 * 1024];
@@ -364,15 +394,4 @@
         s3TransferManager = 
S3TransferManager.builder().s3Client(client).build();
         return s3TransferManager;
     }
-
-    @Override
-    public void close() {
-        if (s3Client != null) {
-            s3Client.close();
-        }
-
-        if (s3TransferManager != null) {
-            s3TransferManager.close();
-        }
-    }
 }

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17773
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I37900dc4d5401530a25ef66b916e7b6827ca93dd
Gerrit-Change-Number: 17773
Gerrit-PatchSet: 1
Gerrit-Owner: Wail Alkowaileet <[email protected]>
Gerrit-MessageType: newchange

Reply via email to