Skip to content

Commit 9e69628

Browse files
bilaharithsteveloughran
authored andcommitted
HADOOP-16455. ABFS: Implement FileSystem.access() method.
Contributed by Bilahari T H.
1 parent 7f2ea2a commit 9e69628

File tree

12 files changed

+405
-5
lines changed

12 files changed

+405
-5
lines changed

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AbfsConfiguration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ public class AbfsConfiguration{
178178
DefaultValue = DEFAULT_USE_UPN)
179179
private boolean useUpn;
180180

181+
@BooleanConfigurationValidatorAnnotation(ConfigurationKey =
182+
FS_AZURE_ENABLE_CHECK_ACCESS, DefaultValue = DEFAULT_ENABLE_CHECK_ACCESS)
183+
private boolean isCheckAccessEnabled;
184+
181185
@BooleanConfigurationValidatorAnnotation(ConfigurationKey = FS_AZURE_ABFS_LATENCY_TRACK,
182186
DefaultValue = DEFAULT_ABFS_LATENCY_TRACK)
183187
private boolean trackLatency;
@@ -403,6 +407,10 @@ public long getAzureBlockSize() {
403407
return this.azureBlockSize;
404408
}
405409

410+
public boolean isCheckAccessEnabled() {
411+
return this.isCheckAccessEnabled;
412+
}
413+
406414
public String getAzureBlockLocationHost() {
407415
return this.azureBlockLocationHost;
408416
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystem.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -861,9 +861,14 @@ public AclStatus getAclStatus(final Path path) throws IOException {
861861
* @throws IOException see specific implementation
862862
*/
863863
@Override
864-
public void access(final Path path, FsAction mode) throws IOException {
865-
// TODO: make it no-op to unblock hive permission issue for now.
866-
// Will add a long term fix similar to the implementation in AdlFileSystem.
864+
public void access(final Path path, final FsAction mode) throws IOException {
865+
LOG.debug("AzureBlobFileSystem.access path : {}, mode : {}", path, mode);
866+
Path qualifiedPath = makeQualified(path);
867+
try {
868+
this.abfsStore.access(qualifiedPath, mode);
869+
} catch (AzureBlobFileSystemException ex) {
870+
checkCheckAccessException(path, ex);
871+
}
867872
}
868873

869874
private FileStatus tryGetFileStatus(final Path f) {
@@ -976,6 +981,18 @@ <T> FileSystemOperation<T> execute(
976981
}
977982
}
978983

984+
private void checkCheckAccessException(final Path path,
985+
final AzureBlobFileSystemException exception) throws IOException {
986+
if (exception instanceof AbfsRestOperationException) {
987+
AbfsRestOperationException ere = (AbfsRestOperationException) exception;
988+
if (ere.getStatusCode() == HttpURLConnection.HTTP_FORBIDDEN) {
989+
throw (IOException) new AccessControlException(ere.getMessage())
990+
.initCause(exception);
991+
}
992+
}
993+
checkException(path, exception);
994+
}
995+
979996
/**
980997
* Given a path and exception, choose which IOException subclass
981998
* to create.

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AzureBlobFileSystemStore.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,25 @@ public AclStatus getAclStatus(final Path path) throws IOException {
10721072
}
10731073
}
10741074

1075+
public void access(final Path path, final FsAction mode)
1076+
throws AzureBlobFileSystemException {
1077+
LOG.debug("access for filesystem: {}, path: {}, mode: {}",
1078+
this.client.getFileSystem(), path, mode);
1079+
if (!this.abfsConfiguration.isCheckAccessEnabled()
1080+
|| !getIsNamespaceEnabled()) {
1081+
LOG.debug("Returning; either check access is not enabled or the account"
1082+
+ " used is not namespace enabled");
1083+
return;
1084+
}
1085+
try (AbfsPerfInfo perfInfo = startTracking("access", "checkAccess")) {
1086+
String relativePath =
1087+
AbfsHttpConstants.FORWARD_SLASH + getRelativePath(path, true);
1088+
final AbfsRestOperation op = this.client
1089+
.checkAccess(relativePath, mode.SYMBOL);
1090+
perfInfo.registerResult(op.getResult()).registerSuccess(true);
1091+
}
1092+
}
1093+
10751094
public boolean isAtomicRenameKey(String key) {
10761095
return isKeyForDirectorySet(key, azureAtomicRenameDirSet);
10771096
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/AbfsHttpConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public final class AbfsHttpConstants {
3737
public static final String SET_PROPERTIES_ACTION = "setProperties";
3838
public static final String SET_ACCESS_CONTROL = "setAccessControl";
3939
public static final String GET_ACCESS_CONTROL = "getAccessControl";
40+
public static final String CHECK_ACCESS = "checkAccess";
4041
public static final String GET_STATUS = "getStatus";
4142
public static final String DEFAULT_TIMEOUT = "90";
4243
public static final String TOKEN_VERSION = "2";

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/ConfigurationKeys.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public final class ConfigurationKeys {
6262
public static final String FS_AZURE_DISABLE_OUTPUTSTREAM_FLUSH = "fs.azure.disable.outputstream.flush";
6363
public static final String FS_AZURE_USER_AGENT_PREFIX_KEY = "fs.azure.user.agent.prefix";
6464
public static final String FS_AZURE_SSL_CHANNEL_MODE_KEY = "fs.azure.ssl.channel.mode";
65+
/** Provides a config to enable/disable the checkAccess API.
66+
* By default this will be
67+
* FileSystemConfigurations.DEFAULT_ENABLE_CHECK_ACCESS. **/
68+
public static final String FS_AZURE_ENABLE_CHECK_ACCESS = "fs.azure.enable.check.access";
6569
public static final String FS_AZURE_USE_UPN = "fs.azure.use.upn";
6670
/** User principal names (UPNs) have the format “{alias}@{domain}”. If true,
6771
* only {alias} is included when a UPN would otherwise appear in the output

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/FileSystemConfigurations.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ public final class FileSystemConfigurations {
6767
public static final boolean DEFAULT_ENABLE_HTTPS = true;
6868

6969
public static final boolean DEFAULT_USE_UPN = false;
70+
public static final boolean DEFAULT_ENABLE_CHECK_ACCESS = false;
7071
public static final boolean DEFAULT_ABFS_LATENCY_TRACK = false;
7172

7273
private FileSystemConfigurations() {}
73-
}
74+
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/constants/HttpQueryParams.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public final class HttpQueryParams {
3232
public static final String QUERY_PARAM_RECURSIVE = "recursive";
3333
public static final String QUERY_PARAM_MAXRESULTS = "maxResults";
3434
public static final String QUERY_PARAM_ACTION = "action";
35+
public static final String QUERY_FS_ACTION = "fsAction";
3536
public static final String QUERY_PARAM_POSITION = "position";
3637
public static final String QUERY_PARAM_TIMEOUT = "timeout";
3738
public static final String QUERY_PARAM_RETAIN_UNCOMMITTED_DATA = "retainUncommittedData";

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsClient.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,28 @@ public AbfsRestOperation getAclStatus(final String path, final boolean useUPN) t
524524
return op;
525525
}
526526

527+
/**
528+
* Talks to the server to check whether the permission specified in
529+
* the rwx parameter is present for the path specified in the path parameter.
530+
*
531+
* @param path Path for which access check needs to be performed
532+
* @param rwx The permission to be checked on the path
533+
* @return The {@link AbfsRestOperation} object for the operation
534+
* @throws AzureBlobFileSystemException in case of bad requests
535+
*/
536+
public AbfsRestOperation checkAccess(String path, String rwx)
537+
throws AzureBlobFileSystemException {
538+
AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
539+
abfsUriQueryBuilder.addQuery(QUERY_PARAM_ACTION, CHECK_ACCESS);
540+
abfsUriQueryBuilder.addQuery(QUERY_FS_ACTION, rwx);
541+
URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
542+
AbfsRestOperation op = new AbfsRestOperation(
543+
AbfsRestOperationType.CheckAccess, this,
544+
AbfsHttpConstants.HTTP_METHOD_HEAD, url, createDefaultHeaders());
545+
op.execute();
546+
return op;
547+
}
548+
527549
private URL createRequestUrl(final String query) throws AzureBlobFileSystemException {
528550
return createRequestUrl(EMPTY_STRING, query);
529551
}

hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsRestOperationType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ public enum AbfsRestOperationType {
3939
Append,
4040
Flush,
4141
ReadFile,
42-
DeletePath
42+
DeletePath,
43+
CheckAccess
4344
}

hadoop-tools/hadoop-azure/src/site/markdown/abfs.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,10 @@ Hflush() being the only documented API that can provide persistent data
661661
transfer, Flush() also attempting to persist buffered data will lead to
662662
performance issues.
663663

664+
### <a name="flushconfigoptions"></a> Access Options
665+
Config `fs.azure.enable.check.access` needs to be set true to enable
666+
the AzureBlobFileSystem.access().
667+
664668
### <a name="perfoptions"></a> Perf Options
665669

666670
#### <a name="abfstracklatencyoptions"></a> 1. HTTP Request Tracking Options

0 commit comments

Comments
 (0)