2222import java .lang .reflect .Field ;
2323
2424import org .apache .hadoop .classification .VisibleForTesting ;
25+ import org .apache .hadoop .fs .azurebfs .constants .AbfsServiceType ;
2526import org .apache .hadoop .fs .azurebfs .services .FixedSASTokenProvider ;
2627import org .apache .hadoop .fs .azurebfs .constants .HttpOperationType ;
2728import org .apache .hadoop .fs .azurebfs .utils .MetricFormat ;
7475import org .slf4j .Logger ;
7576import org .slf4j .LoggerFactory ;
7677
78+ import static org .apache .hadoop .fs .FileSystem .FS_DEFAULT_NAME_KEY ;
7779import static org .apache .hadoop .fs .azurebfs .constants .AbfsHttpConstants .EMPTY_STRING ;
7880import static org .apache .hadoop .fs .azurebfs .constants .ConfigurationKeys .*;
7981import static org .apache .hadoop .fs .azurebfs .constants .FileSystemConfigurations .*;
@@ -87,13 +89,19 @@ public class AbfsConfiguration{
8789
8890 private final Configuration rawConfig ;
8991 private final String accountName ;
92+ // Service type identified from URL used to initialize FileSystem.
93+ private final AbfsServiceType fsConfiguredServiceType ;
9094 private final boolean isSecure ;
9195 private static final Logger LOG = LoggerFactory .getLogger (AbfsConfiguration .class );
9296
9397 @ StringConfigurationValidatorAnnotation (ConfigurationKey = FS_AZURE_ACCOUNT_IS_HNS_ENABLED ,
9498 DefaultValue = DEFAULT_FS_AZURE_ACCOUNT_IS_HNS_ENABLED )
9599 private String isNamespaceEnabledAccount ;
96100
101+ @ BooleanConfigurationValidatorAnnotation (ConfigurationKey = FS_AZURE_ENABLE_DFSTOBLOB_FALLBACK ,
102+ DefaultValue = DEFAULT_FS_AZURE_ENABLE_DFSTOBLOB_FALLBACK )
103+ private boolean isDfsToBlobFallbackEnabled ;
104+
97105 @ IntegerConfigurationValidatorAnnotation (ConfigurationKey = AZURE_WRITE_MAX_CONCURRENT_REQUESTS ,
98106 DefaultValue = -1 )
99107 private int writeMaxConcurrentRequestCount ;
@@ -408,11 +416,14 @@ public class AbfsConfiguration{
408416 private String clientProvidedEncryptionKey ;
409417 private String clientProvidedEncryptionKeySHA ;
410418
411- public AbfsConfiguration (final Configuration rawConfig , String accountName )
412- throws IllegalAccessException , InvalidConfigurationValueException , IOException {
419+ public AbfsConfiguration (final Configuration rawConfig ,
420+ String accountName ,
421+ AbfsServiceType fsConfiguredServiceType )
422+ throws IllegalAccessException , IOException {
413423 this .rawConfig = ProviderUtils .excludeIncompatibleCredentialProviders (
414424 rawConfig , AzureBlobFileSystem .class );
415425 this .accountName = accountName ;
426+ this .fsConfiguredServiceType = fsConfiguredServiceType ;
416427 this .isSecure = getBoolean (FS_AZURE_SECURE_MODE , false );
417428
418429 Field [] fields = this .getClass ().getDeclaredFields ();
@@ -434,10 +445,75 @@ public AbfsConfiguration(final Configuration rawConfig, String accountName)
434445 }
435446 }
436447
448+ public AbfsConfiguration (final Configuration rawConfig , String accountName )
449+ throws IllegalAccessException , IOException {
450+ this (rawConfig , accountName , AbfsServiceType .DFS );
451+ }
452+
437453 public Trilean getIsNamespaceEnabledAccount () {
438454 return Trilean .getTrilean (isNamespaceEnabledAccount );
439455 }
440456
457+ /**
458+ * Returns the service type to be used based on the filesystem configuration.
459+ * Precedence is given to service type configured for FNS Accounts using
460+ * "fs.azure.fns.account.service.type". If not configured, then the service
461+ * type identified from url used to initialize filesystem will be used.
462+ * @return the service type.
463+ */
464+ public AbfsServiceType getFsConfiguredServiceType () {
465+ return getEnum (FS_AZURE_FNS_ACCOUNT_SERVICE_TYPE , fsConfiguredServiceType );
466+ }
467+
468+ /**
469+ * Returns the service type configured for FNS Accounts to override the
470+ * service type identified by URL used to initialize the filesystem.
471+ * @return the service type.
472+ */
473+ public AbfsServiceType getConfiguredServiceTypeForFNSAccounts () {
474+ return getEnum (FS_AZURE_FNS_ACCOUNT_SERVICE_TYPE , null );
475+ }
476+
477+ /**
478+ * Returns the service type to be used for Ingress Operations irrespective of account type.
479+ * Default value is the same as the service type configured for the file system.
480+ * @return the service type.
481+ */
482+ public AbfsServiceType getIngressServiceType () {
483+ return getEnum (FS_AZURE_INGRESS_SERVICE_TYPE , getFsConfiguredServiceType ());
484+ }
485+
486+ /**
487+ * Returns whether there is a need to move traffic from DFS to Blob.
488+ * Needed when the service type is DFS and operations are experiencing compatibility issues.
489+ * @return true if fallback enabled.
490+ */
491+ public boolean isDfsToBlobFallbackEnabled () {
492+ return isDfsToBlobFallbackEnabled ;
493+ }
494+
495+ /**
496+ * Checks if the service type configured is valid for account type used.
497+ * HNS Enabled accounts cannot have service type as BLOB.
498+ * @param isHNSEnabled Flag to indicate if HNS is enabled for the account.
499+ * @throws InvalidConfigurationValueException if the service type is invalid.
500+ */
501+ public void validateConfiguredServiceType (boolean isHNSEnabled )
502+ throws InvalidConfigurationValueException {
503+ // Todo: [FnsOverBlob] - Remove this check, Failing FS Init with Blob Endpoint Until FNS over Blob is ready.
504+ if (getFsConfiguredServiceType () == AbfsServiceType .BLOB ) {
505+ throw new InvalidConfigurationValueException (FS_DEFAULT_NAME_KEY ,
506+ "Blob Endpoint Support not yet available" );
507+ }
508+ if (isHNSEnabled && getConfiguredServiceTypeForFNSAccounts () == AbfsServiceType .BLOB ) {
509+ throw new InvalidConfigurationValueException (
510+ FS_AZURE_FNS_ACCOUNT_SERVICE_TYPE , "Cannot be BLOB for HNS Account" );
511+ } else if (isHNSEnabled && fsConfiguredServiceType == AbfsServiceType .BLOB ) {
512+ throw new InvalidConfigurationValueException (FS_DEFAULT_NAME_KEY ,
513+ "Blob Endpoint Url Cannot be used to initialize filesystem for HNS Account" );
514+ }
515+ }
516+
441517 /**
442518 * Gets the Azure Storage account name corresponding to this instance of configuration.
443519 * @return the Azure Storage account name
@@ -478,6 +554,7 @@ public String get(String key) {
478554 * Returns the account-specific value if it exists, then looks for an
479555 * account-agnostic value.
480556 * @param key Account-agnostic configuration key
557+ * @param defaultValue Value returned if none is configured
481558 * @return value if one exists, else the default value
482559 */
483560 public String getString (String key , String defaultValue ) {
@@ -522,7 +599,7 @@ public int getInt(String key, int defaultValue) {
522599 * looks for an account-agnostic value.
523600 * @param key Account-agnostic configuration key
524601 * @return value in String form if one exists, else null
525- * @throws IOException
602+ * @throws IOException if parsing fails.
526603 */
527604 public String getPasswordString (String key ) throws IOException {
528605 char [] passchars = rawConfig .getPassword (accountConf (key ));
0 commit comments