1
1
/*
2
- * Copyright 2017-2022 the original author or authors.
2
+ * Copyright 2017-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
32
32
import java .util .concurrent .TimeUnit ;
33
33
import java .util .concurrent .TimeoutException ;
34
34
import java .util .concurrent .atomic .AtomicInteger ;
35
+ import java .util .function .Predicate ;
35
36
import java .util .stream .Collectors ;
36
37
37
38
import org .apache .commons .logging .LogFactory ;
61
62
import org .springframework .core .log .LogAccessor ;
62
63
import org .springframework .kafka .KafkaException ;
63
64
import org .springframework .kafka .support .TopicForRetryable ;
65
+ import org .springframework .util .Assert ;
64
66
65
67
/**
66
68
* An admin that delegates to an {@link AdminClient} to create topics defined
@@ -87,6 +89,8 @@ public class KafkaAdmin extends KafkaResourceFactory
87
89
88
90
private ApplicationContext applicationContext ;
89
91
92
+ private Predicate <NewTopic > createOrModifyTopic = nt -> true ;
93
+
90
94
private Duration closeTimeout = DEFAULT_CLOSE_TIMEOUT ;
91
95
92
96
private int operationTimeout = DEFAULT_OPERATION_TIMEOUT ;
@@ -157,6 +161,31 @@ public void setModifyTopicConfigs(boolean modifyTopicConfigs) {
157
161
this .modifyTopicConfigs = modifyTopicConfigs ;
158
162
}
159
163
164
+ /**
165
+ * Set a predicate that returns true if a discovered {@link NewTopic} bean should be
166
+ * considered for creation or modification by this admin instance. The default
167
+ * predicate returns true for all {@link NewTopic}s. Used by the default
168
+ * implementation of {@link #newTopics()}.
169
+ * @param createOrModifyTopic the predicate.
170
+ * @since 2.9.10
171
+ * @see #newTopics()
172
+ */
173
+ public void setCreateOrModifyTopic (Predicate <NewTopic > createOrModifyTopic ) {
174
+ Assert .notNull (createOrModifyTopic , "'createOrModifyTopic' cannot be null" );
175
+ this .createOrModifyTopic = createOrModifyTopic ;
176
+ }
177
+
178
+ /**
179
+ * Return the predicate used to determine whether a {@link NewTopic} should be
180
+ * considered for creation or modification.
181
+ * @return the predicate.
182
+ * @since 2.9.10
183
+ * @see #newTopics()
184
+ */
185
+ protected Predicate <NewTopic > getCreateOrModifyTopic () {
186
+ return this .createOrModifyTopic ;
187
+ }
188
+
160
189
@ Override
161
190
public Map <String , Object > getConfigurationProperties () {
162
191
Map <String , Object > configs2 = new HashMap <>(this .configs );
@@ -219,10 +248,17 @@ public final boolean initialize() {
219
248
return false ;
220
249
}
221
250
222
- /*
223
- * Remove any TopicForRetryable bean if there is also a NewTopic with the same topic name.
251
+ /**
252
+ * Return a collection of {@link NewTopic}s to create or modify. The default
253
+ * implementation retrieves all {@link NewTopic} beans in the application context and
254
+ * applies the {@link #setCreateOrModifyTopic(Predicate)} predicate to each one. It
255
+ * also removes any {@link TopicForRetryable} bean if there is also a NewTopic with
256
+ * the same topic name. This is performed before calling the predicate.
257
+ * @return the collection of {@link NewTopic}s.
258
+ * @since 2.9.10
259
+ * @see #setCreateOrModifyTopic(Predicate)
224
260
*/
225
- private Collection <NewTopic > newTopics () {
261
+ protected Collection <NewTopic > newTopics () {
226
262
Map <String , NewTopic > newTopicsMap = new HashMap <>(
227
263
this .applicationContext .getBeansOfType (NewTopic .class , false , false ));
228
264
Map <String , NewTopics > wrappers = this .applicationContext .getBeansOfType (NewTopics .class , false , false );
@@ -250,6 +286,13 @@ private Collection<NewTopic> newTopics() {
250
286
newTopicsMap .remove (entry .getKey ());
251
287
}
252
288
}
289
+ Iterator <Entry <String , NewTopic >> iterator = newTopicsMap .entrySet ().iterator ();
290
+ while (iterator .hasNext ()) {
291
+ Entry <String , NewTopic > next = iterator .next ();
292
+ if (!this .createOrModifyTopic .test (next .getValue ())) {
293
+ iterator .remove ();
294
+ }
295
+ }
253
296
return new ArrayList <>(newTopicsMap .values ());
254
297
}
255
298
0 commit comments