diff --git a/datax-config/src/main/java/com/alibaba/datax/common/element/ColumnAwareRecord.java b/datax-config/src/main/java/com/alibaba/datax/common/element/ColumnAwareRecord.java
new file mode 100644
index 000000000..75441a120
--- /dev/null
+++ b/datax-config/src/main/java/com/alibaba/datax/common/element/ColumnAwareRecord.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.datax.common.element;
+
+import java.util.Map;
+
+/**
+ *
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-18 17:40
+ **/
+public interface ColumnAwareRecord {
+
+ /**
+ * 设置列名称到列所在index的位置
+ *
+ * @param mapper
+ */
+ public void setCol2Index(Map mapper);
+
+ /**
+ * @param field 字段名称
+ * @param colVal
+ */
+ public void setColumn(String field, final ColValType colVal);
+
+
+ public void setString(String field, final String val);
+
+ /**
+ * @param field 字段名称
+ * @return
+ */
+ public ColValType getColumn(String field);
+
+ public String getString(String field);
+}
diff --git a/datax-config/src/main/java/com/alibaba/datax/common/element/Record.java b/datax-config/src/main/java/com/alibaba/datax/common/element/Record.java
index a7a5c3d00..2ef9695f3 100755
--- a/datax-config/src/main/java/com/alibaba/datax/common/element/Record.java
+++ b/datax-config/src/main/java/com/alibaba/datax/common/element/Record.java
@@ -1,42 +1,51 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.alibaba.datax.common.element;
-import com.alibaba.datax.common.element.Column;
+import java.util.Map;
+
/**
* Created by jingxing on 14-8-24.
*/
-public interface Record {
+public interface Record extends ColumnAwareRecord {
+
+
+ public void addColumn(Column column);
+
+ public void setColumn(int i, final Column column);
- public void addColumn(Column column);
- public void setColumn(int i, final Column column);
+ public Column getColumn(int i);
- public Column getColumn(int i);
+ @Override
+ default String getString(String field) {
+ Column colVal = getColumn(field);
+ return colVal != null ? colVal.asString() : null;
+ }
- public String toString();
+ public String toString();
- public int getColumnNumber();
+ public int getColumnNumber();
- public int getByteSize();
+ public int getByteSize();
- public int getMemorySize();
+ public int getMemorySize();
}
diff --git a/datax-config/src/main/java/com/alibaba/datax/core/job/IJobContainerContext.java b/datax-config/src/main/java/com/alibaba/datax/core/job/IJobContainerContext.java
index 4ad9dd9cd..c07e4be8f 100644
--- a/datax-config/src/main/java/com/alibaba/datax/core/job/IJobContainerContext.java
+++ b/datax-config/src/main/java/com/alibaba/datax/core/job/IJobContainerContext.java
@@ -3,10 +3,12 @@
import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.datax.IDataXTaskRelevant;
+import java.util.Optional;
+
/**
* @author: 百岁(baisui@qlangtech.com)
* @create: 2023-02-23 10:06
**/
public interface IJobContainerContext extends IDataXTaskRelevant, IDataXNameAware {
-
+ Optional getTransformerBuildCfg();
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/VirtualColType.java b/datax-config/src/main/java/com/alibaba/datax/core/job/ITransformerBuildInfo.java
similarity index 70%
rename from tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/VirtualColType.java
rename to datax-config/src/main/java/com/alibaba/datax/core/job/ITransformerBuildInfo.java
index 3b59cfb1b..9d5c04070 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/VirtualColType.java
+++ b/datax-config/src/main/java/com/alibaba/datax/core/job/ITransformerBuildInfo.java
@@ -16,24 +16,15 @@
* limitations under the License.
*/
-package com.qlangtech.tis.plugin.datax.transformer.jdbcprop;
+package com.alibaba.datax.core.job;
-import com.qlangtech.tis.plugin.ds.TypeBase;
+import java.util.List;
/**
+ *
* @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-10 10:14
+ * @create: 2024-06-15 12:34
**/
-public class VirtualColType extends TypeBase {
-
- private String name;
-
- @Override
- public String getName() {
- return this.name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
+public interface ITransformerBuildInfo {
+ List relevantOutterColKeys();
}
diff --git a/datax-config/src/main/java/com/alibaba/datax/core/util/container/TransformerConstant.java b/datax-config/src/main/java/com/alibaba/datax/core/util/container/TransformerConstant.java
new file mode 100644
index 000000000..d3d38df73
--- /dev/null
+++ b/datax-config/src/main/java/com/alibaba/datax/core/util/container/TransformerConstant.java
@@ -0,0 +1,11 @@
+package com.alibaba.datax.core.util.container;
+
+/**
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-15 08:22
+ **/
+public interface TransformerConstant {
+ String JOB_TRANSFORMER = "transformer";
+ String JOB_TRANSFORMER_NAME = "name";
+ String JOB_TRANSFORMER_RELEVANT_KEYS = "cols";
+}
diff --git a/datax-config/src/main/java/com/qlangtech/tis/datax/IDataXNameAware.java b/datax-config/src/main/java/com/qlangtech/tis/datax/IDataXNameAware.java
index 131edae99..f872c12ed 100644
--- a/datax-config/src/main/java/com/qlangtech/tis/datax/IDataXNameAware.java
+++ b/datax-config/src/main/java/com/qlangtech/tis/datax/IDataXNameAware.java
@@ -18,16 +18,30 @@
* limitations under the License.
*/
+import org.apache.commons.lang3.StringUtils;
+
/**
* @author: 百岁(baisui@qlangtech.com)
* @create: 2023-02-23 10:35
**/
public interface IDataXNameAware {
+ /**
+ * 是否在索引
+ *
+ * @return
+ */
+ default boolean isCollectionAware() {
+ return StringUtils.isNotEmpty(getCollectionName());
+ }
+
+ String getCollectionName();
/**
* 取得DataX名称
*
* @return
*/
- public String getTISDataXName();
+ public default String getTISDataXName() {
+ return this.getCollectionName();
+ }
}
diff --git a/tis-base-test/src/main/java/com/qlangtech/tis/test/TISEasyMock.java b/tis-base-test/src/main/java/com/qlangtech/tis/test/TISEasyMock.java
index b1e5115ab..667ec0670 100644
--- a/tis-base-test/src/main/java/com/qlangtech/tis/test/TISEasyMock.java
+++ b/tis-base-test/src/main/java/com/qlangtech/tis/test/TISEasyMock.java
@@ -17,15 +17,13 @@
*/
package com.qlangtech.tis.test;
-import org.junit.Before;
-
/**
* @author 百岁(baisui@qlangtech.com)
* @date 2021-03-04 12:41
*/
public interface TISEasyMock {
- @Before
+
default void clearMocks() {
EasyMockUtil.clearMocks();
}
diff --git a/tis-builder-api/src/main/java/com/qlangtech/tis/realtime/transfer/UnderlineUtils.java b/tis-builder-api/src/main/java/com/qlangtech/tis/realtime/transfer/UnderlineUtils.java
index 291d315b9..e3bb00f83 100644
--- a/tis-builder-api/src/main/java/com/qlangtech/tis/realtime/transfer/UnderlineUtils.java
+++ b/tis-builder-api/src/main/java/com/qlangtech/tis/realtime/transfer/UnderlineUtils.java
@@ -1,19 +1,19 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.qlangtech.tis.realtime.transfer;
@@ -48,13 +48,28 @@ public static StringBuffer removeUnderline(String value) {
}
public static StringBuffer addUnderline(String value) {
+ //return UnderlineUtils.addUnderline(value);
StringBuffer parsedName = new StringBuffer();
char[] nameAry = value.toCharArray();
+ boolean firstAppend = true;
+ boolean previousUnderline = false;
for (int i = 0; i < nameAry.length; i++) {
if (Character.isUpperCase(nameAry[i])) {
- parsedName.append('_').append(Character.toLowerCase(nameAry[i]));
+ if (firstAppend) {
+ parsedName.append(Character.toLowerCase(nameAry[i]));
+ firstAppend = false;
+ } else {
+ if (!previousUnderline) {
+ parsedName.append('_');
+ }
+ parsedName.append(Character.toLowerCase(nameAry[i]));
+ previousUnderline = true;
+ }
} else {
parsedName.append(nameAry[i]);
+ firstAppend = false;
+ previousUnderline = false;
+ // .append(Character.toLowerCase());
}
}
return parsedName;
diff --git a/tis-builder-api/src/test/java/com/qlangtech/tis/TestAll.java b/tis-builder-api/src/test/java/com/qlangtech/tis/TestAll.java
index fde9d6a98..188470d6c 100644
--- a/tis-builder-api/src/test/java/com/qlangtech/tis/TestAll.java
+++ b/tis-builder-api/src/test/java/com/qlangtech/tis/TestAll.java
@@ -20,6 +20,7 @@
import com.qlangtech.tis.fs.TestIPath;
import com.qlangtech.tis.manage.common.TestConfig;
+import com.qlangtech.tis.realtime.transfer.TestUnderlineUtils;
import com.qlangtech.tis.utils.TestTisMetaProps;
import com.qlangtech.tis.utils.TestUtils;
import junit.framework.Test;
@@ -41,6 +42,7 @@ public static Test suite() {
suite.addTestSuite(TestUtils.class);
suite.addTestSuite(TestTisMetaProps.class);
suite.addTestSuite(TestIPath.class);
+ suite.addTestSuite(TestUnderlineUtils.class);
return suite;
}
diff --git a/tis-builder-api/src/test/java/com/qlangtech/tis/realtime/transfer/TestUnderlineUtils.java b/tis-builder-api/src/test/java/com/qlangtech/tis/realtime/transfer/TestUnderlineUtils.java
new file mode 100644
index 000000000..ae907ac7e
--- /dev/null
+++ b/tis-builder-api/src/test/java/com/qlangtech/tis/realtime/transfer/TestUnderlineUtils.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.qlangtech.tis.realtime.transfer;
+
+import junit.framework.TestCase;
+import org.junit.Assert;
+
+/**
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-18 10:18
+ **/
+public class TestUnderlineUtils extends TestCase {
+
+ public void testAddUnderline() {
+ StringBuffer copyValUDF = UnderlineUtils.addUnderline("CopyValUDF");
+ Assert.assertEquals("copy_val_udf", copyValUDF.toString());
+ }
+}
diff --git a/tis-console/src/main/java/com/qlangtech/tis/config/module/action/CollectionAction.java b/tis-console/src/main/java/com/qlangtech/tis/config/module/action/CollectionAction.java
index 8effe77cd..2ca720112 100644
--- a/tis-console/src/main/java/com/qlangtech/tis/config/module/action/CollectionAction.java
+++ b/tis-console/src/main/java/com/qlangtech/tis/config/module/action/CollectionAction.java
@@ -40,6 +40,7 @@
import com.qlangtech.tis.runtime.module.action.CreateIndexConfirmModel;
import com.qlangtech.tis.runtime.module.action.SchemaAction;
import com.qlangtech.tis.runtime.module.action.SysInitializeAction;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import com.qlangtech.tis.solrdao.ISchemaField;
import com.qlangtech.tis.solrdao.ISchemaPluginContext;
import com.qlangtech.tis.solrdao.SchemaResult;
@@ -560,7 +561,7 @@ public AppDomainInfo getAppDomain() {
private TargetColumnMeta getTargetColumnMeta(
- IPluginContext pluginContext, Context context, JSONObject post, String targetTable, PluginItems dataSourceItems)
+ IControlMsgHandler pluginContext, Context context, JSONObject post, String targetTable, PluginItems dataSourceItems)
throws TableNotFoundException {
TargetColumnMeta columnMeta = new TargetColumnMeta(targetTable);
Map colMetas = null;
@@ -572,7 +573,7 @@ private TargetColumnMeta getTargetColumnMeta(
// if (!vals.validate(this, context, false).isValid()) {
// return columnMeta.invalid();
// }
- DataSourceFactory dsFactory = (DataSourceFactory) vals.createDescribable(pluginContext).getInstance();
+ DataSourceFactory dsFactory = (DataSourceFactory) vals.createDescribable(pluginContext, context).getInstance();
List tableMetadata = null;
tableMetadata = dsFactory.getTableMetadata(false, EntityName.parse(targetTable));
@@ -823,7 +824,7 @@ private boolean createIncrSyncChannel(Context context //, WorkFlow df
// 生成DAO脚本
HeteroEnum pluginType = HeteroEnum.MQ;
UploadPluginMeta pluginMeta = UploadPluginMeta.parse(pluginType.identity + ":" + UploadPluginMeta.KEY_REQUIRE);
- PluginItems incrPluginItems = getPluginItems(incrCfg, pluginType, pluginMeta);
+ PluginItems incrPluginItems = getPluginItems(context, incrCfg, pluginType, pluginMeta);
if (incrPluginItems.items.size() < 1) {
throw new IllegalStateException("incr plugin item size can not small than 1");
}
@@ -866,15 +867,15 @@ private boolean createIncrSyncChannel(Context context //, WorkFlow df
return true;
}
- private PluginItems getDataSourceItems(JSONObject datasource) {
- HeteroEnum pluginType = HeteroEnum.DATASOURCE;
- UploadPluginMeta pluginMeta = UploadPluginMeta.parse(pluginType.identity
- + ":" + UploadPluginMeta.KEY_REQUIRE + "," + PostedDSProp.KEY_TYPE + "_detailed,update_false");
- return getPluginItems(datasource, pluginType, pluginMeta);
- }
+// private PluginItems getDataSourceItems(JSONObject datasource) {
+// HeteroEnum pluginType = HeteroEnum.DATASOURCE;
+// UploadPluginMeta pluginMeta = UploadPluginMeta.parse(pluginType.identity
+// + ":" + UploadPluginMeta.KEY_REQUIRE + "," + PostedDSProp.KEY_TYPE + "_detailed,update_false");
+// return getPluginItems(datasource, pluginType, pluginMeta);
+// }
- private PluginItems getPluginItems(JSONObject pluginCfg, HeteroEnum pluginType, UploadPluginMeta pluginMeta) {
+ private PluginItems getPluginItems(Context context, JSONObject pluginCfg, HeteroEnum pluginType, UploadPluginMeta pluginMeta) {
Map dsParams = Maps.newHashMap();
for (String dsKey : pluginCfg.keySet()) {
dsParams.put(dsKey, pluginCfg.getString(dsKey));
@@ -893,7 +894,7 @@ private PluginItems getPluginItems(JSONObject pluginCfg, HeteroEnum pluginType,
dsDescriptpr = pluginDesc.get();
- PluginItems items = new PluginItems(new DftPluginContext(pluginType), pluginMeta);
+ PluginItems items = new PluginItems(new DftPluginContext(pluginType), context, pluginMeta);
JSONArray itemsArray = new JSONArray();
JSONObject item = new JSONObject();
JSONObject vals = new JSONObject();
diff --git a/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/DataxAction.java b/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/DataxAction.java
index a32a25f79..410da6f1f 100644
--- a/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/DataxAction.java
+++ b/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/DataxAction.java
@@ -1434,7 +1434,7 @@ public boolean validate(IFieldErrorHandler msgHandler, Context context, String f
return false;
}
- CMeta.ParsePostMCols postMCols = (new IdlistElementCreatorFactory()).parsePostMCols(null, msgHandler,
+ CMeta.ParsePostMCols postMCols = (new IdlistElementCreatorFactory()).parsePostMCols(null, (IControlMsgHandler) msgHandler,
context, fieldKey /*MultiItemsViewType.keyColsMeta*/, targetCols);
// Map existCols = Maps.newHashMap();
diff --git a/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/PluginAction.java b/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/PluginAction.java
index 480605f14..ca0b22369 100644
--- a/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/PluginAction.java
+++ b/tis-console/src/main/java/com/qlangtech/tis/coredefine/module/action/PluginAction.java
@@ -604,7 +604,7 @@ public void run() {
} catch (InterruptedException e) {
}
// 为了让Assemble等节点的uberClassLoader重新加载一次,需要主动向Assemble等节点发送一个指令
- // notifyPluginUpdate2AssembleNode(TIS.KEY_ACTION_CLEAN_TIS + "=true", "TIS");
+ // notifyPluginUpdate2AssembleNode(TIS.KEY_ACTION_CLEAN_TIS + "=true", "TIS");
InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING);
}
}
@@ -948,7 +948,7 @@ public static PluginItemsParser parsePluginItems(BasicModule module, UploadPlugi
Optional subFormFilter = pluginMeta.getSubFormFilter();
IPluginEnum hEnum = pluginMeta.getHeteroEnum();
- PluginItems pluginItems = new PluginItems(module, pluginMeta);
+ PluginItems pluginItems = new PluginItems(module, context, pluginMeta);
List describableAttrValMapList = AttrValMap.describableAttrValMapList(itemsArray, subFormFilter);
if (pluginMeta.isRequired() && describableAttrValMapList.size() < 1) {
module.addErrorMessage(context, "请设置'" + hEnum.getCaption() + "'表单内容");
@@ -977,7 +977,7 @@ public static PluginItemsParser parsePluginItems(BasicModule module, UploadPlugi
for (IdentityName p : plugins) {
desc = ((Describable) p).getDescriptor();
Descriptor.PluginValidateResult r = new Descriptor.PluginValidateResult(new Descriptor.PostFormVals(desc,
- module, AttrValMap.IAttrVals.rootForm(Collections.emptyMap())), pluginIndex, newAddItemsCount++);
+ module, context, AttrValMap.IAttrVals.rootForm(Collections.emptyMap())), pluginIndex, newAddItemsCount++);
r.setDescriptor(desc);
identityUniqueMap.put(p.identityValue(), r);
}
diff --git a/tis-console/src/main/java/com/qlangtech/tis/manage/common/TisActionMapper.java b/tis-console/src/main/java/com/qlangtech/tis/manage/common/TisActionMapper.java
index 7bad80067..fad8258a8 100644
--- a/tis-console/src/main/java/com/qlangtech/tis/manage/common/TisActionMapper.java
+++ b/tis-console/src/main/java/com/qlangtech/tis/manage/common/TisActionMapper.java
@@ -1,23 +1,24 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.qlangtech.tis.manage.common;
import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.qlangtech.tis.realtime.transfer.UnderlineUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.mapper.DefaultActionMapper;
@@ -53,25 +54,25 @@ protected void parseNameAndNamespace(String uri, ActionMapping mapping, Configur
public static StringBuffer addUnderline(String value) {
- //return UnderlineUtils.addUnderline(value);
- StringBuffer parsedName = new StringBuffer();
- char[] nameAry = value.toCharArray();
- boolean firstAppend = true;
- for (int i = 0; i < nameAry.length; i++) {
- if (Character.isUpperCase(nameAry[i])) {
- if (firstAppend) {
- parsedName.append(Character.toLowerCase(nameAry[i]));
- firstAppend = false;
- } else {
- parsedName.append('_').append(Character.toLowerCase(nameAry[i]));
- }
- } else {
- parsedName.append(nameAry[i]);
- firstAppend = false;
- // .append(Character.toLowerCase());
- }
- }
- return parsedName;
+ return UnderlineUtils.addUnderline(value);
+// StringBuffer parsedName = new StringBuffer();
+// char[] nameAry = value.toCharArray();
+// boolean firstAppend = true;
+// for (int i = 0; i < nameAry.length; i++) {
+// if (Character.isUpperCase(nameAry[i])) {
+// if (firstAppend) {
+// parsedName.append(Character.toLowerCase(nameAry[i]));
+// firstAppend = false;
+// } else {
+// parsedName.append('_').append(Character.toLowerCase(nameAry[i]));
+// }
+// } else {
+// parsedName.append(nameAry[i]);
+// firstAppend = false;
+// // .append(Character.toLowerCase());
+// }
+// }
+// return parsedName;
}
diff --git a/tis-console/src/main/java/com/qlangtech/tis/util/PluginItems.java b/tis-console/src/main/java/com/qlangtech/tis/util/PluginItems.java
index f6103e10e..2d27c6238 100644
--- a/tis-console/src/main/java/com/qlangtech/tis/util/PluginItems.java
+++ b/tis-console/src/main/java/com/qlangtech/tis/util/PluginItems.java
@@ -67,6 +67,7 @@ public class PluginItems {
private final IPluginEnum heteroEnum;
private final UploadPluginMeta pluginMeta;
private final IPluginContext pluginContext;
+ private final Context context;
public List items;
@@ -78,7 +79,7 @@ public static void addPluginItemsSaveObserver(PluginItemsSaveObserver obsv) {
observable.addObserver(obsv);
}
- public PluginItems(IPluginContext pluginContext, UploadPluginMeta pluginMeta) {
+ public PluginItems(IPluginContext pluginContext, Context context, UploadPluginMeta pluginMeta) {
this.heteroEnum = pluginMeta.getHeteroEnum();
this.pluginMeta = pluginMeta;
this.pluginContext = pluginMeta.isDisableBizSet() ? new AdapterPluginContext(pluginContext) {
@@ -87,6 +88,7 @@ public void setBizResult(Context context, Object result) {
//super.setBizResult(context, result);
}
} : pluginContext;
+ this.context = context;
}
@@ -383,7 +385,7 @@ private List> getPlugins(List descri
/**====================================================
* 将客户端POST数据包装
======================================================*/
- describable = attrValMap.createDescribable(pluginContext);
+ describable = attrValMap.createDescribable((IControlMsgHandler) pluginContext, this.context);
dlist.add(describable);
if (!describable.subFormFields) {
describableList.add((Describable) describable.getInstance());
diff --git a/tis-console/src/test/java/com/qlangtech/tis/util/TestPluginItems.java b/tis-console/src/test/java/com/qlangtech/tis/util/TestPluginItems.java
index d6e441169..25e3ed742 100644
--- a/tis-console/src/test/java/com/qlangtech/tis/util/TestPluginItems.java
+++ b/tis-console/src/test/java/com/qlangtech/tis/util/TestPluginItems.java
@@ -1,19 +1,19 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.qlangtech.tis.util;
@@ -157,6 +157,7 @@ private void validatePropertyValue(Map propertiesType, Str
private void validateSubFormSave() {
IPluginContext pluginContext = EasyMock.createMock("pluginContext", IPluginContext.class);
+
EasyMock.expect(pluginContext.isDataSourceAware()).andReturn(false);
EasyMock.expect(pluginContext.isCollectionAware()).andReturn(false).anyTimes();
EasyMock.expect(pluginContext.getRequestHeader(DataxReader.HEAD_KEY_REFERER)).andReturn("/x/" + dataXName + "/config").times(2);
@@ -165,7 +166,7 @@ private void validateSubFormSave() {
Optional subFormFilter = subFieldPluginMeta.getSubFormFilter();
assertTrue("subFormFilter.isPresent():true", subFormFilter.isPresent());
- PluginItems pluginItems = new PluginItems(pluginContext, subFieldPluginMeta);
+ PluginItems pluginItems = new PluginItems(pluginContext, context, subFieldPluginMeta);
IControlMsgHandler fieldErrorHandler = EasyMock.createMock("fieldErrorHandler", IControlMsgHandler.class);
JSONArray jsonArray = IOUtils.loadResourceFromClasspath(TestPluginItems.class
@@ -175,7 +176,7 @@ private void validateSubFormSave() {
JSONArray itemsArray = jsonArray.getJSONArray(0);
// Optional.empty();
- List items = AttrValMap.describableAttrValMapList( itemsArray, subFormFilter);
+ List items = AttrValMap.describableAttrValMapList(itemsArray, subFormFilter);
pluginItems.items = items;
EasyMock.replay(pluginContext, context, fieldErrorHandler);
@@ -195,7 +196,7 @@ private void validateRootFormSave() {
//targetDescriptorName_MySQL,subFormFieldName_selectedTabs
UploadPluginMeta pluginMeta = UploadPluginMeta.parse("dataxReader:require,dataxName_" + dataXName);
- PluginItems pluginItems = new PluginItems(pluginContext, pluginMeta);
+ PluginItems pluginItems = new PluginItems(pluginContext, context, pluginMeta);
IControlMsgHandler fieldErrorHandler = EasyMock.createMock("fieldErrorHandler", IControlMsgHandler.class);
JSONArray jsonArray = IOUtils.loadResourceFromClasspath(TestPluginItems.class, "datax_reader_mysql_post.json", true, (input) -> {
@@ -205,7 +206,7 @@ private void validateRootFormSave() {
JSONArray itemsArray = jsonArray.getJSONArray(0);
Optional subFormFilter = pluginMeta.getSubFormFilter();
assertFalse("subFormFilter.isPresent():false", subFormFilter.isPresent());
- List items = AttrValMap.describableAttrValMapList( itemsArray, subFormFilter);
+ List items = AttrValMap.describableAttrValMapList(itemsArray, subFormFilter);
pluginItems.items = items;
EasyMock.replay(pluginContext, context, fieldErrorHandler);
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/CMeta.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/CMeta.java
index 0bc5ee691..a5f4a3f56 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/CMeta.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/CMeta.java
@@ -181,7 +181,7 @@ public Class> getDescribleClass() {
return IdentityName.super.getDescribleClass();
}
- public static class ParsePostMCols {
+ public static class ParsePostMCols {
public List writerCols = Lists.newArrayList();
public boolean validateFaild = false;
public boolean pkHasSelected = false;
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/ElementCreatorFactory.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/ElementCreatorFactory.java
index 8fae68a26..901459607 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/ElementCreatorFactory.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/ElementCreatorFactory.java
@@ -22,11 +22,11 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qlangtech.tis.extension.IPropertyType;
-import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import java.util.function.BiConsumer;
-public interface ElementCreatorFactory {
+public interface ElementCreatorFactory {
/**
@@ -39,8 +39,8 @@ public interface ElementCreatorFactory {
* @return
*/
public CMeta.ParsePostMCols parsePostMCols(IPropertyType propertyType,
- IFieldErrorHandler msgHandler, Context context, String keyColsMeta,
- JSONArray targetCols);
+ IControlMsgHandler msgHandler, Context context, String keyColsMeta,
+ JSONArray targetCols);
default ViewContent getViewContentType() {
return ViewContent.MongoCols;
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IMultiElement.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IMultiElement.java
new file mode 100644
index 000000000..351370d0a
--- /dev/null
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IMultiElement.java
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.qlangtech.tis.plugin.ds;
+
+/**
+ *
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-16 08:44
+ **/
+public interface IMultiElement {
+ String getName();
+}
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IdlistElementCreatorFactory.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IdlistElementCreatorFactory.java
index fb77430d3..9862fd10d 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IdlistElementCreatorFactory.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/IdlistElementCreatorFactory.java
@@ -23,12 +23,11 @@
import com.alibaba.fastjson.JSONObject;
import com.qlangtech.tis.extension.IPropertyType;
import com.qlangtech.tis.plugin.ds.CMeta.ParsePostMCols;
-import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import java.util.function.BiConsumer;
/**
- *
* //@see com.qlangtech.tis.extension.util.MultiItemsViewType.ViewFormatType
*/
public class IdlistElementCreatorFactory implements ElementCreatorFactory {
@@ -50,7 +49,7 @@ public CMeta create(JSONObject targetCol, BiConsumer errorProces
@Override
public ParsePostMCols parsePostMCols(IPropertyType propertyType,
- IFieldErrorHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
- throw new UnsupportedOperationException();
+ IControlMsgHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
+ throw new UnsupportedOperationException();
}
}
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/TypeBase.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/TypeBase.java
index a55e0b430..7ff307ecc 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/TypeBase.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/plugin/ds/TypeBase.java
@@ -23,7 +23,7 @@
/**
* 有Jdbc类型相关的类型
*/
-public abstract class TypeBase implements JDBCColumnProp {
+public abstract class TypeBase implements JDBCColumnProp, IMultiElement {
private DataType type;
public final DataType getType() {
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/IControlMsgHandler.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/IControlMsgHandler.java
index 9fa41e6b7..cb8632fb3 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/IControlMsgHandler.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/IControlMsgHandler.java
@@ -17,6 +17,8 @@
*/
package com.qlangtech.tis.runtime.module.misc;
+import com.alibaba.citrus.turbine.Context;
+import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.runtime.module.action.IParamGetter;
import java.io.PrintWriter;
@@ -25,7 +27,67 @@
* @author 百岁(baisui@qlangtech.com)
* @date 2020/09/25
*/
-public interface IControlMsgHandler extends IFieldErrorHandler, IMessageHandler, IParamGetter {
+public interface IControlMsgHandler extends IFieldErrorHandler, IMessageHandler, IParamGetter, IDataXNameAware {
+
+ public static IControlMsgHandler namedContext(String collectionName) {
+ return new IControlMsgHandler() {
+ @Override
+ public PrintWriter getEventStreamWriter() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getCollectionName() {
+ return collectionName;
+ }
+
+ @Override
+ public String getString(String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getString(String key, String dftVal) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean getBoolean(String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addFieldError(Context context, String fieldName, String msg, Object... params) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean validateBizLogic(BizLogic logicType, Context context, String fieldName, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void errorsPageShow(Context context) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addActionMessage(Context context, String msg) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setBizResult(Context context, Object result, boolean overwriteable) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addErrorMessage(Context context, String msg) {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
/**
* 获得EventStream 类型的Writer,用于在UI流程中显示执行进度
*
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/AdaperControlMsgHandler.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/AdaperControlMsgHandler.java
new file mode 100644
index 000000000..e8e77f7ec
--- /dev/null
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/AdaperControlMsgHandler.java
@@ -0,0 +1,119 @@
+///**
+// * Licensed to the Apache Software Foundation (ASF) under one
+// * or more contributor license agreements. See the NOTICE file
+// * distributed with this work for additional information
+// * regarding copyright ownership. The ASF licenses this file
+// * to you under the Apache License, Version 2.0 (the
+// * "License"); you may not use this file except in compliance
+// * with the License. You may obtain a copy of the License at
+// *
+// * http://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+//
+//package com.qlangtech.tis.runtime.module.misc.impl;
+//
+//import com.alibaba.citrus.turbine.Context;
+//import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
+//import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+//
+//import java.io.PrintWriter;
+//
+///**
+// * @author: 百岁(baisui@qlangtech.com)
+// * @create: 2024-06-16 20:11
+// **/
+//public class AdaperControlMsgHandler implements IControlMsgHandler {
+//
+//
+//
+// private final IControlMsgHandler delegate;
+//
+// public AdaperControlMsgHandler(IFieldErrorHandler msgHandler) {
+// this((IControlMsgHandler) msgHandler);
+// }
+//
+// public AdaperControlMsgHandler(IControlMsgHandler delegate) {
+// this.delegate = delegate;
+// }
+//
+// @Override
+// public boolean getBoolean(String key) {
+// return delegate.getBoolean(key);
+// }
+//
+// @Override
+// public String getString(String key, String dftVal) {
+// return delegate.getString(key, dftVal);
+// }
+//
+// @Override
+// public String getString(String key) {
+// return delegate.getString(key);
+// }
+//
+// @Override
+// public String getRequestHeader(String key) {
+// return delegate.getRequestHeader(key);
+// }
+//
+// @Override
+// public void addErrorMessage(Context context, String msg) {
+// delegate.addErrorMessage(context, msg);
+// }
+//
+// @Override
+// public void setBizResult(Context context, Object result, boolean overwriteable) {
+// delegate.setBizResult(context, result, overwriteable);
+// }
+//
+// @Override
+// public void setBizResult(Context context, Object result) {
+// delegate.setBizResult(context, result);
+// }
+//
+// @Override
+// public void addActionMessage(Context context, String msg) {
+// delegate.addActionMessage(context, msg);
+// }
+//
+// @Override
+// public void errorsPageShow(Context context) {
+// delegate.errorsPageShow(context);
+// }
+//
+// @Override
+// public boolean validateBizLogic(BizLogic logicType, Context context, String fieldName, String value) {
+// return delegate.validateBizLogic(logicType, context, fieldName, value);
+// }
+//
+// @Override
+// public void addFieldError(Context context, String fieldName, String msg, Object... params) {
+// delegate.addFieldError(context, fieldName, msg, params);
+// }
+//
+//
+// @Override
+// public PrintWriter getEventStreamWriter() {
+// return delegate.getEventStreamWriter();
+// }
+// @Override
+// public String getTISDataXName() {
+// return delegate.getTISDataXName();
+// }
+//
+// @Override
+// public String getCollectionName() {
+// return delegate.getCollectionName();
+// }
+//
+// @Override
+// public boolean isCollectionAware() {
+// return delegate.isCollectionAware();
+// }
+//}
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/BasicDelegateMsgHandler.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/BasicDelegateMsgHandler.java
index a7e0dd5d0..00d7a32c1 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/BasicDelegateMsgHandler.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/runtime/module/misc/impl/BasicDelegateMsgHandler.java
@@ -19,6 +19,9 @@
import com.alibaba.citrus.turbine.Context;
import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
+import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+
+import java.io.PrintWriter;
/**
* @author 百岁(baisui@qlangtech.com)
@@ -26,19 +29,24 @@
*/
public abstract class BasicDelegateMsgHandler implements IControlMsgHandler {
+
private final IControlMsgHandler delegate;
public BasicDelegateMsgHandler(IControlMsgHandler delegate) {
this.delegate = delegate;
}
+ public BasicDelegateMsgHandler(IFieldErrorHandler msgHandler) {
+ this((IControlMsgHandler) msgHandler);
+ }
+
@Override
public boolean validateBizLogic(BizLogic logicType, Context context, String fieldName, String value) {
throw new UnsupportedOperationException();
}
@Override
- public final void addFieldError(Context context, String fieldName, String msg, Object... params) {
+ public void addFieldError(Context context, String fieldName, String msg, Object... params) {
delegate.addFieldError(context, fieldName, msg, params);
}
@@ -61,4 +69,39 @@ public final void setBizResult(Context context, Object result, boolean overwrite
public final void addErrorMessage(Context context, String msg) {
delegate.addErrorMessage(context, msg);
}
+
+ @Override
+ public boolean isCollectionAware() {
+ return delegate.isCollectionAware();
+ }
+
+ @Override
+ public String getCollectionName() {
+ return delegate.getCollectionName();
+ }
+
+ @Override
+ public String getTISDataXName() {
+ return delegate.getTISDataXName();
+ }
+
+ @Override
+ public PrintWriter getEventStreamWriter() {
+ return delegate.getEventStreamWriter();
+ }
+
+ @Override
+ public String getString(String key) {
+ return delegate.getString(key);
+ }
+
+ @Override
+ public String getString(String key, String dftVal) {
+ return delegate.getString(key, dftVal);
+ }
+
+ @Override
+ public boolean getBoolean(String key) {
+ return delegate.getBoolean(key);
+ }
}
diff --git a/tis-manage-pojo/src/main/java/com/qlangtech/tis/util/DescriptorsJSONResult.java b/tis-manage-pojo/src/main/java/com/qlangtech/tis/util/DescriptorsJSONResult.java
index ea9cd22bb..9172975fe 100644
--- a/tis-manage-pojo/src/main/java/com/qlangtech/tis/util/DescriptorsJSONResult.java
+++ b/tis-manage-pojo/src/main/java/com/qlangtech/tis/util/DescriptorsJSONResult.java
@@ -41,11 +41,11 @@ public static T getRootDescInstance() {
return (T) Objects.requireNonNull(rootDescriptorLocal.get(), "rootDescriptorLocal element can not be null");
}
- Map> descs = Maps.newHashMap();
+ Map> descs = Maps.newHashMap();
/**
* 由于describe 可以嵌套,此标志位可以判断 是否是根元素
*/
- final boolean rootDesc;
+ final boolean rootDesc;
public DescriptorsJSONResult(boolean rootDesc) {
this.rootDesc = rootDesc;
@@ -56,9 +56,9 @@ public void addDesc(String id, JSONObject descJson, Object desc) {
}
-
public JSONObject getJSONObject(String descId) {
return Objects.requireNonNull(descs.get(descId)
, "descId:" + descId + " relevant desc can not be null").getLeft();
}
+
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IConsumerHandle.java b/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IConsumerHandle.java
index 4f935944d..bcb711c9a 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IConsumerHandle.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IConsumerHandle.java
@@ -1,19 +1,19 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.qlangtech.tis.async.message.client.consumer;
@@ -31,5 +31,6 @@ public interface IConsumerHandle {
*
* @param asyncMsg
*/
- FLINK_RESULT consume(TargetResName dataxName, AsyncMsg asyncMsg, IDataxProcessor dataXProcessor) throws Exception;
+ FLINK_RESULT consume(TargetResName dataxName, AsyncMsg asyncMsg
+ , IDataxProcessor dataXProcessor, IFlinkColCreator flinkColCreator) throws Exception;
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IFlinkColCreator.java b/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IFlinkColCreator.java
new file mode 100644
index 000000000..4d1554fbb
--- /dev/null
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/async/message/client/consumer/IFlinkColCreator.java
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.qlangtech.tis.async.message.client.consumer;
+
+import com.qlangtech.tis.plugin.ds.IColMetaGetter;
+
+/**
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-19 11:05
+ **/
+public interface IFlinkColCreator {
+ FlinkColType build(IColMetaGetter meta, int colIndex);
+}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/datax/impl/DataXCfgGenerator.java b/tis-plugin/src/main/java/com/qlangtech/tis/datax/impl/DataXCfgGenerator.java
index b67f4a247..22d1183ab 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/datax/impl/DataXCfgGenerator.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/datax/impl/DataXCfgGenerator.java
@@ -18,6 +18,7 @@
package com.qlangtech.tis.datax.impl;
+import com.alibaba.datax.core.util.container.TransformerConstant;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -28,6 +29,7 @@
import com.qlangtech.tis.datax.DBDataXChildTask;
import com.qlangtech.tis.datax.DataXCfgFile;
import com.qlangtech.tis.datax.DataXJobInfo;
+import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.datax.IDataXPluginMeta;
import com.qlangtech.tis.datax.IDataxContext;
import com.qlangtech.tis.datax.IDataxGlobalCfg;
@@ -40,6 +42,7 @@
import com.qlangtech.tis.manage.common.TisUTF8;
import com.qlangtech.tis.offline.DataxUtils;
import com.qlangtech.tis.plugin.datax.CreateTableSqlBuilder;
+import com.qlangtech.tis.plugin.datax.transformer.RecordTransformerRules;
import com.qlangtech.tis.plugin.ds.CMeta;
import com.qlangtech.tis.plugin.ds.ISelectedTab;
import com.qlangtech.tis.plugin.trigger.JobTrigger;
@@ -70,7 +73,7 @@
* @author: baisui 百岁
* @create: 2021-04-20 18:06
**/
-public class DataXCfgGenerator {
+public class DataXCfgGenerator implements IDataXNameAware {
private transient static final VelocityEngine velocityEngine;
@@ -95,6 +98,11 @@ public class DataXCfgGenerator {
private final String dataxName;
private final IPluginContext pluginCtx;
+ @Override
+ public String getCollectionName() {
+ return this.dataxName;
+ }
+
public DataXCfgGenerator(IPluginContext pluginCtx, String dataxName, IDataxProcessor dataxProcessor) {
Objects.requireNonNull(dataxProcessor, "dataXprocessor can not be null");
IDataxGlobalCfg dataXGlobalCfg = dataxProcessor.getDataXGlobalCfg();
@@ -105,22 +113,35 @@ public DataXCfgGenerator(IPluginContext pluginCtx, String dataxName, IDataxProce
this.pluginCtx = pluginCtx;
}
- protected String getTemplateContent(IDataxReader reader, IDataxWriter writer) {
+ protected String getTemplateContent(IDataxReaderContext readerContext, IDataxReader reader, IDataxWriter writer) {
final String tpl = globalCfg.getTemplate();
// List readers = dataxProcessor.getReaders(pluginCtx);
// for (IDataxReader reader : readers) {
//IDataxReader reader = dataxProcessor.getReader(pluginCtx);
// IDataxWriter writer = dataxProcessor.getWriter(pluginCtx);
- String readerTpl = reader.getTemplate();
- String writerTpl = writer.getTemplate();
- if (StringUtils.isEmpty(readerTpl)) {
+ if (StringUtils.isEmpty(reader.getTemplate())) {
throw new IllegalStateException("readerTpl of '" + reader.getDataxMeta().getName() + "' can not be null");
}
+ StringBuffer readerTpl = new StringBuffer(reader.getTemplate());
+ String writerTpl = writer.getTemplate();
+
if (StringUtils.isEmpty(writerTpl)) {
throw new IllegalStateException("writerTpl of '" + writer.getDataxMeta().getName() + "' can not be null");
}
- String template = StringUtils.replace(tpl, "", readerTpl);
+
+ RecordTransformerRules transformerRules
+ = RecordTransformerRules.loadTransformerRules(this, readerContext.getSourceEntityName());
+ if (transformerRules != null) {
+ readerTpl.append(",\n\t\"")
+ .append(TransformerConstant.JOB_TRANSFORMER).append("\":\t\t\n {\"").append(TransformerConstant.JOB_TRANSFORMER_NAME)
+ .append("\":\"").append(readerContext.getSourceEntityName()).append("\",\n\"")
+ .append(TransformerConstant.JOB_TRANSFORMER_RELEVANT_KEYS).append("\":").append("[")
+ .append(transformerRules.relevantColKeys().stream().map((col) -> "\"" + col + "\"").collect(Collectors.joining(",")))
+ .append("]").append("}");
+ }
+
+ String template = StringUtils.replace(tpl, "", readerTpl.toString());
template = StringUtils.replace(template, "", writerTpl);
return template;
// }
@@ -306,6 +327,7 @@ public GenerateCfgs startGenerateCfg(IGenerateScriptFile scriptFileGenerator) th
return cfgs;
}
+
public interface IGenerateScriptFile {
void generateScriptFile(IDataxReader reader, IDataxWriter writer, IDataxReaderContext readerContext,
Set createDDLFiles, Optional tableMapper) throws IOException;
@@ -540,7 +562,9 @@ public String generateDataxConfig(
Optional tableMap) throws IOException {
Objects.requireNonNull(writer, "writer can not be null");
StringWriter writerContent = null;
- final String tpl = getTemplateContent(reader, writer);
+
+
+ final String tpl = getTemplateContent(readerContext, reader, writer);
if (StringUtils.isEmpty(tpl)) {
throw new IllegalStateException("velocity template content can not be null");
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/extension/Descriptor.java b/tis-plugin/src/main/java/com/qlangtech/tis/extension/Descriptor.java
index 022e5c0a4..6e55d2a40 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/extension/Descriptor.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/extension/Descriptor.java
@@ -18,6 +18,7 @@
package com.qlangtech.tis.extension;
import com.alibaba.citrus.turbine.Context;
+import com.alibaba.citrus.turbine.impl.DefaultContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -47,6 +48,7 @@
import com.qlangtech.tis.plugin.annotation.SubForm;
import com.qlangtech.tis.plugin.annotation.Validator;
import com.qlangtech.tis.plugin.ds.CMeta;
+import com.qlangtech.tis.plugin.ds.IMultiElement;
import com.qlangtech.tis.plugin.ds.ISelectedTab;
import com.qlangtech.tis.plugin.ds.TypeBase;
import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
@@ -478,7 +480,15 @@ public final PluginValidateResult verify(IControlMsgHandler msgHandler, Context
, boolean verify //
, AttrVals formData, Optional pTypes, Optional subFormFilter) {
-
+ if (context == null) {
+ throw new IllegalArgumentException("param contenxt can not be null");
+ }
+ if (msgHandler == null) {
+ throw new IllegalArgumentException("param msgHandler can not be null");
+ }
+ if (msgHandler == null) {
+ throw new IllegalArgumentException("formData msgHandler can not be null");
+ }
try {
// IRepositoryTargetFile.TARGET_FILE_CONTEXT.set(targetFile);
// final PluginFormProperties /** * fieldname */
@@ -490,7 +500,7 @@ public final PluginValidateResult verify(IControlMsgHandler msgHandler, Context
@Override
public PluginValidateResult visit(RootFormProperties props) {
- PostFormVals postFormVals = new PostFormVals(Descriptor.this, props, subFormFilter, msgHandler, formData);
+ PostFormVals postFormVals = new PostFormVals(Descriptor.this, props, subFormFilter, msgHandler, context, formData);
PluginValidateResult validateResult = new PluginValidateResult(postFormVals,
(Integer) context.get(DefaultFieldErrorHandler.KEY_VALIDATE_PLUGIN_INDEX),
@@ -498,6 +508,7 @@ public PluginValidateResult visit(RootFormProperties props) {
boolean valid = validatePostFormVals(postFormVals, Optional.empty());
validateResult.valid = valid;
+ validateResult.setDescriptor(Descriptor.this);
return validateResult;
}
@@ -543,7 +554,7 @@ public PluginValidateResult visit(BaseSubFormProperties props) {
if (filter.subformDetailView) {
// 校验的时候子表单是{key1:val1,key2:val2} 的格式
- PostFormVals formVals = new PostFormVals(Descriptor.this, props, subFormFilter, msgHandler, formData);
+ PostFormVals formVals = new PostFormVals(Descriptor.this, props, subFormFilter, msgHandler, context, formData);
// boolean valid = isValid(msgHandler, context, verify, subFormFilter, propertyTypes, formVals);
boolean valid = validatePostFormVals(formVals, subFormFilter);
if (!valid) {
@@ -829,7 +840,7 @@ public PostFormVals getItemForm() {
return this.itemForm;
}
- public T newInstance(IControlMsgHandler msgHandler) {
+ public T newInstance() {
if (this.descriptor == null) {
throw new IllegalStateException("descriptor can not be null");
}
@@ -873,17 +884,17 @@ private void addFieldRequiredError(IFieldErrorHandler msgHandler, Context contex
}
- public ParseDescribable newInstance(IPluginContext pluginContext, //
+ public ParseDescribable newInstance(IControlMsgHandler pluginContext, Context context, //
FormData formData //
) {
- return newInstance(pluginContext, formData, Optional.empty());
+ return newInstance(pluginContext, context, formData, Optional.empty());
}
public ParseDescribable newInstance(String appName, //
FormData formData //
) {
- return newInstance(IPluginContext.namedContext(appName), formData, Optional.empty());
+ return newInstance(IControlMsgHandler.namedContext(appName), new DefaultContext(), formData, Optional.empty());
}
public static class FormData extends AttrVals {
@@ -916,11 +927,11 @@ public JSONObject addSubForm(String key, String formImpl, FormData form) {
}
}
- public ParseDescribable newInstance(IPluginContext pluginContext, //
+ public ParseDescribable newInstance(IControlMsgHandler pluginContext, Context context, //
AttrValMap.IAttrVals formData, //
Optional subFormFilter) {
try {
- return parseDescribable(pluginContext, formData, Optional.empty(), subFormFilter);
+ return parseDescribable(pluginContext, context, formData, Optional.empty(), subFormFilter);
} catch (Exception e) {
throw new RuntimeException("class:" + this.clazz.getName(), e);
}
@@ -931,8 +942,8 @@ public ParseDescribable newInstance(IPluginContext pluginContext, /
// return parseDescribable(pluginContext, keyValMap, , subFormFilter);
// }
- public ParseDescribable parseDescribable(IPluginContext pluginContext
- , AttrValMap.IAttrVals keyValMap, Optional pTypes, Optional subFormFilter) {
+ public ParseDescribable parseDescribable(IControlMsgHandler pluginContext
+ , Context context, AttrValMap.IAttrVals keyValMap, Optional pTypes, Optional subFormFilter) {
PluginFormProperties propertyTypes = getPropertyTypes(pTypes, subFormFilter);
@@ -947,7 +958,7 @@ public ParseDescribable visit(RootFormProperties props) {
private ParseDescribable createPluginInstance() {
try {
ParseDescribable result = new ParseDescribable<>(clazz.newInstance());
- Descriptor.this.buildPluginInstance(pluginContext, keyValMap.asRootFormVals(), result,
+ Descriptor.this.buildPluginInstance(pluginContext, context, keyValMap.asRootFormVals(), result,
propertyTypes);
return result;
} catch (Exception e) {
@@ -984,7 +995,7 @@ public ParseDescribable visit(BaseSubFormProperties props) {
props.visitAllSubDetailed(null, keyValMap, new SuFormProperties.ISubDetailedProcess() {
public Void process(String subFormId, AttrValMap attrVals) {
- ParseDescribable r = attrVals.createDescribable(pluginContext, Optional.of(props.convertRootFormProps()));
+ ParseDescribable r = attrVals.createDescribable(pluginContext, context, Optional.of(props.convertRootFormProps()));
Describable plugin = setParentPluginClass(r);
// if (plugin instanceof IParentHostPluginAware) {
@@ -1034,8 +1045,9 @@ private PluginFormProperties getPropertyTypes(Optional pTy
});
}
- private > TARGET buildPluginInstance(IPluginContext pluginContext, Map keyValMap, ParseDescribable result, PluginFormProperties propertyTypes) {
+ private > TARGET buildPluginInstance(IControlMsgHandler pluginContext, Context context //
+ , Map keyValMap //
+ , ParseDescribable result, PluginFormProperties propertyTypes) {
TARGET describable = result.getInstance();
String attr;
PropertyType attrDesc;
@@ -1049,7 +1061,7 @@ private > TARGET buildPluginInstance(IPluginC
valJ = keyValMap.get(attr);
// attrDesc.getExtraProps(PluginExtraProps.KEY_DISABLE);
if (valJ == null && attrDesc.isInputRequired()) {
- throw new IllegalStateException("prop:" + attr + " can not be empty");
+ throw new IllegalStateException("prop:" + attr + " can not be empty,desc :" + this.clazz.getSimpleName());
}
if (valJ == null) {
valJ = new JSONObject();
@@ -1062,14 +1074,14 @@ private > TARGET buildPluginInstance(IPluginC
if (descriptor == null) {
throw new IllegalStateException("impl:" + impl + " relevant descripotor can not be null");
}
- ParseDescribable vals = descriptor.newInstance(pluginContext,
+ ParseDescribable vals = descriptor.newInstance(pluginContext, context,
parseAttrValMap(descVal.get(AttrValMap.PLUGIN_EXTENSION_VALS)), Optional.empty());
attrDesc.setVal(describable, vals.getInstance());
} else {
if (attrDesc.typeIdentity() == FormFieldType.MULTI_SELECTABLE.getIdentity()) {
- List selectedItems = getSelectedMultiItems(null, null, attrDesc, valJ);
- List multi = selectedItems.stream().filter((item) -> item.isChecked()).map((item) -> {
+ List selectedItems = getSelectedMultiItems(pluginContext, context, attrDesc, valJ);
+ List multi = selectedItems.stream().filter((item) -> item.isChecked()).map((item) -> {
if (item.getCmeta() != null) {
return item.getCmeta();
} else {
@@ -1083,7 +1095,7 @@ private > TARGET buildPluginInstance(IPluginC
if (attrDesc.isCollectionType()) {
attrDesc.setVal(describable, multi);
} else {
- for (TypeBase type : multi) {
+ for (IMultiElement type : multi) {
attrDesc.setVal(describable, type);
}
}
@@ -1094,7 +1106,7 @@ private > TARGET buildPluginInstance(IPluginC
valJ.containsKey(KEY_primaryVal) && StringUtils.isNotBlank(valJ.getString(KEY_primaryVal));
// describable
if (!containVal && attrDesc.isInputRequired()) {
- throw new IllegalStateException("prop:" + attr + " can not be empty ,descriptor:" + describable.getDescriptor());
+ throw new IllegalStateException("prop:" + attr + " can not be empty ,descriptor:" + this.clazz.getSimpleName());
}
if (containVal) {
attrVal = valJ.get(KEY_primaryVal);
@@ -1185,7 +1197,18 @@ public static AttrVals parseAttrValMap(Object vals) {
// Object vals = jsonObject.get("vals");
if (vals instanceof Map) {
((Map) vals).forEach((attrName, val) -> {
- attrValMap.put(attrName, (JSON) val);
+ try {
+ attrValMap.put(attrName, (JSON) val);
+ } catch (Exception e) {
+ // 在multiSelectItem的场景下,可能存在提交的itemProperty没有使用‘ItemPropVal’包装的情况
+ if (val instanceof String) {
+ JSONObject o = new JSONObject();
+ o.put(Descriptor.KEY_primaryVal, val);
+ attrValMap.put(attrName, o);
+ } else {
+ throw new RuntimeException("attrName:" + attrName + ",valType:" + val.getClass().getSimpleName(), e);
+ }
+ }
});
}
return new AttrVals(attrValMap);
@@ -1308,6 +1331,7 @@ public static class PostFormVals {
private final Optional subFormFilter;
private final IControlMsgHandler msgHandler;
+ private final Context context;
private Describable instance;
@@ -1315,7 +1339,7 @@ public T newInstance() {
if (instance == null) {
ParseDescribable plugin = desc.parseDescribable(
- (IPluginContext) msgHandler, this.rawFormData, Optional.of(this.formProperties), subFormFilter);
+ msgHandler, this.context, this.rawFormData, Optional.of(this.formProperties), subFormFilter);
// ParseDescribable plugin = desc.newInstance((IPluginContext) msgHandler, this.rawFormData
// , Optional.empty());
@@ -1325,19 +1349,20 @@ public T newInstance() {
}
public PostFormVals(Descriptor desc //
- , IControlMsgHandler msgHandler, AttrValMap.IAttrVals rawFormData) {
+ , IControlMsgHandler msgHandler, Context context, AttrValMap.IAttrVals rawFormData) {
// Optional subFormFilter = Optional.empty();
- this(desc, desc.getPluginFormPropertyTypes(Optional.empty()), Optional.empty(), msgHandler, rawFormData);
+ this(desc, desc.getPluginFormPropertyTypes(Optional.empty()), Optional.empty(), msgHandler, context, rawFormData);
}
public PostFormVals(Descriptor desc, PluginFormProperties formProperties //
, Optional subFormFilter //
- , IControlMsgHandler msgHandler, AttrValMap.IAttrVals rawFormData) {
+ , IControlMsgHandler msgHandler, Context context, AttrValMap.IAttrVals rawFormData) {
this.rawFormData = rawFormData;
this.desc = desc;
this.formProperties = formProperties;
this.subFormFilter = subFormFilter;
this.msgHandler = msgHandler;
+ this.context = context;
}
private Map fieldVals = Maps.newHashMap();
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/extension/util/MultiItemsViewType.java b/tis-plugin/src/main/java/com/qlangtech/tis/extension/util/MultiItemsViewType.java
index 91aba49fc..68e93df38 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/extension/util/MultiItemsViewType.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/extension/util/MultiItemsViewType.java
@@ -32,10 +32,14 @@
import com.qlangtech.tis.plugin.ds.IdlistElementCreatorFactory;
import com.qlangtech.tis.plugin.ds.ViewContent;
import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
+import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.BeanUtilsBean2;
+import org.apache.commons.beanutils.PropertyUtilsBean;
import org.apache.commons.lang.StringUtils;
+import java.beans.PropertyDescriptor;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
@@ -112,7 +116,14 @@ public void appendExternalJsonProp(JSONObject biz) {
public List getElementPropertyKeys() {
if (elementPropertyKeys == null) {
try {
- elementPropertyKeys = Lists.newArrayList(BeanUtilsBean2.getInstance().describe(tupleFactory.createDefault()).keySet());
+// BeanUtilsBean.getInstance().getPropertyUtils()
+// PropertyUtilsBean
+ PropertyDescriptor[] propertyDescs = BeanUtilsBean2.getInstance().getPropertyUtils().getPropertyDescriptors(tupleFactory.createDefault());
+ elementPropertyKeys = Lists.newArrayList();
+ for (PropertyDescriptor desc : propertyDescs) {
+ elementPropertyKeys.add(desc.getName());
+ }
+ elementPropertyKeys = Collections.unmodifiableList(this.elementPropertyKeys);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -193,7 +204,7 @@ public enum ViewFormatType {
// String keyColsMeta = StringUtils.EMPTY;
JSONArray mcols = eprops.getJSONObject(Descriptor.KEY_ENUM_PROP).getJSONArray("_mcols");
- CMeta.ParsePostMCols> parsePostMCols = elementCreator.parsePostMCols(attrDesc,msgHandler, context, attrDesc.f.getName(), mcols);
+ CMeta.ParsePostMCols> parsePostMCols = elementCreator.parsePostMCols(attrDesc, msgHandler, context, attrDesc.f.getName(), mcols);
if (parsePostMCols.validateFaild) {
return Collections.emptyList();
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/PluginAndCfgsSnapshot.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/PluginAndCfgsSnapshot.java
index d5ad50ed0..d2ece67ed 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/PluginAndCfgsSnapshot.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/PluginAndCfgsSnapshot.java
@@ -23,6 +23,7 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.qlangtech.tis.TIS;
+import com.qlangtech.tis.async.message.client.consumer.IFlinkColCreator;
import com.qlangtech.tis.async.message.client.consumer.impl.MQListenerFactory;
import com.qlangtech.tis.config.flink.IFlinkCluster;
import com.qlangtech.tis.coredefine.module.action.TargetResName;
@@ -38,6 +39,7 @@
import com.qlangtech.tis.manage.common.HttpUtils;
import com.qlangtech.tis.manage.common.TisUTF8;
import com.qlangtech.tis.maven.plugins.tpi.PluginClassifier;
+import com.qlangtech.tis.plugin.ds.IColMetaGetter;
import com.qlangtech.tis.plugin.incr.TISSinkFactory;
import com.qlangtech.tis.trigger.util.JsonUtil;
import com.qlangtech.tis.util.HeteroEnum;
@@ -306,7 +308,12 @@ public static Manifest createFlinkIncrJobManifestCfgAttrs(TargetResName collecti
// 先收集plugmeta,特别是通过dataXWriter的dataSource关联的元数据
IDataxProcessor processor = DataxProcessor.load(null, resourceType, collection.getName());
TISSinkFactory incrSinKFactory = TISSinkFactory.getIncrSinKFactory(collection.getName());
- incrSinKFactory.createSinkFunction(processor);
+ incrSinKFactory.createSinkFunction(processor, new IFlinkColCreator(){
+ @Override
+ public Object build(IColMetaGetter meta, int colIndex) {
+ return null;
+ }
+ });
});
return createFlinkIncrJobManifestCfgAttrs(resourceType, collection, timestamp, pluginMetas);
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/annotation/FormFieldType.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/annotation/FormFieldType.java
index 1af19f819..612dafb74 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/annotation/FormFieldType.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/annotation/FormFieldType.java
@@ -23,6 +23,7 @@
import com.qlangtech.tis.extension.impl.PropertyType;
import com.qlangtech.tis.extension.impl.PropertyType.PropVal;
import com.qlangtech.tis.manage.common.Option;
+import com.qlangtech.tis.plugin.ds.IMultiElement;
import com.qlangtech.tis.plugin.ds.TypeBase;
import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
import org.apache.commons.lang.StringUtils;
@@ -202,7 +203,7 @@ public static class SelectedItem extends Option {
// 是否选中了
private boolean checked;
- private TypeBase cmeta;
+ private IMultiElement cmeta;
public SelectedItem(String name, String value, boolean checked) {
super(name, value);
@@ -210,13 +211,13 @@ public SelectedItem(String name, String value, boolean checked) {
this.checked = checked;
}
- public SelectedItem(TypeBase cmeta) {
+ public SelectedItem(IMultiElement cmeta) {
this(cmeta.getName(), cmeta.getName(), true // !cmeta.isDisable()
);
this.cmeta = cmeta;
}
- public TypeBase getCmeta() {
+ public IMultiElement getCmeta() {
return cmeta;
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformer.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformer.java
index 5989aa477..0a27ceb35 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformer.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformer.java
@@ -18,24 +18,22 @@
package com.qlangtech.tis.plugin.datax.transformer;
-import com.qlangtech.tis.plugin.ds.TypeBase;
+import com.qlangtech.tis.plugin.ds.IMultiElement;
/**
* 定义一条 记录处理规则
*/
-public class RecordTransformer extends TypeBase {
+public class RecordTransformer implements IMultiElement {
-
- public final String getName() {
- // return target;
- return null;
+ @Override
+ public String getName() {
+ return "transformer-rule";
}
/**
* 自定义规则
*/
private UDFDefinition udf;
- // private String target;
public UDFDefinition getUdf() {
return udf;
@@ -44,12 +42,4 @@ public UDFDefinition getUdf() {
public void setUdf(UDFDefinition udf) {
this.udf = udf;
}
-
-// public String getTarget() {
-// return target;
-// }
-//
-// public void setTarget(String target) {
-// this.target = target;
-// }
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformerRules.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformerRules.java
index 5bbf43e3a..4722bd6b8 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformerRules.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/RecordTransformerRules.java
@@ -19,18 +19,24 @@
package com.qlangtech.tis.plugin.datax.transformer;
import com.google.common.collect.Lists;
+import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.extension.Describable;
import com.qlangtech.tis.extension.Descriptor;
import com.qlangtech.tis.extension.TISExtension;
-import com.qlangtech.tis.plugin.IdentityName;
+import com.qlangtech.tis.extension.impl.SuFormProperties;
import com.qlangtech.tis.plugin.annotation.FormField;
import com.qlangtech.tis.plugin.annotation.FormFieldType;
import com.qlangtech.tis.plugin.annotation.Validator;
-import com.qlangtech.tis.plugin.datax.transformer.impl.CopyValUDF;
-import com.qlangtech.tis.plugin.ds.DataType;
+import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
+import com.qlangtech.tis.util.HeteroEnum;
+import com.qlangtech.tis.util.IPluginContext;
+import com.qlangtech.tis.util.UploadPluginMeta;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* 为一条记录Record定义的 Transformer 转化规则
@@ -38,17 +44,56 @@
* @author: 百岁(baisui@qlangtech.com)
* @create: 2023-05-07 12:35
**/
-public class RecordTransformerRules implements Describable, IdentityName {
+public class RecordTransformerRules implements Describable {
- @FormField(ordinal = 0, identity = true, type = FormFieldType.INPUTTEXT, validate = {Validator.require})
- public String name;
+
+ public static Function transformerRulesLoader4Test;
+
+ /**
+ * 加载基于数据通道的表转换(Transformer)规则
+ *
+ * @param collectionName
+ * @param tableName
+ * @return
+ */
+ public static RecordTransformerRules loadTransformerRules(IDataXNameAware collectionName, String tableName) {
+
+ if (StringUtils.isEmpty(tableName)) {
+ throw new IllegalArgumentException("param tableName can not be empty");
+ }
+
+ if (transformerRulesLoader4Test != null) {
+ return transformerRulesLoader4Test.apply(tableName);
+ }
+
+ String rawContent = HeteroEnum.TRANSFORMER_RULES.identity + ":require,"
+ + SuFormProperties.SuFormGetterContext.FIELD_SUBFORM_ID + "_" + tableName;
+
+
+ for (RecordTransformerRules trule
+ : HeteroEnum.TRANSFORMER_RULES.getPlugins(
+ IPluginContext.namedContext(Objects.requireNonNull(collectionName, "collectionName can not be null").getTISDataXName())
+ , UploadPluginMeta.parse(rawContent))) {
+ return trule;
+ }
+
+ return null;
+ }
@FormField(ordinal = 1, type = FormFieldType.MULTI_SELECTABLE, validate = {Validator.require})
public List rules = Lists.newArrayList();
- @Override
- public String identityValue() {
- return this.name;
+ /**
+ * udf集合相关的列
+ *
+ * @return
+ */
+ public final List relevantColKeys() {
+ return this.rules.stream().flatMap((r) -> r.getUdf().outParameters().stream().map((tcol) -> tcol.getName())).collect(Collectors.toList());
+ }
+
+ public final List relevantTypedColKeys() {
+ return this.rules.stream().flatMap((r) -> r.getUdf().outParameters().stream()).collect(Collectors.toList());
}
public static List getRules() {
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/TargetColumn.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/TargetColumn.java
index 76f69515a..fb11d1c73 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/TargetColumn.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/TargetColumn.java
@@ -32,8 +32,15 @@
* @author: 百岁(baisui@qlangtech.com)
* @create: 2024-06-09 13:43
**/
+
public abstract class TargetColumn implements Describable, AfterPluginSaved, PluginLiteriaDesc, IdentityName {
+ /**
+ * 是否是虚拟列(通过原表记录值计算之后新增加的列)
+ *
+ * @return
+ */
+ public abstract boolean isVirtual();
public abstract String getName();
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDefinition.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDefinition.java
index b8baa3587..b891c6f39 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDefinition.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDefinition.java
@@ -19,28 +19,52 @@
package com.qlangtech.tis.plugin.datax.transformer;
import com.alibaba.citrus.turbine.Context;
+import com.alibaba.datax.common.element.ColumnAwareRecord;
+import com.alibaba.datax.common.element.Record;
import com.alibaba.fastjson2.annotation.JSONField;
import com.qlangtech.tis.extension.Describable;
import com.qlangtech.tis.extension.Descriptor;
import com.qlangtech.tis.plugin.IPluginStore.AfterPluginSaved;
+import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
import com.qlangtech.tis.util.IPluginContext;
+import java.io.Serializable;
import java.util.List;
import java.util.Optional;
/**
* DataX 的UDF 定义
* https://github.com/alibaba/DataX/blob/master/transformer/doc/transformer.md
+ *
+ * https://www.processon.com/diagraming/66580c3ee57102599640d679
*
* @author: 百岁(baisui@qlangtech.com)
* @create: 2023-05-07 12:35
**/
-public abstract class UDFDefinition implements Describable, AfterPluginSaved,PluginLiteriaDesc {
+public abstract class UDFDefinition implements Describable, AfterPluginSaved, PluginLiteriaDesc, Serializable {
+
+ protected static final String KEY_FROM = "from";
+ protected static final String KEY_TO = "to";
public final String getImpl() {
return this.getClass().getName();
}
+ /**
+ * 函数的出参
+ *
+ * @return
+ */
+ public abstract List outParameters();
+
+ /**
+ * 对记录进行处理
+ *
+ * @param record
+ */
+ public abstract void evaluate(ColumnAwareRecord record);
+
+
@Override
public final void afterSaved(IPluginContext pluginContext, Optional context) {
try {
@@ -58,7 +82,6 @@ public final void afterSaved(IPluginContext pluginContext, Optional con
}
-
@JSONField(serialize = false)
@Override
public final Descriptor getDescriptor() {
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDesc.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDesc.java
index 23cec6913..8b7eae7f3 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDesc.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/UDFDesc.java
@@ -32,11 +32,19 @@
public class UDFDesc {
private List pairs = Lists.newArrayList();
- public UDFDesc(String key, Object content) {
+ public UDFDesc(String key, String content) {
this.addPair(key, content);
}
- public void addPair(String key, Object content) {
+ public UDFDesc(String key,List content){
+ this.addPair(key, content);
+ }
+
+ public void addPair(String key, String content) {
+ this.pairs.add(new Option(key, content));
+ }
+
+ public void addPair(String key, List content) {
this.pairs.add(new Option(key, content));
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.java
deleted file mode 100644
index 81b840968..000000000
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.qlangtech.tis.plugin.datax.transformer.impl;
-
-import com.google.common.collect.Lists;
-import com.qlangtech.tis.plugin.IdentityName;
-import com.qlangtech.tis.plugin.annotation.FormField;
-import com.qlangtech.tis.plugin.annotation.FormFieldType;
-import com.qlangtech.tis.plugin.annotation.Validator;
-import com.qlangtech.tis.plugin.datax.SelectedTab;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
-import com.qlangtech.tis.plugin.ds.CMeta;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- *
- */
-public abstract class AbstractFromColumnUDFDefinition extends UDFDefinition {
-
- @FormField(ordinal = 1, type = FormFieldType.ENUM, validate = {Validator.require})
- public String from;
-
- @Override
- public List getLiteria() {
- return Lists.newArrayList(new UDFDesc("from", this.from));
- }
-
-
- public static List colsCandidate() {
- List colsCandidate = SelectedTab.getColsCandidate();
- return colsCandidate.stream().collect(Collectors.toList());
- }
-
-}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.java
deleted file mode 100644
index ea9793d49..000000000
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.qlangtech.tis.plugin.datax.transformer.impl;
-
-import com.google.common.collect.Lists;
-import com.qlangtech.tis.extension.Descriptor;
-import com.qlangtech.tis.extension.TISExtension;
-import com.qlangtech.tis.plugin.annotation.FormField;
-import com.qlangtech.tis.plugin.annotation.FormFieldType;
-import com.qlangtech.tis.plugin.annotation.Validator;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
-import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
-
-import java.util.List;
-
-/**
- * 用于使用虚拟列
- */
-public class CopyValUDF extends AbstractFromColumnUDFDefinition {
-
- @FormField(ordinal = 2, type = FormFieldType.MULTI_SELECTABLE, validate = {Validator.require})
- public TargetColType to;
-
- public static List getCols() {
- return Lists.newArrayList();
- }
-
- @Override
- public List getLiteria() {
- List literia = super.getLiteria();
- literia.add(new UDFDesc("to", to.getLiteria()));
- return literia;
- }
-
- @TISExtension
- public static final class DefaultDescriptor extends Descriptor {
- public DefaultDescriptor() {
- super();
- }
-
- @Override
- public String getDisplayName() {
- return "CopyVal";
- }
- }
-}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/ExistTargetCoumn.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/ExistTargetCoumn.java
index c4637dd37..c03f3fa18 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/ExistTargetCoumn.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/ExistTargetCoumn.java
@@ -38,6 +38,11 @@ public class ExistTargetCoumn extends TargetColumn {
@FormField(ordinal = 1, identity = true, type = FormFieldType.ENUM, validate = {Validator.require})
public String name;
+ @Override
+ public boolean isVirtual() {
+ return false;
+ }
+
@Override
public String getName() {
return this.name;
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.java
deleted file mode 100644
index dae364663..000000000
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.qlangtech.tis.plugin.datax.transformer.impl;
-
-import com.google.common.collect.Lists;
-import com.qlangtech.tis.extension.Descriptor;
-import com.qlangtech.tis.extension.TISExtension;
-import com.qlangtech.tis.plugin.annotation.FormField;
-import com.qlangtech.tis.plugin.annotation.FormFieldType;
-import com.qlangtech.tis.plugin.annotation.Validator;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
-import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
-
-import java.util.List;
-
-/**
- * 将某列JSON内容拆解成多个字段
- *
- * @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-11 14:38
- **/
-public class JSONSplitterUDF extends AbstractFromColumnUDFDefinition {
-
- @FormField(ordinal = 2, type = FormFieldType.MULTI_SELECTABLE, validate = {Validator.require})
- public List to;
-
- @Override
- public List getLiteria() {
- List result = Lists.newArrayList(super.getLiteria());
-
- List toDesc = Lists.newArrayList();
- this.to.forEach((colType) -> {
- toDesc.addAll(colType.getLiteria());
- });
- result.add(new UDFDesc("to", toDesc));
- return result;
- }
-
- public static List getCols() {
- return Lists.newArrayList();
- }
-
- @TISExtension
- public static final class DefaultDescriptor extends Descriptor {
- public DefaultDescriptor() {
- super();
- }
-
- @Override
- public String getDisplayName() {
- return "JSON Splitter";
- }
- }
-
-}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/TransformerRuleElementCreatorFactory.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/TransformerRuleElementCreatorFactory.java
index 5ba9ddc5f..a628600f2 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/TransformerRuleElementCreatorFactory.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/TransformerRuleElementCreatorFactory.java
@@ -21,20 +21,16 @@
import com.alibaba.citrus.turbine.Context;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qlangtech.tis.extension.Descriptor.ParseDescribable;
import com.qlangtech.tis.extension.IPropertyType;
import com.qlangtech.tis.plugin.ValidatorCommons;
-import com.qlangtech.tis.plugin.annotation.Validator;
-import com.qlangtech.tis.plugin.datax.SelectedTab;
import com.qlangtech.tis.plugin.datax.transformer.RecordTransformer;
import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
-import com.qlangtech.tis.plugin.ds.CMeta;
import com.qlangtech.tis.plugin.ds.CMeta.ParsePostMCols;
-import com.qlangtech.tis.plugin.ds.DataType;
import com.qlangtech.tis.plugin.ds.ElementCreatorFactory;
import com.qlangtech.tis.plugin.ds.ViewContent;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
import com.qlangtech.tis.util.AttrValMap;
@@ -74,7 +70,7 @@ public RecordTransformer create(JSONObject targetCol, BiConsumer
@Override
public ParsePostMCols parsePostMCols(IPropertyType propertyType,
- IFieldErrorHandler msgHandler, Context context, String _keyColsMeta, JSONArray targetCols) {
+ IControlMsgHandler msgHandler, Context context, String _keyColsMeta, JSONArray targetCols) {
final String keyColsMeta = "rules";
final String keyTarget = "target";
final String keyUdf = "udf";
@@ -141,10 +137,10 @@ public ParsePostMCols parsePostMCols(IPropertyType propertyTy
valsMap = AttrValMap.parseDescribableMap(Optional.empty(), udfObj);
- ParseDescribable describable = valsMap.createDescribable(null);
+ ParseDescribable describable = valsMap.createDescribable(msgHandler, context);
udf = (UDFDefinition) describable.getInstance();
transformerRule.setUdf(udf);
- // transformerRule.setType(dataType);
+ // transformerRule.setType(dataType);
// transformerRule.setTarget(targetColName);
postMCols.writerCols.add(transformerRule);
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/VirtualTargetColumn.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/VirtualTargetColumn.java
index 2fe397296..3bf8c7591 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/VirtualTargetColumn.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/impl/VirtualTargetColumn.java
@@ -38,6 +38,11 @@ public class VirtualTargetColumn extends TargetColumn {
@FormField(ordinal = 1, identity = true, type = FormFieldType.INPUTTEXT, validate = {Validator.require, Validator.db_col_name})
public String name;
+ @Override
+ public boolean isVirtual() {
+ return true;
+ }
+
@Override
public String getName() {
return this.name;
@@ -50,12 +55,12 @@ public String identityValue() {
@Override
public List getLiteria() {
- return Collections.singletonList(new UDFDesc("virtual col", this.name));
+ return Collections.singletonList(new UDFDesc("col", this.name));
}
@TISExtension
- public static class DefaultDesc extends Descriptor {
- public DefaultDesc() {
+ public static class VirtualTargetColumnDesc extends Descriptor {
+ public VirtualTargetColumnDesc() {
super();
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementCreatorFactory.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementCreatorFactory.java
index 23d7c8c09..6e7fd2ac8 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementCreatorFactory.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementCreatorFactory.java
@@ -24,23 +24,24 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qlangtech.tis.extension.Descriptor.ParseDescribable;
+import com.qlangtech.tis.extension.Descriptor.PluginValidateResult;
import com.qlangtech.tis.extension.IPropertyType;
-import com.qlangtech.tis.extension.impl.PropertyType;
import com.qlangtech.tis.plugin.IdentityName;
import com.qlangtech.tis.plugin.ValidatorCommons;
import com.qlangtech.tis.plugin.datax.SelectedTab;
import com.qlangtech.tis.plugin.datax.transformer.TargetColumn;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
import com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn;
+import com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn.VirtualTargetColumnDesc;
import com.qlangtech.tis.plugin.ds.CMeta;
import com.qlangtech.tis.plugin.ds.CMeta.ParsePostMCols;
import com.qlangtech.tis.plugin.ds.DataType;
import com.qlangtech.tis.plugin.ds.ElementCreatorFactory;
-import com.qlangtech.tis.plugin.ds.TypeBase;
import com.qlangtech.tis.plugin.ds.ViewContent;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+import com.qlangtech.tis.runtime.module.misc.impl.BasicDelegateMsgHandler;
import com.qlangtech.tis.util.AttrValMap;
-import org.apache.commons.lang3.StringUtils;
+import com.qlangtech.tis.util.DescriptorsJSON;
import java.util.Collection;
import java.util.Collections;
@@ -53,7 +54,7 @@
* @author: 百岁(baisui@qlangtech.com)
* @create: 2024-06-10 09:20
**/
-public class JdbcPropertyElementCreatorFactory implements ElementCreatorFactory {
+public class JdbcPropertyElementCreatorFactory implements ElementCreatorFactory {
private static final String KEY_TARGET_COL = "name";
@@ -65,6 +66,9 @@ public ViewContent getViewContentType() {
@Override
public void appendExternalJsonProp(IPropertyType propertyType, JSONObject biz) {
biz.put("isList", propertyType.isCollectionType());
+ if (propertyType.isCollectionType()) {
+ setPropertyInCollectionFieldType(biz);
+ }
List colsCandidate = SelectedTab.getColsCandidate();
biz.put("sourceTabCols", colsCandidate);
biz.put("dftStrType", DataType.createVarChar(32));
@@ -72,41 +76,94 @@ public void appendExternalJsonProp(IPropertyType propertyType, JSONObject biz) {
// ElementCreatorFactory.super.appendExternalJsonProp(propertyType, biz);
}
+ protected void setPropertyInCollectionFieldType(JSONObject biz) {
+ biz.put("dftListElementDesc", DescriptorsJSON.desc(new VirtualTargetColumnDesc()));
+ }
+
@Override
- public ParsePostMCols parsePostMCols(IPropertyType propertyType,
- IFieldErrorHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
+ public ParsePostMCols parsePostMCols(IPropertyType propertyType,
+ IControlMsgHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
boolean isCollection = propertyType.isCollectionType();
- ParsePostMCols result = new ParsePostMCols<>();
+ ParsePostMCols result = new ParsePostMCols<>();
if (isCollection) {
final int[] index = new int[1];
Map> duplicateCols = Maps.newHashMap();
for (Object e : targetCols) {
try {
JSONObject element = (JSONObject) e;
- String target = element.getString(KEY_TARGET_COL);
- if (StringUtils.isEmpty(target)) {
- msgHandler.addFieldError(context //
- , IFieldErrorHandler.joinField(keyColsMeta, Collections.singletonList(index[0]), KEY_TARGET_COL) //
- , ValidatorCommons.MSG_EMPTY_INPUT_ERROR);
- result.validateFaild = true;
+ Object targetCol = element.get(KEY_TARGET_COL);
+
+ /**
+ * 这里处理分为两种场景 1,2
+ */
+ VirtualTargetColumn vcol = null;
+ if (targetCol instanceof String) {
+ throw new UnsupportedOperationException();
+// /***************************************
+// * 1:JSONSplitterUDF 表单提交
+// **************************************/
+// final String target = (String) targetCol;
+//
+// if (StringUtils.isEmpty(target)) {
+// msgHandler.addFieldError(context //
+// , IFieldErrorHandler.joinField(keyColsMeta, Collections.singletonList(index[0]), KEY_TARGET_COL) //
+// , ValidatorCommons.MSG_EMPTY_INPUT_ERROR);
+// result.validateFaild = true;
+// }
+//
+// Collection sameKeys = duplicateCols.get(target);
+// if (sameKeys == null) {
+// sameKeys = Lists.newArrayList();
+// duplicateCols.put(target, sameKeys);
+// }
+// sameKeys.add(index[0]);
+//
+// vcol = new VirtualTargetColumn();
+// vcol.name = target;
+ } else if (targetCol instanceof JSONObject) {
+ /***************************************
+ * 2:RecordTransformerRules 表单提交
+ **************************************/
+ AttrValMap attrVals = AttrValMap.parseDescribableMap(Optional.empty(), (JSONObject) targetCol);
+
+ BasicDelegateMsgHandler msgHandle = new BasicDelegateMsgHandler(msgHandler) {
+ @Override
+ public void addFieldError(Context context, String fieldName, String msg, Object... params) {
+ super.addFieldError(context
+ , IFieldErrorHandler.joinField(keyColsMeta, Collections.singletonList(index[0]), fieldName)
+ , msg, params);
+ }
+ };
+
+ PluginValidateResult targetColValidate = attrVals.validate(msgHandle, context, false);
+ if (targetColValidate.isValid()) {
+ vcol = targetColValidate.newInstance();
+ Collection sameKeys = duplicateCols.get(vcol.getName());
+ if (sameKeys == null) {
+ sameKeys = Lists.newArrayList();
+ duplicateCols.put(vcol.getName(), sameKeys);
+ }
+ sameKeys.add(index[0]);
+ } else {
+ result.validateFaild = true;
+ }
+
+
+ } else {
+ throw new IllegalStateException("unsupported type:" + (targetCol == null ? "null" : targetCol.getClass().getSimpleName()));
}
- Collection sameKeys = duplicateCols.get(target);
- if (sameKeys == null) {
- sameKeys = Lists.newArrayList();
- duplicateCols.put(target, sameKeys);
- }
- sameKeys.add(index[0]);
+
DataType type = CMeta.parseType(element, (propKey, errMsg) -> {
msgHandler.addFieldError(context
, IFieldErrorHandler.joinField(keyColsMeta, Collections.singletonList(index[0]), propKey)
, errMsg);
result.validateFaild = true;
});
- TargetColType targetColType = new TargetColType();
- PainTargetColumn vcol = new PainTargetColumn(target);
+ TargetColType targetColType = createDefault();
+
targetColType.setTarget(vcol);
targetColType.setType(type);
result.writerCols.add(targetColType);
@@ -126,18 +183,23 @@ public ParsePostMCols parsePostMCols(IPropertyType propertyType,
}
}
} else {
- this.parseSinglePojo(targetCols, result);
+ this.parseSinglePojo(msgHandler, context, keyColsMeta, targetCols, result);
}
return result;
}
- private void parseSinglePojo(JSONArray targetCols, ParsePostMCols result) {
+ private void parseSinglePojo(IControlMsgHandler pluginContext
+ , Context context, String keyColsMeta, JSONArray targetCols, ParsePostMCols result) {
for (Object e : targetCols) {
JSONObject element = (JSONObject) e;
// JSONObject type = element.getJSONObject("type");
JSONObject target = element.getJSONObject(KEY_TARGET_COL);
-
+ if (target == null) {
+ pluginContext.addFieldError(context, keyColsMeta, ValidatorCommons.MSG_EMPTY_INPUT_ERROR);
+ result.validateFaild = true;
+ break;
+ }
DataType type = CMeta.parseType(element, (propKey, errMsg) -> {
// msgHandler.addFieldError(context
// , IFieldErrorHandler.joinField(keyColsMeta, Collections.singletonList(index), propKey)
@@ -146,9 +208,10 @@ private void parseSinglePojo(JSONArray targetCols, ParsePostMCols resu
});
AttrValMap valsMap = AttrValMap.parseDescribableMap(Optional.empty(), target);
- ParseDescribable describable = valsMap.createDescribable(null);
+
+ ParseDescribable describable = valsMap.createDescribable(pluginContext, context);
TargetColumn targetCol = (TargetColumn) describable.getInstance();
- TargetColType targetColType = new TargetColType();
+ TargetColType targetColType = this.createDefault();
targetColType.setTarget(targetCol);
targetColType.setType(type);
result.writerCols.add(targetColType);
@@ -161,15 +224,14 @@ private void parseSinglePojo(JSONArray targetCols, ParsePostMCols resu
*
* @return
* @see com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType
- * @see com.qlangtech.tis.plugin.datax.transformer.jdbcprop.VirtualColType
*/
@Override
- public TypeBase createDefault() {
- return null;
+ public TargetColType createDefault() {
+ return new TargetColType();
}
@Override
- public TypeBase create(JSONObject targetCol, BiConsumer errorProcess) {
+ public TargetColType create(JSONObject targetCol, BiConsumer errorProcess) {
return null;
}
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumnSerializer.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementSelectFromExistFieldCreatorFactory.java
similarity index 54%
rename from tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumnSerializer.java
rename to tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementSelectFromExistFieldCreatorFactory.java
index 95c05e270..f7a248977 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumnSerializer.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/JdbcPropertyElementSelectFromExistFieldCreatorFactory.java
@@ -18,27 +18,18 @@
package com.qlangtech.tis.plugin.datax.transformer.jdbcprop;
-import com.alibaba.fastjson.serializer.JSONSerializer;
-import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson2.JSONWriter;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Type;
+import com.alibaba.fastjson.JSONObject;
/**
+ * 从已有的数据表中选择一个已有的数据列
+ *
* @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-12 16:56
+ * @create: 2024-06-17 10:21
**/
-public class PainTargetColumnSerializer implements ObjectSerializer {
- @Override
- public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
- PainTargetColumn targetColumn = (PainTargetColumn) object;
- jsonWriter.writeRaw("\"" + targetColumn.getName() + "\"");
- }
-
+public class JdbcPropertyElementSelectFromExistFieldCreatorFactory extends JdbcPropertyElementCreatorFactory {
@Override
- public void write(JSONSerializer jsonSerializer, Object o, Object o1, Type type, int i) throws IOException {
- throw new UnsupportedEncodingException();
+ protected void setPropertyInCollectionFieldType(JSONObject biz) {
+ super.setPropertyInCollectionFieldType(biz);
+ biz.put("selectFromExistField", true);
}
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColType.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColType.java
index 44777ddb0..3a3301363 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColType.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColType.java
@@ -23,21 +23,33 @@
import com.qlangtech.tis.plugin.datax.transformer.PluginLiteria;
import com.qlangtech.tis.plugin.datax.transformer.TargetColumn;
import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
+import com.qlangtech.tis.plugin.ds.IColMetaGetter;
import com.qlangtech.tis.plugin.ds.TypeBase;
import java.util.List;
+import java.util.Objects;
/**
* https://github.com/alibaba/fastjson/wiki/JSONType_serializer
*
* @author: 百岁(baisui@qlangtech.com)
* @create: 2024-06-10 10:10
+ * @see JdbcPropertyElementCreatorFactory
**/
@JSONType(serializer = TargetColTypeSerializer.class)
-public class TargetColType extends TypeBase implements PluginLiteria {
+public final class TargetColType extends TypeBase implements PluginLiteria, IColMetaGetter {
TargetColumn target;
+ public boolean isVirtual() {
+ return Objects.requireNonNull(target, "prop target can not be null").isVirtual();
+ }
+
+ @Override
+ public boolean isPk() {
+ return false;
+ }
+
@Override
public List getLiteria() {
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColTypeSerializer.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColTypeSerializer.java
index 932298b64..61ff03e60 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColTypeSerializer.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TargetColTypeSerializer.java
@@ -18,9 +18,11 @@
package com.qlangtech.tis.plugin.datax.transformer.jdbcprop;
+import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.google.common.collect.Maps;
+import com.qlangtech.tis.util.DescribableJSON;
import java.io.IOException;
import java.lang.reflect.Type;
@@ -30,6 +32,7 @@
/**
* @author: 百岁(baisui@qlangtech.com)
* @create: 2024-06-12 11:43
+ * @see TargetColType
**/
public class TargetColTypeSerializer implements ObjectSerializer {
@Override
@@ -38,10 +41,18 @@ public void write(JSONSerializer serializer, Object object, Object fieldName, Ty
}
- private Map serialize(TargetColType colType) {
- Map result = Maps.newHashMap();
- result.put("name", Objects.requireNonNull(colType.target, "target can not be null"));
- result.put("type", colType.getType());
- return result;
+ private Map serialize(TargetColType colType) {
+ try {
+ Map result = Maps.newHashMap();
+ DescribableJSON target = new DescribableJSON(Objects.requireNonNull(colType.target, "target can not be null"));
+ JSONObject itemJson = target.getItemJson();
+ itemJson.put("literia", colType.target.getLiteria());
+
+ result.put("name", itemJson);
+ result.put("type", colType.getType());
+ return result;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumn.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/CreatedSinkFunction.java
similarity index 50%
rename from tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumn.java
rename to tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/CreatedSinkFunction.java
index ac735a967..560447eb8 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/PainTargetColumn.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/CreatedSinkFunction.java
@@ -16,39 +16,25 @@
* limitations under the License.
*/
-package com.qlangtech.tis.plugin.datax.transformer.jdbcprop;
+package com.qlangtech.tis.plugin.incr;
-import com.alibaba.fastjson.annotation.JSONType;
-import com.google.common.collect.Lists;
-import com.qlangtech.tis.plugin.datax.transformer.TargetColumn;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
+import com.google.common.collect.Maps;
+import com.qlangtech.tis.datax.TableAlias;
-import java.util.List;
+import java.util.Map;
/**
* @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-12 16:56
+ * @create: 2024-06-19 14:10
**/
-@JSONType(serializer = PainTargetColumnSerializer.class)
-public class PainTargetColumn extends TargetColumn {
- private final String colName;
+public class CreatedSinkFunction {
- public PainTargetColumn(String colName) {
- this.colName = colName;
- }
-
- @Override
- public String getName() {
- return this.colName;
- }
+ public final Map tabSinkFunc = Maps.newHashMap();
- @Override
- public String identityValue() {
- throw new UnsupportedOperationException();
+ public CreatedSinkFunction() {
}
- @Override
- public List getLiteria() {
- return Lists.newArrayList(new UDFDesc("column", this.colName));
+ public void addTabSinkFunc(TableAlias tab, SinkFunc sinkFunc) {
+ this.tabSinkFunc.put(tab, sinkFunc);
}
}
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/TISSinkFactory.java b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/TISSinkFactory.java
index 6e1b40d59..b42247901 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/TISSinkFactory.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/plugin/incr/TISSinkFactory.java
@@ -20,8 +20,10 @@
import com.qlangtech.tis.TIS;
import com.qlangtech.tis.annotation.Public;
+import com.qlangtech.tis.async.message.client.consumer.IFlinkColCreator;
import com.qlangtech.tis.async.message.client.consumer.impl.MQListenerFactory;
import com.qlangtech.tis.compiler.incr.ICompileAndPackage;
+import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.datax.IDataXPluginMeta;
import com.qlangtech.tis.datax.IDataxProcessor;
import com.qlangtech.tis.datax.TableAlias;
@@ -36,6 +38,7 @@
import com.qlangtech.tis.util.IPluginContext;
import com.qlangtech.tis.util.Selectable;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -52,7 +55,7 @@
* @see MQListenerFactory
**/
@Public
-public abstract class TISSinkFactory implements Describable, KeyedPluginStore.IPluginKeyAware {
+public abstract class TISSinkFactory implements Describable, KeyedPluginStore.IPluginKeyAware, IDataXNameAware {
// public static final String KEY_FLINK_STREAM_APP_NAME_PREFIX = "flink_stream_";
public static final String KEY_PLUGIN_TPI_CHILD_PATH = "flink/";
private static final Logger logger = LoggerFactory.getLogger(TISSinkFactory.class);
@@ -83,7 +86,7 @@ public static void main(String[] args) throws Exception {
}
@TISExtension
- public static final HeteroEnum sinkFactory = new HeteroEnum(//
+ public static final HeteroEnum sinkFactory = new HeteroEnum<>(//
TISSinkFactory.class, //
"sinkFactory", //
"Incr Sink Factory", //
@@ -116,6 +119,14 @@ public static TISSinkFactory getIncrSinKFactory(IPluginContext pluginContext) {
public transient String dataXName;
+ @Override
+ public final String getCollectionName() {
+ if (StringUtils.isEmpty(this.dataXName)) {
+ throw new IllegalStateException("param dataXName can not be empty");
+ }
+ return this.dataXName;
+ }
+
/**
* 取得增量执行单元,脚本编译器
*
@@ -134,7 +145,8 @@ public void setKey(KeyedPluginStore.Key key) {
* @param dataxProcessor
* @return
*/
- public abstract Map createSinkFunction(IDataxProcessor dataxProcessor);
+ public abstract Map createSinkFunction(
+ IDataxProcessor dataxProcessor, IFlinkColCreator> flinkColCreator);
@Override
@@ -157,7 +169,7 @@ public static abstract class BaseSinkFunctionDescriptor extends Descriptor getExtractProps() {
Map vals = super.getExtractProps();
EndType targetType = this.getTargetType();
- // this.getEndType().appendProps(vals);
+ // this.getEndType().appendProps(vals);
vals.put(IDataXPluginMeta.END_TARGET_TYPE, targetType.getVal());
vals.put(ISelectedTabExtendFactory.KEY_EXTEND_SELECTED_TAB_PROP
, (this instanceof ISelectedTabExtendFactory)
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/util/AttrValMap.java b/tis-plugin/src/main/java/com/qlangtech/tis/util/AttrValMap.java
index 2fc972907..33ae8377e 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/util/AttrValMap.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/util/AttrValMap.java
@@ -127,12 +127,12 @@ public String createOrGetNotebook(IControlMsgHandler msgHandler, Context context
throw new IllegalStateException("desc:" + this.descriptor.getClass().getName() + " must be instance of " + INotebookable.class.getSimpleName());
}
INotebookable notebook = (INotebookable) this.descriptor;
- return notebook.createOrGetNotebook((new Descriptor.PostFormVals(this.descriptor, msgHandler,
+ return notebook.createOrGetNotebook((new Descriptor.PostFormVals(this.descriptor, msgHandler, context,
this.attrValMap)).newInstance());
}
- public Descriptor.ParseDescribable createDescribable(IPluginContext pluginContext) {
- return this.createDescribable(pluginContext, Optional.empty());
+ public Descriptor.ParseDescribable createDescribable(IControlMsgHandler pluginContext, Context context) {
+ return this.createDescribable(pluginContext, context, Optional.empty());
}
/**
@@ -140,8 +140,8 @@ public Descriptor.ParseDescribable createDescribable(IPluginContext pluginContex
*
* @return
*/
- public Descriptor.ParseDescribable createDescribable(IPluginContext pluginContext, Optional formProperties) {
- return this.descriptor.parseDescribable(pluginContext, this.attrValMap, (formProperties), this.subFormFilter);
+ public Descriptor.ParseDescribable createDescribable(IControlMsgHandler pluginContext, Context context, Optional formProperties) {
+ return this.descriptor.parseDescribable(pluginContext, context, this.attrValMap, (formProperties), this.subFormFilter);
}
public int size() {
diff --git a/tis-plugin/src/main/java/com/qlangtech/tis/util/IPluginContext.java b/tis-plugin/src/main/java/com/qlangtech/tis/util/IPluginContext.java
index 427aadaa8..6332df78e 100644
--- a/tis-plugin/src/main/java/com/qlangtech/tis/util/IPluginContext.java
+++ b/tis-plugin/src/main/java/com/qlangtech/tis/util/IPluginContext.java
@@ -18,6 +18,7 @@
package com.qlangtech.tis.util;
import com.alibaba.citrus.turbine.Context;
+import com.qlangtech.tis.datax.IDataXNameAware;
import com.qlangtech.tis.extension.Descriptor;
import com.qlangtech.tis.extension.impl.SuFormProperties.SuFormGetterContext;
import com.qlangtech.tis.plugin.ds.DataSourceFactory;
@@ -29,7 +30,7 @@
* @author 百岁(baisui@qlangtech.com)
* @date 2020/04/13
*/
-public interface IPluginContext extends IMessageHandler {
+public interface IPluginContext extends IMessageHandler, IDataXNameAware {
@@ -94,13 +95,10 @@ public void addErrorMessage(Context context, String msg) {
*/
String getExecId();
- /**
- * 是否在索引
- *
- * @return
- */
- boolean isCollectionAware();
- String getCollectionName();
+
+
+
+
/**
* 是否和数据源相关
*
diff --git a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.json b/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.json
deleted file mode 100644
index e8c2e7a64..000000000
--- a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/AbstractFromColumnUDFDefinition.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "from": {
- "enum": "com.qlangtech.tis.plugin.datax.transformer.impl.AbstractFromColumnUDFDefinition.colsCandidate():uncache_true"
- }
-}
\ No newline at end of file
diff --git a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.json b/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.json
deleted file mode 100644
index 45942ab4f..000000000
--- a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/CopyValUDF.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "to": {
- "elementCreator": "com.qlangtech.tis.plugin.datax.transformer.jdbcprop.JdbcPropertyElementCreatorFactory",
- "enum": "com.qlangtech.tis.plugin.datax.transformer.impl.CopyValUDF.getCols():uncache_true",
- "viewtype": "tuplelist"
- }
-}
\ No newline at end of file
diff --git a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.json b/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.json
deleted file mode 100644
index c4d7230ee..000000000
--- a/tis-plugin/src/main/resources/com/qlangtech/tis/plugin/datax/transformer/impl/JSONSplitterUDF.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "to": {
- "elementCreator": "com.qlangtech.tis.plugin.datax.transformer.jdbcprop.JdbcPropertyElementCreatorFactory",
- "enum": "com.qlangtech.tis.plugin.datax.transformer.impl.JSONSplitterUDF.getCols():uncache_true",
- "viewtype": "tuplelist"
- }
-}
\ No newline at end of file
diff --git a/tis-plugin/src/test/java/TestAll.java b/tis-plugin/src/test/java/TestAll.java
index cdff43281..df1a0fd4a 100644
--- a/tis-plugin/src/test/java/TestAll.java
+++ b/tis-plugin/src/test/java/TestAll.java
@@ -17,6 +17,7 @@
*/
import com.qlangtech.tis.TestTIS;
+import com.qlangtech.tis.datax.impl.TestDataXCfgGenerator;
import com.qlangtech.tis.datax.impl.TestDataxReader;
import com.qlangtech.tis.datax.impl.TestTableAlias;
import com.qlangtech.tis.datax.job.TestServerLaunchToken;
@@ -40,7 +41,7 @@
import com.qlangtech.tis.plugin.datax.TestSelectedTab;
import com.qlangtech.tis.plugin.datax.transformer.impl.TestCopyValUDF;
import com.qlangtech.tis.plugin.datax.transformer.impl.TestTransformerRuleElementCreatorFactory;
-import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TestPainTargetColumn;
+//import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TestPainTargetColumn;
import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TestTargetColType;
import com.qlangtech.tis.plugin.ds.TestDataSourceFactoryPluginStore;
import com.qlangtech.tis.plugin.ds.TestTableInDB;
@@ -92,9 +93,10 @@ public static Test suite() {
suite.addTestSuite(TestK8sImage.class);
suite.addTestSuite(TestServerLaunchToken.class);
suite.addTestSuite(TestTransformerRuleElementCreatorFactory.class);
- suite.addTestSuite(TestCopyValUDF.class);
+ // suite.addTestSuite(TestCopyValUDF.class);
suite.addTestSuite(TestTargetColType.class);
- suite.addTestSuite(TestPainTargetColumn.class);
+ // suite.addTestSuite(TestPainTargetColumn.class);
+ suite.addTestSuite(TestDataXCfgGenerator.class);
return suite;
}
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/datax/impl/TestDataXCfgGenerator.java b/tis-plugin/src/test/java/com/qlangtech/tis/datax/impl/TestDataXCfgGenerator.java
new file mode 100644
index 000000000..3fa2c7631
--- /dev/null
+++ b/tis-plugin/src/test/java/com/qlangtech/tis/datax/impl/TestDataXCfgGenerator.java
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.qlangtech.tis.datax.impl;
+
+import com.qlangtech.tis.common.utils.Assert;
+import com.qlangtech.tis.datax.IDataXPluginMeta.DataXMeta;
+import com.qlangtech.tis.datax.IDataxContext;
+import com.qlangtech.tis.datax.IDataxGlobalCfg;
+import com.qlangtech.tis.datax.IDataxProcessor;
+import com.qlangtech.tis.datax.IDataxReader;
+import com.qlangtech.tis.datax.IDataxReaderContext;
+import com.qlangtech.tis.datax.IDataxWriter;
+import com.qlangtech.tis.plugin.datax.transformer.RecordTransformer;
+import com.qlangtech.tis.plugin.datax.transformer.RecordTransformerRules;
+import com.qlangtech.tis.plugin.datax.transformer.impl.TestCopyValUDF;
+import com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn;
+import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
+import com.qlangtech.tis.trigger.util.JsonUtil;
+import com.qlangtech.tis.util.IPluginContext;
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+import java.util.Optional;
+
+/**
+ * @author: 百岁(baisui@qlangtech.com)
+ * @create: 2024-06-15 08:48
+ **/
+public class TestDataXCfgGenerator extends TestCase {
+
+ /**
+ * 测试Transformer的json生成
+ *
+ * @throws Exception
+ */
+ public void testGenerateDataxConfigForTransformer() throws Exception {
+ String dataxName = "test";
+ String transformerTable = "base";
+
+ RecordTransformerRules.transformerRulesLoader4Test = (tab) -> {
+ RecordTransformerRules tRules = new RecordTransformerRules();
+ RecordTransformer transformer = new RecordTransformer();
+ TestCopyValUDF cpUDF = new TestCopyValUDF();
+ cpUDF.from = "base_id";
+ TargetColType targetColType = new TargetColType();
+ VirtualTargetColumn targetColumn = new VirtualTargetColumn();
+ final String baseId = "new_base_id";
+ targetColumn.name = baseId;
+ targetColType.setTarget(targetColumn);
+ cpUDF.to = targetColType;
+ transformer.setUdf(cpUDF);
+ tRules.rules.add(transformer);
+
+ //
+ Assert.assertEquals(baseId, String.join(",", tRules.relevantColKeys()));
+ return tRules;
+ };
+
+ IPluginContext pluginCtx = IPluginContext.namedContext(dataxName);
+
+ IDataxProcessor dataxProcessor = EasyMock.createMock("processor", IDataxProcessor.class);
+
+ IDataxGlobalCfg globalCfg = EasyMock.createMock("globalCfg", IDataxGlobalCfg.class);
+
+ EasyMock.expect(globalCfg.getTemplate())
+ .andReturn("{\n" +
+ " \"job\": {\n" +
+ " \"content\": [\n" +
+ " {\n" +
+ " \"reader\": ,\n" +
+ " \"writer\": \n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "}");
+
+ EasyMock.expect(dataxProcessor.getDataXGlobalCfg()).andReturn(globalCfg);
+
+ IDataxReaderContext readerContext = EasyMock.createMock("readerContext", IDataxReaderContext.class);
+ EasyMock.expect(readerContext.getSourceEntityName()).andReturn(transformerTable).anyTimes();
+
+ IDataxWriter writer = EasyMock.createMock("write", IDataxWriter.class);
+ IDataxReader reader = EasyMock.createMock("reader", IDataxReader.class);
+ EasyMock.expect(reader.getTemplate()).andReturn("{}").times(2);
+ EasyMock.expect(writer.getTemplate()).andReturn("{}");
+ EasyMock.expect(writer.getSubTask(Optional.empty())).andReturn(new IDataxContext() {
+ });
+ DataXMeta writeDataXMeta = new DataXMeta();
+ EasyMock.expect(writer.getDataxMeta()).andReturn(writeDataXMeta);
+ DataXMeta readerDataXMeta = new DataXMeta();
+ EasyMock.expect(reader.getDataxMeta()).andReturn(readerDataXMeta);
+ Optional tableMap = Optional.empty();
+
+ EasyMock.replay(writer, reader, readerContext, dataxProcessor, globalCfg);
+
+ DataXCfgGenerator generator = new DataXCfgGenerator(pluginCtx, dataxName, dataxProcessor);
+ String dataXCfg = generator.generateDataxConfig(readerContext, writer, reader, tableMap);
+
+ String assertFileName = "generate-datax-config-for-transformer.json";
+
+ JsonUtil.assertJSONEqual(TestDataXCfgGenerator.class, assertFileName, dataXCfg, (message, expected, actual) -> {
+ Assert.assertEquals(message, expected, actual);
+ });
+
+ EasyMock.verify(writer, reader, readerContext, dataxProcessor, globalCfg);
+ }
+
+}
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/extension/util/TestPluginExtraProps.java b/tis-plugin/src/test/java/com/qlangtech/tis/extension/util/TestPluginExtraProps.java
index f90961d81..bc788edb1 100644
--- a/tis-plugin/src/test/java/com/qlangtech/tis/extension/util/TestPluginExtraProps.java
+++ b/tis-plugin/src/test/java/com/qlangtech/tis/extension/util/TestPluginExtraProps.java
@@ -27,6 +27,7 @@
import com.qlangtech.tis.plugin.ds.CMeta;
import com.qlangtech.tis.plugin.ds.CMeta.ParsePostMCols;
import com.qlangtech.tis.plugin.ds.ElementCreatorFactory;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
import com.qlangtech.tis.trigger.util.JsonUtil;
import com.qlangtech.tis.util.DescriptorsJSON;
@@ -44,7 +45,7 @@ public class TestPluginExtraProps extends TestCase {
public void testParsePostMCols() {
ElementCreatorFactory elementCreator = new TestElementCreatorFactory();
- IFieldErrorHandler msgHandler = null;
+ IControlMsgHandler msgHandler = null;
Context context = null;
String keyColsMeta = null;
JSONArray targetCols = null;
@@ -64,7 +65,7 @@ public CMeta create(JSONObject targetCol, BiConsumer errorProces
}
@Override
- public ParsePostMCols parsePostMCols(IPropertyType propertyType,IFieldErrorHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
+ public ParsePostMCols parsePostMCols(IPropertyType propertyType, IControlMsgHandler msgHandler, Context context, String keyColsMeta, JSONArray targetCols) {
throw new UnsupportedOperationException();
}
// @Override
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestCopyValUDF.java b/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestCopyValUDF.java
index 8dace4e12..1b11d7bd9 100644
--- a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestCopyValUDF.java
+++ b/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestCopyValUDF.java
@@ -18,19 +18,74 @@
package com.qlangtech.tis.plugin.datax.transformer.impl;
-import com.qlangtech.tis.extension.util.impl.DefaultGroovyShellFactory;
-import com.qlangtech.tis.plugin.datax.transformer.TestRecordTransformerRules;
-import junit.framework.TestCase;
+import com.alibaba.datax.common.element.ColumnAwareRecord;
+import com.alibaba.datax.common.element.Record;
+import com.google.common.collect.Lists;
+import com.qlangtech.tis.extension.Descriptor;
+import com.qlangtech.tis.extension.TISExtension;
+import com.qlangtech.tis.plugin.IdentityName;
+import com.qlangtech.tis.plugin.annotation.FormField;
+import com.qlangtech.tis.plugin.annotation.FormFieldType;
+import com.qlangtech.tis.plugin.annotation.Validator;
+import com.qlangtech.tis.plugin.datax.SelectedTab;
+import com.qlangtech.tis.plugin.datax.transformer.UDFDefinition;
+import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
+import com.qlangtech.tis.plugin.datax.transformer.jdbcprop.TargetColType;
+import com.qlangtech.tis.plugin.ds.CMeta;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
/**
- *
- * @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-10 11:38
- **/
-public class TestCopyValUDF extends TestCase {
-
- public void testDescJsonGen() {
- DefaultGroovyShellFactory.setInConsoleModule();
- TestRecordTransformerRules.assertDesc(CopyValUDF.class,"record-transformer-rules-descriptor.json");
+ * 用于使用虚拟列
+ */
+public class TestCopyValUDF extends UDFDefinition {
+
+ @FormField(ordinal = 1, type = FormFieldType.ENUM, validate = {Validator.require})
+ public String from;
+
+ @Override
+ public List getLiteria() {
+ List literia = Lists.newArrayList(new UDFDesc("from", this.from));
+ literia.add(new UDFDesc("to", to.getLiteria()));
+ return literia;
+ }
+
+
+ public static List colsCandidate() {
+ List colsCandidate = SelectedTab.getColsCandidate();
+ return colsCandidate.stream().collect(Collectors.toList());
+ }
+
+ @FormField(ordinal = 2, type = FormFieldType.MULTI_SELECTABLE, validate = {Validator.require})
+ public TargetColType to;
+
+ public static List getCols() {
+ return Lists.newArrayList();
+ }
+
+ @Override
+ public List outParameters() {
+ return Collections.singletonList(this.to);
+ }
+
+ @Override
+ public void evaluate(ColumnAwareRecord record) {
+
+ record.setColumn(this.to.getName(), record.getColumn(this.from));
+ }
+
+
+ @TISExtension
+ public static final class DefaultDescriptor extends Descriptor {
+ public DefaultDescriptor() {
+ super();
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "TestCopyVal";
+ }
}
}
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestTransformerRuleElementCreatorFactory.java b/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestTransformerRuleElementCreatorFactory.java
index 4350917bf..441428511 100644
--- a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestTransformerRuleElementCreatorFactory.java
+++ b/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/impl/TestTransformerRuleElementCreatorFactory.java
@@ -25,7 +25,7 @@
import com.qlangtech.tis.extension.impl.IOUtils;
import com.qlangtech.tis.plugin.datax.transformer.RecordTransformer;
import com.qlangtech.tis.plugin.ds.CMeta.ParsePostMCols;
-import com.qlangtech.tis.runtime.module.misc.IFieldErrorHandler;
+import com.qlangtech.tis.runtime.module.misc.IControlMsgHandler;
import junit.framework.TestCase;
import org.easymock.EasyMock;
@@ -34,7 +34,7 @@ public class TestTransformerRuleElementCreatorFactory extends TestCase {
public void testParsePostMCols() {
TransformerRuleElementCreatorFactory creatorFactory = new TransformerRuleElementCreatorFactory();
IPropertyType propertyType = null;
- IFieldErrorHandler msgHandler = EasyMock.createMock("msgHandler", IFieldErrorHandler.class);
+ IControlMsgHandler msgHandler = EasyMock.createMock("msgHandler", IControlMsgHandler.class);
Context context = EasyMock.createMock("context", Context.class);
String keyColsMeta = "colsMeta";
JSONArray jsonArray
@@ -43,24 +43,25 @@ public void testParsePostMCols() {
EasyMock.replay(msgHandler, context);
ParsePostMCols postResult
- = creatorFactory.parsePostMCols(propertyType,msgHandler, context, keyColsMeta, jsonArray);
+ = creatorFactory.parsePostMCols(propertyType, msgHandler, context, keyColsMeta, jsonArray);
Assert.assertFalse(postResult.validateFaild);
Assert.assertEquals(1, postResult.writerCols.size());
- // DataType type = null;
- CopyValUDF udf = null;
+ // DataType type = null;
+ TestCopyValUDF udf = null;
for (RecordTransformer transformer : postResult.writerCols) {
- // Assert.assertEquals("sort_num", transformer.getTarget());
+ // Assert.assertEquals("sort_num", transformer.getTarget());
// type = transformer.getType();
// Assert.assertNotNull("type can not be null", type);
// Assert.assertEquals(-5, type.getType());
- Assert.assertTrue(transformer.getUdf() instanceof CopyValUDF);
- udf = (CopyValUDF) transformer.getUdf();
+ Assert.assertTrue(transformer.getUdf() instanceof TestCopyValUDF);
+ udf = (TestCopyValUDF) transformer.getUdf();
Assert.assertNotNull(udf);
Assert.assertEquals("emp_id", udf.from);
-
+ Assert.assertNotNull("udf.to can not be null", udf.to);
+ Assert.assertEquals("new_add_field", udf.to.getName());
}
EasyMock.verify(msgHandler, context);
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TestPainTargetColumn.java b/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TestPainTargetColumn.java
deleted file mode 100644
index e4c8cb6f2..000000000
--- a/tis-plugin/src/test/java/com/qlangtech/tis/plugin/datax/transformer/jdbcprop/TestPainTargetColumn.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.qlangtech.tis.plugin.datax.transformer.jdbcprop;
-
-import com.qlangtech.tis.common.utils.Assert;
-import com.qlangtech.tis.manage.common.Option;
-import com.qlangtech.tis.plugin.datax.transformer.UDFDesc;
-import com.qlangtech.tis.trigger.util.JsonUtil;
-import junit.framework.TestCase;
-import org.junit.Test;
-
-import java.util.List;
-
-/**
- * @author: 百岁(baisui@qlangtech.com)
- * @create: 2024-06-12 17:01
- **/
-public class TestPainTargetColumn extends TestCase {
-
- @Test
- public void testSerialize() {
- String colName = "user_name";
- PainTargetColumn targetColumn = new PainTargetColumn(colName);
- Assert.assertEquals("\"" + colName + "\"", JsonUtil.toString(targetColumn, true));
-
- List descs = targetColumn.getLiteria();
- Assert.assertEquals(1, descs.size());
- for (UDFDesc desc : descs) {
- Assert.assertEquals(1, desc.getPairs().size());
- for (Option opt : desc.getPairs()) {
- Assert.assertEquals("column", opt.getName());
- Assert.assertEquals(colName, opt.getValue());
- }
- }
- }
-}
diff --git a/tis-plugin/src/test/java/com/qlangtech/tis/util/TestAttrValMap.java b/tis-plugin/src/test/java/com/qlangtech/tis/util/TestAttrValMap.java
index 7c356dcfa..afd1f1a3d 100644
--- a/tis-plugin/src/test/java/com/qlangtech/tis/util/TestAttrValMap.java
+++ b/tis-plugin/src/test/java/com/qlangtech/tis/util/TestAttrValMap.java
@@ -1,23 +1,24 @@
/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.qlangtech.tis.util;
+import com.alibaba.citrus.turbine.Context;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qlangtech.tis.extension.Descriptor;
@@ -38,17 +39,18 @@ public class TestAttrValMap extends TestCase {
public void testCreateDescribable() {
IControlMsgHandler fieldErrorHandler = EasyMock.createMock("fieldErrorHandler", IControlMsgHandler.class);
- IPluginContext pluginContext = EasyMock.createMock("pluginContext", IPluginContext.class);
+ IControlMsgHandler pluginContext = EasyMock.createMock("pluginContext", IControlMsgHandler.class);
+ Context context = EasyMock.createMock("context", Context.class);
JSONObject jsonObject = IOUtils.loadResourceFromClasspath(TestPluginImpl.class
, "testPluginImpl-post-content.json", true, (input) -> {
return JSON.parseObject(org.apache.commons.io.IOUtils.toString(input, TisUTF8.get()));
});
- EasyMock.replay(fieldErrorHandler, pluginContext);
- AttrValMap attrValMap = AttrValMap.parseDescribableMap( Optional.empty(), jsonObject);
+ EasyMock.replay(fieldErrorHandler, pluginContext, context);
+ AttrValMap attrValMap = AttrValMap.parseDescribableMap(Optional.empty(), jsonObject);
- Descriptor.ParseDescribable describable = attrValMap.createDescribable(pluginContext);
+ Descriptor.ParseDescribable describable = attrValMap.createDescribable(pluginContext, context);
assertNotNull(describable);
TestPluginImpl testPlugin = (TestPluginImpl) describable.getInstance();
assertNotNull(testPlugin);
@@ -56,6 +58,6 @@ public void testCreateDescribable() {
assertTrue("testPlugin.connectionsPerHost must be null", testPlugin.connectionsPerHost == null);
assertEquals(12, (int) testPlugin.maxPendingPerConnection);
- EasyMock.verify(fieldErrorHandler, pluginContext);
+ EasyMock.verify(fieldErrorHandler, pluginContext, context);
}
}
diff --git a/tis-plugin/src/test/resources/com/qlangtech/tis/datax/impl/generate-datax-config-for-transformer.json b/tis-plugin/src/test/resources/com/qlangtech/tis/datax/impl/generate-datax-config-for-transformer.json
new file mode 100644
index 000000000..3eb654958
--- /dev/null
+++ b/tis-plugin/src/test/resources/com/qlangtech/tis/datax/impl/generate-datax-config-for-transformer.json
@@ -0,0 +1,18 @@
+{
+ "job": {
+ "content": [
+ {
+ "transformer": {
+ "cols": [
+ "new_base_id"
+ ],
+ "name": "base"
+ },
+ "reader": {
+ },
+ "writer": {
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/copy-val-udf-descriptor.json b/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/copy-val-udf-descriptor.json
deleted file mode 100644
index 9e26dfeeb..000000000
--- a/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/copy-val-udf-descriptor.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/transformer-rule-sample.json b/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/transformer-rule-sample.json
index f628baaad..5a83841e1 100644
--- a/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/transformer-rule-sample.json
+++ b/tis-plugin/src/test/resources/com/qlangtech/tis/plugin/datax/transformer/impl/transformer-rule-sample.json
@@ -10,162 +10,110 @@
"disabled": false,
"key": "from",
"pk": false,
+ "placeholder": "",
+ "dateTimeFormat": "yyyy-MM-dd HH:mm:ss",
+ "required": true,
+ "type": 5
+ },
+ "to": {
+ "updateModel": true,
+ "has_set_primaryVal": false,
+ "disabled": false,
+ "key": "to",
+ "pk": false,
"_eprops": {
- "enum": [{
- "val": "id",
- "label": "id"
- }, {
- "val": "emp_id",
- "label": "emp_id"
- }, {
- "val": "photo_sn",
- "label": "photo_sn"
- }, {
- "val": "photo_file",
- "label": "photo_file"
- }, {
- "val": "photo_url",
- "label": "photo_url"
- }, {
- "val": "photo_data",
- "label": "photo_data"
- }, {
- "val": "photo_sign",
- "label": "photo_sign"
- }, {
- "val": "is_analyse",
- "label": "is_analyse"
- }, {
- "val": "photo_time",
- "label": "photo_time"
- }, {
- "val": "is_active",
- "label": "is_active"
- }, {
- "val": "quality_score",
- "label": "quality_score"
- }, {
- "val": "create_by",
- "label": "create_by"
- }, {
- "val": "create_time",
- "label": "create_time"
- }, {
- "val": "modify_by",
- "label": "modify_by"
- }, {
- "val": "modify_time",
- "label": "modify_time"
- }, {
- "val": "use_scene",
- "label": "use_scene"
- }, {
- "val": "is_deleted",
- "label": "is_deleted"
- }, {
- "val": "delete_time",
- "label": "delete_time"
- }, {
- "val": "sort_num",
- "label": "sort_num"
- }, {
- "val": "time_stamp",
- "label": "time_stamp"
- }]
+ "viewtype": "tuplelist",
+ "elementCreator": "com.qlangtech.tis.plugin.datax.transformer.jdbcprop.JdbcPropertyElementCreatorFactory",
+ "enum": {
+ "_mcols": [{
+ "error_name": {
+ "impl": "com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn",
+ "literia": [{
+ "pairs": [{
+ "name": "virtual col",
+ "value": "test"
+ }]
+ }],
+ "name": "test"
+ },
+
+ "name": {
+ "updateModel": false,
+ "impl": "com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn",
+ "vals": {
+ "name": {
+ "updateModel": true,
+ "_primaryVal": "new_add_field",
+ "has_set_primaryVal": false,
+ "disabled": false,
+ "key": "name",
+ "pk": true,
+ "_eprops": {},
+ "placeholder": "",
+ "dateTimeFormat": "yyyy-MM-dd HH:mm:ss",
+ "required": true,
+ "type": 1
+ }
+ },
+ "displayName": "",
+ "showAllField": false,
+ "dspt": {
+ "impl": "com.qlangtech.tis.plugin.datax.transformer.impl.VirtualTargetColumn",
+ "pkField": "name",
+ "implUrl": "http://tis.pub/docs/plugin/plugins/#comqlangtechtisplugindataxtransformerimplvirtualtargetcolumn",
+ "displayName": "Virtual Column",
+ "extendPoint": "com.qlangtech.tis.plugin.datax.transformer.TargetColumn",
+ "containAdvance": false,
+ "veriflable": false,
+ "extractProps": {
+ "notebook": {
+ "activate": false,
+ "ability": false
+ }
+ },
+ "attrs": [{
+ "ord": 1,
+ "describable": false,
+ "pk": true,
+ "type": 1,
+ "key": "name",
+ "required": true
+ }]
+ }
+ },
+ "type": {
+ "columnSize": 32,
+ "decimalDigits": -1,
+ "type": 12,
+ "typeDesc": "varchar(32)",
+ "typeName": "VARCHAR"
+ },
+ "ip": {
+ "updateModel": false,
+ "has_set_primaryVal": false,
+ "disabled": false
+ }
+ }],
+ "isCollection": false,
+ "_typeMetas": [],
+ "tabColsMapper": {},
+ "dftType": {
+ "columnSize": 32,
+ "decimalDigits": -1,
+ "type": 12,
+ "typeDesc": "varchar(32)",
+ "typeName": "VARCHAR"
+ }
+ }
},
"placeholder": "",
"dateTimeFormat": "yyyy-MM-dd HH:mm:ss",
"required": true,
- "type": 5
+ "type": 8,
+ "_tupleViewType": "jdbcTypeProps"
}
},
"displayName": "CopyVal",
- "showAllField": false,
- "dspt": {
- "impl": "com.qlangtech.tis.plugin.datax.transformer.impl.CopyValUDF",
- "implUrl": "http://tis.pub/docs/plugin/plugins/#comqlangtechtisplugindataxtransformerimplcopyvaludf",
- "displayName": "CopyVal",
- "extendPoint": "com.qlangtech.tis.plugin.datax.transformer.UDFDefinition",
- "containAdvance": false,
- "veriflable": false,
- "extractProps": {
- "notebook": {
- "activate": false,
- "ability": false
- }
- },
- "attrs": [{
- "ord": 200,
- "eprops": {
- "enum": [{
- "val": "id",
- "label": "id"
- }, {
- "val": "emp_id",
- "label": "emp_id"
- }, {
- "val": "photo_sn",
- "label": "photo_sn"
- }, {
- "val": "photo_file",
- "label": "photo_file"
- }, {
- "val": "photo_url",
- "label": "photo_url"
- }, {
- "val": "photo_data",
- "label": "photo_data"
- }, {
- "val": "photo_sign",
- "label": "photo_sign"
- }, {
- "val": "is_analyse",
- "label": "is_analyse"
- }, {
- "val": "photo_time",
- "label": "photo_time"
- }, {
- "val": "is_active",
- "label": "is_active"
- }, {
- "val": "quality_score",
- "label": "quality_score"
- }, {
- "val": "create_by",
- "label": "create_by"
- }, {
- "val": "create_time",
- "label": "create_time"
- }, {
- "val": "modify_by",
- "label": "modify_by"
- }, {
- "val": "modify_time",
- "label": "modify_time"
- }, {
- "val": "use_scene",
- "label": "use_scene"
- }, {
- "val": "is_deleted",
- "label": "is_deleted"
- }, {
- "val": "delete_time",
- "label": "delete_time"
- }, {
- "val": "sort_num",
- "label": "sort_num"
- }, {
- "val": "time_stamp",
- "label": "time_stamp"
- }]
- },
- "describable": false,
- "pk": false,
- "type": 5,
- "key": "from",
- "required": true
- }]
- },
- "implUrl": "http://tis.pub/docs/plugin/plugins/#comqlangtechtisplugindataxtransformerimplcopyvaludf"
+ "showAllField": false
}
}]
\ No newline at end of file
diff --git a/tis-scala-compiler/src/test/java/com/qlangtech/tis/compiler/streamcode/TestGenerateDAOAndIncrScript.java b/tis-scala-compiler/src/test/java/com/qlangtech/tis/compiler/streamcode/TestGenerateDAOAndIncrScript.java
index 521ebca6c..2ccd3771f 100644
--- a/tis-scala-compiler/src/test/java/com/qlangtech/tis/compiler/streamcode/TestGenerateDAOAndIncrScript.java
+++ b/tis-scala-compiler/src/test/java/com/qlangtech/tis/compiler/streamcode/TestGenerateDAOAndIncrScript.java
@@ -126,5 +126,9 @@ public void setBizResult(Context context, Object result, boolean o) {
public void addErrorMessage(Context context, String msg) {
}
+ @Override
+ public String getCollectionName() {
+ throw new UnsupportedOperationException();
+ }
}
}