nastra commented on code in PR #11577:
URL: https://github.com/apache/iceberg/pull/11577#discussion_r1991831422


##########
azure/src/test/java/org/apache/iceberg/azure/adlsv2/VendedAdlsCredentialProviderTest.java:
##########
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iceberg.azure.adlsv2;
+
+import static 
org.apache.iceberg.azure.AzureProperties.ADLS_SAS_TOKEN_EXPIRES_AT_MS_PREFIX;
+import static org.apache.iceberg.azure.AzureProperties.ADLS_SAS_TOKEN_PREFIX;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+
+import com.azure.core.http.HttpMethod;
+import java.io.IOException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import org.apache.iceberg.TestHelpers;
+import org.apache.iceberg.exceptions.RESTException;
+import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
+import org.apache.iceberg.rest.credentials.Credential;
+import org.apache.iceberg.rest.credentials.ImmutableCredential;
+import org.apache.iceberg.rest.responses.ImmutableLoadCredentialsResponse;
+import org.apache.iceberg.rest.responses.LoadCredentialsResponse;
+import org.apache.iceberg.rest.responses.LoadCredentialsResponseParser;
+import org.junit.jupiter.api.Test;
+import org.mockserver.model.HttpRequest;
+import org.mockserver.model.HttpResponse;
+import org.mockserver.verify.VerificationTimes;
+
+public class VendedAdlsCredentialProviderTest extends 
BaseVendedCredentialsTest {
+  private static final String CREDENTIALS_URI = String.format("%s%s", 
BASE_URI, "/v1/credentials");
+  private static final String STORAGE_ACCOUNT = "account1";
+  private static final String CREDENTIAL_PREFIX =
+      "abfs://contai...@account1.dfs.core.windows.net/dir";
+  private static final String STORAGE_ACCOUNT_2 = "account2";
+  private static final String CREDENTIAL_PREFIX_2 =
+      "abfs://contai...@account2.dfs.core.windows.net/dir";
+
+  @Test
+  public void invalidOrMissingUri() {
+    assertThatThrownBy(() -> new VendedAdlsCredentialProvider(null))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("Invalid properties: null");
+    assertThatThrownBy(() -> new 
VendedAdlsCredentialProvider(ImmutableMap.of()))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessage("Invalid URI: null");
+
+    try (VendedAdlsCredentialProvider provider =
+        new VendedAdlsCredentialProvider(
+            ImmutableMap.of(VendedAdlsCredentialProvider.URI, "invalid uri"))) 
{
+      assertThatThrownBy(() -> provider.credentialForAccount(STORAGE_ACCOUNT))
+          .isInstanceOf(RESTException.class)
+          .hasMessageStartingWith("Failed to create request URI from base 
invalid uri");
+    }
+  }
+
+  @Test
+  public void noADLSCredentials() {
+    HttpRequest mockRequest = 
request("/v1/credentials").withMethod(HttpMethod.GET.name());
+
+    HttpResponse mockResponse =
+        response(
+                LoadCredentialsResponseParser.toJson(
+                    ImmutableLoadCredentialsResponse.builder().build()))
+            .withStatusCode(200);
+    mockServer.when(mockRequest).respond(mockResponse);
+
+    try (VendedAdlsCredentialProvider provider =
+        new VendedAdlsCredentialProvider(
+            ImmutableMap.of(VendedAdlsCredentialProvider.URI, 
CREDENTIALS_URI))) {
+      assertThatThrownBy(() -> provider.credentialForAccount(STORAGE_ACCOUNT))
+          .isInstanceOf(IllegalStateException.class)
+          .hasMessage("Invalid ADLS Credentials for storage-account account1: 
empty");
+    }
+  }
+
+  @Test
+  public void expirationNotSet() {
+    HttpRequest mockRequest = 
request("/v1/credentials").withMethod(HttpMethod.GET.name());
+    LoadCredentialsResponse response =
+        ImmutableLoadCredentialsResponse.builder()
+            .addCredentials(
+                ImmutableCredential.builder()
+                    .prefix(CREDENTIAL_PREFIX)
+                    .config(
+                        ImmutableMap.of(ADLS_SAS_TOKEN_PREFIX + 
STORAGE_ACCOUNT, "randomSasToken"))
+                    .build())
+            .build();
+    HttpResponse mockResponse =
+        
response(LoadCredentialsResponseParser.toJson(response)).withStatusCode(200);
+    mockServer.when(mockRequest).respond(mockResponse);
+
+    try (VendedAdlsCredentialProvider provider =
+        new VendedAdlsCredentialProvider(
+            ImmutableMap.of(VendedAdlsCredentialProvider.URI, 
CREDENTIALS_URI))) {
+      assertThatThrownBy(() -> provider.credentialForAccount(STORAGE_ACCOUNT))
+          .isInstanceOf(IllegalStateException.class)
+          .hasMessage("Invalid ADLS Credentials: 
adls.sas-token-expires-at-ms.account1 not set");
+    }
+  }
+
+  @Test
+  public void nonExpiredSasToken() {
+    HttpRequest mockRequest = 
request("/v1/credentials").withMethod(HttpMethod.GET.name());
+    Credential credential =
+        ImmutableCredential.builder()
+            .prefix(CREDENTIAL_PREFIX)
+            .config(
+                ImmutableMap.of(
+                    ADLS_SAS_TOKEN_PREFIX + STORAGE_ACCOUNT,
+                    "randomSasToken",
+                    ADLS_SAS_TOKEN_EXPIRES_AT_MS_PREFIX + STORAGE_ACCOUNT,
+                    Long.toString(Instant.now().plus(1, 
ChronoUnit.HOURS).toEpochMilli())))
+            .build();
+    LoadCredentialsResponse response =
+        
ImmutableLoadCredentialsResponse.builder().addCredentials(credential).build();
+    HttpResponse mockResponse =
+        
response(LoadCredentialsResponseParser.toJson(response)).withStatusCode(200);
+    mockServer.when(mockRequest).respond(mockResponse);
+
+    try (VendedAdlsCredentialProvider provider =
+        new VendedAdlsCredentialProvider(
+            ImmutableMap.of(VendedAdlsCredentialProvider.URI, 
CREDENTIALS_URI))) {
+      String azureSasCredential = 
provider.credentialForAccount(STORAGE_ACCOUNT);
+      assertThat(azureSasCredential)
+          .isEqualTo(credential.config().get(ADLS_SAS_TOKEN_PREFIX + 
STORAGE_ACCOUNT));
+
+      for (int i = 0; i < 5; i++) {
+        // resolving credentials multiple times should not hit the credentials 
endpoint again
+        
assertThat(provider.credentialForAccount(STORAGE_ACCOUNT)).isSameAs(azureSasCredential);
+      }
+    }
+    mockServer.verify(mockRequest, VerificationTimes.once());
+  }
+
+  @Test
+  public void expiredSasToken() throws InterruptedException {

Review Comment:
   ```suggestion
     public void expiredSasToken() {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org
For additional commands, e-mail: issues-h...@iceberg.apache.org

Reply via email to