32
32
import org .apache .kafka .common .config .ConfigDef .Type ;
33
33
import org .apache .kafka .common .config .ConfigException ;
34
34
import org .apache .kafka .connect .errors .ConnectException ;
35
+ import org .bson .conversions .Bson ;
35
36
import org .slf4j .Logger ;
36
37
import org .slf4j .LoggerFactory ;
37
38
38
39
import java .io .IOException ;
40
+ import java .lang .reflect .InvocationTargetException ;
39
41
import java .util .*;
40
42
import java .util .stream .Collectors ;
41
43
@@ -47,17 +49,6 @@ public enum FieldProjectionTypes {
47
49
WHITELIST
48
50
}
49
51
50
- public enum IdStrategyModes {
51
- OBJECTID ,
52
- UUID ,
53
- KAFKAMETA ,
54
- FULLKEY ,
55
- PARTIALKEY ,
56
- PARTIALVALUE ,
57
- PROVIDEDINKEY ,
58
- PROVIDEDINVALUE
59
- }
60
-
61
52
public static final String FIELD_LIST_SPLIT_CHAR = "," ;
62
53
63
54
public static final String MONGODB_URI_SCHEME = "mongodb://" ;
@@ -75,7 +66,8 @@ public enum IdStrategyModes {
75
66
public static final int MONGODB_RETRIES_DEFER_TIMEOUT_DEFAULT = 10000 ;
76
67
public static final String MONGODB_VALUE_PROJECTION_TYPE_DEFAULT = "none" ;
77
68
public static final String MONGODB_VALUE_PROJECTION_LIST_DEFAULT = "" ;
78
- public static final String MONGODB_DOCUMENT_ID_STRATEGY_DEFAULT = "objectid" ;
69
+ public static final String MONGODB_DOCUMENT_ID_STRATEGY_DEFAULT = "at.grahsl.kafka.connect.mongodb.processor.id.strategy.BsonOidStrategy" ;
70
+ public static final String MONGODB_DOCUMENT_ID_STRATEGIES_DEFAULT = "" ;
79
71
public static final String MONGODB_KEY_PROJECTION_TYPE_DEFAULT = "none" ;
80
72
public static final String MONGODB_KEY_PROJECTION_LIST_DEFAULT = "" ;
81
73
public static final String MONGODB_FIELD_RENAMER_MAPPING_DEFAULT = "[]" ;
@@ -125,7 +117,10 @@ public enum IdStrategyModes {
125
117
private static final String MONGODB_VALUE_PROJECTION_LIST_DOC = "comma separated list of field names for value projection" ;
126
118
127
119
public static final String MONGODB_DOCUMENT_ID_STRATEGY_CONF = "mongodb.document.id.strategy" ;
128
- private static final String MONGODB_DOCUMENT_ID_STRATEGY_CONF_DOC = "which strategy to use for a unique document id (_id)" ;
120
+ private static final String MONGODB_DOCUMENT_ID_STRATEGY_CONF_DOC = "class name of strategy to use for generating a unique document id (_id)" ;
121
+
122
+ public static final String MONGODB_DOCUMENT_ID_STRATEGIES_CONF = "mongodb.document.id.strategies" ;
123
+ private static final String MONGODB_DOCUMENT_ID_STRATEGIES_CONF_DOC = "comma separated list of custom strategy classes to register for usage" ;
129
124
130
125
public static final String MONGODB_KEY_PROJECTION_TYPE_CONF = "mongodb.key.projection.type" ;
131
126
private static final String MONGODB_KEY_PROJECTION_TYPE_DOC = "whether or not and which key projection to use" ;
@@ -169,7 +164,8 @@ public static ConfigDef conf() {
169
164
.define (MONGODB_RETRIES_DEFER_TIMEOUT_CONF , Type .INT , MONGODB_RETRIES_DEFER_TIMEOUT_DEFAULT , ConfigDef .Range .atLeast (0 ), Importance .MEDIUM , MONGODB_RETRIES_DEFER_TIME_OUT_DOC )
170
165
.define (MONGODB_VALUE_PROJECTION_TYPE_CONF , Type .STRING , MONGODB_VALUE_PROJECTION_TYPE_DEFAULT , EnumValidator .in (FieldProjectionTypes .values ()), Importance .LOW , MONGODB_VALUE_PROJECTION_TYPE_DOC )
171
166
.define (MONGODB_VALUE_PROJECTION_LIST_CONF , Type .STRING , MONGODB_VALUE_PROJECTION_LIST_DEFAULT , Importance .LOW , MONGODB_VALUE_PROJECTION_LIST_DOC )
172
- .define (MONGODB_DOCUMENT_ID_STRATEGY_CONF , Type .STRING , MONGODB_DOCUMENT_ID_STRATEGY_DEFAULT , EnumValidator .in (IdStrategyModes .values ()), Importance .HIGH , MONGODB_DOCUMENT_ID_STRATEGY_CONF_DOC )
167
+ .define (MONGODB_DOCUMENT_ID_STRATEGY_CONF , Type .STRING , MONGODB_DOCUMENT_ID_STRATEGY_DEFAULT , Importance .HIGH , MONGODB_DOCUMENT_ID_STRATEGY_CONF_DOC )
168
+ .define (MONGODB_DOCUMENT_ID_STRATEGIES_CONF , Type .STRING , MONGODB_DOCUMENT_ID_STRATEGIES_DEFAULT , Importance .LOW , MONGODB_DOCUMENT_ID_STRATEGIES_CONF_DOC )
173
169
.define (MONGODB_KEY_PROJECTION_TYPE_CONF , Type .STRING , MONGODB_KEY_PROJECTION_TYPE_DEFAULT , EnumValidator .in (FieldProjectionTypes .values ()), Importance .LOW , MONGODB_KEY_PROJECTION_TYPE_DOC )
174
170
.define (MONGODB_KEY_PROJECTION_LIST_CONF , Type .STRING , MONGODB_KEY_PROJECTION_LIST_DEFAULT , Importance .LOW , MONGODB_KEY_PROJECTION_LIST_DOC )
175
171
.define (MONGODB_FIELD_RENAMER_MAPPING , Type .STRING , MONGODB_FIELD_RENAMER_MAPPING_DEFAULT , Importance .LOW , MONGODB_FIELD_RENAMER_MAPPING_DOC )
@@ -372,29 +368,50 @@ private Set<String> buildProjectionList(String projectionType, String fieldList)
372
368
throw new ConfigException ("error: invalid settings for " + projectionType );
373
369
}
374
370
375
- public AbstractIdStrategy getIdStrategy () {
376
-
377
- IdStrategyModes mode = IdStrategyModes
378
- .valueOf (getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF ).toUpperCase ());
379
-
380
- switch (mode ) {
381
- case OBJECTID :
382
- return new BsonOidStrategy ();
383
- case UUID :
384
- return new UuidStrategy ();
385
- case KAFKAMETA :
386
- return new KafkaMetaDataStrategy ();
387
- case FULLKEY :
388
- return new FullKeyStrategy ();
389
- case PARTIALKEY :
390
- return new PartialKeyStrategy (this .getKeyProjector ());
391
- case PARTIALVALUE :
392
- return new PartialValueStrategy (this .getKeyProjector ());
393
- case PROVIDEDINKEY :
394
- case PROVIDEDINVALUE :
395
- return new ProvidedStrategy (mode );
396
- default :
397
- throw new ConfigException ("error: unexpected IdStrategyMode " +mode .name ());
371
+ public static Set <String > getPredefinedStrategyClassNames () {
372
+ Set <String > strategies = new HashSet <String >();
373
+ strategies .add (BsonOidStrategy .class .getName ());
374
+ strategies .add (FullKeyStrategy .class .getName ());
375
+ strategies .add (KafkaMetaDataStrategy .class .getName ());
376
+ strategies .add (PartialKeyStrategy .class .getName ());
377
+ strategies .add (PartialValueStrategy .class .getName ());
378
+ strategies .add (ProvidedInKeyStrategy .class .getName ());
379
+ strategies .add (ProvidedInValueStrategy .class .getName ());
380
+ strategies .add (UuidStrategy .class .getName ());
381
+ return strategies ;
382
+ }
383
+
384
+ public IdStrategy getIdStrategy () {
385
+
386
+ Set <String > predefinedStrategies = getPredefinedStrategyClassNames ();
387
+
388
+ Set <String > customStrategies = Arrays .asList (getString (MONGODB_DOCUMENT_ID_STRATEGIES_CONF )
389
+ .split (FIELD_LIST_SPLIT_CHAR ))
390
+ .stream ().filter (s -> !s .isEmpty ()).collect (Collectors .toSet ());
391
+
392
+ predefinedStrategies .addAll (customStrategies );
393
+
394
+ String strategy = getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF );
395
+
396
+ if (!predefinedStrategies .contains (strategy )) {
397
+ throw new ConfigException ("error: unkown id strategy " +strategy );
398
+ }
399
+
400
+ try {
401
+ if (strategy .equals (PartialKeyStrategy .class .getName ())
402
+ || strategy .equals (PartialValueStrategy .class .getName ())) {
403
+ return (IdStrategy )Class .forName (strategy )
404
+ .getConstructor (FieldProjector .class )
405
+ .newInstance (this .getKeyProjector ());
406
+ }
407
+ return (IdStrategy )Class .forName (strategy )
408
+ .getConstructor ().newInstance ();
409
+ } catch (ReflectiveOperationException e ) {
410
+ throw new ConfigException (e .getMessage (),e );
411
+ } catch (ClassCastException e ) {
412
+ throw new ConfigException ("error: specified class " + strategy
413
+ + " violates the contract since it doesn't implement " +
414
+ IdStrategy .class );
398
415
}
399
416
400
417
}
@@ -405,14 +422,14 @@ public FieldProjector getKeyProjector() {
405
422
.equalsIgnoreCase (FieldProjectionTypes .BLACKLIST .name ())) {
406
423
407
424
if (getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF ).
408
- equalsIgnoreCase ( IdStrategyModes . PARTIALVALUE . name ())) {
425
+ equals ( PartialValueStrategy . class . getName ())) {
409
426
410
427
return new BlacklistValueProjector (this ,
411
428
this .getKeyProjectionList (),cfg -> cfg .isUsingBlacklistKeyProjection ());
412
429
}
413
430
414
431
if (getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF ).
415
- equalsIgnoreCase ( IdStrategyModes . PARTIALKEY . name ())) {
432
+ equals ( PartialKeyStrategy . class . getName ())) {
416
433
417
434
return new BlacklistKeyProjector (this ,
418
435
this .getKeyProjectionList (),cfg -> cfg .isUsingBlacklistKeyProjection ());
@@ -423,14 +440,14 @@ public FieldProjector getKeyProjector() {
423
440
.equalsIgnoreCase (FieldProjectionTypes .WHITELIST .name ())) {
424
441
425
442
if (getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF ).
426
- equalsIgnoreCase ( IdStrategyModes . PARTIALVALUE . name ())) {
443
+ equals ( PartialValueStrategy . class . getName ())) {
427
444
428
445
return new WhitelistValueProjector (this ,
429
446
this .getKeyProjectionList (),cfg -> cfg .isUsingWhitelistKeyProjection ());
430
447
}
431
448
432
449
if (getString (MONGODB_DOCUMENT_ID_STRATEGY_CONF ).
433
- equalsIgnoreCase ( IdStrategyModes . PARTIALKEY . name ())) {
450
+ equals ( PartialKeyStrategy . class . getName ())) {
434
451
435
452
return new WhitelistKeyProjector (this ,
436
453
this .getKeyProjectionList (),cfg -> cfg .isUsingWhitelistKeyProjection ());
0 commit comments