2222import java .lang .reflect .Field ;
2323
2424import org .apache .hadoop .classification .VisibleForTesting ;
25+ import org .apache .hadoop .fs .azurebfs .services .FixedSASTokenProvider ;
2526import org .apache .hadoop .util .Preconditions ;
2627
2728import org .apache .commons .lang3 .StringUtils ;
@@ -980,33 +981,63 @@ public AccessTokenProvider getTokenProvider() throws TokenAccessProviderExceptio
980981 }
981982 }
982983
984+ /**
985+ * Returns the SASTokenProvider implementation to be used to generate SAS token.<br>
986+ * Users can choose between a custom implementation of {@link SASTokenProvider}
987+ * or an in house implementation {@link FixedSASTokenProvider}.<br>
988+ * For Custom implementation "fs.azure.sas.token.provider.type" needs to be provided.<br>
989+ * For Fixed SAS Token use "fs.azure.sas.fixed.token" needs to be provided.<br>
990+ * In case both are provided, Preference will be given to Custom implementation.<br>
991+ * Avoid using a custom tokenProvider implementation just to read the configured
992+ * fixed token, as this could create confusion. Also,implementing the SASTokenProvider
993+ * requires relying on the raw configurations. It is more stable to depend on
994+ * the AbfsConfiguration with which a filesystem is initialized, and eliminate
995+ * chances of dynamic modifications and spurious situations.<br>
996+ * @return sasTokenProvider object based on configurations provided
997+ * @throws AzureBlobFileSystemException
998+ */
983999 public SASTokenProvider getSASTokenProvider () throws AzureBlobFileSystemException {
9841000 AuthType authType = getEnum (FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME , AuthType .SharedKey );
9851001 if (authType != AuthType .SAS ) {
9861002 throw new SASTokenProviderException (String .format (
987- "Invalid auth type: %s is being used, expecting SAS" , authType ));
1003+ "Invalid auth type: %s is being used, expecting SAS. " , authType ));
9881004 }
9891005
9901006 try {
991- String configKey = FS_AZURE_SAS_TOKEN_PROVIDER_TYPE ;
992- Class <? extends SASTokenProvider > sasTokenProviderClass =
993- getTokenProviderClass (authType , configKey , null ,
994- SASTokenProvider .class );
995-
996- Preconditions .checkArgument (sasTokenProviderClass != null ,
997- String .format ("The configuration value for \" %s\" is invalid." , configKey ));
998-
999- SASTokenProvider sasTokenProvider = ReflectionUtils
1000- .newInstance (sasTokenProviderClass , rawConfig );
1001- Preconditions .checkArgument (sasTokenProvider != null ,
1002- String .format ("Failed to initialize %s" , sasTokenProviderClass ));
1003-
1004- LOG .trace ("Initializing {}" , sasTokenProviderClass .getName ());
1005- sasTokenProvider .initialize (rawConfig , accountName );
1006- LOG .trace ("{} init complete" , sasTokenProviderClass .getName ());
1007- return sasTokenProvider ;
1007+ Class <? extends SASTokenProvider > customSasTokenProviderImplementation =
1008+ getTokenProviderClass (authType , FS_AZURE_SAS_TOKEN_PROVIDER_TYPE ,
1009+ null , SASTokenProvider .class );
1010+ String configuredFixedToken = this .getTrimmedPasswordString (FS_AZURE_SAS_FIXED_TOKEN , EMPTY_STRING );
1011+
1012+ if (customSasTokenProviderImplementation == null && configuredFixedToken .isEmpty ()) {
1013+ throw new SASTokenProviderException (String .format (
1014+ "At least one of the \" %s\" and \" %s\" must be set." ,
1015+ FS_AZURE_SAS_TOKEN_PROVIDER_TYPE , FS_AZURE_SAS_FIXED_TOKEN ));
1016+ }
1017+
1018+ // Prefer Custom SASTokenProvider Implementation if configured.
1019+ if (customSasTokenProviderImplementation != null ) {
1020+ LOG .trace ("Using Custom SASTokenProvider implementation because it is given precedence when it is set." );
1021+ SASTokenProvider sasTokenProvider = ReflectionUtils .newInstance (
1022+ customSasTokenProviderImplementation , rawConfig );
1023+ if (sasTokenProvider == null ) {
1024+ throw new SASTokenProviderException (String .format (
1025+ "Failed to initialize %s" , customSasTokenProviderImplementation ));
1026+ }
1027+ LOG .trace ("Initializing {}" , customSasTokenProviderImplementation .getName ());
1028+ sasTokenProvider .initialize (rawConfig , accountName );
1029+ LOG .trace ("{} init complete" , customSasTokenProviderImplementation .getName ());
1030+ return sasTokenProvider ;
1031+ } else {
1032+ LOG .trace ("Using FixedSASTokenProvider implementation" );
1033+ FixedSASTokenProvider fixedSASTokenProvider = new FixedSASTokenProvider (configuredFixedToken );
1034+ return fixedSASTokenProvider ;
1035+ }
1036+ } catch (SASTokenProviderException e ) {
1037+ throw e ;
10081038 } catch (Exception e ) {
1009- throw new TokenAccessProviderException ("Unable to load SAS token provider class: " + e , e );
1039+ throw new SASTokenProviderException (
1040+ "Unable to load SAS token provider class: " + e , e );
10101041 }
10111042 }
10121043
@@ -1019,14 +1050,14 @@ public EncryptionContextProvider createEncryptionContextProvider() {
10191050 Class <? extends EncryptionContextProvider > encryptionContextClass =
10201051 getAccountSpecificClass (configKey , null ,
10211052 EncryptionContextProvider .class );
1022- Preconditions .checkArgument (encryptionContextClass != null , String . format (
1053+ Preconditions .checkArgument (encryptionContextClass != null ,
10231054 "The configuration value for %s is invalid, or config key is not account-specific" ,
1024- configKey )) ;
1055+ configKey );
10251056
10261057 EncryptionContextProvider encryptionContextProvider =
10271058 ReflectionUtils .newInstance (encryptionContextClass , rawConfig );
10281059 Preconditions .checkArgument (encryptionContextProvider != null ,
1029- String . format ( "Failed to initialize %s" , encryptionContextClass ) );
1060+ "Failed to initialize %s" , encryptionContextClass );
10301061
10311062 LOG .trace ("{} init complete" , encryptionContextClass .getName ());
10321063 return encryptionContextProvider ;
0 commit comments