Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sdk/storage/azure-storage-file-datalake/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## 12.30.0-beta.1 (Unreleased)

### Features Added
- Added `DataLakeServiceClientBuilder.blobEndpoint(String)` to configure the Blob service endpoint separately from
the Data Lake service endpoint for custom endpoint and proxy scenarios.

### Breaking Changes

Expand Down Expand Up @@ -925,4 +927,3 @@ This package's
[documentation](https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/storage/azure-storage-file-datalake/README.md)
and
[samples](https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/storage/azure-storage-file-datalake/src/samples/java/com/azure/storage/file/datalake)

13 changes: 11 additions & 2 deletions sdk/storage/azure-storage-file-datalake/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClientBuilder()
.buildClient();
```

Some environments expose the Data Lake and Blob services through separate custom or proxy URLs. In that case, set
the Data Lake endpoint with `endpoint` and the Blob endpoint with `blobEndpoint`:

```java readme-sample-getDataLakeServiceClientWithCustomEndpoints
DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClientBuilder()
.endpoint("https://dfs-proxy.example.com")
.blobEndpoint("https://blob-proxy.example.com")
.sasToken("<your-sasToken>")
.buildClient();
```

or

```java readme-sample-getDataLakeServiceClient2
Expand Down Expand Up @@ -446,5 +457,3 @@ This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For m
[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[coc_contact]: mailto:opencode@microsoft.com
[performance_tuning]: https://github.com/Azure/azure-sdk-for-java/blob/main/docs/performance-tuning.md


Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class DataLakeServiceClientBuilder implements TokenCredentialTrait<DataLa
private final BlobServiceClientBuilder blobServiceClientBuilder;

private String endpoint;
private String blobEndpoint;
private String accountName;

private StorageSharedKeyCredential storageSharedKeyCredential;
Expand Down Expand Up @@ -160,7 +161,9 @@ public DataLakeServiceAsyncClient buildAsyncClient() {
public DataLakeServiceClientBuilder endpoint(String endpoint) {
// Ensure endpoint provided is dfs endpoint
endpoint = DataLakeImplUtils.endpointToDesiredEndpoint(endpoint, "dfs", "blob");
blobServiceClientBuilder.endpoint(DataLakeImplUtils.endpointToDesiredEndpoint(endpoint, "blob", "dfs"));
if (blobEndpoint == null) {
blobServiceClientBuilder.endpoint(DataLakeImplUtils.endpointToDesiredEndpoint(endpoint, "blob", "dfs"));
}
try {
BlobUrlParts parts = BlobUrlParts.parse(new URL(endpoint));

Expand All @@ -179,6 +182,24 @@ public DataLakeServiceClientBuilder endpoint(String endpoint) {
return this;
}

/**
* Sets the Blob service endpoint used for operations that are routed through the Blob service. If this is not set,
* the Blob service endpoint is derived from the endpoint set by {@link #endpoint(String)}.
*
* @param blobEndpoint URL of the Blob service.
* @return the updated DataLakeServiceClientBuilder object.
* @throws IllegalArgumentException If {@code blobEndpoint} is {@code null} or is a malformed URL.
*/
public DataLakeServiceClientBuilder blobEndpoint(String blobEndpoint) {
if (blobEndpoint == null) {
throw LOGGER.logExceptionAsError(new IllegalArgumentException("'blobEndpoint' cannot be null."));
}
blobEndpoint = DataLakeImplUtils.endpointToDesiredEndpoint(blobEndpoint, "blob", "dfs");
blobServiceClientBuilder.endpoint(blobEndpoint);
this.blobEndpoint = blobEndpoint;
return this;
}

/**
* Sets the {@link StorageSharedKeyCredential} used to authorize requests sent to the service.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,14 @@ public void authWithIdentity() {
// END: readme-sample-authWithIdentity
}

}
public void getDataLakeServiceClientWithCustomEndpoints() {
// BEGIN: readme-sample-getDataLakeServiceClientWithCustomEndpoints
DataLakeServiceClient dataLakeServiceClient = new DataLakeServiceClientBuilder()
.endpoint("https://dfs-proxy.example.com")
.blobEndpoint("https://blob-proxy.example.com")
.sasToken("<your-sasToken>")
.buildClient();
// END: readme-sample-getDataLakeServiceClientWithCustomEndpoints
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
package com.azure.storage.file.datalake;

import com.azure.storage.common.StorageSharedKeyCredential;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class UrlTests {
private static final StorageSharedKeyCredential CREDENTIAL
Expand Down Expand Up @@ -54,4 +56,48 @@ public void testCorrectServiceUrlSet(String url, String expectedBlobUrl, String
assertEquals(expectedDfsUrl + "/container/blob", pathClient.getPathUrl());
assertEquals(expectedBlobUrl + "/container/blob", pathClient.blockBlobClient.getBlobUrl());
}

@Test
public void testExplicitBlobServiceUrl() {
String dfsEndpoint = "https://dfs-proxy.example.com";
String blobEndpoint = "https://blob-proxy.example.com";
DataLakeServiceClient serviceClient = new DataLakeServiceClientBuilder().credential(CREDENTIAL)
.endpoint(dfsEndpoint)
.blobEndpoint(blobEndpoint)
.buildClient();

assertEquals(dfsEndpoint, serviceClient.getAccountUrl());
assertEquals(blobEndpoint, serviceClient.blobServiceClient.getAccountUrl());
}

@Test
public void testExplicitBlobServiceUrlAsyncEndpointOrderIndependent() {
String dfsEndpoint = "https://dfs-proxy.example.com";
String blobEndpoint = "https://blob-proxy.example.com";
DataLakeServiceAsyncClient serviceAsyncClient = new DataLakeServiceClientBuilder().credential(CREDENTIAL)
.blobEndpoint(blobEndpoint)
.endpoint(dfsEndpoint)
.buildAsyncClient();

assertEquals(dfsEndpoint, serviceAsyncClient.getAccountUrl());
assertEquals(blobEndpoint + "/container",
serviceAsyncClient.getFileSystemAsyncClient("container")
.getBlobContainerAsyncClient()
.getBlobContainerUrl());
}

@Test
public void testExplicitBlobServiceUrlNormalizesDfsEndpoint() {
DataLakeServiceClient serviceClient = new DataLakeServiceClientBuilder().credential(CREDENTIAL)
.endpoint("https://account.dfs.core.windows.net")
.blobEndpoint("https://account.dfs.core.windows.net")
.buildClient();

assertEquals("https://account.blob.core.windows.net", serviceClient.blobServiceClient.getAccountUrl());
}

@Test
public void testExplicitBlobServiceUrlRejectsNullEndpoint() {
assertThrows(IllegalArgumentException.class, () -> new DataLakeServiceClientBuilder().blobEndpoint(null));
}
}
Loading