>From Michael Blow <[email protected]>:

Michael Blow has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21190?usp=email )


Change subject: [NO ISSUE][*DB][STO] Clean up Azure cloud client configuration
......................................................................

[NO ISSUE][*DB][STO] Clean up Azure cloud client configuration

Ext-ref: MB-71312
Change-Id: I83760d446ee5c0859332e7783cc458274494de3d

(cherry picked from commit 11359d40f98e91b85eba3c7695738be489576806)

Change-Id: Ied2e8017898c425318d139134cb145daaf65e964
---
M 
asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageClientConfig.java
M 
asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
M 
asterixdb/asterix-cloud/src/test/java/org/apache/asterix/cloud/azure/LSMAzBlobStorageTest.java
M 
hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/StringUtil.java
4 files changed, 66 insertions(+), 53 deletions(-)



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

diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageClientConfig.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageClientConfig.java
index daea8d2..38b0e0f 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageClientConfig.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageClientConfig.java
@@ -18,6 +18,8 @@
  */
 package org.apache.asterix.cloud.clients.azure.blobstorage;

+import static org.apache.hyracks.util.StringUtil.quoteNullableString;
+
 import java.util.Map;
 import java.util.Objects;

@@ -25,58 +27,57 @@
 import org.apache.asterix.common.config.ICloudProperties;
 import org.apache.asterix.external.util.ExternalDataConstants;
 import org.apache.asterix.external.util.azure.AzureConstants;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;

