Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ public class AbfsConfiguration{
DefaultValue = DEFAULT_USE_UPN)
private boolean useUpn;

@BooleanConfigurationValidatorAnnotation(ConfigurationKey =
FS_AZURE_ENABLE_CHECK_ACCESS, DefaultValue = DEFAULT_ENABLE_CHECK_ACCESS)
private boolean isCheckAccessEnabled;

private Map<String, String> storageAccountKeys;

public AbfsConfiguration(final Configuration rawConfig, String accountName)
Expand Down Expand Up @@ -399,6 +403,10 @@ public long getAzureBlockSize() {
return this.azureBlockSize;
}

public boolean isCheckAccessEnabled() {
return this.isCheckAccessEnabled;
}

public String getAzureBlockLocationHost() {
return this.azureBlockLocationHost;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -861,9 +861,14 @@ public AclStatus getAclStatus(final Path path) throws IOException {
* @throws IOException see specific implementation
*/
@Override
public void access(final Path path, FsAction mode) throws IOException {
// TODO: make it no-op to unblock hive permission issue for now.
// Will add a long term fix similar to the implementation in AdlFileSystem.
public void access(final Path path, final FsAction mode) throws IOException {
LOG.debug("AzureBlobFileSystem.access path : {}, mode : {}", path, mode);
Path qualifiedPath = makeQualified(path);
try {
this.abfsStore.access(qualifiedPath, mode);
} catch (AzureBlobFileSystemException ex) {
checkCheckAccessException(path, ex);
}
}

private FileStatus tryGetFileStatus(final Path f) {
Expand Down Expand Up @@ -976,6 +981,18 @@ <T> FileSystemOperation<T> execute(
}
}

private void checkCheckAccessException(final Path path,
final AzureBlobFileSystemException exception) throws IOException {
if (exception instanceof AbfsRestOperationException) {
AbfsRestOperationException ere = (AbfsRestOperationException) exception;
if (ere.getStatusCode() == HttpURLConnection.HTTP_FORBIDDEN) {
throw (IOException) new AccessControlException(ere.getMessage())
.initCause(exception);
}
}
checkException(path, exception);
}

/**
* Given a path and exception, choose which IOException subclass
* to create.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
Copy link
Contributor

Choose a reason for hiding this comment

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

not needed according to checkstyle

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
Expand Down Expand Up @@ -90,6 +91,7 @@
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.http.client.utils.URIBuilder;
import org.slf4j.Logger;
Expand Down Expand Up @@ -892,6 +894,21 @@ public AclStatus getAclStatus(final Path path) throws IOException {
return aclStatusBuilder.build();
}

public void access(final Path path, final FsAction mode)
throws AzureBlobFileSystemException {
LOG.debug("access for filesystem: {}, path: {}, mode: {}",
this.client.getFileSystem(), path, mode);
if (!this.abfsConfiguration.isCheckAccessEnabled()
|| !getIsNamespaceEnabled()) {
LOG.debug("Returning; either check access is not enabled or the account"
+ " used is not namespace enabled");
return;
}
String relativePath =
AbfsHttpConstants.FORWARD_SLASH + getRelativePath(path, true);
this.client.checkAccess(relativePath, mode.SYMBOL);
}

public boolean isAtomicRenameKey(String key) {
return isKeyForDirectorySet(key, azureAtomicRenameDirSet);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public final class AbfsHttpConstants {
public static final String SET_PROPERTIES_ACTION = "setProperties";
public static final String SET_ACCESS_CONTROL = "setAccessControl";
public static final String GET_ACCESS_CONTROL = "getAccessControl";
public static final String CHECK_ACCESS = "checkAccess";
public static final String GET_STATUS = "getStatus";
public static final String DEFAULT_TIMEOUT = "90";
public static final String TOKEN_VERSION = "2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public final class ConfigurationKeys {
public static final String FS_AZURE_DISABLE_OUTPUTSTREAM_FLUSH = "fs.azure.disable.outputstream.flush";
public static final String FS_AZURE_USER_AGENT_PREFIX_KEY = "fs.azure.user.agent.prefix";
public static final String FS_AZURE_SSL_CHANNEL_MODE_KEY = "fs.azure.ssl.channel.mode";
/** Provides a config to enable/disable the checkAccess API.
* By default this will be
* FileSystemConfigurations.DEFAULT_ENABLE_CHECK_ACCESS. **/
public static final String FS_AZURE_ENABLE_CHECK_ACCESS = "fs.azure.enable.check.access";
public static final String FS_AZURE_USE_UPN = "fs.azure.use.upn";
/** User principal names (UPNs) have the format “{alias}@{domain}”. If true,
* only {alias} is included when a UPN would otherwise appear in the output
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public final class FileSystemConfigurations {
public static final boolean DEFAULT_ENABLE_HTTPS = true;

public static final boolean DEFAULT_USE_UPN = false;
public static final boolean DEFAULT_ENABLE_CHECK_ACCESS = false;

private FileSystemConfigurations() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public final class HttpQueryParams {
public static final String QUERY_PARAM_RECURSIVE = "recursive";
public static final String QUERY_PARAM_MAXRESULTS = "maxResults";
public static final String QUERY_PARAM_ACTION = "action";
public static final String QUERY_FS_ACTION = "fsAction";
public static final String QUERY_PARAM_POSITION = "position";
public static final String QUERY_PARAM_TIMEOUT = "timeout";
public static final String QUERY_PARAM_RETAIN_UNCOMMITTED_DATA = "retainUncommittedData";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,28 @@ public AbfsRestOperation getAclStatus(final String path, final boolean useUPN) t
return op;
}

/**
* Talks to the server to check whether the permission specified in
* the rwx parameter is present for the path specified in the path parameter.
*
* @param path Path for which access check needs to be performed
* @param rwx The permission to be checked on the path
* @return The {@link AbfsRestOperation} object for the operation
* @throws AzureBlobFileSystemException in case of bad requests
*/
public AbfsRestOperation checkAccess(String path, String rwx)
throws AzureBlobFileSystemException {
AbfsUriQueryBuilder abfsUriQueryBuilder = createDefaultUriQueryBuilder();
abfsUriQueryBuilder.addQuery(QUERY_PARAM_ACTION, CHECK_ACCESS);
abfsUriQueryBuilder.addQuery(QUERY_FS_ACTION, rwx);
URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
AbfsRestOperation op = new AbfsRestOperation(
AbfsRestOperationType.CheckAccess, this,
AbfsHttpConstants.HTTP_METHOD_HEAD, url, createDefaultHeaders());
op.execute();
return op;
}

private URL createRequestUrl(final String query) throws AzureBlobFileSystemException {
return createRequestUrl(EMPTY_STRING, query);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ public enum AbfsRestOperationType {
Append,
Flush,
ReadFile,
DeletePath
DeletePath,
CheckAccess
}
4 changes: 4 additions & 0 deletions hadoop-tools/hadoop-azure/src/site/markdown/abfs.md
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,10 @@ Hflush() being the only documented API that can provide persistent data
transfer, Flush() also attempting to persist buffered data will lead to
performance issues.

### <a name="flushconfigoptions"></a> Access Options
Config `fs.azure.enable.check.access` needs to be set true to enable
the AzureBlobFileSystem.access().

## <a name="troubleshooting"></a> Troubleshooting

The problems associated with the connector usually come down to, in order
Expand Down
Loading