Skip to content

Commit a05ba93

Browse files
authored
[feature][core] Unified engine initialization connector logic (#8536)
1 parent 9268f5a commit a05ba93

File tree

25 files changed

+314
-623
lines changed

25 files changed

+314
-623
lines changed

Diff for: seatunnel-plugin-discovery/src/main/java/org/apache/seatunnel/plugin/discovery/PluginIdentifier.java renamed to seatunnel-api/src/main/java/org/apache/seatunnel/api/common/PluginIdentifier.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.seatunnel.plugin.discovery;
18+
package org.apache.seatunnel.api.common;
1919

2020
import org.apache.commons.lang3.StringUtils;
2121

Diff for: seatunnel-api/src/main/java/org/apache/seatunnel/api/table/factory/FactoryUtil.java

+104-19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.seatunnel.api.table.factory;
1919

2020
import org.apache.seatunnel.api.common.CommonOptions;
21+
import org.apache.seatunnel.api.common.PluginIdentifier;
2122
import org.apache.seatunnel.api.configuration.ReadonlyConfig;
2223
import org.apache.seatunnel.api.configuration.util.ConfigValidator;
2324
import org.apache.seatunnel.api.configuration.util.OptionRule;
@@ -36,11 +37,13 @@
3637
import org.apache.seatunnel.api.table.connector.TableSource;
3738
import org.apache.seatunnel.api.table.type.SeaTunnelDataType;
3839
import org.apache.seatunnel.api.transform.SeaTunnelTransform;
40+
import org.apache.seatunnel.common.utils.ExceptionUtils;
3941

4042
import org.slf4j.Logger;
4143
import org.slf4j.LoggerFactory;
4244

4345
import lombok.NonNull;
46+
import lombok.extern.slf4j.Slf4j;
4447
import scala.Tuple2;
4548

4649
import java.io.Serializable;
@@ -51,12 +54,17 @@
5154
import java.util.Optional;
5255
import java.util.ServiceConfigurationError;
5356
import java.util.ServiceLoader;
57+
import java.util.function.Consumer;
58+
import java.util.function.Function;
5459
import java.util.stream.Collectors;
5560

61+
import static org.apache.seatunnel.api.common.CommonOptions.PLUGIN_NAME;
62+
5663
/**
5764
* Use SPI to create {@link TableSourceFactory}, {@link TableSinkFactory} and {@link
5865
* CatalogFactory}.
5966
*/
67+
@Slf4j
6068
public final class FactoryUtil {
6169

6270
private static final Logger LOG = LoggerFactory.getLogger(FactoryUtil.class);
@@ -65,31 +73,60 @@ public final class FactoryUtil {
6573

6674
public static <T, SplitT extends SourceSplit, StateT extends Serializable>
6775
Tuple2<SeaTunnelSource<T, SplitT, StateT>, List<CatalogTable>> createAndPrepareSource(
68-
ReadonlyConfig options, ClassLoader classLoader, String factoryIdentifier) {
69-
return restoreAndPrepareSource(options, classLoader, factoryIdentifier, null);
76+
ReadonlyConfig options,
77+
ClassLoader classLoader,
78+
String factoryIdentifier,
79+
Function<PluginIdentifier, SeaTunnelSource> fallbackCreateSource,
80+
TableSourceFactory factory) {
81+
return restoreAndPrepareSource(
82+
options, classLoader, factoryIdentifier, null, fallbackCreateSource, factory);
7083
}
7184

7285
public static <T, SplitT extends SourceSplit, StateT extends Serializable>
7386
Tuple2<SeaTunnelSource<T, SplitT, StateT>, List<CatalogTable>> restoreAndPrepareSource(
7487
ReadonlyConfig options,
7588
ClassLoader classLoader,
7689
String factoryIdentifier,
77-
ChangeStreamTableSourceCheckpoint checkpoint) {
90+
ChangeStreamTableSourceCheckpoint checkpoint,
91+
Function<PluginIdentifier, SeaTunnelSource> fallbackCreateSource,
92+
TableSourceFactory factory) {
7893

7994
try {
80-
final TableSourceFactory factory =
81-
discoverFactory(classLoader, TableSourceFactory.class, factoryIdentifier);
95+
8296
SeaTunnelSource<T, SplitT, StateT> source;
83-
if (factory instanceof ChangeStreamTableSourceFactory && checkpoint != null) {
84-
ChangeStreamTableSourceFactory changeStreamTableSourceFactory =
85-
(ChangeStreamTableSourceFactory) factory;
86-
ChangeStreamTableSourceState<Serializable, SourceSplit> state =
87-
changeStreamTableSourceFactory.deserializeTableSourceState(checkpoint);
97+
final String factoryId = options.get(PLUGIN_NAME);
98+
99+
boolean fallback =
100+
isFallback(
101+
classLoader,
102+
TableSourceFactory.class,
103+
factoryId,
104+
(sourceFactory) -> sourceFactory.createSource(null));
105+
106+
if (fallback) {
88107
source =
89-
restoreAndPrepareSource(
90-
changeStreamTableSourceFactory, options, classLoader, state);
108+
fallbackCreateSource.apply(
109+
PluginIdentifier.of("seatunnel", "source", factoryId));
110+
source.prepare(options.toConfig());
111+
91112
} else {
92-
source = createAndPrepareSource(factory, options, classLoader);
113+
if (factory == null) {
114+
factory =
115+
discoverFactory(
116+
classLoader, TableSourceFactory.class, factoryIdentifier);
117+
}
118+
119+
if (factory instanceof ChangeStreamTableSourceFactory && checkpoint != null) {
120+
ChangeStreamTableSourceFactory changeStreamTableSourceFactory =
121+
(ChangeStreamTableSourceFactory) factory;
122+
ChangeStreamTableSourceState<Serializable, SourceSplit> state =
123+
changeStreamTableSourceFactory.deserializeTableSourceState(checkpoint);
124+
source =
125+
restoreAndPrepareSource(
126+
changeStreamTableSourceFactory, options, classLoader, state);
127+
} else {
128+
source = createAndPrepareSource(factory, options, classLoader);
129+
}
93130
}
94131
List<CatalogTable> catalogTables;
95132
try {
@@ -115,6 +152,7 @@ Tuple2<SeaTunnelSource<T, SplitT, StateT>, List<CatalogTable>> restoreAndPrepare
115152
catalogTables.add(catalogTable);
116153
}
117154
return new Tuple2<>(source, catalogTables);
155+
118156
} catch (Throwable t) {
119157
throw new FactoryException(
120158
String.format(
@@ -150,25 +188,50 @@ SeaTunnelSink<IN, StateT, CommitInfoT, AggregatedCommitInfoT> createAndPrepareSi
150188
CatalogTable catalogTable,
151189
ReadonlyConfig config,
152190
ClassLoader classLoader,
153-
String factoryIdentifier) {
191+
String factoryIdentifier,
192+
Function<PluginIdentifier, SeaTunnelSink> fallbackCreateSink,
193+
TableSinkFactory<IN, StateT, CommitInfoT, AggregatedCommitInfoT>
194+
tableSinkFactory) {
154195
try {
155-
TableSinkFactory<IN, StateT, CommitInfoT, AggregatedCommitInfoT> factory =
156-
discoverFactory(classLoader, TableSinkFactory.class, factoryIdentifier);
196+
final String factoryId = config.get(PLUGIN_NAME);
197+
198+
boolean fallback =
199+
isFallback(
200+
classLoader,
201+
TableSinkFactory.class,
202+
factoryId,
203+
(sinkFactory) -> sinkFactory.createSink(null));
204+
205+
if (fallback) {
206+
SeaTunnelSink sink =
207+
fallbackCreateSink.apply(
208+
PluginIdentifier.of("seatunnel", "sink", factoryId));
209+
sink.prepare(config.toConfig());
210+
sink.setTypeInfo(catalogTable.getSeaTunnelRowType());
211+
212+
return sink;
213+
}
214+
215+
if (tableSinkFactory == null) {
216+
tableSinkFactory =
217+
discoverFactory(classLoader, TableSinkFactory.class, factoryIdentifier);
218+
}
219+
157220
TableSinkFactoryContext context =
158221
TableSinkFactoryContext.replacePlaceholderAndCreate(
159222
catalogTable,
160223
config,
161224
classLoader,
162-
factory.excludeTablePlaceholderReplaceKeys());
163-
ConfigValidator.of(context.getOptions()).validate(factory.optionRule());
225+
tableSinkFactory.excludeTablePlaceholderReplaceKeys());
226+
ConfigValidator.of(context.getOptions()).validate(tableSinkFactory.optionRule());
164227

165228
LOG.info(
166229
"Create sink '{}' with upstream input catalog-table[database: {}, schema: {}, table: {}]",
167230
factoryIdentifier,
168231
catalogTable.getTablePath().getDatabaseName(),
169232
catalogTable.getTablePath().getSchemaName(),
170233
catalogTable.getTablePath().getTableName());
171-
return factory.createSink(context).createSink();
234+
return tableSinkFactory.createSink(context).createSink();
172235
} catch (Throwable t) {
173236
throw new FactoryException(
174237
String.format(
@@ -351,4 +414,26 @@ public static SeaTunnelTransform<?> createAndPrepareMultiTableTransform(
351414
ConfigValidator.of(context.getOptions()).validate(factory.optionRule());
352415
return factory.createTransform(context).createTransform();
353416
}
417+
418+
private static <T extends Factory> boolean isFallback(
419+
ClassLoader classLoader,
420+
Class<T> factoryClass,
421+
String factoryId,
422+
Consumer<T> virtualCreator) {
423+
Optional<T> factory = discoverOptionalFactory(classLoader, factoryClass, factoryId);
424+
if (!factory.isPresent()) {
425+
return true;
426+
}
427+
try {
428+
virtualCreator.accept(factory.get());
429+
} catch (Exception e) {
430+
if (e instanceof UnsupportedOperationException
431+
&& "The Factory has not been implemented and the deprecated Plugin will be used."
432+
.equals(e.getMessage())) {
433+
return true;
434+
}
435+
log.debug(ExceptionUtils.getMessage(e));
436+
}
437+
return false;
438+
}
354439
}

0 commit comments

Comments
 (0)