17
17
18
18
import com .fasterxml .jackson .databind .ObjectMapper ;
19
19
import io .awspring .cloud .autoconfigure .AwsAsyncClientCustomizer ;
20
- import io .awspring .cloud .autoconfigure .core .AwsClientBuilderConfigurer ;
21
- import io .awspring .cloud .autoconfigure .core .AwsClientCustomizer ;
22
- import io .awspring .cloud .autoconfigure .core .AwsConnectionDetails ;
23
- import io .awspring .cloud .autoconfigure .core .CredentialsProviderAutoConfiguration ;
24
- import io .awspring .cloud .autoconfigure .core .RegionProviderAutoConfiguration ;
20
+ import io .awspring .cloud .autoconfigure .core .*;
25
21
import io .awspring .cloud .sqs .config .SqsBootstrapConfiguration ;
26
22
import io .awspring .cloud .sqs .config .SqsListenerConfigurer ;
27
23
import io .awspring .cloud .sqs .config .SqsMessageListenerContainerFactory ;
30
26
import io .awspring .cloud .sqs .listener .errorhandler .ErrorHandler ;
31
27
import io .awspring .cloud .sqs .listener .interceptor .AsyncMessageInterceptor ;
32
28
import io .awspring .cloud .sqs .listener .interceptor .MessageInterceptor ;
29
+ import io .awspring .cloud .sqs .operations .BatchingSqsClientAdapter ;
33
30
import io .awspring .cloud .sqs .operations .SqsTemplate ;
34
31
import io .awspring .cloud .sqs .operations .SqsTemplateBuilder ;
35
32
import io .awspring .cloud .sqs .support .converter .MessagingMessageConverter ;
48
45
import org .springframework .boot .context .properties .PropertyMapper ;
49
46
import org .springframework .context .annotation .Bean ;
50
47
import org .springframework .context .annotation .Import ;
48
+ import org .springframework .context .annotation .Primary ;
51
49
import software .amazon .awssdk .services .sqs .SqsAsyncClient ;
52
50
import software .amazon .awssdk .services .sqs .SqsAsyncClientBuilder ;
51
+ import software .amazon .awssdk .services .sqs .batchmanager .BatchOverrideConfiguration ;
52
+ import software .amazon .awssdk .services .sqs .batchmanager .SqsAsyncBatchManager ;
53
53
import software .amazon .awssdk .services .sqs .model .Message ;
54
54
55
55
/**
@@ -82,9 +82,35 @@ public SqsAsyncClient sqsAsyncClient(AwsClientBuilderConfigurer awsClientBuilder
82
82
ObjectProvider <AwsConnectionDetails > connectionDetails ,
83
83
ObjectProvider <SqsAsyncClientCustomizer > sqsAsyncClientCustomizers ,
84
84
ObjectProvider <AwsAsyncClientCustomizer > awsAsyncClientCustomizers ) {
85
- return awsClientBuilderConfigurer .configureAsyncClient (SqsAsyncClient .builder (), this .sqsProperties ,
86
- connectionDetails .getIfAvailable (), configurer .getIfAvailable (),
87
- sqsAsyncClientCustomizers .orderedStream (), awsAsyncClientCustomizers .orderedStream ()).build ();
85
+ return awsClientBuilderConfigurer .configureAsyncClient (SqsAsyncClient .builder (), this .sqsProperties ,
86
+ connectionDetails .getIfAvailable (), configurer .getIfAvailable (),
87
+ sqsAsyncClientCustomizers .orderedStream (), awsAsyncClientCustomizers .orderedStream ()).build ();
88
+ }
89
+
90
+ @ ConditionalOnProperty (name = "spring.cloud.aws.sqs.batch.enabled" , havingValue = "true" )
91
+ @ Bean
92
+ @ Primary
93
+ public SqsAsyncClient batchSqsAsyncClient (SqsAsyncClient sqsAsyncClient ) {
94
+ SqsAsyncBatchManager batchManager = createBatchManager (sqsAsyncClient );
95
+ return new BatchingSqsClientAdapter (batchManager );
96
+ }
97
+
98
+ private SqsAsyncBatchManager createBatchManager (SqsAsyncClient sqsAsyncClient ) {
99
+ return SqsAsyncBatchManager .builder ()
100
+ .client (sqsAsyncClient )
101
+ .overrideConfiguration (this ::configurationProperties )
102
+ .build ();
103
+ }
104
+
105
+ private void configurationProperties (BatchOverrideConfiguration .Builder options ) {
106
+ PropertyMapper mapper = PropertyMapper .get ().alwaysApplyingWhenNonNull ();
107
+ mapper .from (this .sqsProperties .getBatch ().getMaxNumberOfMessages ()).to (options ::maxBatchSize );
108
+ mapper .from (this .sqsProperties .getBatch ().getSendBatchFrequency ()).to (options ::sendRequestFrequency );
109
+ mapper .from (this .sqsProperties .getBatch ().getWaitTimeSeconds ()).to (options ::receiveMessageMinWaitDuration );
110
+ mapper .from (this .sqsProperties .getBatch ().getVisibilityTimeout ()).to (options ::receiveMessageVisibilityTimeout );
111
+ mapper .from (this .sqsProperties .getBatch ().getSystemAttributeNames ())
112
+ .to (options ::receiveMessageSystemAttributeNames );
113
+ mapper .from (this .sqsProperties .getBatch ().getAttributeNames ()).to (options ::receiveMessageAttributeNames );
88
114
}
89
115
90
116
@ ConditionalOnMissingBean
@@ -93,15 +119,15 @@ public SqsTemplate sqsTemplate(SqsAsyncClient sqsAsyncClient, ObjectProvider<Obj
93
119
ObjectProvider <ObservationRegistry > observationRegistryProvider ,
94
120
ObjectProvider <SqsTemplateObservation .Convention > observationConventionProvider ,
95
121
MessagingMessageConverter <Message > messageConverter ) {
96
- SqsTemplateBuilder builder = SqsTemplate .builder ().sqsAsyncClient (sqsAsyncClient )
97
- .messageConverter (messageConverter );
122
+ SqsTemplateBuilder builder = SqsTemplate .builder ().sqsAsyncClient (sqsAsyncClient )
123
+ .messageConverter (messageConverter );
98
124
objectMapperProvider .ifAvailable (om -> setMapperToConverter (messageConverter , om ));
99
- if (this .sqsProperties .isObservationEnabled ()) {
100
- observationRegistryProvider
101
- .ifAvailable (registry -> builder .configure (options -> options .observationRegistry (registry )));
102
- observationConventionProvider
103
- .ifAvailable (convention -> builder .configure (options -> options .observationConvention (convention )));
104
- }
125
+ if (this .sqsProperties .isObservationEnabled ()) {
126
+ observationRegistryProvider
127
+ .ifAvailable (registry -> builder .configure (options -> options .observationRegistry (registry )));
128
+ observationConventionProvider
129
+ .ifAvailable (convention -> builder .configure (options -> options .observationConvention (convention )));
130
+ }
105
131
if (sqsProperties .getQueueNotFoundStrategy () != null ) {
106
132
builder .configure ((options ) -> options .queueNotFoundStrategy (sqsProperties .getQueueNotFoundStrategy ()));
107
133
}
@@ -127,12 +153,12 @@ public SqsMessageListenerContainerFactory<Object> defaultSqsListenerContainerFac
127
153
interceptors .forEach (factory ::addMessageInterceptor );
128
154
asyncInterceptors .forEach (factory ::addMessageInterceptor );
129
155
objectMapperProvider .ifAvailable (om -> setMapperToConverter (messagingMessageConverter , om ));
130
- if (this .sqsProperties .isObservationEnabled ()) {
131
- observationRegistry
132
- .ifAvailable (registry -> factory .configure (options -> options .observationRegistry (registry )));
133
- observationConventionProvider
134
- .ifAvailable (convention -> factory .configure (options -> options .observationConvention (convention )));
135
- }
156
+ if (this .sqsProperties .isObservationEnabled ()) {
157
+ observationRegistry
158
+ .ifAvailable (registry -> factory .configure (options -> options .observationRegistry (registry )));
159
+ observationConventionProvider
160
+ .ifAvailable (convention -> factory .configure (options -> options .observationConvention (convention )));
161
+ }
136
162
factory .configure (options -> options .messageConverter (messagingMessageConverter ));
137
163
return factory ;
138
164
}
0 commit comments