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 .fs .azurebfs .utils .MetricFormat ;
2627import org .apache .hadoop .util .Preconditions ;
2728
@@ -1025,33 +1026,63 @@ public AccessTokenProvider getTokenProvider() throws TokenAccessProviderExceptio
10251026 }
10261027 }
10271028
1029+ /**
1030+ * Returns the SASTokenProvider implementation to be used to generate SAS token.<br>
1031+ * Users can choose between a custom implementation of {@link SASTokenProvider}
1032+ * or an in house implementation {@link FixedSASTokenProvider}.<br>
1033+ * For Custom implementation "fs.azure.sas.token.provider.type" needs to be provided.<br>
1034+ * For Fixed SAS Token use "fs.azure.sas.fixed.token" needs to be provided.<br>
1035+ * In case both are provided, Preference will be given to Custom implementation.<br>
1036+ * Avoid using a custom tokenProvider implementation just to read the configured
1037+ * fixed token, as this could create confusion. Also,implementing the SASTokenProvider
1038+ * requires relying on the raw configurations. It is more stable to depend on
1039+ * the AbfsConfiguration with which a filesystem is initialized, and eliminate
1040+ * chances of dynamic modifications and spurious situations.<br>
1041+ * @return sasTokenProvider object based on configurations provided
1042+ * @throws AzureBlobFileSystemException
1043+ */
10281044 public SASTokenProvider getSASTokenProvider () throws AzureBlobFileSystemException {
10291045 AuthType authType = getEnum (FS_AZURE_ACCOUNT_AUTH_TYPE_PROPERTY_NAME , AuthType .SharedKey );
10301046 if (authType != AuthType .SAS ) {
10311047 throw new SASTokenProviderException (String .format (
1032- "Invalid auth type: %s is being used, expecting SAS" , authType ));
1048+ "Invalid auth type: %s is being used, expecting SAS. " , authType ));
10331049 }
10341050
10351051 try {
1036- String configKey = FS_AZURE_SAS_TOKEN_PROVIDER_TYPE ;
1037- Class <? extends SASTokenProvider > sasTokenProviderClass =
1038- getTokenProviderClass (authType , configKey , null ,
1039- SASTokenProvider .class );
1040-
1041- Preconditions .checkArgument (sasTokenProviderClass != null ,
1042- String .format ("The configuration value for \" %s\" is invalid." , configKey ));
1043-
1044- SASTokenProvider sasTokenProvider = ReflectionUtils
1045- .newInstance (sasTokenProviderClass , rawConfig );
1046- Preconditions .checkArgument (sasTokenProvider != null ,
1047- String .format ("Failed to initialize %s" , sasTokenProviderClass ));
1048-
1049- LOG .trace ("Initializing {}" , sasTokenProviderClass .getName ());
1050- sasTokenProvider .initialize (rawConfig , accountName );
1051- LOG .trace ("{} init complete" , sasTokenProviderClass .getName ());
1052- return sasTokenProvider ;
1052+ Class <? extends SASTokenProvider > customSasTokenProviderImplementation =
1053+ getTokenProviderClass (authType , FS_AZURE_SAS_TOKEN_PROVIDER_TYPE ,
1054+ null , SASTokenProvider .class );
1055+ String configuredFixedToken = this .getTrimmedPasswordString (FS_AZURE_SAS_FIXED_TOKEN , EMPTY_STRING );
1056+
1057+ if (customSasTokenProviderImplementation == null && configuredFixedToken .isEmpty ()) {
1058+ throw new SASTokenProviderException (String .format (
1059+ "At least one of the \" %s\" and \" %s\" must be set." ,
1060+ FS_AZURE_SAS_TOKEN_PROVIDER_TYPE , FS_AZURE_SAS_FIXED_TOKEN ));
1061+ }
1062+
1063+ // Prefer Custom SASTokenProvider Implementation if configured.
1064+ if (customSasTokenProviderImplementation != null ) {
1065+ LOG .trace ("Using Custom SASTokenProvider implementation because it is given precedence when it is set." );
1066+ SASTokenProvider sasTokenProvider = ReflectionUtils .newInstance (
1067+ customSasTokenProviderImplementation , rawConfig );
1068+ if (sasTokenProvider == null ) {
1069+ throw new SASTokenProviderException (String .format (
1070+ "Failed to initialize %s" , customSasTokenProviderImplementation ));
1071+ }
1072+ LOG .trace ("Initializing {}" , customSasTokenProviderImplementation .getName ());
1073+ sasTokenProvider .initialize (rawConfig , accountName );
1074+ LOG .trace ("{} init complete" , customSasTokenProviderImplementation .getName ());
1075+ return sasTokenProvider ;
1076+ } else {
1077+ LOG .trace ("Using FixedSASTokenProvider implementation" );
1078+ FixedSASTokenProvider fixedSASTokenProvider = new FixedSASTokenProvider (configuredFixedToken );
1079+ return fixedSASTokenProvider ;
1080+ }
1081+ } catch (SASTokenProviderException e ) {
1082+ throw e ;
10531083 } catch (Exception e ) {
1054- throw new TokenAccessProviderException ("Unable to load SAS token provider class: " + e , e );
1084+ throw new SASTokenProviderException (
1085+ "Unable to load SAS token provider class: " + e , e );
10551086 }
10561087 }
10571088
@@ -1064,14 +1095,14 @@ public EncryptionContextProvider createEncryptionContextProvider() {
10641095 Class <? extends EncryptionContextProvider > encryptionContextClass =
10651096 getAccountSpecificClass (configKey , null ,
10661097 EncryptionContextProvider .class );
1067- Preconditions .checkArgument (encryptionContextClass != null , String . format (
1098+ Preconditions .checkArgument (encryptionContextClass != null ,
10681099 "The configuration value for %s is invalid, or config key is not account-specific" ,
1069- configKey )) ;
1100+ configKey );
10701101
10711102 EncryptionContextProvider encryptionContextProvider =
10721103 ReflectionUtils .newInstance (encryptionContextClass , rawConfig );
10731104 Preconditions .checkArgument (encryptionContextProvider != null ,
1074- String . format ( "Failed to initialize %s" , encryptionContextClass ) );
1105+ "Failed to initialize %s" , encryptionContextClass );
10751106
10761107 LOG .trace ("{} init complete" , encryptionContextClass .getName ());
10771108 return encryptionContextProvider ;
0 commit comments