Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
import static org.apache.hadoop.fs.Options.OpenFileOptions.FS_OPTION_OPENFILE_STANDARD_OPTIONS;
import static org.apache.hadoop.fs.azurebfs.AbfsStatistic.*;
import static org.apache.hadoop.fs.azurebfs.constants.AbfsHttpConstants.CPK_IN_NON_HNS_ACCOUNT_ERROR_MESSAGE;
import static org.apache.hadoop.fs.azurebfs.constants.AbfsServiceType.DFS;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.DATA_BLOCKS_BUFFER;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_IS_HNS_ENABLED;
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_BLOCK_UPLOAD_ACTIVE_BLOCKS;
Expand Down Expand Up @@ -250,6 +251,7 @@ public void initialize(URI uri, Configuration configuration)
try {
if (abfsConfiguration.getAuthType(abfsConfiguration.getAccountName()) == AuthType.SAS && // Auth type is SAS
!tryGetIsNamespaceEnabled(new TracingContext(initFSTracingContext)) && // Account is FNS
abfsConfiguration.getFsConfiguredServiceType() == DFS && // Service type is DFS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the constant for DFS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is using the AbfsServiceType.DFS constant here

!abfsConfiguration.isFixedSASTokenProviderConfigured()) { // Fixed SAS Token Provider is not configured
throw new InvalidConfigurationValueException(FS_AZURE_SAS_FIXED_TOKEN, UNAUTHORIZED_SAS);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@
public interface SASTokenProvider {

String CHECK_ACCESS_OPERATION = "check-access";
String COPY_BLOB_DST_OPERATION = "copy-blob-dst";
String COPY_BLOB_SRC_OPERATION = "copy-blob-src";
String CREATE_DIRECTORY_OPERATION = "create-directory";
String CREATE_FILE_OPERATION = "create-file";
String DELETE_OPERATION = "delete";
String DELETE_RECURSIVE_OPERATION = "delete-recursive";
String GET_ACL_OPERATION = "get-acl";
String GET_STATUS_OPERATION = "get-status";
String GET_PROPERTIES_OPERATION = "get-properties";
String LEASE_BLOB_OPERATION = "lease-blob";
String LIST_OPERATION = "list";
String LIST_OPERATION_BLOB = "list-blob";
String READ_OPERATION = "read";
String RENAME_SOURCE_OPERATION = "rename-source";
String RENAME_DESTINATION_OPERATION = "rename-destination";
Expand All @@ -49,8 +53,6 @@ public interface SASTokenProvider {
String SET_PERMISSION_OPERATION = "set-permission";
String SET_PROPERTIES_OPERATION = "set-properties";
String WRITE_OPERATION = "write";
// Generic HTTP operation can be used with FixedSASTokenProvider.
String FIXED_SAS_STORE_OPERATION = "fixed-sas";

/**
* Initialize authorizer for Azure Blob File System.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ public AbfsRestOperation listPath(final String relativePath, final boolean recur
abfsUriQueryBuilder.addQuery(QUERY_PARAM_DELIMITER, FORWARD_SLASH);
}
abfsUriQueryBuilder.addQuery(QUERY_PARAM_MAX_RESULTS, String.valueOf(listMaxResults));
appendSASTokenToQuery(relativePath, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(relativePath, SASTokenProvider.LIST_OPERATION_BLOB, abfsUriQueryBuilder);

final URL url = createRequestUrl(abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -539,11 +539,14 @@ public AbfsRestOperation createPathRestOp(final String path,
final ContextEncryptionAdapter contextEncryptionAdapter,
final TracingContext tracingContext) throws AzureBlobFileSystemException {
final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();
final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
if (isFile) {
addEncryptionKeyRequestHeaders(path, requestHeaders, true,
contextEncryptionAdapter, tracingContext);
appendSASTokenToQuery(path, SASTokenProvider.CREATE_FILE_OPERATION, abfsUriQueryBuilder);
} else {
requestHeaders.add(new AbfsHttpHeader(X_MS_META_HDI_ISFOLDER, TRUE));
appendSASTokenToQuery(path, SASTokenProvider.CREATE_DIRECTORY_OPERATION, abfsUriQueryBuilder);
}
requestHeaders.add(new AbfsHttpHeader(CONTENT_LENGTH, ZERO));
if (isAppendBlob) {
Expand All @@ -558,9 +561,6 @@ public AbfsRestOperation createPathRestOp(final String path,
requestHeaders.add(new AbfsHttpHeader(HttpHeaderConfigurations.IF_MATCH, eTag));
}

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
AbfsRestOperationType.PutBlob,
Expand Down Expand Up @@ -682,7 +682,7 @@ public AbfsRestOperation acquireLease(final String path,

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, LEASE);
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(path, SASTokenProvider.LEASE_BLOB_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -710,7 +710,7 @@ public AbfsRestOperation renewLease(final String path, final String leaseId,

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, LEASE);
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(path, SASTokenProvider.LEASE_BLOB_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -738,7 +738,7 @@ public AbfsRestOperation releaseLease(final String path, final String leaseId,

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, LEASE);
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(path, SASTokenProvider.LEASE_BLOB_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand All @@ -765,7 +765,7 @@ public AbfsRestOperation breakLease(final String path,

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, LEASE);
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(path, SASTokenProvider.LEASE_BLOB_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -813,12 +813,15 @@ destination, sourceEtag, isAtomicRenameKey(source), tracingContext
if (blobRenameHandler.execute()) {
final AbfsUriQueryBuilder abfsUriQueryBuilder
= createDefaultUriQueryBuilder();
appendSASTokenToQuery(source, SASTokenProvider.RENAME_SOURCE_OPERATION,
abfsUriQueryBuilder);
final URL url = createRequestUrl(destination,
abfsUriQueryBuilder.toString());
final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();
final AbfsRestOperation successOp = getSuccessOp(
AbfsRestOperationType.RenamePath, HTTP_METHOD_PUT,
url, requestHeaders);
successOp.setMask();
Copy link
Contributor

@anmolanmol1234 anmolanmol1234 Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this performed only in the rename case ? By default we mask for all cases if auth type is SAS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, yes we mask for all SAS cases

return new AbfsClientRenameResult(successOp, true, false);
} else {
throw new AbfsRestOperationException(HTTP_INTERNAL_ERROR,
Expand Down Expand Up @@ -886,7 +889,7 @@ public AbfsRestOperation append(final String path,
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, BLOCK);
abfsUriQueryBuilder.addQuery(QUERY_PARAM_BLOCKID, reqParams.getBlockId());

String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION,
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.WRITE_OPERATION,
abfsUriQueryBuilder, cachedSasToken);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
Expand Down Expand Up @@ -959,7 +962,7 @@ public AbfsRestOperation appendBlock(final String path,
}
final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, APPEND_BLOCK);
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.WRITE_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -1051,7 +1054,7 @@ public AbfsRestOperation flush(byte[] buffer,
final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, BLOCKLIST);
abfsUriQueryBuilder.addQuery(QUERY_PARAM_CLOSE, String.valueOf(isClose));
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION,
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.WRITE_OPERATION,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is using WRITE_OPERATION for the flush call a good idea? Should we create another operation type for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the same operation type for DFS flush call as well. We can keep it as it is I think

abfsUriQueryBuilder, cachedSasToken);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
Expand Down Expand Up @@ -1113,7 +1116,7 @@ public AbfsRestOperation setPathProperties(final String path,

AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, METADATA);
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
appendSASTokenToQuery(path, SASTokenProvider.SET_PROPERTIES_OPERATION, abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
final AbfsRestOperation op = getAbfsRestOperation(
Expand Down Expand Up @@ -1194,7 +1197,7 @@ public AbfsRestOperation getPathStatus(final String path,
final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(HttpQueryParams.QUERY_PARAM_UPN,
String.valueOf(getAbfsConfiguration().isUpnUsed()));
appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION,
appendSASTokenToQuery(path, SASTokenProvider.GET_PROPERTIES_OPERATION,
abfsUriQueryBuilder);

final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
Expand Down Expand Up @@ -1271,7 +1274,7 @@ public AbfsRestOperation read(final String path,
}

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.FIXED_SAS_STORE_OPERATION,
String sasTokenForReuse = appendSASTokenToQuery(path, SASTokenProvider.READ_OPERATION,
abfsUriQueryBuilder, cachedSasToken);

URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
Expand Down Expand Up @@ -1433,7 +1436,7 @@ public AbfsRestOperation getBlockList(final String path,
final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();

final AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
String operation = SASTokenProvider.FIXED_SAS_STORE_OPERATION;
String operation = SASTokenProvider.READ_OPERATION;
appendSASTokenToQuery(path, operation, abfsUriQueryBuilder);

abfsUriQueryBuilder.addQuery(QUERY_PARAM_COMP, BLOCKLIST);
Expand Down Expand Up @@ -1471,9 +1474,9 @@ public AbfsRestOperation copyBlob(Path sourceBlobPath,
String dstBlobRelativePath = destinationBlobPath.toUri().getPath();
String srcBlobRelativePath = sourceBlobPath.toUri().getPath();
appendSASTokenToQuery(dstBlobRelativePath,
SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilderDst);
SASTokenProvider.COPY_BLOB_DST_OPERATION, abfsUriQueryBuilderDst);
appendSASTokenToQuery(srcBlobRelativePath,
SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilderSrc);
SASTokenProvider.COPY_BLOB_SRC_OPERATION, abfsUriQueryBuilderSrc);
final URL url = createRequestUrl(dstBlobRelativePath,
abfsUriQueryBuilderDst.toString());
final String sourcePathUrl = createRequestUrl(srcBlobRelativePath,
Expand Down Expand Up @@ -1507,7 +1510,7 @@ public AbfsRestOperation deleteBlobPath(final Path blobPath,
AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
String blobRelativePath = blobPath.toUri().getPath();
appendSASTokenToQuery(blobRelativePath,
SASTokenProvider.FIXED_SAS_STORE_OPERATION, abfsUriQueryBuilder);
SASTokenProvider.DELETE_OPERATION, abfsUriQueryBuilder);
final URL url = createRequestUrl(blobRelativePath,
abfsUriQueryBuilder.toString());
final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public final class AbfsErrors {
/**
* Exception message on filesystem init if token-provider-auth-type configs are provided
*/
public static final String UNAUTHORIZED_SAS = "Incorrect SAS token provider configured for non-hierarchical namespace account.";
public static final String UNAUTHORIZED_SAS = "Incorrect SAS token provider configured for non-hierarchical namespace account with DFS service type.";
public static final String ERR_RENAME_BLOB =
"FNS-Blob rename was not successful for source and destination path: ";
public static final String ERR_DELETE_BLOB =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ public AbfsHttpOperation getResult() {
return result;
}

public void setMask() {
result.setMaskForSAS();
}

public void hardSetResult(int httpStatus) {
result = AbfsHttpOperation.getAbfsHttpOperationWithFixedResult(this.url,
this.method, httpStatus);
Expand Down
8 changes: 4 additions & 4 deletions hadoop-tools/hadoop-azure/src/site/markdown/abfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -663,13 +663,13 @@ To know more about how SAS Authentication works refer to
[Grant limited access to Azure Storage resources using shared access signatures (SAS)](https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview)

There are three types of SAS supported by Azure Storage:
- [User Delegation SAS](https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas): Recommended for use with ABFS Driver with HNS Enabled ADLS Gen2 accounts. It is Identity based SAS that works at blob/directory level)
- [User Delegation SAS](https://learn.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas): Recommended for use with ABFS Driver with HNS Enabled ADLS Gen2 accounts or HNS-Disabled Blob Storage accounts. It is Identity based SAS that works at blob/directory level)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This recommended line should say HNS only

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes recommended only for HNS-DFS.
Supported on HNS-DFS and FNS-BLOB
Not supported on FNS-DFS

This should be clearly conveyed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, rectified

- [Service SAS](https://learn.microsoft.com/en-us/rest/api/storageservices/create-service-sas): Global and works at container level.
- [Account SAS](https://learn.microsoft.com/en-us/rest/api/storageservices/create-account-sas): Global and works at account level.

#### Known Issues With SAS
- SAS Based Authentication works only with HNS Enabled ADLS Gen2 Accounts which
is a recommended account type to be used with ABFS.
- SAS Based Authentication works with HNS Enabled ADLS Gen2 Accounts (which
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does SAS work correctly with FNS DFS ? We should say FNS here only if we confirm the behaviour for both the endpoints

is a recommended account type to be used with ABFS) and HNS-Disabled Blob Storage accounts.
- Certain root level operations are known to fail with SAS Based Authentication.

#### Using User Delegation SAS with ABFS
Expand Down Expand Up @@ -737,7 +737,7 @@ the following configurations apart from above two:

- **Security**: More secure than Shared Key and allows granting limited access
to data without exposing the access key. Recommended to be used only with HNS Enabled,
ADLS Gen 2 storage accounts.
ADLS Gen 2 storage accounts or HNS-Disabled Blob Storage accounts.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again remove non HNS for recommended


#### Using Account/Service SAS with ABFS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,17 @@ public ITestAzureBlobFileSystemDelegationSAS() throws Exception {
public void setup() throws Exception {
isHNSEnabled = this.getConfiguration().getBoolean(
TestConfigurationKeys.FS_AZURE_TEST_NAMESPACE_ENABLED_ACCOUNT, false);
Assume.assumeTrue(isHNSEnabled);
if(!isHNSEnabled){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add more tests around user delegation SAS specific to FNS Blob and see it works correctly for all cases of implicit, explicit, root path, container path

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some new tests. Please review

assumeBlobServiceType();
}
createFilesystemForSASTests();
super.setup();
}

@Test
// Test filesystem operations access, create, mkdirs, setOwner, getFileStatus
public void testCheckAccess() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();

Path rootPath = new Path("/");
Expand Down Expand Up @@ -217,6 +220,7 @@ public void testReadAndWrite() throws Exception {

@Test
public void checkExceptionForRenameOverwrites() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();

Path src = new Path("a/b/f1.txt");
Expand Down Expand Up @@ -315,6 +319,7 @@ public void testList() throws Exception {
// Test filesystem operations setAcl, getAclStatus, removeAcl
// setPermissions and getFileStatus
public void testAcl() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();
Path reqPath = new Path(UUID.randomUUID().toString());

Expand Down Expand Up @@ -344,6 +349,7 @@ public void testAcl() throws Exception {
@Test
// Test getFileStatus and getAclStatus operations on root path
public void testRootPath() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();
Path rootPath = new Path(AbfsHttpConstants.ROOT_PATH);

Expand Down Expand Up @@ -443,6 +449,7 @@ null, getTestTracingContext(getFileSystem(), false),
@Test
// SetPermission should fail when saoid is not the owner and succeed when it is.
public void testSetPermissionForNonOwner() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();

Path rootPath = new Path("/");
Expand Down Expand Up @@ -478,6 +485,7 @@ public void testSetPermissionForNonOwner() throws Exception {
@Test
// Without saoid or suoid, setPermission should succeed with sp=p for a non-owner.
public void testSetPermissionWithoutAgentForNonOwner() throws Exception {
assumeHnsEnabled();
final AzureBlobFileSystem fs = getFileSystem();
Path path = new Path(MockDelegationSASTokenProvider.NO_AGENT_PATH);
fs.create(path).close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public String getDelegationSAS(String accountName, String containerName, String
case SASTokenProvider.CREATE_DIRECTORY_OPERATION:
case SASTokenProvider.WRITE_OPERATION:
case SASTokenProvider.SET_PROPERTIES_OPERATION:
case SASTokenProvider.LEASE_BLOB_OPERATION:
case SASTokenProvider.COPY_BLOB_DST_OPERATION:
sp = "w";
break;
case SASTokenProvider.DELETE_OPERATION:
Expand All @@ -75,11 +77,16 @@ public String getDelegationSAS(String accountName, String containerName, String
case SASTokenProvider.GET_STATUS_OPERATION:
sp = "e";
break;
case SASTokenProvider.LIST_OPERATION_BLOB:
sp = "l";
sr="c";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spacing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected

break;
case SASTokenProvider.LIST_OPERATION:
sp = "l";
break;
case SASTokenProvider.GET_PROPERTIES_OPERATION:
case SASTokenProvider.READ_OPERATION:
case SASTokenProvider.COPY_BLOB_SRC_OPERATION:
sp = "r";
break;
case SASTokenProvider.RENAME_DESTINATION_OPERATION:
Expand Down