+import com.azure.core.util.Configuration;
 import com.azure.identity.DefaultAzureCredential;
 import com.azure.identity.DefaultAzureCredentialBuilder;
 import com.azure.storage.blob.models.AccessTier;

 public class AzBlobStorageClientConfig {
+    private static final Logger LOGGER = LogManager.getLogger();
     // Ref: 
https://learn.microsoft.com/en-us/rest/api/storageservices/blob-batch?tabs=microsoft-entra-id
     static final int MAX_CONCURRENT_REQUESTS = 20;

     private static final AccessTier INTERNAL_STORAGE_ACCESS_TIER = 
AccessTier.HOT;
-    private final int writeBufferSize;
-    private final String region;
     private final String endpoint;
+    private final String container;
     private final String prefix;
-
-    private final boolean anonymousAuth;
-    private final long profilerLogInterval;
-    private final String bucket;
+    private final AccessTier accessTier;
+    private final int writeBufferSize;
     private final long tokenAcquireTimeout;
     private final int writeMaxRequestsPerSeconds;
     private final int readMaxRequestsPerSeconds;
+    private final long profilerLogInterval;
     private final boolean storageDisableSSLVerify;
     private final int requestsMaxHttpConnections;
     private final int requestsMaxPendingHttpConnections;
     private final int requestsHttpConnectionAcquireTimeout;
-    private final AccessTier accessTier;
     private final int maxIdleSeconds;
     private final int maxLifetimeSeconds;
+    private final String clientId;

-    public AzBlobStorageClientConfig(String region, String endpoint, String 
prefix, boolean anonymousAuth,
-            long profilerLogInterval, String bucket, int writeBufferSize) {
+    public AzBlobStorageClientConfig(String endpoint, String prefix, long 
profilerLogInterval, String container,
+            int writeBufferSize) {
         // TODO(mblow): using the same values as our defaults for blob storage 
seems sus, refactor to configurable and
         //              and use reasonable defaults
-        this(region, endpoint, prefix, anonymousAuth, profilerLogInterval, 
bucket, 1, 0, 0, writeBufferSize, false,
-                null, CloudProperties.MAX_HTTP_CONNECTIONS_DEFAULT,
-                CloudProperties.MAX_PENDING_HTTP_CONNECTIONS_DEFAULT,
+        this(endpoint, container, prefix, profilerLogInterval, 1, 0, 0, 
writeBufferSize, false, null,
+                CloudProperties.MAX_HTTP_CONNECTIONS_DEFAULT, 
CloudProperties.MAX_PENDING_HTTP_CONNECTIONS_DEFAULT,
                 CloudProperties.HTTP_CONNECTION_ACQUIRE_TIMEOUT_DEFAULT,
                 CloudProperties.HTTP_CONNECTION_MAX_IDLE_SECONDS_DEFAULT,
-                CloudProperties.HTTP_CONNECTION_MAX_LIFETIME_SECONDS_DEFAULT);
+                CloudProperties.HTTP_CONNECTION_MAX_LIFETIME_SECONDS_DEFAULT, 
null);
     }

-    public AzBlobStorageClientConfig(String region, String endpoint, String 
prefix, boolean anonymousAuth,
-            long profilerLogInterval, String bucket, long tokenAcquireTimeout, 
int writeMaxRequestsPerSeconds,
-            int readMaxRequestsPerSeconds, int writeBufferSize, boolean 
storageDisableSSLVerify, AccessTier accessTier,
-            int requestsMaxHttpConnections, int 
requestsMaxPendingHttpConnections,
-            int requestsHttpConnectionAcquireTimeout, int maxIdleSeconds, int 
maxLifetimeSeconds) {
-        this.region = Objects.requireNonNull(region, "region");
+    public AzBlobStorageClientConfig(String endpoint, String container, String 
prefix, long profilerLogInterval,
+            long tokenAcquireTimeout, int writeMaxRequestsPerSeconds, int 
readMaxRequestsPerSeconds,
+            int writeBufferSize, boolean storageDisableSSLVerify, AccessTier 
accessTier, int requestsMaxHttpConnections,
+            int requestsMaxPendingHttpConnections, int 
requestsHttpConnectionAcquireTimeout, int maxIdleSeconds,
+            int maxLifetimeSeconds, String clientId) {
         this.endpoint = endpoint;
         this.prefix = Objects.requireNonNull(prefix, "prefix");
-        this.anonymousAuth = anonymousAuth;
         this.profilerLogInterval = profilerLogInterval;
-        this.bucket = bucket;
+        this.container = container;
         this.tokenAcquireTimeout = tokenAcquireTimeout;
         this.writeMaxRequestsPerSeconds = writeMaxRequestsPerSeconds;
         this.readMaxRequestsPerSeconds = readMaxRequestsPerSeconds;
@@ -89,19 +90,21 @@
         this.accessTier = accessTier;
         this.maxIdleSeconds = maxIdleSeconds;
         this.maxLifetimeSeconds = maxLifetimeSeconds;
+        this.clientId = clientId;
     }

     public static AzBlobStorageClientConfig of(ICloudProperties 
cloudProperties) {
-        return new 
AzBlobStorageClientConfig(cloudProperties.getStorageRegion(), 
cloudProperties.getStorageEndpoint(),
-                cloudProperties.getStoragePrefix(), 
cloudProperties.isStorageAnonymousAuth(),
-                cloudProperties.getProfilerLogInterval(), 
cloudProperties.getStorageBucket(),
+        // TODO(mblow): the client id should be coming in by way fo the cloud 
properties
+        String clientId = 
System.getenv(Configuration.PROPERTY_AZURE_CLIENT_ID);
+        return new 
AzBlobStorageClientConfig(cloudProperties.getStorageEndpoint(), 
cloudProperties.getStorageBucket(),
+                cloudProperties.getStoragePrefix(), 
cloudProperties.getProfilerLogInterval(),
                 cloudProperties.getTokenAcquireTimeout(), 
cloudProperties.getWriteMaxRequestsPerSecond(),
                 cloudProperties.getReadMaxRequestsPerSecond(), 
cloudProperties.getWriteBufferSize(),
                 cloudProperties.isStorageDisableSSLVerify(), 
INTERNAL_STORAGE_ACCESS_TIER,
                 cloudProperties.getRequestsMaxHttpConnections(), 
cloudProperties.getRequestsMaxPendingHttpConnections(),
                 cloudProperties.getRequestsHttpConnectionAcquireTimeout(),
                 cloudProperties.getRequestsHttpConnectionMaxIdleSeconds(),
-                cloudProperties.getRequestsHttpConnectionMaxLifetimeSeconds());
+                cloudProperties.getRequestsHttpConnectionMaxLifetimeSeconds(), 
clientId);
     }

     public static AzBlobStorageClientConfig of(Map<String, String> 
configuration, int writeBufferSize) {
@@ -114,14 +117,8 @@
         // Dummy values;
         String region = "";
         String prefix = "";
-        boolean anonymousAuth = false;

-        return new AzBlobStorageClientConfig(region, endPoint, prefix, 
anonymousAuth, profilerLogInterval, bucket,
-                writeBufferSize);
-    }
-
-    public String getRegion() {
-        return region;
+        return new AzBlobStorageClientConfig(endPoint, prefix, 
profilerLogInterval, bucket, writeBufferSize);
     }

     public String getEndpoint() {
@@ -132,24 +129,20 @@
         return prefix;
     }

-    public String getBucket() {
-        return bucket;
+    public String getContainer() {
+        return container;
     }

     public long getProfilerLogInterval() {
         return profilerLogInterval;
     }

-    public boolean isAnonymousAuth() {
-        return anonymousAuth;
-    }
-
     public boolean isStorageDisableSSLVerify() {
         return storageDisableSSLVerify;
     }

     public DefaultAzureCredential createCredentialsProvider() {
-        return new DefaultAzureCredentialBuilder().build();
+        return new 
DefaultAzureCredentialBuilder().managedIdentityClientId(clientId).build();
     }

     public long getTokenAcquireTimeout() {
@@ -198,4 +191,23 @@
     public int getMaxLifetimeSeconds() {
         return maxLifetimeSeconds;
     }
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    @Override
+    public String toString() {
+        return "AzBlobStorageClientConfig{" + "endpoint=" + 
quoteNullableString(endpoint) + ", " + "container="
+                + quoteNullableString(container) + ", " + "prefix=" + 
quoteNullableString(prefix) + ", " + "accessTier="
+                + accessTier + ", " + "writeBufferSize=" + writeBufferSize + 
", " + "tokenAcquireTimeout="
+                + tokenAcquireTimeout + ", " + "writeMaxRequestsPerSeconds=" + 
writeMaxRequestsPerSeconds + ", "
+                + "readMaxRequestsPerSeconds=" + readMaxRequestsPerSeconds + 
", " + "profilerLogInterval="
+                + profilerLogInterval + ", " + "storageDisableSSLVerify=" + 
storageDisableSSLVerify + ", "
+                + "requestsMaxHttpConnections=" + requestsMaxHttpConnections + 
", "
+                + "requestsMaxPendingHttpConnections=" + 
requestsMaxPendingHttpConnections + ", "
+                + "requestsHttpConnectionAcquireTimeout=" + 
requestsHttpConnectionAcquireTimeout + ", "
+                + "maxIdleSeconds=" + maxIdleSeconds + ", " + 
"maxLifetimeSeconds=" + maxLifetimeSeconds + ", "
+                + "clientId=" + quoteNullableString(clientId) + '}';
+    }
 }
diff --git 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
index 49e911e..bb59992 100644
--- 
a/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
+++ 
b/asterixdb/asterix-cloud/src/main/java/org/apache/asterix/cloud/clients/azure/blobstorage/AzBlobStorageCloudClient.java
@@ -90,10 +90,6 @@
 public class AzBlobStorageCloudClient implements ICloudClient {

     private static final String BUCKET_ROOT_PATH = "";
-    public static final String AZURITE_ENDPOINT = 
"http://127.0.0.1:15055/devstoreaccount1/";;
-    private static final String AZURITE_ACCOUNT_NAME = "devstoreaccount1";
-    private static final String AZURITE_ACCOUNT_KEY =
-            
"Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
     private final ICloudGuardian guardian;
     private final BlobContainerClient blobContainerClient;
     private final BlobContainerAsyncClient blobContainerAsyncClient;
@@ -108,8 +104,8 @@

     public AzBlobStorageCloudClient(AzBlobStorageClientConfig config, 
BlobServiceClient blobServiceClient,
             BlobServiceAsyncClient asyncBlobServiceClient, ICloudGuardian 
guardian) {
-        this.blobContainerClient = 
blobServiceClient.getBlobContainerClient(config.getBucket());
-        this.blobContainerAsyncClient = 
asyncBlobServiceClient.getBlobContainerAsyncClient(config.getBucket());
+        this.blobContainerClient = 
blobServiceClient.getBlobContainerClient(config.getContainer());
+        this.blobContainerAsyncClient = 
asyncBlobServiceClient.getBlobContainerAsyncClient(config.getContainer());
         this.config = config;
         this.guardian = guardian;
         this.accessTier = config.getAccessTier();
@@ -121,6 +117,7 @@
             profiler = new RequestLimiterNoOpProfiler(limiter);
         }
         guardian.setCloudClient(this);
+        LOGGER.debug("Created Azure Cloud Client with config: {}", config);
     }

     @Override
@@ -442,17 +439,12 @@

         if (storageAccount != null && storageKey != null) {
             builder.credential(new StorageSharedKeyCredential(storageAccount, 
storageKey));
-        } else if (config.isAnonymousAuth()) {
-            // TODO(mblow): this mapping anonymous auth -> Azurite default 
account (hack) should be removed ASAP
-            builder.credential(new 
StorageSharedKeyCredential(AZURITE_ACCOUNT_NAME, AZURITE_ACCOUNT_KEY));
         } else {
             builder.credential(config.createCredentialsProvider());
         }
     }

     private static String getEndpoint(AzBlobStorageClientConfig config) {
-        // TODO(mblow): this mapping anonymous auth -> Azurite default 
endpoint (hack) should be removed ASAP
-        return config.isAnonymousAuth() ? AZURITE_ENDPOINT + config.getBucket()
-                : config.getEndpoint() + "/" + config.getBucket();
+        return config.getEndpoint() + "/" + config.getContainer();
     }
 }
diff --git 
a/asterixdb/asterix-cloud/src/test/java/org/apache/asterix/cloud/azure/LSMAzBlobStorageTest.java
 
b/asterixdb/asterix-cloud/src/test/java/org/apache/asterix/cloud/azure/LSMAzBlobStorageTest.java
index e876834..dc0e4f4 100644
--- 
a/asterixdb/asterix-cloud/src/test/java/org/apache/asterix/cloud/azure/LSMAzBlobStorageTest.java
+++ 
b/asterixdb/asterix-cloud/src/test/java/org/apache/asterix/cloud/azure/LSMAzBlobStorageTest.java
@@ -116,8 +116,8 @@
         int writeBufferSize = StorageUtil.getIntSizeInBytes(5, 
StorageUtil.StorageUnit.MEGABYTE);
         URI blobStore = URI.create(blobServiceClient.getAccountUrl());
         String endpoint = blobStore.getScheme() + "://" + 
blobStore.getAuthority() + "/devstoreaccount1";
-        AzBlobStorageClientConfig config = new 
AzBlobStorageClientConfig(MOCK_SERVER_REGION, endpoint, "", false, 0,
-                PLAYGROUND_CONTAINER, 1, 0, 0, writeBufferSize, true, null, 
1000, 10000, 120, 120, 0);
+        AzBlobStorageClientConfig config = new 
AzBlobStorageClientConfig(endpoint, PLAYGROUND_CONTAINER, "", 0, 1, 0, 0,
+                writeBufferSize, true, null, 1000, 10000, 120, 120, 0, null);
         CLOUD_CLIENT = new AzBlobStorageCloudClient(config, 
ICloudGuardian.NoOpCloudGuardian.INSTANCE);
     }

diff --git 
a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/StringUtil.java
 
b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/StringUtil.java
index df33f6b..a7d131e 100644
--- 
a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/StringUtil.java
+++ 
b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/StringUtil.java
@@ -24,6 +24,7 @@

 import org.apache.commons.collections4.map.LRUMap;
 import org.apache.commons.text.WordUtils;
+import org.apache.hyracks.util.annotations.AiProvenance;

 public class StringUtil {
     private static final Map<String, String> CAMEL_CACHE = 
Collections.synchronizedMap(new LRUMap<>(1024));
@@ -51,6 +52,14 @@
         return sb.toString();
     }

+    /**
+     * Quotes a nullable string value with single quotes if non-null, 
otherwise returns null (no quotes).
+     */
+    @AiProvenance(agent = AiProvenance.Agent.GPT_4_1, tool = 
AiProvenance.Tool.GITHUB_COPILOT, contributionKind = 
AiProvenance.ContributionKind.GENERATED)
+    public static String quoteNullableString(String value) {
+        return value == null ? "null" : "'" + value + "'";
+    }
+
     @FunctionalInterface
     public interface ICharAccessor<T> {
         char charAt(T input, int index);

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

Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: phoenix
Gerrit-Change-Id: Ied2e8017898c425318d139134cb145daaf65e964
Gerrit-Change-Number: 21190
Gerrit-PatchSet: 1
Gerrit-Owner: Michael Blow <[email protected]>

Reply via email to