1616package io .awspring .cloud .autoconfigure .s3 ;
1717
1818import com .fasterxml .jackson .databind .ObjectMapper ;
19- import com .fasterxml .jackson .databind .json .JsonMapper ;
2019import io .awspring .cloud .autoconfigure .AwsSyncClientCustomizer ;
2120import io .awspring .cloud .autoconfigure .core .AwsClientBuilderConfigurer ;
2221import io .awspring .cloud .autoconfigure .core .AwsConnectionDetails ;
2322import io .awspring .cloud .autoconfigure .core .AwsProperties ;
2423import io .awspring .cloud .autoconfigure .s3 .properties .S3Properties ;
25- import io .awspring .cloud .core .support .JacksonPresent ;
2624import io .awspring .cloud .s3 .*;
27-
2825import java .util .Optional ;
2926import org .springframework .beans .factory .ObjectProvider ;
3027import org .springframework .boot .autoconfigure .AutoConfiguration ;
31- import org .springframework .boot .autoconfigure .condition .*;
28+ import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
29+ import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
30+ import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
31+ import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
32+ import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
3233import org .springframework .boot .context .properties .EnableConfigurationProperties ;
3334import org .springframework .boot .context .properties .PropertyMapper ;
3435import org .springframework .context .annotation .Bean ;
4445import software .amazon .awssdk .services .s3 .S3ClientBuilder ;
4546import software .amazon .awssdk .services .s3 .presigner .S3Presigner ;
4647import software .amazon .encryption .s3 .S3EncryptionClient ;
48+ import tools .jackson .databind .json .JsonMapper ;
4749
4850/**
4951 * {@link AutoConfiguration} for {@link S3Client} and {@link S3ProtocolResolver}.
@@ -119,11 +121,50 @@ else if (awsProperties.getEndpoint() != null) {
119121 return builder .build ();
120122 }
121123
124+ @ Bean
125+ @ ConditionalOnMissingBean
126+ S3Client s3Client (S3ClientBuilder s3ClientBuilder ) {
127+ return s3ClientBuilder .build ();
128+ }
129+
130+ @ Bean
131+ @ ConditionalOnMissingBean
132+ S3OutputStreamProvider inMemoryBufferingS3StreamProvider (S3Client s3Client ,
133+ Optional <S3ObjectContentTypeResolver > contentTypeResolver ) {
134+ return new InMemoryBufferingS3OutputStreamProvider (s3Client ,
135+ contentTypeResolver .orElseGet (PropertiesS3ObjectContentTypeResolver ::new ));
136+ }
137+
122138 @ Conditional (S3EncryptionConditional .class )
123139 @ ConditionalOnClass (name = "software.amazon.encryption.s3.S3EncryptionClient" )
124140 @ Configuration
125141 public static class S3EncryptionConfiguration {
126142
143+ private static void configureEncryptionProperties (S3Properties properties ,
144+ ObjectProvider <S3RsaProvider > rsaProvider , ObjectProvider <S3AesProvider > aesProvider ,
145+ S3EncryptionClient .Builder builder ) {
146+ PropertyMapper propertyMapper = PropertyMapper .get ();
147+ var encryptionProperties = properties .getEncryption ();
148+
149+ propertyMapper .from (encryptionProperties ::isEnableDelayedAuthenticationMode )
150+ .to (builder ::enableDelayedAuthenticationMode );
151+ propertyMapper .from (encryptionProperties ::isEnableLegacyUnauthenticatedModes )
152+ .to (builder ::enableLegacyUnauthenticatedModes );
153+ propertyMapper .from (encryptionProperties ::isEnableMultipartPutObject ).to (builder ::enableMultipartPutObject );
154+
155+ if (!StringUtils .hasText (properties .getEncryption ().getKeyId ())) {
156+ if (aesProvider .getIfAvailable () != null ) {
157+ builder .aesKey (aesProvider .getObject ().generateSecretKey ());
158+ }
159+ else {
160+ builder .rsaKeyPair (rsaProvider .getObject ().generateKeyPair ());
161+ }
162+ }
163+ else {
164+ propertyMapper .from (encryptionProperties ::getKeyId ).to (builder ::kmsKeyId );
165+ }
166+ }
167+
127168 @ Bean
128169 @ ConditionalOnMissingBean
129170 S3Client s3EncryptionClient (S3EncryptionClient .Builder s3EncryptionBuilder , S3ClientBuilder s3ClientBuilder ) {
@@ -149,62 +190,28 @@ S3EncryptionClient.Builder s3EncrpytionClientBuilder(S3Properties properties,
149190 configureEncryptionProperties (properties , rsaProvider , aesProvider , builder );
150191 return builder ;
151192 }
193+ }
152194
153- private static void configureEncryptionProperties (S3Properties properties ,
154- ObjectProvider <S3RsaProvider > rsaProvider , ObjectProvider <S3AesProvider > aesProvider ,
155- S3EncryptionClient .Builder builder ) {
156- PropertyMapper propertyMapper = PropertyMapper .get ();
157- var encryptionProperties = properties .getEncryption ();
158-
159- propertyMapper .from (encryptionProperties ::isEnableDelayedAuthenticationMode )
160- .to (builder ::enableDelayedAuthenticationMode );
161- propertyMapper .from (encryptionProperties ::isEnableLegacyUnauthenticatedModes )
162- .to (builder ::enableLegacyUnauthenticatedModes );
163- propertyMapper .from (encryptionProperties ::isEnableMultipartPutObject ).to (builder ::enableMultipartPutObject );
195+ @ Configuration
196+ @ AutoConfigureAfter (Jackson2JsonS3ObjectConverterConfiguration .class )
197+ @ ConditionalOnClass (value = ObjectMapper .class )
198+ static class LegacyJackson2JsonS3ObjectConverterConfiguration {
164199
165- if (!StringUtils .hasText (properties .getEncryption ().getKeyId ())) {
166- if (aesProvider .getIfAvailable () != null ) {
167- builder .aesKey (aesProvider .getObject ().generateSecretKey ());
168- }
169- else {
170- builder .rsaKeyPair (rsaProvider .getObject ().generateKeyPair ());
171- }
172- }
173- else {
174- propertyMapper .from (encryptionProperties ::getKeyId ).to (builder ::kmsKeyId );
175- }
200+ @ ConditionalOnMissingBean
201+ @ Bean
202+ S3ObjectConverter s3ObjectConverter (Optional <ObjectMapper > objectMapper ) {
203+ return new LegacyJackson2JsonS3ObjectConverter (objectMapper .orElseGet (ObjectMapper ::new ));
176204 }
177205 }
178206
179- @ Bean
180- @ ConditionalOnMissingBean
181- S3Client s3Client (S3ClientBuilder s3ClientBuilder ) {
182- return s3ClientBuilder .build ();
183- }
184-
185207 @ Configuration
186- @ ConditionalOnClass (ObjectMapper .class )
208+ @ ConditionalOnClass (value = JsonMapper .class )
187209 static class Jackson2JsonS3ObjectConverterConfiguration {
188210
189211 @ ConditionalOnMissingBean
190212 @ Bean
191- S3ObjectConverter s3ObjectConverter (Optional <JsonMapper > jsonMapper , Optional <ObjectMapper > objectMapper ) {
192- if (JacksonPresent .isJackson2Present ()) {
193- return new LegacyJackson2JsonS3ObjectConverter (objectMapper .orElseGet (ObjectMapper ::new ));
194- } else if (JacksonPresent .isJackson3Present ()) {
195- return new Jackson2JsonS3ObjectConverter (jsonMapper .orElseGet (JsonMapper ::new ));
196- } else {
197- throw new IllegalStateException (
198- "SecretsManagerPropertySource requires a Jackson 2 or Jackson 3 library on the classpath" );
199- }
213+ S3ObjectConverter s3ObjectConverter (Optional <JsonMapper > jsonMapper ) {
214+ return new Jackson2JsonS3ObjectConverter (jsonMapper .orElseGet (JsonMapper ::new ));
200215 }
201216 }
202-
203- @ Bean
204- @ ConditionalOnMissingBean
205- S3OutputStreamProvider inMemoryBufferingS3StreamProvider (S3Client s3Client ,
206- Optional <S3ObjectContentTypeResolver > contentTypeResolver ) {
207- return new InMemoryBufferingS3OutputStreamProvider (s3Client ,
208- contentTypeResolver .orElseGet (PropertiesS3ObjectContentTypeResolver ::new ));
209- }
210217}
0 commit comments