@@ -74,14 +74,7 @@ impl ObjectStoreFactory for S3ObjectStoreFactory {
74
74
) -> DeltaResult < ( ObjectStoreRef , Path ) > {
75
75
let options = self . with_env_s3 ( storage_options) ;
76
76
77
- let sdk_config = if options. 0 . contains_key ( constants:: AWS_ENDPOINT_URL ) {
78
- None
79
- } else {
80
- Some ( execute_sdk_future (
81
- crate :: credentials:: resolve_credentials ( storage_options. clone ( ) ) ,
82
- ) ??)
83
- } ;
84
-
77
+ // All S3-likes should start their builder the same way
85
78
let mut builder = AmazonS3Builder :: new ( ) . with_url ( url. to_string ( ) ) ;
86
79
87
80
for ( key, value) in options. 0 . iter ( ) {
@@ -95,14 +88,18 @@ impl ObjectStoreFactory for S3ObjectStoreFactory {
95
88
source : Box :: new ( e) ,
96
89
} ) ?;
97
90
let prefix = Path :: parse ( path) ?;
98
- let inner = if let Some ( sdk_config) = sdk_config {
99
- builder. with_credentials ( Arc :: new ( crate :: credentials:: AWSForObjectStore :: new (
100
- sdk_config,
101
- ) ) )
102
- } else {
103
- builder
91
+
92
+ if is_aws ( storage_options) {
93
+ debug ! ( "Detected AWS S3, resolving credentials" ) ;
94
+ let sdk_config = execute_sdk_future ( crate :: credentials:: resolve_credentials (
95
+ storage_options. clone ( ) ,
96
+ ) ) ??;
97
+ builder = builder. with_credentials ( Arc :: new (
98
+ crate :: credentials:: AWSForObjectStore :: new ( sdk_config) ,
99
+ ) ) ;
104
100
}
105
- . build ( ) ?;
101
+
102
+ let inner = builder. build ( ) ?;
106
103
107
104
let store = aws_storage_handler ( limit_store_handler ( inner, & options) , & options) ?;
108
105
debug ! ( "Initialized the object store: {store:?}" ) ;
@@ -136,6 +133,26 @@ fn aws_storage_handler(
136
133
}
137
134
}
138
135
136
+ // Determine whether this crate is being configured for use with native AWS S3 or an S3-alike
137
+ //
138
+ // This function will rteturn true in the default case since it's most likely that the absence of
139
+ // options will mean default/S3 configuration
140
+ fn is_aws ( options : & StorageOptions ) -> bool {
141
+ if options
142
+ . 0
143
+ . contains_key ( crate :: constants:: AWS_FORCE_CREDENTIAL_LOAD )
144
+ {
145
+ return true ;
146
+ }
147
+ if options
148
+ . 0
149
+ . contains_key ( crate :: constants:: AWS_S3_LOCKING_PROVIDER )
150
+ {
151
+ return true ;
152
+ }
153
+ !options. 0 . contains_key ( crate :: constants:: AWS_ENDPOINT_URL )
154
+ }
155
+
139
156
/// Options used to configure the [S3StorageBackend].
140
157
///
141
158
/// Available options are described in [s3_constants].
@@ -208,12 +225,14 @@ impl S3StorageOptions {
208
225
209
226
let storage_options = StorageOptions ( options. clone ( ) ) ;
210
227
211
- let sdk_config = if storage_options. 0 . contains_key ( constants:: AWS_ENDPOINT_URL ) {
212
- None
213
- } else {
214
- Some ( execute_sdk_future (
215
- crate :: credentials:: resolve_credentials ( storage_options. clone ( ) ) ,
216
- ) ??)
228
+ let sdk_config = match is_aws ( & storage_options) {
229
+ false => None ,
230
+ true => {
231
+ debug ! ( "Detected AWS S3, resolving credentials" ) ;
232
+ Some ( execute_sdk_future (
233
+ crate :: credentials:: resolve_credentials ( storage_options. clone ( ) ) ,
234
+ ) ??)
235
+ }
217
236
} ;
218
237
219
238
Ok ( Self {
@@ -528,10 +547,12 @@ mod tests {
528
547
let options = S3StorageOptions :: try_default ( ) . unwrap ( ) ;
529
548
assert_eq ! (
530
549
S3StorageOptions {
531
- sdk_config: SdkConfig :: builder( )
532
- . endpoint_url( "http://localhost" . to_string( ) )
533
- . region( Region :: from_static( "us-west-1" ) )
534
- . build( ) ,
550
+ sdk_config: Some (
551
+ SdkConfig :: builder( )
552
+ . endpoint_url( "http://localhost" . to_string( ) )
553
+ . region( Region :: from_static( "us-west-1" ) )
554
+ . build( )
555
+ ) ,
535
556
virtual_hosted_style_request: false ,
536
557
locking_provider: Some ( "dynamodb" . to_string( ) ) ,
537
558
dynamodb_endpoint: None ,
@@ -560,9 +581,11 @@ mod tests {
560
581
. unwrap ( ) ;
561
582
562
583
let mut expected = S3StorageOptions :: try_default ( ) . unwrap ( ) ;
563
- expected. sdk_config = SdkConfig :: builder ( )
564
- . region ( Region :: from_static ( "eu-west-1" ) )
565
- . build ( ) ;
584
+ expected. sdk_config = Some (
585
+ SdkConfig :: builder ( )
586
+ . region ( Region :: from_static ( "eu-west-1" ) )
587
+ . build ( ) ,
588
+ ) ;
566
589
assert_eq ! ( expected, options) ;
567
590
} ) ;
568
591
}
@@ -670,10 +693,12 @@ mod tests {
670
693
671
694
assert_eq ! (
672
695
S3StorageOptions {
673
- sdk_config: SdkConfig :: builder( )
674
- . endpoint_url( "http://localhost" . to_string( ) )
675
- . region( Region :: from_static( "us-west-2" ) )
676
- . build( ) ,
696
+ sdk_config: Some (
697
+ SdkConfig :: builder( )
698
+ . endpoint_url( "http://localhost" . to_string( ) )
699
+ . region( Region :: from_static( "us-west-2" ) )
700
+ . build( )
701
+ ) ,
677
702
virtual_hosted_style_request: false ,
678
703
locking_provider: Some ( "dynamodb" . to_string( ) ) ,
679
704
dynamodb_endpoint: Some ( "http://localhost:dynamodb" . to_string( ) ) ,
@@ -767,4 +792,23 @@ mod tests {
767
792
}
768
793
} ) ;
769
794
}
795
+
796
+ #[ test]
797
+ fn test_is_aws ( ) {
798
+ let options = StorageOptions :: default ( ) ;
799
+ assert ! ( is_aws( & options) ) ;
800
+
801
+ let minio: HashMap < String , String > = hashmap ! {
802
+ crate :: constants:: AWS_ENDPOINT_URL . to_string( ) => "http://minio:8080" . to_string( ) ,
803
+ } ;
804
+ let options = StorageOptions :: from ( minio) ;
805
+ assert ! ( !is_aws( & options) ) ;
806
+
807
+ let localstack: HashMap < String , String > = hashmap ! {
808
+ crate :: constants:: AWS_FORCE_CREDENTIAL_LOAD . to_string( ) => "true" . to_string( ) ,
809
+ crate :: constants:: AWS_ENDPOINT_URL . to_string( ) => "http://minio:8080" . to_string( ) ,
810
+ } ;
811
+ let options = StorageOptions :: from ( localstack) ;
812
+ assert ! ( is_aws( & options) ) ;
813
+ }
770
814
}
0 commit comments