@@ -91,6 +91,16 @@ static boolean hasStateStoreConfig(String stateStoreName, Config config) {
91
91
return stateStores .contains (stateStoreName );
92
92
}
93
93
94
+ static boolean hasDLQConfig (String channelName , Config config ) {
95
+ String propertyKey = getChannelPropertyKey (channelName , "failure-strategy" , true );
96
+ Optional <String > channelFailureStrategy = config .getOptionalValue (propertyKey , String .class );
97
+ Optional <String > failureStrategy = channelFailureStrategy .or (() -> getConnectorProperty ("failure-strategy" , config ));
98
+
99
+ return failureStrategy .isPresent ()
100
+ && (failureStrategy .get ().equals ("dead-letter-queue" )
101
+ || failureStrategy .get ().equals ("delayed-retry-topic" ));
102
+ }
103
+
94
104
private static Optional <String > getConnectorProperty (String keySuffix , Config config ) {
95
105
return config .getOptionalValue ("mp.messaging.connector." + KafkaConnector .CONNECTOR_NAME + "." + keySuffix ,
96
106
String .class );
@@ -207,8 +217,8 @@ void discoverDefaultSerdeConfig(DefaultSerdeDiscoveryState discovery,
207
217
BuildProducer <RunTimeConfigurationDefaultBuildItem > config ,
208
218
BuildProducer <GeneratedClassBuildItem > generatedClass ,
209
219
BuildProducer <ReflectiveClassBuildItem > reflection ) {
210
- Map <String , String > alreadyGeneratedSerializers = new HashMap <>();
211
- Map <String , String > alreadyGeneratedDeserializers = new HashMap <>();
220
+ Map <String , Result > alreadyGeneratedSerializers = new HashMap <>();
221
+ Map <String , Result > alreadyGeneratedDeserializers = new HashMap <>();
212
222
for (AnnotationInstance annotation : discovery .findRepeatableAnnotationsOnMethods (DotNames .INCOMING )) {
213
223
String channelName = annotation .value ().asString ();
214
224
if (!discovery .isKafkaConnector (channelsManagedByConnectors , true , channelName )) {
@@ -220,7 +230,7 @@ void discoverDefaultSerdeConfig(DefaultSerdeDiscoveryState discovery,
220
230
Type incomingType = getIncomingTypeFromMethod (method );
221
231
222
232
processIncomingType (discovery , config , incomingType , channelName , generatedClass , reflection ,
223
- alreadyGeneratedDeserializers );
233
+ alreadyGeneratedDeserializers , alreadyGeneratedSerializers );
224
234
}
225
235
226
236
for (AnnotationInstance annotation : discovery .findRepeatableAnnotationsOnMethods (DotNames .OUTGOING )) {
@@ -257,7 +267,7 @@ void discoverDefaultSerdeConfig(DefaultSerdeDiscoveryState discovery,
257
267
Type incomingType = getIncomingTypeFromChannelInjectionPoint (injectionPointType );
258
268
259
269
processIncomingType (discovery , config , incomingType , channelName , generatedClass , reflection ,
260
- alreadyGeneratedDeserializers );
270
+ alreadyGeneratedDeserializers , alreadyGeneratedSerializers );
261
271
262
272
processKafkaTransactions (discovery , config , channelName , injectionPointType );
263
273
@@ -293,11 +303,12 @@ private void processKafkaTransactions(DefaultSerdeDiscoveryState discovery,
293
303
private void processIncomingType (DefaultSerdeDiscoveryState discovery ,
294
304
BuildProducer <RunTimeConfigurationDefaultBuildItem > config , Type incomingType , String channelName ,
295
305
BuildProducer <GeneratedClassBuildItem > generatedClass , BuildProducer <ReflectiveClassBuildItem > reflection ,
296
- Map <String , String > alreadyGeneratedDeserializers ) {
306
+ Map <String , Result > alreadyGeneratedDeserializers , Map < String , Result > alreadyGeneratedSerializers ) {
297
307
extractKeyValueType (incomingType , (key , value , isBatchType ) -> {
298
- Result keyDeserializer = deserializerFor (discovery , key , generatedClass , reflection , alreadyGeneratedDeserializers );
299
- Result valueDeserializer = deserializerFor (discovery , value , generatedClass , reflection ,
300
- alreadyGeneratedDeserializers );
308
+ Result keyDeserializer = deserializerFor (discovery , key , true , channelName , generatedClass , reflection ,
309
+ alreadyGeneratedDeserializers , alreadyGeneratedSerializers );
310
+ Result valueDeserializer = deserializerFor (discovery , value , false , channelName , generatedClass , reflection ,
311
+ alreadyGeneratedDeserializers , alreadyGeneratedSerializers );
301
312
302
313
produceRuntimeConfigurationDefaultBuildItem (discovery , config ,
303
314
getChannelPropertyKey (channelName , "key.deserializer" , true ), keyDeserializer );
@@ -494,7 +505,7 @@ private Type getOutgoingTypeFromChannelInjectionPoint(Type injectionPointType) {
494
505
495
506
private void processOutgoingType (DefaultSerdeDiscoveryState discovery , Type outgoingType ,
496
507
BiConsumer <Result , Result > serializerAcceptor , BuildProducer <GeneratedClassBuildItem > generatedClass ,
497
- BuildProducer <ReflectiveClassBuildItem > reflection , Map <String , String > alreadyGeneratedSerializer ) {
508
+ BuildProducer <ReflectiveClassBuildItem > reflection , Map <String , Result > alreadyGeneratedSerializer ) {
498
509
extractKeyValueType (outgoingType , (key , value , isBatch ) -> {
499
510
Result keySerializer = serializerFor (discovery , key , generatedClass , reflection ,
500
511
alreadyGeneratedSerializer );
@@ -766,10 +777,14 @@ private static boolean isRawMessage(Type type) {
766
777
);
767
778
// @formatter:on
768
779
769
- private Result deserializerFor (DefaultSerdeDiscoveryState discovery , Type type ,
780
+ private Result deserializerFor (DefaultSerdeDiscoveryState discovery ,
781
+ Type type ,
782
+ boolean key ,
783
+ String channelName ,
770
784
BuildProducer <GeneratedClassBuildItem > generatedClass ,
771
785
BuildProducer <ReflectiveClassBuildItem > reflection ,
772
- Map <String , String > alreadyGeneratedSerializers ) {
786
+ Map <String , Result > alreadyGeneratedDeserializers ,
787
+ Map <String , Result > alreadyGeneratedSerializers ) {
773
788
Result result = serializerDeserializerFor (discovery , type , false );
774
789
if (result != null && !result .exists ) {
775
790
// avoid returning Result.nonexistent() to callers, they expect a non-null Result to always be known
@@ -779,24 +794,34 @@ private Result deserializerFor(DefaultSerdeDiscoveryState discovery, Type type,
779
794
// also, only generate the serializer/deserializer for classes and only generate once
780
795
if (result == null && type != null && generatedClass != null && type .kind () == Type .Kind .CLASS ) {
781
796
// Check if already generated
782
- String clazz = alreadyGeneratedSerializers .get (type .toString ());
783
- if (clazz == null ) {
784
- clazz = JacksonSerdeGenerator .generateDeserializer (generatedClass , type );
797
+ result = alreadyGeneratedDeserializers .get (type .toString ());
798
+ if (result == null ) {
799
+ String clazz = JacksonSerdeGenerator .generateDeserializer (generatedClass , type );
785
800
LOGGER .infof ("Generating Jackson deserializer for type %s" , type .name ().toString ());
786
801
// Deserializers are access by reflection.
787
802
reflection .produce (
788
803
ReflectiveClassBuildItem .builder (clazz ).methods ().build ());
789
- alreadyGeneratedSerializers .put (type .toString (), clazz );
804
+ alreadyGeneratedDeserializers .put (type .toString (), result );
805
+ // if the channel has a DLQ config generate a serializer as well
806
+ if (hasDLQConfig (channelName , discovery .getConfig ())) {
807
+ Result serializer = serializerFor (discovery , type , generatedClass , reflection , alreadyGeneratedSerializers );
808
+ if (serializer != null ) {
809
+ result = Result .of (clazz )
810
+ .with (key , "dead-letter-queue.key.serializer" , serializer .value )
811
+ .with (!key , "dead-letter-queue.value.serializer" , serializer .value );
812
+ }
813
+ } else {
814
+ result = Result .of (clazz );
815
+ }
790
816
}
791
- result = Result .of (clazz );
792
817
}
793
818
return result ;
794
819
}
795
820
796
821
private Result serializerFor (DefaultSerdeDiscoveryState discovery , Type type ,
797
822
BuildProducer <GeneratedClassBuildItem > generatedClass ,
798
823
BuildProducer <ReflectiveClassBuildItem > reflection ,
799
- Map <String , String > alreadyGeneratedSerializers ) {
824
+ Map <String , Result > alreadyGeneratedSerializers ) {
800
825
Result result = serializerDeserializerFor (discovery , type , true );
801
826
if (result != null && !result .exists ) {
802
827
// avoid returning Result.nonexistent() to callers, they expect a non-null Result to always be known
@@ -806,16 +831,16 @@ private Result serializerFor(DefaultSerdeDiscoveryState discovery, Type type,
806
831
// also, only generate the serializer/deserializer for classes and only generate once
807
832
if (result == null && type != null && generatedClass != null && type .kind () == Type .Kind .CLASS ) {
808
833
// Check if already generated
809
- String clazz = alreadyGeneratedSerializers .get (type .toString ());
810
- if (clazz == null ) {
811
- clazz = JacksonSerdeGenerator .generateSerializer (generatedClass , type );
834
+ result = alreadyGeneratedSerializers .get (type .toString ());
835
+ if (result == null ) {
836
+ String clazz = JacksonSerdeGenerator .generateSerializer (generatedClass , type );
812
837
LOGGER .infof ("Generating Jackson serializer for type %s" , type .name ().toString ());
813
838
// Serializers are access by reflection.
814
839
reflection .produce (
815
840
ReflectiveClassBuildItem .builder (clazz ).methods ().build ());
816
- alreadyGeneratedSerializers .put (type .toString (), clazz );
841
+ result = Result .of (clazz );
842
+ alreadyGeneratedSerializers .put (type .toString (), result );
817
843
}
818
- result = Result .of (clazz );
819
844
}
820
845
821
846
return result ;
0 commit comments