Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] KIP-891: Connect Multiversion Support (Transformation and Predicate Changes) #17742

Open
wants to merge 147 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 141 commits
Commits
Show all changes
147 commits
Select commit Hold shift + click to select a range
49b37c7
Add multiversioning apis to isolation
snehashisp Aug 23, 2024
1b740cc
add method for header converter
snehashisp Aug 23, 2024
3aba36e
init commit
snehashisp Aug 31, 2024
c96a8d1
update validation logic for connector versions
snehashisp Sep 19, 2024
017df62
add getter for all plugins for a class
snehashisp Sep 19, 2024
0f1cdaf
Merge branch 'multiversioning' into mvn-validation
snehashisp Sep 19, 2024
855e77a
minor edits
snehashisp Sep 21, 2024
4744f4f
Allow super to load class but do a version check
snehashisp Sep 21, 2024
c708ade
Merge branch 'multiversioning' into mvn-validation
snehashisp Sep 21, 2024
8beac31
validate the version when loaded from parent correctly
snehashisp Sep 21, 2024
df16999
Merge branch 'multiversioning' into mvn-validation
snehashisp Sep 21, 2024
6fb6471
Tested connector multiple verions
snehashisp Sep 22, 2024
84ed0da
revert changes to filestream sink
snehashisp Sep 22, 2024
814ddb7
bug in loadclass, should use fullname
snehashisp Sep 22, 2024
7905708
Merge branch 'multiversioning' into mvn-validation
snehashisp Sep 22, 2024
7497ef7
add available version to exception and minor changes
snehashisp Sep 22, 2024
27aba58
Merge branch 'multiversioning' into mvn-validation
snehashisp Sep 22, 2024
b9c0ab5
validation supporting connector version
snehashisp Oct 1, 2024
d9cad93
fix lf to cr
snehashisp Oct 1, 2024
7df37cf
Add configs and recommendors
snehashisp Oct 1, 2024
cbbbc95
converter tested
snehashisp Oct 2, 2024
5282a3f
Add converter validatoins
snehashisp Oct 2, 2024
7ad8a32
Remove changes to json
snehashisp Oct 5, 2024
2cdf67c
Validation and recommendors for versioning transformations and predic…
snehashisp Oct 10, 2024
53068f8
update recommendation logic
snehashisp Oct 10, 2024
7676408
minor fixes
snehashisp Oct 28, 2024
2119a91
Add default version getter
snehashisp Oct 28, 2024
eb3e693
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 28, 2024
9d83a1c
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 28, 2024
dd150a5
add defaults
snehashisp Oct 28, 2024
79a7e02
Update default version
snehashisp Oct 28, 2024
f973fd0
add a null check
snehashisp Oct 29, 2024
cce53be
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 29, 2024
ec7892b
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 29, 2024
baea3cf
Update log and comment
snehashisp Oct 29, 2024
5238dd0
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 29, 2024
ae243dc
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 29, 2024
efbe73b
adress backwards compatiblity
snehashisp Oct 30, 2024
f228fbc
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 30, 2024
ddec0d8
Rename default version to latest version
snehashisp Oct 30, 2024
ab0c8d8
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 30, 2024
d5f765b
Add logic for getting defaults
snehashisp Oct 30, 2024
84fb4fe
fix worker converter fetching
snehashisp Oct 31, 2024
9ded1af
fix header converter version
snehashisp Oct 31, 2024
a385dd4
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 31, 2024
a490ac1
Remove existing default logic
snehashisp Oct 31, 2024
d929a02
remove unwanted imports
snehashisp Oct 31, 2024
edd1067
Remove unwanted imports
snehashisp Oct 31, 2024
8f79bc3
Update imports
snehashisp Oct 31, 2024
648691b
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 31, 2024
9604dfe
refactor default version getting logic
snehashisp Oct 31, 2024
a9fe400
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 31, 2024
74a0d8f
Use current classloader when version is not present
snehashisp Oct 31, 2024
7190808
Merge branch 'multiversioning' into mvn-validation
snehashisp Oct 31, 2024
c604c74
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Oct 31, 2024
680fffc
checkpoint
snehashisp Nov 9, 2024
bfa73e7
Remove transformation and predicate getters
snehashisp Nov 9, 2024
0cc0f8a
Merge branch 'multiversioning' into mvn-validation
snehashisp Nov 9, 2024
49f1522
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Nov 9, 2024
fbbb0b8
add rawtype annotation
snehashisp Nov 9, 2024
bd4b665
Merge branch 'multiversioning' into mvn-validation
snehashisp Nov 9, 2024
105e746
Merge branch 'multiversioning' into mvn-validation-transforms
snehashisp Nov 9, 2024
5d7a335
remove json changes
snehashisp Nov 10, 2024
69381f3
Add version configs to worker
snehashisp Nov 10, 2024
4edbe2a
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Nov 10, 2024
8c334b9
Add a static loader swap method
snehashisp Nov 13, 2024
4a8f0d2
Merge branch 'multiversioning' into mvn-validation
snehashisp Nov 13, 2024
2c7693a
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Nov 13, 2024
c51270c
add null checks
snehashisp Nov 15, 2024
8ac4d56
Minor updates to get connectors
snehashisp Nov 24, 2024
ff108b0
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Nov 24, 2024
27cb9b1
add comment for servie loading bug and rename some methods
snehashisp Nov 29, 2024
720d619
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Nov 29, 2024
1f04289
remove some unndeded code
snehashisp Nov 29, 2024
5fef3f4
Resolve comments on 1st review
snehashisp Dec 5, 2024
5e9f3c7
Remove extra code
snehashisp Dec 5, 2024
d796f22
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
b2b51c6
Add plugin version utils for parsing versions
snehashisp Dec 5, 2024
da2c5f5
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
f8e2837
Remove unused imports
snehashisp Dec 5, 2024
093e9ef
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 5, 2024
aff9ac1
Use PluginVersionUtils version range requirement
snehashisp Dec 5, 2024
56fd5af
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 5, 2024
1c35aa9
Should return loader
snehashisp Dec 5, 2024
9c1c50d
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
ca43739
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 5, 2024
8d64cfa
address first set of comments
snehashisp Dec 5, 2024
73ecfb1
Add a delegated newPlugin class
snehashisp Dec 5, 2024
037d9af
Update abstract herder converter plugin fetching
snehashisp Dec 5, 2024
229cfa9
Update pluginversion util
snehashisp Dec 5, 2024
155271b
fix incorrect classloader equality check
snehashisp Dec 5, 2024
1d41648
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
5efd761
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 5, 2024
8c88d4c
fix whitespace issue
snehashisp Dec 5, 2024
d6e3392
Update version loading logic and add return delegating loader
snehashisp Dec 5, 2024
f969159
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
b6e2226
Combine loader logic
snehashisp Dec 5, 2024
e05bf9e
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 5, 2024
7d995ee
Use instanced PluginVersionUtil
snehashisp Dec 5, 2024
1ac60e4
Update default fetching and recommendor logic
snehashisp Dec 6, 2024
821a7fe
Don't expose some plugins methods
snehashisp Dec 6, 2024
b3c28f7
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 6, 2024
6d1aed4
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 6, 2024
261e697
Update suffix for verison
snehashisp Dec 6, 2024
f52a8fc
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 6, 2024
5b41efe
add safe swap loader instead of static swaploader
snehashisp Dec 6, 2024
773d9b0
Merge branch 'multiversioning' into mvn-validation
snehashisp Dec 6, 2024
475514d
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 6, 2024
dbbc843
Merge branch 'trunk' of https://github.com/apache/kafka into mvn-vali…
snehashisp Dec 8, 2024
0e89ba4
Cleanup and changes post multiversioning merge
snehashisp Dec 8, 2024
17ceac2
fix checkstyle
snehashisp Dec 8, 2024
3e6c910
Update and Isolate getConnector logic
snehashisp Dec 8, 2024
47d4991
fix tests for herders
snehashisp Dec 8, 2024
b0aee4c
attempt to fix large diff in distributed herder
snehashisp Dec 8, 2024
e0c3b16
spotlessJavaFix
snehashisp Dec 9, 2024
9a8fc1b
updates based on comments
snehashisp Dec 9, 2024
7efacbf
remove plugins.recommendor, use header converter defaults
snehashisp Dec 9, 2024
b980c03
minor changes
snehashisp Dec 9, 2024
871ae0a
Do validations for invalid versions
snehashisp Dec 10, 2024
f7d964d
Update plugin loading logic
snehashisp Dec 10, 2024
cba6924
test fix and minor adjustments
snehashisp Dec 10, 2024
520681c
bug fixes
snehashisp Dec 11, 2024
dc4f686
revert unwanted changes
snehashisp Dec 11, 2024
18b8d16
add recommendor for invalid version, attempt to remove unwanted update
snehashisp Dec 11, 2024
978e84b
remove changes in connector config
snehashisp Dec 11, 2024
b29b373
more unwanted change removal
snehashisp Dec 11, 2024
a0f2bd0
fix test
snehashisp Dec 11, 2024
72d86aa
checkstyle fix and remove gitignore changes
snehashisp Dec 11, 2024
14cf633
remove unwanted changes
snehashisp Dec 11, 2024
357d461
newline in gitignore
snehashisp Dec 11, 2024
642221d
Merge branch 'mvn-validation' into mvn-validation-transforms
snehashisp Dec 12, 2024
0c57bf9
remove unwanted changes
snehashisp Dec 12, 2024
87fb31a
Merge branch 'trunk' of https://github.com/apache/kafka into mvn-vali…
snehashisp Dec 13, 2024
4d8ec98
Attempt to fix diff
snehashisp Dec 13, 2024
53a7c78
checkstyle fix
snehashisp Dec 13, 2024
58869c1
fix bug in plugin versionloading and some tests
snehashisp Dec 13, 2024
e1a3ce0
add back concrete class check
snehashisp Dec 13, 2024
2fcf63a
fix abstract herder test
snehashisp Dec 13, 2024
6e997e9
Validate plugin type while getting verison to avoid showing wrong def…
snehashisp Dec 15, 2024
8458124
bug fixes to version fetching
snehashisp Dec 15, 2024
8d59940
checkstyle fix
snehashisp Dec 15, 2024
e0fa30d
add back config exception
snehashisp Dec 17, 2024
f3e82ab
use version plugin loading exception in validation
snehashisp Dec 18, 2024
2cfbf62
fix newPlugin
snehashisp Dec 23, 2024
37560be
cached connectors should throw original exception
snehashisp Dec 25, 2024
ac394b0
reorder operations in validate
snehashisp Dec 26, 2024
b9204d6
Remove unused method
snehashisp Dec 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.kafka.connect.runtime.isolation;

