[ASTERIXDB-2935]: Add support to managedIdentityId

Change-Id: I9eb01a7fb53197ad47aab7b87f7d8d48c21782db
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13143
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataConstants.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataConstants.java
index 546e390..391bb5d 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataConstants.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataConstants.java
@@ -357,11 +357,13 @@
          * Asterix Configuration Keys
          */
         public static final String CONNECTION_STRING_FIELD_NAME = "connectionString";
+        public static final String MANAGED_IDENTITY_ID_FIELD_NAME = "managedIdentityId";
         public static final String TENANT_ID_FIELD_NAME = "tenantId";
         public static final String CLIENT_ID_FIELD_NAME = "clientId";
         public static final String CLIENT_SECRET_FIELD_NAME = "clientSecret";
         public static final String CLIENT_CERTIFICATE_FIELD_NAME = "clientCertificate";
         public static final String CLIENT_CERTIFICATE_PASSWORD_FIELD_NAME = "clientCertificatePassword";
+        public static final String ENDPOINT_FIELD_NAME = "endpoint";
 
         /*
          * Hadoop-Azure
diff --git a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
index 754aecf..ac02c92 100644
--- a/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
+++ b/asterixdb/asterix-external-data/src/main/java/org/apache/asterix/external/util/ExternalDataUtils.java
@@ -22,6 +22,7 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.asterix.common.exceptions.ErrorCode.EXTERNAL_SOURCE_ERROR;
 import static org.apache.asterix.common.exceptions.ErrorCode.PARAMETERS_NOT_ALLOWED_AT_SAME_TIME;
+import static org.apache.asterix.common.exceptions.ErrorCode.PARAMETERS_REQUIRED;
 import static org.apache.asterix.common.exceptions.ErrorCode.REQUIRED_PARAM_IF_PARAM_IS_PRESENT;
 import static org.apache.asterix.common.exceptions.ErrorCode.REQUIRED_PARAM_OR_PARAM_IF_PARAM_IS_PRESENT;
 import static org.apache.asterix.external.util.ExternalDataConstants.AwsS3.ACCESS_KEY_ID_FIELD_NAME;
@@ -42,9 +43,11 @@
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.CLIENT_ID_FIELD_NAME;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.CLIENT_SECRET_FIELD_NAME;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.CONNECTION_STRING_FIELD_NAME;
+import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.ENDPOINT_FIELD_NAME;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.HADOOP_AZURE_BLOB_PROTOCOL;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.HADOOP_AZURE_FS_ACCOUNT_KEY;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.HADOOP_AZURE_FS_SAS;
+import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.MANAGED_IDENTITY_ID_FIELD_NAME;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.SAS_KEY_PREFIX;
 import static org.apache.asterix.external.util.ExternalDataConstants.AzureBlob.TENANT_ID_FIELD_NAME;
 import static org.apache.asterix.external.util.ExternalDataConstants.GCS.JSON_CREDENTIALS_FIELD_NAME;
@@ -121,6 +124,7 @@
 
 import com.azure.identity.ClientCertificateCredentialBuilder;
 import com.azure.identity.ClientSecretCredentialBuilder;
+import com.azure.identity.ManagedIdentityCredentialBuilder;
 import com.azure.storage.blob.BlobContainerClient;
 import com.azure.storage.blob.BlobServiceClient;
 import com.azure.storage.blob.BlobServiceClientBuilder;
@@ -1236,11 +1240,13 @@
         public static BlobServiceClient buildAzureClient(Map<String, String> configuration)
                 throws CompilationException {
             String connectionString = configuration.get(CONNECTION_STRING_FIELD_NAME);
+            String managedIdentityId = configuration.get(MANAGED_IDENTITY_ID_FIELD_NAME);
             String tenantId = configuration.get(TENANT_ID_FIELD_NAME);
             String clientId = configuration.get(CLIENT_ID_FIELD_NAME);
             String clientSecret = configuration.get(CLIENT_SECRET_FIELD_NAME);
             String clientCertificate = configuration.get(CLIENT_CERTIFICATE_FIELD_NAME);
             String clientCertificatePassword = configuration.get(CLIENT_CERTIFICATE_PASSWORD_FIELD_NAME);
+            String endpoint = configuration.get(ENDPOINT_FIELD_NAME);
 
             // Client builder
             BlobServiceClientBuilder builder = new BlobServiceClientBuilder();
@@ -1258,9 +1264,19 @@
                         ExternalDataConstants.FORMAT_PARQUET);
             }
 
+            // TODO(htowaileb): Endpoint will be required for Data lake implementation
+            if (endpoint != null) {
+                builder.endpoint(endpoint);
+            }
+
+            // Managed identity credentials
+            if (managedIdentityId != null) {
+                builder.credential(new ManagedIdentityCredentialBuilder().clientId(managedIdentityId).build());
+            }
+
             // Active Directory authentication
             if (clientId != null) {
-                // Both (or neither) client secret and client secret were provided, only one is allowed
+                // Both (or neither) client secret and client certificate were provided, only one is allowed
                 if ((clientSecret == null) == (clientCertificate == null)) {
                     if (clientSecret != null) {
                         throw new CompilationException(PARAMETERS_NOT_ALLOWED_AT_SAME_TIME, CLIENT_SECRET_FIELD_NAME,
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 898d9e9..b93138f 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -1054,6 +1054,10 @@
         <classifier>tests</classifier>
         <exclusions>
           <exclusion>
+            <groupId>com.nimbusds</groupId>
+            <artifactId>nimbus-jose-jwt</artifactId>
+          </exclusion>
+          <exclusion>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
           </exclusion>