Skip to content

Commit 3550cbc

Browse files
committed
Rename @PulsarTypeMapping -> @PulsarMessage
1 parent 1c31e6c commit 3550cbc

File tree

10 files changed

+154
-160
lines changed

10 files changed

+154
-160
lines changed

Diff for: spring-pulsar-docs/src/main/antora/modules/ROOT/pages/reference/schema-info/custom-schema-mapping.adoc

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,14 @@ public SchemaResolverCustomizer<DefaultSchemaResolver> schemaResolverCustomizer(
3636
----
3737

3838
==== Type mapping annotation
39-
Another option for specifying default schema information to use for a particular message type is to mark the message class with the `@PulsarTypeMapping` annotation.
39+
Another option for specifying default schema information to use for a particular message type is to mark the message class with the `@PulsarMessage` annotation.
4040
The schema info can be specified via the `schemaType` attribute on the annotation.
4141

4242
The following example configures the system to use JSON as the default schema when producing or consuming messages of type `Foo`:
4343

4444
[source,java,indent=0,subs="verbatim"]
4545
----
46-
@PulsarTypeMapping(schemaType = SchemaType.JSON)
46+
@PulsarMessage(schemaType = SchemaType.JSON)
4747
record Foo(String value) {
4848
}
4949
----
50-
51-
NOTE: The annotations are looked up on-demand and their result is cached. However, there is still a small performance hit on the first lookup. If you want to disable this feature you can invoke the `usePulsarTypeMappingAnnotations(false)` method on the `DefaultSchemaResolver`.

Diff for: spring-pulsar-docs/src/main/antora/modules/ROOT/pages/reference/topic-resolution.adoc

+2-4
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,18 @@ WARNING: If the message (or the first message of a `Publisher` input) is `null`,
3636

3737
=== Specified via annotation
3838

39-
When no topic is passed into the API and there are no custom topic mappings configured, the system looks for a `@PulsarTypeMapping` annotation on the class of the message being produced or consumed.
39+
When no topic is passed into the API and there are no custom topic mappings configured, the system looks for a `@PulsarMessage` annotation on the class of the message being produced or consumed.
4040
The default topic can be specified via the `topic` attribute on the annotation.
4141

4242
The following example configures the default topic to use when producing or consuming messages of type `Foo`:
4343

4444
[source,java,indent=0,subs="verbatim"]
4545
----
46-
@PulsarTypeMapping(topic = "foo-topic")
46+
@PulsarMessage(topic = "foo-topic")
4747
record Foo(String value) {
4848
}
4949
----
5050

51-
NOTE: The annotations are looked up on-demand and their result is cached. However, there is still a small performance hit on the first lookup. If you want to disable this feature you can invoke the `usePulsarTypeMappingAnnotations(false)` method on the `DefaultTopicResolver`.
52-
5351
=== Custom topic resolver
5452
The preferred method of adding mappings is via the property mentioned above.
5553
However, if more control is needed you can replace the default resolver by proving your own implementation, for example:

Diff for: spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarTypeMapping.java renamed to spring-pulsar/src/main/java/org/springframework/pulsar/annotation/PulsarMessage.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
@Target(ElementType.TYPE)
3838
@Retention(RetentionPolicy.RUNTIME)
3939
@Documented
40-
public @interface PulsarTypeMapping {
40+
public @interface PulsarMessage {
4141

4242
/**
4343
* Default topic for the annotated message class.

Diff for: spring-pulsar/src/main/java/org/springframework/pulsar/core/DefaultSchemaResolver.java

+10-11
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.springframework.core.ResolvableType;
4242
import org.springframework.core.log.LogAccessor;
4343
import org.springframework.lang.Nullable;
44-
import org.springframework.pulsar.annotation.PulsarTypeMapping;
44+
import org.springframework.pulsar.annotation.PulsarMessage;
4545
import org.springframework.util.Assert;
4646

4747
/**
@@ -92,18 +92,17 @@ public class DefaultSchemaResolver implements SchemaResolver {
9292

9393
private final Map<Class<?>, Schema<?>> customSchemaMappings = new LinkedHashMap<>();
9494

95-
private final PulsarTypeMappingRegistry pulsarTypeMappingRegistry = new PulsarTypeMappingRegistry();
95+
private final PulsarMessageAnnotationRegistry pulsarMessageAnnotationRegistry = new PulsarMessageAnnotationRegistry();
9696

97-
private boolean usePulsarTypeMappingAnnotations = true;
97+
private boolean usePulsarMessageAnnotations = true;
9898

9999
/**
100100
* Sets whether to inspect message classes for the
101-
* {@link PulsarTypeMapping @PulsarTypeMapping} annotation during schema resolution.
102-
* @param usePulsarTypeMappingAnnotations whether to inspect messages for the
103-
* annotation
101+
* {@link PulsarMessage @PulsarMessage} annotation during schema resolution.
102+
* @param usePulsarMessageAnnotations whether to inspect messages for the annotation
104103
*/
105-
public void usePulsarTypeMappingAnnotations(boolean usePulsarTypeMappingAnnotations) {
106-
this.usePulsarTypeMappingAnnotations = usePulsarTypeMappingAnnotations;
104+
public void usePulsarMessageAnnotations(boolean usePulsarMessageAnnotations) {
105+
this.usePulsarMessageAnnotations = usePulsarMessageAnnotations;
107106
}
108107

109108
/**
@@ -157,8 +156,8 @@ protected Schema<?> getCustomSchemaOrMaybeDefault(@Nullable Class<?> messageClas
157156
// Check for custom schema mapping
158157
Schema<?> schema = this.customSchemaMappings.get(messageClass);
159158

160-
// If no custom schema mapping found, look for @PulsarTypeMapping (if enabled)
161-
if (this.usePulsarTypeMappingAnnotations && schema == null && messageClass != null) {
159+
// If no custom schema mapping found, look for @PulsarMessage (if enabled)
160+
if (this.usePulsarMessageAnnotations && schema == null && messageClass != null) {
162161
schema = getAnnotatedSchemaType(messageClass);
163162
if (schema != null) {
164163
this.addCustomSchemaMapping(messageClass, schema);
@@ -182,7 +181,7 @@ protected Schema<?> getCustomSchemaOrMaybeDefault(@Nullable Class<?> messageClas
182181

183182
// VisibleForTesting
184183
Schema<?> getAnnotatedSchemaType(Class<?> messageClass) {
185-
PulsarTypeMapping annotation = this.pulsarTypeMappingRegistry.getTypeMappingFor(messageClass).orElse(null);
184+
PulsarMessage annotation = this.pulsarMessageAnnotationRegistry.getAnnotationFor(messageClass).orElse(null);
186185
if (annotation == null || annotation.schemaType() == SchemaType.NONE) {
187186
return null;
188187
}

Diff for: spring-pulsar/src/main/java/org/springframework/pulsar/core/DefaultTopicResolver.java

+11-12
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import java.util.function.Supplier;
2323

2424
import org.springframework.lang.Nullable;
25-
import org.springframework.pulsar.annotation.PulsarTypeMapping;
25+
import org.springframework.pulsar.annotation.PulsarMessage;
2626
import org.springframework.util.StringUtils;
2727

2828
/**
@@ -39,18 +39,17 @@ public class DefaultTopicResolver implements TopicResolver {
3939

4040
private final Map<Class<?>, String> customTopicMappings = new LinkedHashMap<>();
4141

42-
private final PulsarTypeMappingRegistry pulsarTypeMappingRegistry = new PulsarTypeMappingRegistry();
42+
private final PulsarMessageAnnotationRegistry pulsarMessageAnnotationRegistry = new PulsarMessageAnnotationRegistry();
4343

44-
private boolean usePulsarTypeMappingAnnotations = true;
44+
private boolean usePulsarMessageAnnotations = true;
4545

4646
/**
4747
* Sets whether to inspect message classes for the
48-
* {@link PulsarTypeMapping @PulsarTypeMapping} annotation during topic resolution.
49-
* @param usePulsarTypeMappingAnnotations whether to inspect messages for the
50-
* annotation
48+
* {@link PulsarMessage @PulsarMessage} annotation during topic resolution.
49+
* @param usePulsarMessageAnnotations whether to inspect messages for the annotation
5150
*/
52-
public void usePulsarTypeMappingAnnotations(boolean usePulsarTypeMappingAnnotations) {
53-
this.usePulsarTypeMappingAnnotations = usePulsarTypeMappingAnnotations;
51+
public void usePulsarMessageAnnotations(boolean usePulsarMessageAnnotations) {
52+
this.usePulsarMessageAnnotations = usePulsarMessageAnnotations;
5453
}
5554

5655
/**
@@ -119,8 +118,8 @@ protected Resolved<String> doResolveTopic(@Nullable String userSpecifiedTopic, @
119118
// Check for custom topic mapping
120119
String topic = this.customTopicMappings.get(messageType);
121120

122-
// If no custom topic mapping found, look for @PulsarTypeMapping (if enabled)
123-
if (this.usePulsarTypeMappingAnnotations && topic == null) {
121+
// If no custom topic mapping found, look for @PulsarMessage (if enabled)
122+
if (this.usePulsarMessageAnnotations && topic == null) {
124123
topic = getAnnotatedTopicInfo(messageType);
125124
if (topic != null) {
126125
this.addCustomTopicMapping(messageType, topic);
@@ -137,8 +136,8 @@ protected Resolved<String> doResolveTopic(@Nullable String userSpecifiedTopic, @
137136

138137
// VisibleForTesting
139138
String getAnnotatedTopicInfo(Class<?> messageType) {
140-
return this.pulsarTypeMappingRegistry.getTypeMappingFor(messageType)
141-
.map(PulsarTypeMapping::topic)
139+
return this.pulsarMessageAnnotationRegistry.getAnnotationFor(messageType)
140+
.map(PulsarMessage::topic)
142141
.filter(StringUtils::hasText)
143142
.orElse(null);
144143
}

Diff for: spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarTypeMappingRegistry.java renamed to spring-pulsar/src/main/java/org/springframework/pulsar/core/PulsarMessageAnnotationRegistry.java

+22-22
Original file line numberDiff line numberDiff line change
@@ -21,61 +21,61 @@
2121

2222
import org.springframework.core.annotation.AnnotationUtils;
2323
import org.springframework.core.log.LogAccessor;
24-
import org.springframework.pulsar.annotation.PulsarTypeMapping;
24+
import org.springframework.pulsar.annotation.PulsarMessage;
2525
import org.springframework.util.Assert;
2626

2727
/**
28-
* A registry that holds the {@link PulsarTypeMapping @PulsarTypeMapping} annotations and
29-
* each associated class that is marked with the annotation.
28+
* A registry that holds the {@link PulsarMessage @PulsarMessage} annotations and each
29+
* associated class that is marked with the annotation.
3030
* <p>
3131
* The annotations are looked up on-demand and the result is cached.
3232
* <p>
33-
* Once the cache reaches a {@link #maxNumberOfMappingsCached certain size} (default of
33+
* Once the cache reaches a {@link #maxNumberOfAnnotationsCached certain size} (default of
3434
* {@link #DEFAULT_MAX_CACHE_SIZE}) it is cleared and the annotations will be looked up
3535
* again the next time they are requested.
3636
*
3737
* @author Chris Bono
3838
*/
39-
class PulsarTypeMappingRegistry {
39+
class PulsarMessageAnnotationRegistry {
4040

4141
private static final int DEFAULT_MAX_CACHE_SIZE = 1000;
4242

43-
private final int maxNumberOfMappingsCached;
43+
private final int maxNumberOfAnnotationsCached;
4444

4545
private final LogAccessor logger = new LogAccessor(this.getClass());
4646

47-
private ConcurrentHashMap<Class<?>, Optional<PulsarTypeMapping>> typeMappingsByClass = new ConcurrentHashMap<>();
47+
private ConcurrentHashMap<Class<?>, Optional<PulsarMessage>> annotationsByClass = new ConcurrentHashMap<>();
4848

49-
PulsarTypeMappingRegistry() {
49+
PulsarMessageAnnotationRegistry() {
5050
this(DEFAULT_MAX_CACHE_SIZE);
5151
}
5252

53-
PulsarTypeMappingRegistry(int maxNumberOfMappingsCached) {
54-
Assert.state(maxNumberOfMappingsCached > 0, "maxNumberOfMappingsCached must be > 0");
55-
this.maxNumberOfMappingsCached = maxNumberOfMappingsCached;
53+
PulsarMessageAnnotationRegistry(int maxNumberOfAnnotationsCached) {
54+
Assert.state(maxNumberOfAnnotationsCached > 0, "maxNumberOfAnnotationsCached must be > 0");
55+
this.maxNumberOfAnnotationsCached = maxNumberOfAnnotationsCached;
5656
}
5757

5858
/**
59-
* Gets the {@link PulsarTypeMapping @PulsarTypeMapping} on the specified class or
60-
* empty if the class is not marked with the annotation.
59+
* Gets the {@link PulsarMessage @PulsarMessage} on the specified class or empty if
60+
* the class is not marked with the annotation.
6161
* @param targetClass the class to check for the annotation
6262
* @return an optional containing the annotation or empty if the class is not marked
6363
* with the annotation.
6464
*/
65-
Optional<PulsarTypeMapping> getTypeMappingFor(Class<?> targetClass) {
66-
var optionalTypeMapping = this.typeMappingsByClass.computeIfAbsent(targetClass, this::findTypeMappingOn);
67-
if (this.typeMappingsByClass.size() > this.maxNumberOfMappingsCached) {
65+
Optional<PulsarMessage> getAnnotationFor(Class<?> targetClass) {
66+
var annotation = this.annotationsByClass.computeIfAbsent(targetClass, this::findAnnotationOn);
67+
if (this.annotationsByClass.size() > this.maxNumberOfAnnotationsCached) {
6868
this.logger
69-
.info(() -> "Clearing cache - max entries exceeded (%d)".formatted(this.maxNumberOfMappingsCached));
70-
this.typeMappingsByClass = new ConcurrentHashMap<>();
69+
.info(() -> "Clearing cache - max entries exceeded (%d)".formatted(this.maxNumberOfAnnotationsCached));
70+
this.annotationsByClass = new ConcurrentHashMap<>();
7171
}
72-
return optionalTypeMapping;
72+
return annotation;
7373
}
7474

7575
// VisibleForTesting
76-
protected Optional<PulsarTypeMapping> findTypeMappingOn(Class<?> targetClass) {
77-
this.logger.debug(() -> "Looking for @PulsarTypeMapping on " + targetClass);
78-
PulsarTypeMapping annotation = AnnotationUtils.findAnnotation(targetClass, PulsarTypeMapping.class);
76+
protected Optional<PulsarMessage> findAnnotationOn(Class<?> targetClass) {
77+
this.logger.debug(() -> "Looking for @PulsarMessage on " + targetClass);
78+
PulsarMessage annotation = AnnotationUtils.findAnnotation(targetClass, PulsarMessage.class);
7979
return Optional.ofNullable(annotation);
8080
}
8181

Diff for: spring-pulsar/src/test/java/org/springframework/pulsar/core/DefaultSchemaResolverTests.java

+8-8
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import org.junit.jupiter.params.provider.MethodSource;
5555

5656
import org.springframework.core.ResolvableType;
57-
import org.springframework.pulsar.annotation.PulsarTypeMapping;
57+
import org.springframework.pulsar.annotation.PulsarMessage;
5858
import org.springframework.pulsar.listener.Proto;
5959
import org.springframework.pulsar.listener.Proto.Person;
6060

@@ -431,7 +431,7 @@ void annotatedMessageTypeNoSchemaInfo() {
431431

432432
@Test
433433
void annotationMappingIgnoredWhenFeatureDisabled() {
434-
resolver.usePulsarTypeMappingAnnotations(false);
434+
resolver.usePulsarMessageAnnotations(false);
435435
assertThatIllegalArgumentException()
436436
.isThrownBy(() -> resolver.resolveSchema(JsonMsgType.class, false).orElseThrow())
437437
.withMessage("Schema not specified and no schema found for " + JsonMsgType.class);
@@ -443,24 +443,24 @@ void customMappingTakesPrecedenceOverAnnotationMapping() {
443443
assertThat(resolver.resolveSchema(JsonMsgType.class, false).orElseThrow()).isEqualTo(Schema.STRING);
444444
}
445445

446-
@PulsarTypeMapping(schemaType = SchemaType.JSON)
446+
@PulsarMessage(schemaType = SchemaType.JSON)
447447
record JsonMsgType(String value) {
448448
}
449449

450-
@PulsarTypeMapping(schemaType = SchemaType.KEY_VALUE, messageKeyType = String.class,
450+
@PulsarMessage(schemaType = SchemaType.KEY_VALUE, messageKeyType = String.class,
451451
messageValueSchemaType = SchemaType.JSON)
452452
record KeyValueMsgType(String key) {
453453
}
454454

455-
@PulsarTypeMapping(schemaType = SchemaType.KEY_VALUE, messageValueSchemaType = SchemaType.JSON)
455+
@PulsarMessage(schemaType = SchemaType.KEY_VALUE, messageValueSchemaType = SchemaType.JSON)
456456
record KeyValueMsgTypeNoKeyInfo(String key) {
457457
}
458458

459-
@PulsarTypeMapping(schemaType = SchemaType.KEY_VALUE, messageKeyType = String.class)
459+
@PulsarMessage(schemaType = SchemaType.KEY_VALUE, messageKeyType = String.class)
460460
record KeyValueMsgTypeNoValueInfo(String key) {
461461
}
462462

463-
@PulsarTypeMapping(topic = "ignore-topic")
463+
@PulsarMessage(topic = "ignore-topic")
464464
record NoSchemaInfoMsgType(String value) {
465465
}
466466

@@ -475,7 +475,7 @@ record Bar<T>(T value) {
475475
record Zaa(String value) {
476476
}
477477

478-
@PulsarTypeMapping(schemaType = SchemaType.STRING)
478+
@PulsarMessage(schemaType = SchemaType.STRING)
479479
record Zaz(String value) {
480480
}
481481

Diff for: spring-pulsar/src/test/java/org/springframework/pulsar/core/DefaultTopicResolverTests.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import org.junit.jupiter.params.provider.MethodSource;
3535

3636
import org.springframework.lang.Nullable;
37-
import org.springframework.pulsar.annotation.PulsarTypeMapping;
37+
import org.springframework.pulsar.annotation.PulsarMessage;
3838

3939
/**
4040
* Unit tests for {@link DefaultTopicResolver}.
@@ -145,7 +145,7 @@ void customMappingTakesPrecedenceOverAnnotationMapping() {
145145

146146
@Test
147147
void annotationMappingIgnoredWhenFeatureDisabled() {
148-
resolver.usePulsarTypeMappingAnnotations(false);
148+
resolver.usePulsarMessageAnnotations(false);
149149
assertThat(resolver.resolveTopic(null, Baz.class, () -> defaultTopic).value().orElse(null))
150150
.isEqualTo(defaultTopic);
151151
}
@@ -211,11 +211,11 @@ record Foo(String value) {
211211
record Bar(String value) {
212212
}
213213

214-
@PulsarTypeMapping(topic = bazTopic)
214+
@PulsarMessage(topic = bazTopic)
215215
record Baz(String value) {
216216
}
217217

218-
@PulsarTypeMapping(schemaType = SchemaType.STRING)
218+
@PulsarMessage(schemaType = SchemaType.STRING)
219219
record BazNoTopicInfo(String value) {
220220
}
221221

0 commit comments

Comments
 (0)