15
15
*/
16
16
package com .ibm .eventstreams .connect .mqsource .builders ;
17
17
18
- import com .ibm .eventstreams .connect .mqsource .MQSourceConnector ;
19
- import com .ibm .eventstreams .connect .mqsource .processor .JmsToKafkaHeaderConverter ;
18
+ import java .util .Map ;
19
+ import java .util .Optional ;
20
+
21
+ import javax .jms .JMSContext ;
22
+ import javax .jms .JMSException ;
23
+ import javax .jms .Message ;
24
+
20
25
import org .apache .kafka .connect .data .Schema ;
21
26
import org .apache .kafka .connect .data .SchemaAndValue ;
22
27
import org .apache .kafka .connect .source .SourceRecord ;
23
-
24
28
import org .slf4j .Logger ;
25
29
import org .slf4j .LoggerFactory ;
26
30
27
- import javax .jms .JMSContext ;
28
- import javax .jms .JMSException ;
29
- import javax .jms .Message ;
30
- import java .util .Map ;
31
- import java .util .Optional ;
31
+ import com .ibm .eventstreams .connect .mqsource .MQSourceConnector ;
32
+ import com .ibm .eventstreams .connect .mqsource .processor .JmsToKafkaHeaderConverter ;
33
+ import com .ibm .eventstreams .connect .mqsource .util .ErrorHandler ;
32
34
33
35
/**
34
36
* Builds Kafka Connect SourceRecords from messages.
35
37
*/
36
38
public abstract class BaseRecordBuilder implements RecordBuilder {
37
39
private static final Logger log = LoggerFactory .getLogger (BaseRecordBuilder .class );
38
40
39
- public enum KeyHeader { NONE , MESSAGE_ID , CORRELATION_ID , CORRELATION_ID_AS_BYTES , DESTINATION };
40
- protected KeyHeader keyheader = KeyHeader .NONE ;
41
+ public enum KeyHeader {
42
+ NONE , MESSAGE_ID , CORRELATION_ID , CORRELATION_ID_AS_BYTES , DESTINATION
43
+ };
41
44
45
+ protected KeyHeader keyheader = KeyHeader .NONE ;
42
46
43
47
private boolean copyJmsPropertiesFlag = Boolean .FALSE ;
44
48
private JmsToKafkaHeaderConverter jmsToKafkaHeaderConverter ;
49
+ private ErrorHandler errorHandler = new ErrorHandler ();
45
50
46
51
/**
47
52
* Configure this class.
48
53
*
49
54
* @param props initial configuration
50
55
*
51
- * @throws RecordBuilderException Operation failed and connector should stop.
56
+ * @throws RecordBuilderException Operation failed and connector should stop.
52
57
*/
53
- @ Override public void configure (final Map <String , String > props ) {
58
+ @ Override
59
+ public void configure (final Map <String , String > props ) {
54
60
log .trace ("[{}] Entry {}.configure, props={}" , Thread .currentThread ().getId (), this .getClass ().getName (),
55
61
props );
56
62
63
+ configureKeyHeader (props );
64
+ configureJmsProperties (props );
65
+ configureErrorHandler (props );
66
+
67
+ log .trace ("[{}] Exit {}.configure" , Thread .currentThread ().getId (), this .getClass ().getName ());
68
+ }
69
+
70
+ /**
71
+ * Configure key header settings.
72
+ */
73
+ private void configureKeyHeader (final Map <String , String > props ) {
57
74
final String kh = props .get (MQSourceConnector .CONFIG_NAME_MQ_RECORD_BUILDER_KEY_HEADER );
58
75
if (kh != null ) {
59
76
if (kh .equals (MQSourceConnector .CONFIG_VALUE_MQ_RECORD_BUILDER_KEY_HEADER_JMSMESSAGEID )) {
@@ -73,12 +90,22 @@ public enum KeyHeader { NONE, MESSAGE_ID, CORRELATION_ID, CORRELATION_ID_AS_BYTE
73
90
throw new RecordBuilderException ("Unsupported MQ record builder key header value" );
74
91
}
75
92
}
93
+ }
76
94
95
+ /**
96
+ * Configure JMS properties settings.
97
+ */
98
+ private void configureJmsProperties (final Map <String , String > props ) {
77
99
final String str = props .get (MQSourceConnector .CONFIG_NAME_MQ_JMS_PROPERTY_COPY_TO_KAFKA_HEADER );
78
100
copyJmsPropertiesFlag = Boolean .parseBoolean (Optional .ofNullable (str ).orElse ("false" ));
79
101
jmsToKafkaHeaderConverter = new JmsToKafkaHeaderConverter ();
102
+ }
80
103
81
- log .trace ("[{}] Exit {}.configure" , Thread .currentThread ().getId (), this .getClass ().getName ());
104
+ /**
105
+ * Configure error handler.
106
+ */
107
+ public void configureErrorHandler (final Map <String , String > props ) {
108
+ errorHandler .configure (props , copyJmsPropertiesFlag , jmsToKafkaHeaderConverter );
82
109
}
83
110
84
111
/**
@@ -160,38 +187,58 @@ public abstract SchemaAndValue getValue(JMSContext context, String topic, boolea
160
187
* @throws JMSException Message could not be converted
161
188
*/
162
189
@ Override
163
- public SourceRecord toSourceRecord (final JMSContext context , final String topic , final boolean messageBodyJms , final Message message ) throws JMSException {
190
+ public SourceRecord toSourceRecord (final JMSContext context , final String topic , final boolean messageBodyJms ,
191
+ final Message message ) throws JMSException {
164
192
return toSourceRecord (context , topic , messageBodyJms , message , null , null );
165
193
}
166
194
167
195
@ Override
168
- public SourceRecord toSourceRecord (final JMSContext context , final String topic , final boolean messageBodyJms , final Message message , final Map <String , Long > sourceOffset , final Map <String , String > sourceQueuePartition ) throws JMSException {
169
- final SchemaAndValue key = this .getKey (context , topic , message );
170
- final SchemaAndValue value = this .getValue (context , topic , messageBodyJms , message );
171
-
172
- if (copyJmsPropertiesFlag && messageBodyJms ) {
173
- return new SourceRecord (
174
- sourceQueuePartition ,
175
- sourceOffset ,
176
- topic ,
177
- null ,
178
- key .schema (),
179
- key .value (),
180
- value .schema (),
181
- value .value (),
182
- message .getJMSTimestamp (),
183
- jmsToKafkaHeaderConverter .convertJmsPropertiesToKafkaHeaders (message )
184
- );
185
- } else {
186
- return new SourceRecord (
187
- sourceQueuePartition ,
188
- sourceOffset ,
189
- topic ,
190
- key .schema (),
191
- key .value (),
192
- value .schema (),
193
- value .value ()
194
- );
196
+ public SourceRecord toSourceRecord (final JMSContext context , final String topic , final boolean messageBodyJms ,
197
+ final Message message , final Map <String , Long > sourceOffset , final Map <String , String > sourceQueuePartition )
198
+ throws JMSException {
199
+
200
+ SchemaAndValue key = new SchemaAndValue (null , null );
201
+
202
+ try {
203
+ // Extract key and value
204
+ final SchemaAndValue value = this .getValue (context , topic , messageBodyJms , message );
205
+ key = this .getKey (context , topic , message );
206
+
207
+ // Create and return appropriate record based on configuration
208
+ if (copyJmsPropertiesFlag && messageBodyJms ) {
209
+ return new SourceRecord (
210
+ sourceQueuePartition ,
211
+ sourceOffset ,
212
+ topic ,
213
+ null ,
214
+ key .schema (),
215
+ key .value (),
216
+ value .schema (),
217
+ value .value (),
218
+ message .getJMSTimestamp (),
219
+ jmsToKafkaHeaderConverter .convertJmsPropertiesToKafkaHeaders (message ));
220
+ } else {
221
+ return new SourceRecord (
222
+ sourceQueuePartition ,
223
+ sourceOffset ,
224
+ topic ,
225
+ null ,
226
+ key .schema (),
227
+ key .value (),
228
+ value .schema (),
229
+ value .value ());
230
+ }
231
+ } catch (final Exception e ) {
232
+ // Log the error using error handler
233
+ errorHandler .logError (e , topic , message );
234
+
235
+ // If errors are not tolerated, rethrow
236
+ if (!errorHandler .shouldTolerateErrors ()) {
237
+ throw e ;
238
+ }
239
+
240
+ // Handle the error based on configured error tolerance
241
+ return errorHandler .handleBuildException (message , sourceQueuePartition , sourceOffset , topic , key , e );
195
242
}
196
243
}
197
244
}
0 commit comments