import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.VersionRange;
import org.slf4j.Logger;
Expand All @@ -28,6 +27,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -127,19 +127,7 @@ String resolveFullClassName(String classOrAlias) {
return aliases.getOrDefault(classOrAlias, classOrAlias);
}

String latestVersion(String classOrAlias) {
if (classOrAlias == null) {
return null;
}
String fullName = aliases.getOrDefault(classOrAlias, classOrAlias);
SortedMap<PluginDesc<?>, ClassLoader> inner = pluginLoaders.get(fullName);
if (inner == null) {
return null;
}
return inner.lastKey().version();
}

String versionInLocation(String classOrAlias, String location) {
PluginDesc<?> pluginDesc(String classOrAlias, String preferredLocation, Set<PluginType> allowedTypes) {
if (classOrAlias == null) {
return null;
}
Expand All @@ -148,12 +136,17 @@ String versionInLocation(String classOrAlias, String location) {
if (inner == null) {
return null;
}
PluginDesc<?> result = null;
for (Map.Entry<PluginDesc<?>, ClassLoader> entry : inner.entrySet()) {
if (entry.getKey().location().equals(location)) {
return entry.getKey().version();
if (!allowedTypes.contains(entry.getKey().type())) {
continue;
}
result = entry.getKey();
if (result.location().equals(preferredLocation)) {
return result;
}
}
return null;
return result;
}

private ClassLoader findPluginLoader(
Expand All @@ -170,7 +163,6 @@ private ClassLoader findPluginLoader(
+ "Provided soft version: %s ", range));
}

ArtifactVersion version = null;
ClassLoader loader = null;
for (Map.Entry<PluginDesc<?>, ClassLoader> entry : loaders.entrySet()) {
// the entries should be in sorted order of versions so this should end up picking the latest version which matches the range
Expand Down Expand Up @@ -227,19 +219,19 @@ protected Class<?> loadVersionedPluginClass(
if (range == null) {
return plugin;
}
verifyClasspathVersionedPlugin(name, plugin, range);
verifyClasspathVersionedPlugin(fullName, plugin, range);
}
return plugin;
}

private void verifyClasspathVersionedPlugin(String name, Class<?> plugin, VersionRange range) throws VersionedPluginLoadingException {
private void verifyClasspathVersionedPlugin(String fullName, Class<?> plugin, VersionRange range) throws VersionedPluginLoadingException {
String pluginVersion;
SortedMap<PluginDesc<?>, ClassLoader> scannedPlugin = pluginLoaders.get(name);
SortedMap<PluginDesc<?>, ClassLoader> scannedPlugin = pluginLoaders.get(fullName);

if (scannedPlugin == null) {
throw new VersionedPluginLoadingException(String.format(
"Plugin %s is not part of Connect's plugin loading mechanism (ClassPath or Plugin Path)",
name
fullName
));
}

Expand All @@ -255,7 +247,7 @@ private void verifyClasspathVersionedPlugin(String name, Class<?> plugin, Versio
throw new VersionedPluginLoadingException(String.format(
"Plugin %s has multiple versions specified in class path, "
+ "only one version is allowed in class path for loading a plugin with version range",
name
fullName
));
} else if (classpathPlugins.isEmpty()) {
throw new VersionedPluginLoadingException("Invalid plugin found in classpath");
Expand All @@ -264,7 +256,7 @@ private void verifyClasspathVersionedPlugin(String name, Class<?> plugin, Versio
if (!range.containsVersion(new DefaultArtifactVersion(pluginVersion))) {
throw new VersionedPluginLoadingException(String.format(
"Plugin %s has version %s which does not match the required version range %s",
name,
fullName,
pluginVersion,
range
), Collections.singletonList(pluginVersion));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -265,15 +266,17 @@ public Function<ClassLoader, LoaderSwap> safeLoaderSwapper() {
};
}

public String latestVersion(String classOrAlias) {
return delegatingLoader.latestVersion(classOrAlias);
public String latestVersion(String classOrAlias, PluginType... allowedTypes) {
return pluginVersion(classOrAlias, null, allowedTypes);
}

public String pluginVersion(String classOrAlias, ClassLoader sourceLoader) {
if (!(sourceLoader instanceof PluginClassLoader)) {
return latestVersion(classOrAlias);
public String pluginVersion(String classOrAlias, ClassLoader sourceLoader, PluginType... allowedTypes) {
String location = (sourceLoader instanceof PluginClassLoader) ? ((PluginClassLoader) sourceLoader).location() : null;
PluginDesc<?> desc = delegatingLoader.pluginDesc(classOrAlias, location, new HashSet<>(Arrays.asList(allowedTypes)));
if (desc != null) {
return desc.version();
}
return delegatingLoader.versionInLocation(classOrAlias, ((PluginClassLoader) sourceLoader).location());
return null;
}

public DelegatingClassLoader delegatingLoader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@

import org.apache.kafka.common.config.ConfigDef;
import org.apache.kafka.connect.runtime.ConnectorConfig;
import org.apache.kafka.connect.transforms.Transformation;
import org.apache.kafka.connect.transforms.predicates.Predicate;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -74,6 +77,14 @@ public HeaderConverterPluginVersionRecommender headerConverterPluginVersionRecom
return headerConverterPluginVersionRecommender;
}

public TransformationPluginRecommender transformationPluginRecommender(String classOrAlias) {
return new TransformationPluginRecommender(classOrAlias);
}

public PredicatePluginRecommender predicatePluginRecommender(String classOrAlias) {
return new PredicatePluginRecommender(classOrAlias);
}

public class ConnectorPluginVersionRecommender implements ConfigDef.Recommender {

@SuppressWarnings({"unchecked", "rawtypes"})
Expand Down Expand Up @@ -195,4 +206,60 @@ protected Function<String, List<Object>> recommendations() {
.map(PluginDesc::version).distinct().collect(Collectors.toList());
}
}

// Recommender for transformation and predicate plugins
public abstract class SMTPluginRecommender<T> implements ConfigDef.Recommender {

protected abstract Function<String, Set<PluginDesc<T>>> plugins();

protected final String classOrAliasConfig;

public SMTPluginRecommender(String classOrAliasConfig) {
this.classOrAliasConfig = classOrAliasConfig;
}

@Override
@SuppressWarnings({"rawtypes"})
public List<Object> validValues(String name, Map<String, Object> parsedConfig) {
if (plugins == null) {
return Collections.emptyList();
}
if (parsedConfig.get(classOrAliasConfig) == null) {
return Collections.emptyList();
}

Class classOrAlias = (Class) parsedConfig.get(classOrAliasConfig);
return plugins().apply(classOrAlias.getName())
.stream().map(PluginDesc::version).distinct().collect(Collectors.toList());
}

@Override
public boolean visible(String name, Map<String, Object> parsedConfig) {
return true;
}
}

public class TransformationPluginRecommender extends SMTPluginRecommender<Transformation<?>> {

public TransformationPluginRecommender(String classOrAliasConfig) {
super(classOrAliasConfig);
}

@Override
protected Function<String, Set<PluginDesc<Transformation<?>>>> plugins() {
return plugins::transformations;
}
}

public class PredicatePluginRecommender extends SMTPluginRecommender<Predicate<?>> {

public PredicatePluginRecommender(String classOrAliasConfig) {
super(classOrAliasConfig);
}

@Override
protected Function<String, Set<PluginDesc<Predicate<?>>>> plugins() {
return plugins::predicates;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
Expand Down Expand Up @@ -559,12 +560,14 @@ public void testConfigValidationTopicsRegexWithDlq() {
}

@Test
public void testConfigValidationTransformsExtendResults() {
@SuppressWarnings("rawtypes")
public void testConfigValidationTransformsExtendResults() throws ClassNotFoundException {
final Class<? extends Connector> connectorClass = SampleSourceConnector.class;
AbstractHerder herder = createConfigValidationHerder(connectorClass, noneConnectorClientConfigOverridePolicy);

// 2 transform aliases defined -> 2 plugin lookups
when(plugins.transformations()).thenReturn(Collections.singleton(transformationPluginDesc()));
Mockito.lenient().when(plugins.transformations()).thenReturn(Collections.singleton(transformationPluginDesc()));
Mockito.lenient().when(plugins.newPlugin(SampleTransformation.class.getName(), null, classLoader)).thenReturn(new SampleTransformation());

// Define 2 transformations. One has a class defined and so can get embedded configs, the other is missing
// class info that should generate an error.
Expand All @@ -575,6 +578,7 @@ public void testConfigValidationTransformsExtendResults() {
config.put(ConnectorConfig.TRANSFORMS_CONFIG + ".xformA.type", SampleTransformation.class.getName());
config.put("required", "value"); // connector required config
ConfigInfos result = herder.validateConnectorConfig(config, s -> null, false);

assertEquals(herder.connectorType(config), ConnectorType.SOURCE);

// We expect there to be errors due to the missing name and .... Note that these assertions depend heavily on
Expand All @@ -596,7 +600,7 @@ public void testConfigValidationTransformsExtendResults() {
assertEquals(1, result.errorCount());
Map<String, ConfigInfo> infos = result.values().stream()
.collect(Collectors.toMap(info -> info.configKey().name(), Function.identity()));
assertEquals(31, infos.size());
assertEquals(33, infos.size());
// Should get 2 type fields from the transforms, first adds its own config since it has a valid class
assertEquals("transforms.xformA.type",
infos.get("transforms.xformA.type").configValue().name());
Expand All @@ -611,12 +615,15 @@ public void testConfigValidationTransformsExtendResults() {
}

@Test
public void testConfigValidationPredicatesExtendResults() {
@SuppressWarnings("rawtypes")
public void testConfigValidationPredicatesExtendResults() throws ClassNotFoundException {
final Class<? extends Connector> connectorClass = SampleSourceConnector.class;
AbstractHerder herder = createConfigValidationHerder(connectorClass, noneConnectorClientConfigOverridePolicy);

when(plugins.transformations()).thenReturn(Collections.singleton(transformationPluginDesc()));
when(plugins.predicates()).thenReturn(Collections.singleton(predicatePluginDesc()));
Mockito.lenient().when(plugins.transformations()).thenReturn(Collections.singleton(transformationPluginDesc()));
Mockito.lenient().when(plugins.predicates()).thenReturn(Collections.singleton(predicatePluginDesc()));
Mockito.lenient().when(plugins.newPlugin(SampleTransformation.class.getName(), null, classLoader)).thenReturn(new SampleTransformation());
Mockito.lenient().when(plugins.newPlugin(SamplePredicate.class.getName(), null, classLoader)).thenReturn(new SamplePredicate());

// Define 2 predicates. One has a class defined and so can get embedded configs, the other is missing
// class info that should generate an error.
Expand Down Expand Up @@ -653,7 +660,7 @@ public void testConfigValidationPredicatesExtendResults() {
assertEquals(1, result.errorCount());
Map<String, ConfigInfo> infos = result.values().stream()
.collect(Collectors.toMap(info -> info.configKey().name(), Function.identity()));
assertEquals(33, infos.size());
assertEquals(36, infos.size());
// Should get 2 type fields from the transforms, first adds its own config since it has a valid class
assertEquals("transforms.xformA.type", infos.get("transforms.xformA.type").configValue().name());
assertTrue(infos.get("transforms.xformA.type").configValue().errors().isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ConnectorConfigTest<R extends ConnectRecord<R>> {

Expand Down Expand Up @@ -455,13 +457,19 @@ public static class Value<R extends ConnectRecord<R>> extends AbstractKeyValueTr
}

@Test
public void testEnrichedConfigDef() {
@SuppressWarnings("rawtypes")
public void testEnrichedConfigDef() throws ClassNotFoundException {
String alias = "hdt";
String prefix = ConnectorConfig.TRANSFORMS_CONFIG + "." + alias + ".";
Map<String, String> props = new HashMap<>();
props.put(ConnectorConfig.TRANSFORMS_CONFIG, alias);
props.put(ConnectorConfig.CONNECTOR_CLASS_CONFIG, TestConnector.class.getName());
props.put(prefix + "type", HasDuplicateConfigTransformation.class.getName());
ConfigDef def = ConnectorConfig.enrich(MOCK_PLUGINS, new ConfigDef(), props, false);
Plugins mockPlugins = mock(Plugins.class);
when(mockPlugins.newPlugin(HasDuplicateConfigTransformation.class.getName(),
null, (ClassLoader) null)).thenReturn(new HasDuplicateConfigTransformation());
when(mockPlugins.transformations()).thenReturn(Collections.emptySet());
ConfigDef def = ConnectorConfig.enrich(mockPlugins, new ConfigDef(), props, false);
assertEnrichedConfigDef(def, prefix, HasDuplicateConfigTransformation.MUST_EXIST_KEY, ConfigDef.Type.BOOLEAN);
assertEnrichedConfigDef(def, prefix, TransformationStage.PREDICATE_CONFIG, ConfigDef.Type.STRING);
assertEnrichedConfigDef(def, prefix, TransformationStage.NEGATE_CONFIG, ConfigDef.Type.BOOLEAN);
Expand Down
Loading
Loading