mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
fixed CanalAdmin instanceLog and polardbx columnar test
This commit is contained in:
@@ -39,13 +39,10 @@ public class ES7xTemplate implements ESTemplate {
|
|||||||
.getLogger(ESTemplate.class);
|
.getLogger(ESTemplate.class);
|
||||||
|
|
||||||
private static final int MAX_BATCH_SIZE = 1000;
|
private static final int MAX_BATCH_SIZE = 1000;
|
||||||
|
|
||||||
private ESConnection esConnection;
|
|
||||||
|
|
||||||
private ESBulkRequest esBulkRequest;
|
|
||||||
|
|
||||||
// es 字段类型本地缓存
|
// es 字段类型本地缓存
|
||||||
private static ConcurrentMap<String, Map<String, String>> esFieldTypes = new ConcurrentHashMap<>();
|
private static ConcurrentMap<String, Map<String, String>> esFieldTypes = new ConcurrentHashMap<>();
|
||||||
|
private ESConnection esConnection;
|
||||||
|
private ESBulkRequest esBulkRequest;
|
||||||
|
|
||||||
public ES7xTemplate(ESConnection esConnection){
|
public ES7xTemplate(ESConnection esConnection){
|
||||||
this.esConnection = esConnection;
|
this.esConnection = esConnection;
|
||||||
@@ -65,8 +62,9 @@ public class ES7xTemplate implements ESTemplate {
|
|||||||
if (mapping.getId() != null) {
|
if (mapping.getId() != null) {
|
||||||
String parentVal = (String) esFieldData.remove("$parent_routing");
|
String parentVal = (String) esFieldData.remove("$parent_routing");
|
||||||
if (mapping.isUpsert()) {
|
if (mapping.isUpsert()) {
|
||||||
ESUpdateRequest updateRequest = esConnection.new ES7xUpdateRequest(mapping.getIndex(),
|
ESUpdateRequest updateRequest = esConnection.new ES7xUpdateRequest(mapping.getIndex(), pkVal.toString())
|
||||||
pkVal.toString()).setDoc(esFieldData).setDocAsUpsert(true);
|
.setDoc(esFieldData)
|
||||||
|
.setDocAsUpsert(true);
|
||||||
if (StringUtils.isNotEmpty(parentVal)) {
|
if (StringUtils.isNotEmpty(parentVal)) {
|
||||||
updateRequest.setRouting(parentVal);
|
updateRequest.setRouting(parentVal);
|
||||||
}
|
}
|
||||||
@@ -283,7 +281,8 @@ public class ES7xTemplate implements ESTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getESDataFromDmlData(ESMapping mapping, Map<String, Object> dmlData, Map<String, Object> esFieldData) {
|
public Object getESDataFromDmlData(ESMapping mapping, Map<String, Object> dmlData,
|
||||||
|
Map<String, Object> esFieldData) {
|
||||||
SchemaItem schemaItem = mapping.getSchemaItem();
|
SchemaItem schemaItem = mapping.getSchemaItem();
|
||||||
String idFieldName = mapping.getId() == null ? mapping.getPk() : mapping.getId();
|
String idFieldName = mapping.getId() == null ? mapping.getPk() : mapping.getId();
|
||||||
Object resultIdVal = null;
|
Object resultIdVal = null;
|
||||||
@@ -307,8 +306,8 @@ public class ES7xTemplate implements ESTemplate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getESDataFromDmlData(ESMapping mapping,String owner, Map<String, Object> dmlData, Map<String, Object> dmlOld,
|
public Object getESDataFromDmlData(ESMapping mapping, String owner, Map<String, Object> dmlData,
|
||||||
Map<String, Object> esFieldData) {
|
Map<String, Object> dmlOld, Map<String, Object> esFieldData) {
|
||||||
SchemaItem schemaItem = mapping.getSchemaItem();
|
SchemaItem schemaItem = mapping.getSchemaItem();
|
||||||
String idFieldName = mapping.getId() == null ? mapping.getPk() : mapping.getId();
|
String idFieldName = mapping.getId() == null ? mapping.getPk() : mapping.getId();
|
||||||
Object resultIdVal = null;
|
Object resultIdVal = null;
|
||||||
@@ -329,7 +328,7 @@ public class ES7xTemplate implements ESTemplate {
|
|||||||
|
|
||||||
if (dmlOld.containsKey(columnName) && !mapping.getSkips().contains(fieldItem.getFieldName())) {
|
if (dmlOld.containsKey(columnName) && !mapping.getSkips().contains(fieldItem.getFieldName())) {
|
||||||
esFieldData.put(Util.cleanColumn(fieldItem.getFieldName()),
|
esFieldData.put(Util.cleanColumn(fieldItem.getFieldName()),
|
||||||
getValFromData(mapping, dmlData, fieldItem.getFieldName(), columnName));
|
getValFromData(mapping, dmlData, fieldItem.getFieldName(), columnName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,16 +55,9 @@ import com.alibaba.otter.canal.client.adapter.es.core.support.ESBulkRequest;
|
|||||||
public class ESConnection {
|
public class ESConnection {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ESConnection.class);
|
private static final Logger logger = LoggerFactory.getLogger(ESConnection.class);
|
||||||
|
|
||||||
public enum ESClientMode {
|
|
||||||
TRANSPORT, REST
|
|
||||||
}
|
|
||||||
|
|
||||||
private ESClientMode mode;
|
private ESClientMode mode;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
private TransportClient transportClient;
|
private TransportClient transportClient;
|
||||||
|
|
||||||
private RestHighLevelClient restHighLevelClient;
|
private RestHighLevelClient restHighLevelClient;
|
||||||
|
|
||||||
public ESConnection(String[] hosts, Map<String, String> properties, ESClientMode mode) throws UnknownHostException{
|
public ESConnection(String[] hosts, Map<String, String> properties, ESClientMode mode) throws UnknownHostException{
|
||||||
@@ -86,9 +79,10 @@ public class ESConnection {
|
|||||||
if (StringUtils.isNotEmpty(nameAndPwd) && nameAndPwd.contains(":")) {
|
if (StringUtils.isNotEmpty(nameAndPwd) && nameAndPwd.contains(":")) {
|
||||||
String[] nameAndPwdArr = nameAndPwd.split(":");
|
String[] nameAndPwdArr = nameAndPwd.split(":");
|
||||||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
|
||||||
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(nameAndPwdArr[0],
|
credentialsProvider.setCredentials(AuthScope.ANY,
|
||||||
nameAndPwdArr[1]));
|
new UsernamePasswordCredentials(nameAndPwdArr[0], nameAndPwdArr[1]));
|
||||||
restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
|
restClientBuilder.setHttpClientConfigCallback(
|
||||||
|
httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
|
||||||
}
|
}
|
||||||
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
|
restHighLevelClient = new RestHighLevelClient(restClientBuilder);
|
||||||
}
|
}
|
||||||
@@ -143,6 +137,78 @@ public class ESConnection {
|
|||||||
return mappingMetaData;
|
return mappingMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------ get/set ------
|
||||||
|
public ESClientMode getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMode(ESClientMode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransportClient getTransportClient() {
|
||||||
|
return transportClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransportClient(TransportClient transportClient) {
|
||||||
|
this.transportClient = transportClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestHighLevelClient getRestHighLevelClient() {
|
||||||
|
return restHighLevelClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
|
||||||
|
this.restHighLevelClient = restHighLevelClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHost createHttpHost(String uriStr) {
|
||||||
|
URI uri = URI.create(uriStr);
|
||||||
|
if (!org.springframework.util.StringUtils.hasLength(uri.getUserInfo())) {
|
||||||
|
return HttpHost.create(uri.toString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return HttpHost.create(new URI(uri
|
||||||
|
.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment())
|
||||||
|
.toString());
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ESClientMode {
|
||||||
|
TRANSPORT, REST
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ES7xBulkResponse implements ESBulkRequest.ESBulkResponse {
|
||||||
|
|
||||||
|
private BulkResponse bulkResponse;
|
||||||
|
|
||||||
|
public ES7xBulkResponse(BulkResponse bulkResponse){
|
||||||
|
this.bulkResponse = bulkResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFailures() {
|
||||||
|
return bulkResponse.hasFailures();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processFailBulkResponse(String errorMsg) {
|
||||||
|
for (BulkItemResponse itemResponse : bulkResponse.getItems()) {
|
||||||
|
if (!itemResponse.isFailed()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemResponse.getFailure().getStatus() == RestStatus.NOT_FOUND) {
|
||||||
|
logger.error(itemResponse.getFailureMessage());
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(errorMsg + itemResponse.getFailureMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ES7xIndexRequest implements ESBulkRequest.ESIndexRequest {
|
public class ES7xIndexRequest implements ESBulkRequest.ESIndexRequest {
|
||||||
|
|
||||||
private IndexRequestBuilder indexRequestBuilder;
|
private IndexRequestBuilder indexRequestBuilder;
|
||||||
@@ -443,71 +509,4 @@ public class ESConnection {
|
|||||||
this.bulkRequest = bulkRequest;
|
this.bulkRequest = bulkRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ES7xBulkResponse implements ESBulkRequest.ESBulkResponse {
|
|
||||||
|
|
||||||
private BulkResponse bulkResponse;
|
|
||||||
|
|
||||||
public ES7xBulkResponse(BulkResponse bulkResponse){
|
|
||||||
this.bulkResponse = bulkResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFailures() {
|
|
||||||
return bulkResponse.hasFailures();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processFailBulkResponse(String errorMsg) {
|
|
||||||
for (BulkItemResponse itemResponse : bulkResponse.getItems()) {
|
|
||||||
if (!itemResponse.isFailed()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemResponse.getFailure().getStatus() == RestStatus.NOT_FOUND) {
|
|
||||||
logger.error(itemResponse.getFailureMessage());
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException(errorMsg + itemResponse.getFailureMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------ get/set ------
|
|
||||||
public ESClientMode getMode() {
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMode(ESClientMode mode) {
|
|
||||||
this.mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TransportClient getTransportClient() {
|
|
||||||
return transportClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTransportClient(TransportClient transportClient) {
|
|
||||||
this.transportClient = transportClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RestHighLevelClient getRestHighLevelClient() {
|
|
||||||
return restHighLevelClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
|
|
||||||
this.restHighLevelClient = restHighLevelClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHost createHttpHost(String uriStr) {
|
|
||||||
URI uri = URI.create(uriStr);
|
|
||||||
if (!org.springframework.util.StringUtils.hasLength(uri.getUserInfo())) {
|
|
||||||
return HttpHost.create(uri.toString());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return HttpHost.create(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(),
|
|
||||||
uri.getQuery(), uri.getFragment()).toString());
|
|
||||||
} catch (URISyntaxException ex) {
|
|
||||||
throw new IllegalStateException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
package com.alibaba.otter.canal.client.adapter.es8x;
|
package com.alibaba.otter.canal.client.adapter.es8x;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
|
|
||||||
import com.alibaba.otter.canal.client.adapter.es.core.ESAdapter;
|
import com.alibaba.otter.canal.client.adapter.es.core.ESAdapter;
|
||||||
import com.alibaba.otter.canal.client.adapter.es.core.config.ESSyncConfig;
|
import com.alibaba.otter.canal.client.adapter.es.core.config.ESSyncConfig;
|
||||||
import com.alibaba.otter.canal.client.adapter.es8x.etl.ESEtlService;
|
import com.alibaba.otter.canal.client.adapter.es8x.etl.ESEtlService;
|
||||||
@@ -9,13 +18,6 @@ import com.alibaba.otter.canal.client.adapter.support.DatasourceConfig;
|
|||||||
import com.alibaba.otter.canal.client.adapter.support.EtlResult;
|
import com.alibaba.otter.canal.client.adapter.support.EtlResult;
|
||||||
import com.alibaba.otter.canal.client.adapter.support.OuterAdapterConfig;
|
import com.alibaba.otter.canal.client.adapter.support.OuterAdapterConfig;
|
||||||
import com.alibaba.otter.canal.client.adapter.support.SPI;
|
import com.alibaba.otter.canal.client.adapter.support.SPI;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ES 8.x 外部适配器
|
* ES 8.x 外部适配器
|
||||||
|
|||||||
@@ -39,13 +39,10 @@ public class ES8xTemplate implements ESTemplate {
|
|||||||
.getLogger(ESTemplate.class);
|
.getLogger(ESTemplate.class);
|
||||||
|
|
||||||
private static final int MAX_BATCH_SIZE = 1000;
|
private static final int MAX_BATCH_SIZE = 1000;
|
||||||
|
|
||||||
private ESConnection esConnection;
|
|
||||||
|
|
||||||
private ESBulkRequest esBulkRequest;
|
|
||||||
|
|
||||||
// es 字段类型本地缓存
|
// es 字段类型本地缓存
|
||||||
private static ConcurrentMap<String, Map<String, String>> esFieldTypes = new ConcurrentHashMap<>();
|
private static ConcurrentMap<String, Map<String, String>> esFieldTypes = new ConcurrentHashMap<>();
|
||||||
|
private ESConnection esConnection;
|
||||||
|
private ESBulkRequest esBulkRequest;
|
||||||
|
|
||||||
public ES8xTemplate(ESConnection esConnection){
|
public ES8xTemplate(ESConnection esConnection){
|
||||||
this.esConnection = esConnection;
|
this.esConnection = esConnection;
|
||||||
|
|||||||
@@ -147,6 +147,57 @@ public class ESConnection {
|
|||||||
return mappingMetaData;
|
return mappingMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RestHighLevelClient getRestHighLevelClient() {
|
||||||
|
return restHighLevelClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
|
||||||
|
this.restHighLevelClient = restHighLevelClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHost createHttpHost(String uriStr) {
|
||||||
|
URI uri = URI.create(uriStr);
|
||||||
|
if (!org.springframework.util.StringUtils.hasLength(uri.getUserInfo())) {
|
||||||
|
return HttpHost.create(uri.toString());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return HttpHost.create(new URI(uri
|
||||||
|
.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment())
|
||||||
|
.toString());
|
||||||
|
} catch (URISyntaxException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ES8xBulkResponse implements ESBulkRequest.ESBulkResponse {
|
||||||
|
|
||||||
|
private BulkResponse bulkResponse;
|
||||||
|
|
||||||
|
public ES8xBulkResponse(BulkResponse bulkResponse){
|
||||||
|
this.bulkResponse = bulkResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFailures() {
|
||||||
|
return bulkResponse.hasFailures();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processFailBulkResponse(String errorMsg) {
|
||||||
|
for (BulkItemResponse itemResponse : bulkResponse.getItems()) {
|
||||||
|
if (!itemResponse.isFailed()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemResponse.getFailure().getStatus() == RestStatus.NOT_FOUND) {
|
||||||
|
logger.error(itemResponse.getFailureMessage());
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(errorMsg + itemResponse.getFailureMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ES8xIndexRequest implements ESBulkRequest.ESIndexRequest {
|
public class ES8xIndexRequest implements ESBulkRequest.ESIndexRequest {
|
||||||
|
|
||||||
private IndexRequestBuilder indexRequestBuilder;
|
private IndexRequestBuilder indexRequestBuilder;
|
||||||
@@ -395,55 +446,4 @@ public class ESConnection {
|
|||||||
this.bulkRequest = bulkRequest;
|
this.bulkRequest = bulkRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ES8xBulkResponse implements ESBulkRequest.ESBulkResponse {
|
|
||||||
|
|
||||||
private BulkResponse bulkResponse;
|
|
||||||
|
|
||||||
public ES8xBulkResponse(BulkResponse bulkResponse){
|
|
||||||
this.bulkResponse = bulkResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFailures() {
|
|
||||||
return bulkResponse.hasFailures();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processFailBulkResponse(String errorMsg) {
|
|
||||||
for (BulkItemResponse itemResponse : bulkResponse.getItems()) {
|
|
||||||
if (!itemResponse.isFailed()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itemResponse.getFailure().getStatus() == RestStatus.NOT_FOUND) {
|
|
||||||
logger.error(itemResponse.getFailureMessage());
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException(errorMsg + itemResponse.getFailureMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RestHighLevelClient getRestHighLevelClient() {
|
|
||||||
return restHighLevelClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
|
|
||||||
this.restHighLevelClient = restHighLevelClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
private HttpHost createHttpHost(String uriStr) {
|
|
||||||
URI uri = URI.create(uriStr);
|
|
||||||
if (!org.springframework.util.StringUtils.hasLength(uri.getUserInfo())) {
|
|
||||||
return HttpHost.create(uri.toString());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return HttpHost.create(new URI(uri
|
|
||||||
.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment())
|
|
||||||
.toString());
|
|
||||||
} catch (URISyntaxException ex) {
|
|
||||||
throw new IllegalStateException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.alibaba.otter.canal.common.utils;
|
package com.alibaba.otter.canal.common.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -88,8 +89,43 @@ public class FileUtils {
|
|||||||
return res.toString();
|
return res.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
/**
|
||||||
String res = readFileFromOffset("test2.txt", 2, "UTF-8");
|
* 校验自定义的文件名,是否在允许的基目录范围内,如何合法就返回全路径,否则就直接报错
|
||||||
System.out.println(res);
|
*
|
||||||
|
* @param baseDir
|
||||||
|
* @param destination
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String validateFileName(String baseDir, String destination) {
|
||||||
|
try {
|
||||||
|
// 验证 destination 是否在允许的基目录范围内
|
||||||
|
String basePath = new File(baseDir).getCanonicalPath();
|
||||||
|
String fullPath = new File(basePath, destination).getCanonicalPath();
|
||||||
|
|
||||||
|
// 检查 fullPath 是否以 basePath 开头
|
||||||
|
if (!fullPath.startsWith(basePath + File.separator)) {
|
||||||
|
throw new IllegalArgumentException("Invalid destination path");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullPath;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to read file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
String fullPath = validateFileName("/tmp/", "1.txt");
|
||||||
|
System.out.println(fullPath);
|
||||||
|
System.out.println(org.apache.commons.io.FileUtils.readLines(new File(fullPath)));
|
||||||
|
|
||||||
|
fullPath = validateFileName("/tmp/", "test");
|
||||||
|
fullPath = validateFileName(fullPath,"1.txt");
|
||||||
|
System.out.println(fullPath);
|
||||||
|
System.out.println(org.apache.commons.io.FileUtils.readLines(new File(fullPath)));
|
||||||
|
|
||||||
|
|
||||||
|
fullPath = validateFileName("/tmp/", "../etc/hosts");
|
||||||
|
System.out.println(fullPath);
|
||||||
|
System.out.println(org.apache.commons.io.FileUtils.readLines(new File(fullPath)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.alibaba.otter.canal.deployer.admin;
|
package com.alibaba.otter.canal.deployer.admin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -203,7 +204,10 @@ public class CanalAdminController implements CanalAdmin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String listInstanceLog(String destination) {
|
public String listInstanceLog(String destination) {
|
||||||
Collection<File> files = org.apache.commons.io.FileUtils.listFiles(new File("../logs/" + destination + "/"),
|
// 校验destination
|
||||||
|
String desPath = FileUtils.validateFileName("../logs", destination);
|
||||||
|
|
||||||
|
Collection<File> files = org.apache.commons.io.FileUtils.listFiles(new File(desPath),
|
||||||
TrueFileFilter.TRUE,
|
TrueFileFilter.TRUE,
|
||||||
TrueFileFilter.TRUE);
|
TrueFileFilter.TRUE);
|
||||||
List<String> names = files.stream().map(File::getName).collect(Collectors.toList());
|
List<String> names = files.stream().map(File::getName).collect(Collectors.toList());
|
||||||
@@ -215,7 +219,12 @@ public class CanalAdminController implements CanalAdmin {
|
|||||||
if (StringUtils.isEmpty(fileName)) {
|
if (StringUtils.isEmpty(fileName)) {
|
||||||
fileName = destination + ".log";
|
fileName = destination + ".log";
|
||||||
}
|
}
|
||||||
return FileUtils.readFileFromOffset("../logs/" + destination + "/" + fileName, lines, "UTF-8");
|
|
||||||
|
// 分别校验destination和fileName目录
|
||||||
|
String desPath = FileUtils.validateFileName("../logs", destination);
|
||||||
|
String fullPath = FileUtils.validateFileName(desPath , fileName);
|
||||||
|
|
||||||
|
return FileUtils.readFileFromOffset(fullPath, lines, "UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceAction getInstanceAction(String destination) {
|
private InstanceAction getInstanceAction(String destination) {
|
||||||
|
|||||||
@@ -131,4 +131,26 @@ public class MemoryTableMeta_DDL_Test {
|
|||||||
Assert.assertTrue(field.isUnique());
|
Assert.assertTrue(field.isUnique());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_polardbx_columnar_index () throws Throwable {
|
||||||
|
MemoryTableMeta memoryTableMeta = new MemoryTableMeta();
|
||||||
|
URL url = Thread.currentThread().getContextClassLoader().getResource("dummy.txt");
|
||||||
|
File dummyFile = new File(url.getFile());
|
||||||
|
File create = new File(dummyFile.getParent() + "/ddl", "ddl_test4.sql");
|
||||||
|
String sql = StringUtils.join(IOUtils.readLines(new FileInputStream(create)), "\n");
|
||||||
|
memoryTableMeta.apply(null, "test", sql, null);
|
||||||
|
|
||||||
|
List<String> tableNames = new ArrayList<>();
|
||||||
|
for (Schema schema : memoryTableMeta.getRepository().getSchemas()) {
|
||||||
|
tableNames.addAll(schema.showTables());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String table : tableNames) {
|
||||||
|
TableMeta sourceMeta = memoryTableMeta.find("test", table);
|
||||||
|
TableMeta.FieldMeta field = sourceMeta.getFieldMetaByName("address");
|
||||||
|
System.out.println(sourceMeta.toString());
|
||||||
|
Assert.assertTrue(field.isUnique());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
parse/src/test/resources/ddl/ddl_test4.sql
Normal file
1
parse/src/test/resources/ddl/ddl_test4.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE `test_columnar` (
|
||||||
Reference in New Issue
Block a user