HADOOP-17725. Improve error message for token providers in ABFS (#3041)
Contributed by Viraj Jasani.
This commit is contained in:
parent
762a83e044
commit
00d372b663
@ -402,6 +402,24 @@ public String getPasswordString(String key) throws IOException {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a value for the key if the value exists and is not null.
|
||||||
|
* Otherwise, throws {@link ConfigurationPropertyNotFoundException} with
|
||||||
|
* key name.
|
||||||
|
*
|
||||||
|
* @param key Account-agnostic configuration key
|
||||||
|
* @return value if exists
|
||||||
|
* @throws IOException if error in fetching password or
|
||||||
|
* ConfigurationPropertyNotFoundException for missing key
|
||||||
|
*/
|
||||||
|
private String getMandatoryPasswordString(String key) throws IOException {
|
||||||
|
String value = getPasswordString(key);
|
||||||
|
if (value == null) {
|
||||||
|
throw new ConfigurationPropertyNotFoundException(key);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns account-specific token provider class if it exists, else checks if
|
* Returns account-specific token provider class if it exists, else checks if
|
||||||
* an account-agnostic setting is present for token provider class if AuthType
|
* an account-agnostic setting is present for token provider class if AuthType
|
||||||
@ -742,25 +760,33 @@ public AccessTokenProvider getTokenProvider() throws TokenAccessProviderExceptio
|
|||||||
FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME, null,
|
FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME, null,
|
||||||
AccessTokenProvider.class);
|
AccessTokenProvider.class);
|
||||||
|
|
||||||
AccessTokenProvider tokenProvider = null;
|
AccessTokenProvider tokenProvider;
|
||||||
if (tokenProviderClass == ClientCredsTokenProvider.class) {
|
if (tokenProviderClass == ClientCredsTokenProvider.class) {
|
||||||
String authEndpoint = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT);
|
String authEndpoint =
|
||||||
String clientId = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT);
|
||||||
String clientSecret = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_SECRET);
|
String clientId =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
||||||
|
String clientSecret =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_SECRET);
|
||||||
tokenProvider = new ClientCredsTokenProvider(authEndpoint, clientId, clientSecret);
|
tokenProvider = new ClientCredsTokenProvider(authEndpoint, clientId, clientSecret);
|
||||||
LOG.trace("ClientCredsTokenProvider initialized");
|
LOG.trace("ClientCredsTokenProvider initialized");
|
||||||
} else if (tokenProviderClass == UserPasswordTokenProvider.class) {
|
} else if (tokenProviderClass == UserPasswordTokenProvider.class) {
|
||||||
String authEndpoint = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT);
|
String authEndpoint =
|
||||||
String username = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_USER_NAME);
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT);
|
||||||
String password = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_USER_PASSWORD);
|
String username =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_USER_NAME);
|
||||||
|
String password =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_USER_PASSWORD);
|
||||||
tokenProvider = new UserPasswordTokenProvider(authEndpoint, username, password);
|
tokenProvider = new UserPasswordTokenProvider(authEndpoint, username, password);
|
||||||
LOG.trace("UserPasswordTokenProvider initialized");
|
LOG.trace("UserPasswordTokenProvider initialized");
|
||||||
} else if (tokenProviderClass == MsiTokenProvider.class) {
|
} else if (tokenProviderClass == MsiTokenProvider.class) {
|
||||||
String authEndpoint = getTrimmedPasswordString(
|
String authEndpoint = getTrimmedPasswordString(
|
||||||
FS_AZURE_ACCOUNT_OAUTH_MSI_ENDPOINT,
|
FS_AZURE_ACCOUNT_OAUTH_MSI_ENDPOINT,
|
||||||
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_MSI_ENDPOINT);
|
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_MSI_ENDPOINT);
|
||||||
String tenantGuid = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_MSI_TENANT);
|
String tenantGuid =
|
||||||
String clientId = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_MSI_TENANT);
|
||||||
|
String clientId =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
||||||
String authority = getTrimmedPasswordString(
|
String authority = getTrimmedPasswordString(
|
||||||
FS_AZURE_ACCOUNT_OAUTH_MSI_AUTHORITY,
|
FS_AZURE_ACCOUNT_OAUTH_MSI_AUTHORITY,
|
||||||
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_MSI_AUTHORITY);
|
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_MSI_AUTHORITY);
|
||||||
@ -772,8 +798,10 @@ public AccessTokenProvider getTokenProvider() throws TokenAccessProviderExceptio
|
|||||||
String authEndpoint = getTrimmedPasswordString(
|
String authEndpoint = getTrimmedPasswordString(
|
||||||
FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN_ENDPOINT,
|
FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN_ENDPOINT,
|
||||||
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN_ENDPOINT);
|
AuthConfigurations.DEFAULT_FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN_ENDPOINT);
|
||||||
String refreshToken = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN);
|
String refreshToken =
|
||||||
String clientId = getPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_REFRESH_TOKEN);
|
||||||
|
String clientId =
|
||||||
|
getMandatoryPasswordString(FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID);
|
||||||
tokenProvider = new RefreshTokenBasedTokenProvider(authEndpoint,
|
tokenProvider = new RefreshTokenBasedTokenProvider(authEndpoint,
|
||||||
clientId, refreshToken);
|
clientId, refreshToken);
|
||||||
LOG.trace("RefreshTokenBasedTokenProvider initialized");
|
LOG.trace("RefreshTokenBasedTokenProvider initialized");
|
||||||
|
@ -19,18 +19,22 @@
|
|||||||
package org.apache.hadoop.fs.azurebfs;
|
package org.apache.hadoop.fs.azurebfs;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
import org.assertj.core.api.Assertions;
|
import java.util.Collections;
|
||||||
import org.junit.Test;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.ConfigurationPropertyNotFoundException;
|
||||||
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.InvalidConfigurationValueException;
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.InvalidConfigurationValueException;
|
||||||
|
import org.apache.hadoop.fs.azurebfs.contracts.exceptions.TokenAccessProviderException;
|
||||||
import org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider;
|
import org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider;
|
||||||
import org.apache.hadoop.fs.azurebfs.oauth2.CustomTokenProviderAdapter;
|
import org.apache.hadoop.fs.azurebfs.oauth2.CustomTokenProviderAdapter;
|
||||||
import org.apache.hadoop.fs.azurebfs.services.AuthType;
|
import org.apache.hadoop.fs.azurebfs.services.AuthType;
|
||||||
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
import org.apache.hadoop.test.LambdaTestUtils;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.assertj.core.api.Assertions;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME;
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME;
|
||||||
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT;
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT;
|
||||||
@ -38,6 +42,8 @@
|
|||||||
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_OAUTH_CLIENT_SECRET;
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_OAUTH_CLIENT_SECRET;
|
||||||
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME;
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_ACCOUNT_TOKEN_PROVIDER_TYPE_PROPERTY_NAME;
|
||||||
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_SAS_TOKEN_PROVIDER_TYPE;
|
import static org.apache.hadoop.fs.azurebfs.constants.ConfigurationKeys.FS_AZURE_SAS_TOKEN_PROVIDER_TYPE;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests correct precedence of various configurations that might be returned.
|
* Tests correct precedence of various configurations that might be returned.
|
||||||
@ -60,6 +66,12 @@ public class TestAccountConfiguration {
|
|||||||
private static final String TEST_CLIENT_ID = "clientId";
|
private static final String TEST_CLIENT_ID = "clientId";
|
||||||
private static final String TEST_CLIENT_SECRET = "clientSecret";
|
private static final String TEST_CLIENT_SECRET = "clientSecret";
|
||||||
|
|
||||||
|
private static final List<String> CONFIG_KEYS =
|
||||||
|
Collections.unmodifiableList(Arrays.asList(
|
||||||
|
FS_AZURE_ACCOUNT_OAUTH_CLIENT_ENDPOINT,
|
||||||
|
FS_AZURE_ACCOUNT_OAUTH_CLIENT_ID,
|
||||||
|
FS_AZURE_ACCOUNT_OAUTH_CLIENT_SECRET));
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringPrecedence()
|
public void testStringPrecedence()
|
||||||
throws IllegalAccessException, IOException, InvalidConfigurationValueException {
|
throws IllegalAccessException, IOException, InvalidConfigurationValueException {
|
||||||
@ -361,6 +373,33 @@ public void testAccessTokenProviderPrecedence()
|
|||||||
testGlobalAndAccountOAuthPrecedence(abfsConf, null, AuthType.OAuth);
|
testGlobalAndAccountOAuthPrecedence(abfsConf, null, AuthType.OAuth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConfigPropNotFound() throws Throwable {
|
||||||
|
final String accountName = "account";
|
||||||
|
|
||||||
|
final Configuration conf = new Configuration();
|
||||||
|
final AbfsConfiguration abfsConf = new AbfsConfiguration(conf, accountName);
|
||||||
|
|
||||||
|
for (String key : CONFIG_KEYS) {
|
||||||
|
setAuthConfig(abfsConf, true, AuthType.OAuth);
|
||||||
|
abfsConf.unset(key + "." + accountName);
|
||||||
|
testMissingConfigKey(abfsConf, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsetAuthConfig(abfsConf, false);
|
||||||
|
unsetAuthConfig(abfsConf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testMissingConfigKey(final AbfsConfiguration abfsConf,
|
||||||
|
final String confKey) throws Throwable {
|
||||||
|
GenericTestUtils.assertExceptionContains("Configuration property "
|
||||||
|
+ confKey + " not found.",
|
||||||
|
LambdaTestUtils.verifyCause(
|
||||||
|
ConfigurationPropertyNotFoundException.class,
|
||||||
|
LambdaTestUtils.intercept(TokenAccessProviderException.class,
|
||||||
|
() -> abfsConf.getTokenProvider().getClass().getTypeName())));
|
||||||
|
}
|
||||||
|
|
||||||
public void testGlobalAndAccountOAuthPrecedence(AbfsConfiguration abfsConf,
|
public void testGlobalAndAccountOAuthPrecedence(AbfsConfiguration abfsConf,
|
||||||
AuthType globalAuthType,
|
AuthType globalAuthType,
|
||||||
AuthType accountSpecificAuthType)
|
AuthType accountSpecificAuthType)
|
||||||
|
Loading…
Reference in New Issue
Block a user