Kerwin
3 years ago
committed by
GitHub
150 changed files with 11732 additions and 285 deletions
@ -0,0 +1,84 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* command types |
||||||
|
*/ |
||||||
|
public enum CommandType { |
||||||
|
|
||||||
|
/** |
||||||
|
* command types |
||||||
|
* 0 start a new process |
||||||
|
* 1 start a new process from current nodes |
||||||
|
* 2 recover tolerance fault process |
||||||
|
* 3 recover suspended process |
||||||
|
* 4 start process from failure task nodes |
||||||
|
* 5 complement data |
||||||
|
* 6 start a new process from scheduler |
||||||
|
* 7 repeat running a process |
||||||
|
* 8 pause a process |
||||||
|
* 9 stop a process |
||||||
|
* 10 recover waiting thread |
||||||
|
*/ |
||||||
|
START_PROCESS(0, "start a new process"), |
||||||
|
START_CURRENT_TASK_PROCESS(1, "start a new process from current nodes"), |
||||||
|
RECOVER_TOLERANCE_FAULT_PROCESS(2, "recover tolerance fault process"), |
||||||
|
RECOVER_SUSPENDED_PROCESS(3, "recover suspended process"), |
||||||
|
START_FAILURE_TASK_PROCESS(4, "start process from failure task nodes"), |
||||||
|
COMPLEMENT_DATA(5, "complement data"), |
||||||
|
SCHEDULER(6, "start a new process from scheduler"), |
||||||
|
REPEAT_RUNNING(7, "repeat running a process"), |
||||||
|
PAUSE(8, "pause a process"), |
||||||
|
STOP(9, "stop a process"), |
||||||
|
RECOVER_WAITING_THREAD(10, "recover waiting thread"); |
||||||
|
|
||||||
|
CommandType(int code, String descp) { |
||||||
|
this.code = code; |
||||||
|
this.descp = descp; |
||||||
|
} |
||||||
|
|
||||||
|
private final int code; |
||||||
|
private final String descp; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescp() { |
||||||
|
return descp; |
||||||
|
} |
||||||
|
|
||||||
|
private static final Map<Integer, CommandType> COMMAND_TYPE_MAP = new HashMap<>(); |
||||||
|
|
||||||
|
static { |
||||||
|
for (CommandType commandType : CommandType.values()) { |
||||||
|
COMMAND_TYPE_MAP.put(commandType.code,commandType); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static CommandType of(Integer status) { |
||||||
|
if (COMMAND_TYPE_MAP.containsKey(status)) { |
||||||
|
return COMMAND_TYPE_MAP.get(status); |
||||||
|
} |
||||||
|
throw new IllegalArgumentException("invalid status : " + status); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
/** |
||||||
|
* data types in user define parameter |
||||||
|
*/ |
||||||
|
public enum DataType { |
||||||
|
/** |
||||||
|
* 0 string |
||||||
|
* 1 integer |
||||||
|
* 2 long |
||||||
|
* 3 float |
||||||
|
* 4 double |
||||||
|
* 5 date, "YYYY-MM-DD" |
||||||
|
* 6 time, "HH:MM:SS" |
||||||
|
* 7 time stamp |
||||||
|
* 8 Boolean |
||||||
|
* 9 list <String> |
||||||
|
*/ |
||||||
|
VARCHAR,INTEGER,LONG,FLOAT,DOUBLE,DATE,TIME,TIMESTAMP,BOOLEAN,LIST |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
public enum DbConnectType { |
||||||
|
|
||||||
|
ORACLE_SERVICE_NAME(0, "Oracle Service Name"), |
||||||
|
ORACLE_SID(1, "Oracle SID"); |
||||||
|
|
||||||
|
DbConnectType(int code, String descp) { |
||||||
|
this.code = code; |
||||||
|
this.descp = descp; |
||||||
|
} |
||||||
|
|
||||||
|
private final int code; |
||||||
|
|
||||||
|
private final String descp; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescp() { |
||||||
|
return descp; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
import static java.util.stream.Collectors.toMap; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import com.google.common.base.Functions; |
||||||
|
|
||||||
|
public enum DbType { |
||||||
|
|
||||||
|
MYSQL(0), |
||||||
|
POSTGRESQL(1), |
||||||
|
HIVE(2), |
||||||
|
SPARK(3), |
||||||
|
CLICKHOUSE(4), |
||||||
|
ORACLE(5), |
||||||
|
SQLSERVER(6), |
||||||
|
DB2(7), |
||||||
|
PRESTO(8), |
||||||
|
H2(9); |
||||||
|
|
||||||
|
DbType(int code) { |
||||||
|
this.code = code; |
||||||
|
} |
||||||
|
|
||||||
|
private final int code; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
private static final Map<Integer, DbType> DB_TYPE_MAP = |
||||||
|
Arrays.stream(DbType.values()).collect(toMap(DbType::getCode, Functions.identity())); |
||||||
|
|
||||||
|
public static DbType of(int type) { |
||||||
|
if (DB_TYPE_MAP.containsKey(type)) { |
||||||
|
return DB_TYPE_MAP.get(type); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +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. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
/** |
||||||
|
* have_script |
||||||
|
* have_file |
||||||
|
* can_retry |
||||||
|
* have_arr_variables |
||||||
|
* have_map_variables |
||||||
|
* have_alert |
||||||
|
*/ |
||||||
|
public enum Flag { |
||||||
|
/** |
||||||
|
* 0 no |
||||||
|
* 1 yes |
||||||
|
*/ |
||||||
|
NO(0, "no"), |
||||||
|
YES(1, "yes"); |
||||||
|
|
||||||
|
Flag(int code, String descp) { |
||||||
|
this.code = code; |
||||||
|
this.descp = descp; |
||||||
|
} |
||||||
|
|
||||||
|
private final int code; |
||||||
|
private final String descp; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescp() { |
||||||
|
return descp; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
/** |
||||||
|
* data base types |
||||||
|
*/ |
||||||
|
public enum ResUploadType { |
||||||
|
/** |
||||||
|
* 0 hdfs |
||||||
|
* 1 s3 |
||||||
|
* 2 none |
||||||
|
*/ |
||||||
|
HDFS,S3,NONE |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.enums; |
||||||
|
|
||||||
|
/** |
||||||
|
* task timeout strategy |
||||||
|
*/ |
||||||
|
public enum TaskTimeoutStrategy { |
||||||
|
/** |
||||||
|
* 0 warn |
||||||
|
* 1 failed |
||||||
|
* 2 warn+failed |
||||||
|
*/ |
||||||
|
WARN(0, "warn"), |
||||||
|
FAILED(1,"failed"), |
||||||
|
WARNFAILED(2,"warnfailed"); |
||||||
|
|
||||||
|
TaskTimeoutStrategy(int code, String descp) { |
||||||
|
this.code = code; |
||||||
|
this.descp = descp; |
||||||
|
} |
||||||
|
|
||||||
|
private final int code; |
||||||
|
private final String descp; |
||||||
|
|
||||||
|
public int getCode() { |
||||||
|
return code; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescp() { |
||||||
|
return descp; |
||||||
|
} |
||||||
|
|
||||||
|
public static TaskTimeoutStrategy of(int status) { |
||||||
|
for (TaskTimeoutStrategy es : values()) { |
||||||
|
if (es.getCode() == status) { |
||||||
|
return es; |
||||||
|
} |
||||||
|
} |
||||||
|
throw new IllegalArgumentException("invalid status : " + status); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,188 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext; |
||||||
|
import com.fasterxml.jackson.databind.KeyDeserializer; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf function |
||||||
|
*/ |
||||||
|
public class UdfFuncBean { |
||||||
|
/** |
||||||
|
* id |
||||||
|
*/ |
||||||
|
private int id; |
||||||
|
/** |
||||||
|
* user id |
||||||
|
*/ |
||||||
|
private int userId; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf function name |
||||||
|
*/ |
||||||
|
private String funcName; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf class name |
||||||
|
*/ |
||||||
|
private String className; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf argument types |
||||||
|
*/ |
||||||
|
private String argTypes; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf data base |
||||||
|
*/ |
||||||
|
private String database; |
||||||
|
|
||||||
|
/** |
||||||
|
* udf description |
||||||
|
*/ |
||||||
|
private String description; |
||||||
|
|
||||||
|
/** |
||||||
|
* resource id |
||||||
|
*/ |
||||||
|
private int resourceId; |
||||||
|
|
||||||
|
/** |
||||||
|
* resource name |
||||||
|
*/ |
||||||
|
private String resourceName; |
||||||
|
|
||||||
|
public int getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(int id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public int getUserId() { |
||||||
|
return userId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserId(int userId) { |
||||||
|
this.userId = userId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getFuncName() { |
||||||
|
return funcName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setFuncName(String funcName) { |
||||||
|
this.funcName = funcName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getClassName() { |
||||||
|
return className; |
||||||
|
} |
||||||
|
|
||||||
|
public void setClassName(String className) { |
||||||
|
this.className = className; |
||||||
|
} |
||||||
|
|
||||||
|
public String getArgTypes() { |
||||||
|
return argTypes; |
||||||
|
} |
||||||
|
|
||||||
|
public void setArgTypes(String argTypes) { |
||||||
|
this.argTypes = argTypes; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDatabase() { |
||||||
|
return database; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDatabase(String database) { |
||||||
|
this.database = database; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescription() { |
||||||
|
return description; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDescription(String description) { |
||||||
|
this.description = description; |
||||||
|
} |
||||||
|
|
||||||
|
public int getResourceId() { |
||||||
|
return resourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResourceId(int resourceId) { |
||||||
|
this.resourceId = resourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public String getResourceName() { |
||||||
|
return resourceName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResourceName(String resourceName) { |
||||||
|
this.resourceName = resourceName; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object o) { |
||||||
|
if (this == o) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
if (o == null || getClass() != o.getClass()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
UdfFuncBean udfFunc = (UdfFuncBean) o; |
||||||
|
|
||||||
|
if (id != udfFunc.id) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
return !(funcName != null ? !funcName.equals(udfFunc.funcName) : udfFunc.funcName != null); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() { |
||||||
|
int result = id; |
||||||
|
result = 31 * result + (funcName != null ? funcName.hashCode() : 0); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return JSONUtils.toJsonString(this); |
||||||
|
} |
||||||
|
|
||||||
|
public static class UdfFuncDeserializer extends KeyDeserializer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException { |
||||||
|
if (StringUtils.isBlank(key)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return JSONUtils.parseObject(key, UdfFuncBean.class); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
public abstract class AbstractDatasourceProcessor implements DatasourceProcessor { |
||||||
|
|
||||||
|
private static final Pattern IPV4_PATTERN = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.]+$"); |
||||||
|
|
||||||
|
private static final Pattern IPV6_PATTERN = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.\\:\\[\\]]+$"); |
||||||
|
|
||||||
|
private static final Pattern DATABASE_PATTER = Pattern.compile("^[a-zA-Z0-9\\_\\-\\.]+$"); |
||||||
|
|
||||||
|
private static final Pattern PARAMS_PATTER = Pattern.compile("^[a-zA-Z0-9\\-\\_\\/]+$"); |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkDatasourceParam(BaseDataSourceParamDTO baseDataSourceParamDTO) { |
||||||
|
checkHost(baseDataSourceParamDTO.getHost()); |
||||||
|
checkDatasourcePatter(baseDataSourceParamDTO.getDatabase()); |
||||||
|
checkOther(baseDataSourceParamDTO.getOther()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Check the host is valid |
||||||
|
* |
||||||
|
* @param host datasource host |
||||||
|
*/ |
||||||
|
protected void checkHost(String host) { |
||||||
|
if (!IPV4_PATTERN.matcher(host).matches() || !IPV6_PATTERN.matcher(host).matches()) { |
||||||
|
throw new IllegalArgumentException("datasource host illegal"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* check database name is valid |
||||||
|
* |
||||||
|
* @param database database name |
||||||
|
*/ |
||||||
|
protected void checkDatasourcePatter(String database) { |
||||||
|
if (!DATABASE_PATTER.matcher(database).matches()) { |
||||||
|
throw new IllegalArgumentException("datasource name illegal"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* check other is valid |
||||||
|
* |
||||||
|
* @param other other |
||||||
|
*/ |
||||||
|
protected void checkOther(Map<String, String> other) { |
||||||
|
if (MapUtils.isEmpty(other)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
boolean paramsCheck = other.entrySet().stream().allMatch(p -> PARAMS_PATTER.matcher(p.getValue()).matches()); |
||||||
|
if (!paramsCheck) { |
||||||
|
throw new IllegalArgumentException("datasource other params illegal"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickhouseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerConnectionParam; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include; |
||||||
|
|
||||||
|
/** |
||||||
|
* The base model of connection param |
||||||
|
* <p> |
||||||
|
* {@link ClickhouseConnectionParam} |
||||||
|
* {@link Db2ConnectionParam} |
||||||
|
* {@link HiveConnectionParam} |
||||||
|
* {@link MysqlConnectionParam} |
||||||
|
* {@link OracleConnectionParam} |
||||||
|
* {@link PostgreSqlConnectionParam} |
||||||
|
* {@link PrestoConnectionParam} |
||||||
|
* {@link SparkConnectionParam} |
||||||
|
* {@link SqlServerConnectionParam} |
||||||
|
*/ |
||||||
|
@JsonInclude(Include.NON_NULL) |
||||||
|
public abstract class BaseConnectionParam implements ConnectionParam { |
||||||
|
|
||||||
|
protected String user; |
||||||
|
|
||||||
|
protected String password; |
||||||
|
|
||||||
|
protected String address; |
||||||
|
|
||||||
|
protected String database; |
||||||
|
|
||||||
|
protected String jdbcUrl; |
||||||
|
|
||||||
|
protected String other; |
||||||
|
|
||||||
|
public String getUser() { |
||||||
|
return user; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUser(String user) { |
||||||
|
this.user = user; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPassword() { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPassword(String password) { |
||||||
|
this.password = password; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAddress() { |
||||||
|
return address; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAddress(String address) { |
||||||
|
this.address = address; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDatabase() { |
||||||
|
return database; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDatabase(String database) { |
||||||
|
this.database = database; |
||||||
|
} |
||||||
|
|
||||||
|
public String getJdbcUrl() { |
||||||
|
return jdbcUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJdbcUrl(String jdbcUrl) { |
||||||
|
this.jdbcUrl = jdbcUrl; |
||||||
|
} |
||||||
|
|
||||||
|
public String getOther() { |
||||||
|
return other; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOther(String other) { |
||||||
|
this.other = other; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickHouseDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2DatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkDatasourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerDatasourceParamDTO; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes; |
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
||||||
|
|
||||||
|
/** |
||||||
|
* Basic datasource params submitted to api. |
||||||
|
* <p> |
||||||
|
* see {@link MysqlDatasourceParamDTO} |
||||||
|
* see {@link PostgreSqlDatasourceParamDTO} |
||||||
|
* see {@link HiveDataSourceParamDTO} |
||||||
|
* see {@link SparkDatasourceParamDTO} |
||||||
|
* see {@link ClickHouseDatasourceParamDTO} |
||||||
|
* see {@link OracleDatasourceParamDTO} |
||||||
|
* see {@link SqlServerDatasourceParamDTO} |
||||||
|
* see {@link Db2DatasourceParamDTO} |
||||||
|
* see {@link PrestoDatasourceParamDTO} |
||||||
|
*/ |
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") |
||||||
|
@JsonSubTypes(value = { |
||||||
|
@JsonSubTypes.Type(value = MysqlDatasourceParamDTO.class, name = "MYSQL"), |
||||||
|
@JsonSubTypes.Type(value = PostgreSqlDatasourceParamDTO.class, name = "POSTGRESQL"), |
||||||
|
@JsonSubTypes.Type(value = HiveDataSourceParamDTO.class, name = "HIVE"), |
||||||
|
@JsonSubTypes.Type(value = SparkDatasourceParamDTO.class, name = "SPARK"), |
||||||
|
@JsonSubTypes.Type(value = ClickHouseDatasourceParamDTO.class, name = "CLICKHOUSE"), |
||||||
|
@JsonSubTypes.Type(value = OracleDatasourceParamDTO.class, name = "ORACLE"), |
||||||
|
@JsonSubTypes.Type(value = SqlServerDatasourceParamDTO.class, name = "SQLSERVER"), |
||||||
|
@JsonSubTypes.Type(value = Db2DatasourceParamDTO.class, name = "DB2"), |
||||||
|
@JsonSubTypes.Type(value = PrestoDatasourceParamDTO.class, name = "PRESTO"), |
||||||
|
}) |
||||||
|
public abstract class BaseDataSourceParamDTO implements Serializable { |
||||||
|
|
||||||
|
protected Integer id; |
||||||
|
|
||||||
|
protected String name; |
||||||
|
|
||||||
|
protected String note; |
||||||
|
|
||||||
|
protected String host; |
||||||
|
|
||||||
|
protected Integer port; |
||||||
|
|
||||||
|
protected String database; |
||||||
|
|
||||||
|
protected String userName; |
||||||
|
|
||||||
|
protected String password; |
||||||
|
|
||||||
|
protected Map<String, String> other; |
||||||
|
|
||||||
|
public Integer getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
public void setId(Integer id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public void setName(String name) { |
||||||
|
this.name = name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getNote() { |
||||||
|
return note; |
||||||
|
} |
||||||
|
|
||||||
|
public void setNote(String note) { |
||||||
|
this.note = note; |
||||||
|
} |
||||||
|
|
||||||
|
public String getHost() { |
||||||
|
return host; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHost(String host) { |
||||||
|
this.host = host; |
||||||
|
} |
||||||
|
|
||||||
|
public Integer getPort() { |
||||||
|
return port; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPort(Integer port) { |
||||||
|
this.port = port; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDatabase() { |
||||||
|
return database; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDatabase(String database) { |
||||||
|
this.database = database; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUserName() { |
||||||
|
return userName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUserName(String userName) { |
||||||
|
this.userName = userName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPassword() { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPassword(String password) { |
||||||
|
this.password = password; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<String, String> getOther() { |
||||||
|
return other; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOther(Map<String, String> other) { |
||||||
|
this.other = other; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get the datasource type |
||||||
|
* see{@link DbType} |
||||||
|
* |
||||||
|
* @return datasource type code |
||||||
|
*/ |
||||||
|
public abstract DbType getType(); |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
public class BaseHdfsConnectionParam extends BaseConnectionParam { |
||||||
|
protected String principal; |
||||||
|
protected String javaSecurityKrb5Conf; |
||||||
|
protected String loginUserKeytabUsername; |
||||||
|
protected String loginUserKeytabPath; |
||||||
|
|
||||||
|
public String getPrincipal() { |
||||||
|
return principal; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPrincipal(String principal) { |
||||||
|
this.principal = principal; |
||||||
|
} |
||||||
|
|
||||||
|
public String getJavaSecurityKrb5Conf() { |
||||||
|
return javaSecurityKrb5Conf; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJavaSecurityKrb5Conf(String javaSecurityKrb5Conf) { |
||||||
|
this.javaSecurityKrb5Conf = javaSecurityKrb5Conf; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLoginUserKeytabUsername() { |
||||||
|
return loginUserKeytabUsername; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoginUserKeytabUsername(String loginUserKeytabUsername) { |
||||||
|
this.loginUserKeytabUsername = loginUserKeytabUsername; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLoginUserKeytabPath() { |
||||||
|
return loginUserKeytabPath; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoginUserKeytabPath(String loginUserKeytabPath) { |
||||||
|
this.loginUserKeytabPath = loginUserKeytabPath; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
public abstract class BaseHdfsDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
protected String principal; |
||||||
|
|
||||||
|
protected String javaSecurityKrb5Conf; |
||||||
|
|
||||||
|
protected String loginUserKeytabUsername; |
||||||
|
|
||||||
|
protected String loginUserKeytabPath; |
||||||
|
|
||||||
|
public String getPrincipal() { |
||||||
|
return principal; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPrincipal(String principal) { |
||||||
|
this.principal = principal; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLoginUserKeytabUsername() { |
||||||
|
return loginUserKeytabUsername; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoginUserKeytabUsername(String loginUserKeytabUsername) { |
||||||
|
this.loginUserKeytabUsername = loginUserKeytabUsername; |
||||||
|
} |
||||||
|
|
||||||
|
public String getLoginUserKeytabPath() { |
||||||
|
return loginUserKeytabPath; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLoginUserKeytabPath(String loginUserKeytabPath) { |
||||||
|
this.loginUserKeytabPath = loginUserKeytabPath; |
||||||
|
} |
||||||
|
|
||||||
|
public String getJavaSecurityKrb5Conf() { |
||||||
|
return javaSecurityKrb5Conf; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJavaSecurityKrb5Conf(String javaSecurityKrb5Conf) { |
||||||
|
this.javaSecurityKrb5Conf = javaSecurityKrb5Conf; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
/** |
||||||
|
* The model of Datasource Connection param |
||||||
|
*/ |
||||||
|
public interface ConnectionParam extends Serializable { |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.SQLException; |
||||||
|
|
||||||
|
public interface DatasourceProcessor { |
||||||
|
|
||||||
|
/** |
||||||
|
* check datasource param is valid |
||||||
|
*/ |
||||||
|
void checkDatasourceParam(BaseDataSourceParamDTO datasourceParam); |
||||||
|
|
||||||
|
/** |
||||||
|
* create BaseDataSourceParamDTO by connectionJson |
||||||
|
* |
||||||
|
* @param connectionJson see{@link org.apache.dolphinscheduler.dao.entity.Datasource} |
||||||
|
* @return {@link BaseDataSourceParamDTO} |
||||||
|
*/ |
||||||
|
BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson); |
||||||
|
|
||||||
|
/** |
||||||
|
* create datasource connection parameter which will be stored at DataSource |
||||||
|
* <p> |
||||||
|
* see {@code org.apache.dolphinscheduler.dao.entity.DataSource.connectionParams} |
||||||
|
*/ |
||||||
|
ConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam); |
||||||
|
|
||||||
|
/** |
||||||
|
* deserialize json to datasource connection param |
||||||
|
* |
||||||
|
* @param connectionJson {@code org.apache.dolphinscheduler.dao.entity.DataSource.connectionParams} |
||||||
|
* @return {@link BaseConnectionParam} |
||||||
|
*/ |
||||||
|
ConnectionParam createConnectionParams(String connectionJson); |
||||||
|
|
||||||
|
/** |
||||||
|
* get datasource Driver |
||||||
|
*/ |
||||||
|
String getDatasourceDriver(); |
||||||
|
|
||||||
|
/** |
||||||
|
* get jdbcUrl by connection param, the jdbcUrl is different with ConnectionParam.jdbcUrl, this method will inject |
||||||
|
* other to jdbcUrl |
||||||
|
* |
||||||
|
* @param connectionParam connection param |
||||||
|
*/ |
||||||
|
String getJdbcUrl(ConnectionParam connectionParam); |
||||||
|
|
||||||
|
/** |
||||||
|
* get connection by connectionParam |
||||||
|
* |
||||||
|
* @param connectionParam connectionParam |
||||||
|
* @return {@link Connection} |
||||||
|
*/ |
||||||
|
Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException, IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* @return {@link DbType} |
||||||
|
*/ |
||||||
|
DbType getDbType(); |
||||||
|
} |
@ -0,0 +1,121 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.clickhouse.ClickHouseDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.db2.Db2DatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.hive.HiveDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.mysql.MysqlDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.oracle.OracleDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.postgresql.PostgreSqlDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.presto.PrestoDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.spark.SparkDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.sqlserver.SqlServerDatasourceProcessor; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
public class DatasourceUtil { |
||||||
|
|
||||||
|
private DatasourceUtil() { |
||||||
|
} |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatasourceUtil.class); |
||||||
|
|
||||||
|
private static final DatasourceProcessor mysqlProcessor = new MysqlDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor postgreSqlProcessor = new PostgreSqlDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor hiveProcessor = new HiveDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor sparkProcessor = new SparkDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor clickhouseProcessor = new ClickHouseDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor oracleProcessor = new OracleDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor sqlServerProcessor = new SqlServerDatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor db2PROCESSOR = new Db2DatasourceProcessor(); |
||||||
|
private static final DatasourceProcessor prestoPROCESSOR = new PrestoDatasourceProcessor(); |
||||||
|
|
||||||
|
/** |
||||||
|
* check datasource param |
||||||
|
* |
||||||
|
* @param baseDataSourceParamDTO datasource param |
||||||
|
*/ |
||||||
|
public static void checkDatasourceParam(BaseDataSourceParamDTO baseDataSourceParamDTO) { |
||||||
|
getDatasourceProcessor(baseDataSourceParamDTO.getType()).checkDatasourceParam(baseDataSourceParamDTO); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build connection url |
||||||
|
* |
||||||
|
* @param baseDataSourceParamDTO datasourceParam |
||||||
|
*/ |
||||||
|
public static ConnectionParam buildConnectionParams(BaseDataSourceParamDTO baseDataSourceParamDTO) { |
||||||
|
ConnectionParam connectionParams = getDatasourceProcessor(baseDataSourceParamDTO.getType()) |
||||||
|
.createConnectionParams(baseDataSourceParamDTO); |
||||||
|
if (logger.isDebugEnabled()) { |
||||||
|
logger.info("parameters map:{}", connectionParams); |
||||||
|
} |
||||||
|
return connectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public static ConnectionParam buildConnectionParams(DbType dbType, String connectionJson) { |
||||||
|
return getDatasourceProcessor(dbType).createConnectionParams(connectionJson); |
||||||
|
} |
||||||
|
|
||||||
|
public static Connection getConnection(DbType dbType, ConnectionParam connectionParam) { |
||||||
|
try { |
||||||
|
return getDatasourceProcessor(dbType).getConnection(connectionParam); |
||||||
|
} catch (Exception e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static String getJdbcUrl(DbType dbType, ConnectionParam baseConnectionParam) { |
||||||
|
return getDatasourceProcessor(dbType).getJdbcUrl(baseConnectionParam); |
||||||
|
} |
||||||
|
|
||||||
|
public static BaseDataSourceParamDTO buildDatasourceParamDTO(DbType dbType, String connectionParams) { |
||||||
|
return getDatasourceProcessor(dbType).createDatasourceParamDTO(connectionParams); |
||||||
|
} |
||||||
|
|
||||||
|
public static DatasourceProcessor getDatasourceProcessor(DbType dbType) { |
||||||
|
switch (dbType) { |
||||||
|
case MYSQL: |
||||||
|
return mysqlProcessor; |
||||||
|
case POSTGRESQL: |
||||||
|
return postgreSqlProcessor; |
||||||
|
case HIVE: |
||||||
|
return hiveProcessor; |
||||||
|
case SPARK: |
||||||
|
return sparkProcessor; |
||||||
|
case CLICKHOUSE: |
||||||
|
return clickhouseProcessor; |
||||||
|
case ORACLE: |
||||||
|
return oracleProcessor; |
||||||
|
case SQLSERVER: |
||||||
|
return sqlServerProcessor; |
||||||
|
case DB2: |
||||||
|
return db2PROCESSOR; |
||||||
|
case PRESTO: |
||||||
|
return prestoPROCESSOR; |
||||||
|
default: |
||||||
|
throw new IllegalArgumentException("datasource type illegal:" + dbType); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import org.apache.hadoop.hive.conf.HiveConf; |
||||||
|
import org.apache.hadoop.hive.conf.HiveConf.ConfVars; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* hive conf utils |
||||||
|
*/ |
||||||
|
public class HiveConfUtils { |
||||||
|
|
||||||
|
private HiveConfUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct HiveConfUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
private static class HiveConfHandler { |
||||||
|
private static HiveConf singleton; |
||||||
|
|
||||||
|
private static Map<String,Object> hiveConfVars; |
||||||
|
|
||||||
|
static { |
||||||
|
singleton = new HiveConf(); |
||||||
|
hiveConfVars = new HashMap<>(); |
||||||
|
Arrays.stream(ConfVars.values()).forEach(confVar -> hiveConfVars.put(confVar.varname,confVar)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get HiveConf instance |
||||||
|
* @return HiveConf hiveConf |
||||||
|
*/ |
||||||
|
public static HiveConf getInstance() { |
||||||
|
return HiveConfHandler.singleton; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get hive conf vars |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static Map<String,Object> getHiveConfVars() { |
||||||
|
return HiveConfHandler.hiveConfVars; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determine if it belongs to a hive conf property |
||||||
|
* @param conf config |
||||||
|
* @return boolean result |
||||||
|
*/ |
||||||
|
public static boolean isHiveConfVar(String conf) { |
||||||
|
// the default hive conf var name
|
||||||
|
String confKey = conf.split("=")[0]; |
||||||
|
Map<String, Object> hiveConfVars = HiveConfUtils.getHiveConfVars(); |
||||||
|
if (hiveConfVars.get(confKey) != null) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
// the security authorization hive conf var name
|
||||||
|
HiveConf hiveConf = HiveConfUtils.getInstance(); |
||||||
|
String hiveAuthorizationSqlStdAuthConfigWhitelist = hiveConf.getVar(HiveConf.ConfVars.HIVE_AUTHORIZATION_SQL_STD_AUTH_CONFIG_WHITELIST); |
||||||
|
Pattern modWhiteListPattern = Pattern.compile(hiveAuthorizationSqlStdAuthConfigWhitelist); |
||||||
|
Matcher matcher = modWhiteListPattern.matcher(confKey); |
||||||
|
return matcher.matches(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_ENABLE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_SALT; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DATASOURCE_ENCRYPTION_SALT_DEFAULT; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.utils.PropertyUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
public class PasswordUtils { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PasswordUtils.class); |
||||||
|
|
||||||
|
private static final Base64 BASE64 = new Base64(); |
||||||
|
|
||||||
|
private PasswordUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct PasswordUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* encode password |
||||||
|
*/ |
||||||
|
public static String encodePassword(String password) { |
||||||
|
if (StringUtils.isEmpty(password)) { |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
//if encryption is not turned on, return directly
|
||||||
|
boolean encryptionEnable = PropertyUtils.getBoolean(DATASOURCE_ENCRYPTION_ENABLE, false); |
||||||
|
if (!encryptionEnable) { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
// Using Base64 + salt to process password
|
||||||
|
String salt = PropertyUtils.getString(DATASOURCE_ENCRYPTION_SALT, DATASOURCE_ENCRYPTION_SALT_DEFAULT); |
||||||
|
String passwordWithSalt = salt + new String(BASE64.encode(password.getBytes( |
||||||
|
StandardCharsets.UTF_8))); |
||||||
|
return new String(BASE64.encode(passwordWithSalt.getBytes(StandardCharsets.UTF_8))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* decode password |
||||||
|
*/ |
||||||
|
public static String decodePassword(String password) { |
||||||
|
if (StringUtils.isEmpty(password)) { |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
//if encryption is not turned on, return directly
|
||||||
|
boolean encryptionEnable = PropertyUtils.getBoolean(DATASOURCE_ENCRYPTION_ENABLE, false); |
||||||
|
if (!encryptionEnable) { |
||||||
|
return password; |
||||||
|
} |
||||||
|
|
||||||
|
// Using Base64 + salt to process password
|
||||||
|
String salt = PropertyUtils.getString(DATASOURCE_ENCRYPTION_SALT, DATASOURCE_ENCRYPTION_SALT_DEFAULT); |
||||||
|
String passwordWithSalt = new String(BASE64.decode(password), StandardCharsets.UTF_8); |
||||||
|
if (!passwordWithSalt.startsWith(salt)) { |
||||||
|
logger.warn("There is a password and salt mismatch: {} ", password); |
||||||
|
return password; |
||||||
|
} |
||||||
|
return new String(BASE64.decode(passwordWithSalt.substring(salt.length())), StandardCharsets.UTF_8); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.clickhouse; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class ClickHouseDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "ClickHouseDatasourceParamDTO{" |
||||||
|
+ "host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.CLICKHOUSE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,131 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.clickhouse; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_CLICKHOUSE_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_CLICKHOUSE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class ClickHouseDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
ClickhouseConnectionParam connectionParams = (ClickhouseConnectionParam) createConnectionParams(connectionJson); |
||||||
|
|
||||||
|
ClickHouseDatasourceParamDTO clickHouseDatasourceParamDTO = new ClickHouseDatasourceParamDTO(); |
||||||
|
clickHouseDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
clickHouseDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
clickHouseDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
|
||||||
|
String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
clickHouseDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
clickHouseDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
|
||||||
|
return clickHouseDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
ClickHouseDatasourceParamDTO clickHouseParam = (ClickHouseDatasourceParamDTO) datasourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_CLICKHOUSE, clickHouseParam.getHost(), clickHouseParam.getPort()); |
||||||
|
String jdbcUrl = address + "/" + clickHouseParam.getDatabase(); |
||||||
|
|
||||||
|
ClickhouseConnectionParam clickhouseConnectionParam = new ClickhouseConnectionParam(); |
||||||
|
clickhouseConnectionParam.setDatabase(clickHouseParam.getDatabase()); |
||||||
|
clickhouseConnectionParam.setAddress(address); |
||||||
|
clickhouseConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
clickhouseConnectionParam.setUser(clickHouseParam.getUserName()); |
||||||
|
clickhouseConnectionParam.setPassword(encodePassword(clickHouseParam.getPassword())); |
||||||
|
clickhouseConnectionParam.setOther(transformOther(clickHouseParam.getOther())); |
||||||
|
return clickhouseConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, ClickhouseConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_CLICKHOUSE_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
ClickhouseConnectionParam clickhouseConnectionParam = (ClickhouseConnectionParam) connectionParam; |
||||||
|
String jdbcUrl = clickhouseConnectionParam.getJdbcUrl(); |
||||||
|
if (StringUtils.isNotEmpty(clickhouseConnectionParam.getOther())) { |
||||||
|
jdbcUrl = String.format("%s?%s", jdbcUrl, clickhouseConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return jdbcUrl; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
ClickhouseConnectionParam clickhouseConnectionParam = (ClickhouseConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(clickhouseConnectionParam), |
||||||
|
clickhouseConnectionParam.getUser(), decodePassword(clickhouseConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.CLICKHOUSE; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s%s", key, value, "&"))); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (other == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
String[] configs = other.split("&"); |
||||||
|
for (String config : configs) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.spi.task.datasource.clickhouse; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class ClickhouseConnectionParam extends BaseConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "ClickhouseConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.spi.task.datasource.db2; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class Db2ConnectionParam extends BaseConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "Db2ConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.db2; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class Db2DatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "Db2DatasourceParamDTO{" |
||||||
|
+ "name='" + name + '\'' |
||||||
|
+ ", note='" + note + '\'' |
||||||
|
+ ", host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.DB2; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.db2; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_DB2_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_DB2; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class Db2DatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
Db2ConnectionParam connectionParams = (Db2ConnectionParam) createConnectionParams(connectionJson); |
||||||
|
|
||||||
|
Db2DatasourceParamDTO db2DatasourceParamDTO = new Db2DatasourceParamDTO(); |
||||||
|
db2DatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
db2DatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
db2DatasourceParamDTO.setUserName(db2DatasourceParamDTO.getUserName()); |
||||||
|
|
||||||
|
String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
db2DatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
db2DatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
|
||||||
|
return db2DatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
Db2DatasourceParamDTO db2Param = (Db2DatasourceParamDTO) datasourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_DB2, db2Param.getHost(), db2Param.getPort()); |
||||||
|
String jdbcUrl = String.format("%s/%s", address, db2Param.getDatabase()); |
||||||
|
|
||||||
|
Db2ConnectionParam db2ConnectionParam = new Db2ConnectionParam(); |
||||||
|
db2ConnectionParam.setAddress(address); |
||||||
|
db2ConnectionParam.setDatabase(db2Param.getDatabase()); |
||||||
|
db2ConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
db2ConnectionParam.setUser(db2Param.getUserName()); |
||||||
|
db2ConnectionParam.setPassword(encodePassword(db2Param.getPassword())); |
||||||
|
db2ConnectionParam.setOther(transformOther(db2Param.getOther())); |
||||||
|
|
||||||
|
return db2ConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, Db2ConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_DB2_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
Db2ConnectionParam db2ConnectionParam = (Db2ConnectionParam) connectionParam; |
||||||
|
if (StringUtils.isNotEmpty(db2ConnectionParam.getOther())) { |
||||||
|
return String.format("%s;%s", db2ConnectionParam.getJdbcUrl(), db2ConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return db2ConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
Db2ConnectionParam db2ConnectionParam = (Db2ConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(db2ConnectionParam), |
||||||
|
db2ConnectionParam.getUser(), decodePassword(db2ConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.DB2; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s%s", key, value, ";"))); |
||||||
|
stringBuilder.deleteCharAt(stringBuilder.length() - 1); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (other == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
for (String config : other.split("&")) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.hive; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsConnectionParam; |
||||||
|
|
||||||
|
public class HiveConnectionParam extends BaseHdfsConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "HiveConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ ", principal='" + principal + '\'' |
||||||
|
+ ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\'' |
||||||
|
+ ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\'' |
||||||
|
+ ", loginUserKeytabPath='" + loginUserKeytabPath + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.hive; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsDatasourceParamDTO; |
||||||
|
|
||||||
|
public class HiveDataSourceParamDTO extends BaseHdfsDatasourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "HiveDataSourceParamDTO{" |
||||||
|
+ "host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", principal='" + principal + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\'' |
||||||
|
+ ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\'' |
||||||
|
+ ", loginUserKeytabPath='" + loginUserKeytabPath + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.HIVE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,192 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.hive; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_HIVE_2; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_APACHE_HIVE_JDBC_HIVE_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.HiveConfUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.CommonUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class HiveDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
HiveDataSourceParamDTO hiveDataSourceParamDTO = new HiveDataSourceParamDTO(); |
||||||
|
HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) createConnectionParams(connectionJson); |
||||||
|
|
||||||
|
hiveDataSourceParamDTO.setDatabase(hiveConnectionParam.getDatabase()); |
||||||
|
hiveDataSourceParamDTO.setUserName(hiveConnectionParam.getUser()); |
||||||
|
hiveDataSourceParamDTO.setOther(parseOther(hiveConnectionParam.getOther())); |
||||||
|
hiveDataSourceParamDTO.setLoginUserKeytabUsername(hiveConnectionParam.getLoginUserKeytabUsername()); |
||||||
|
hiveDataSourceParamDTO.setLoginUserKeytabPath(hiveConnectionParam.getLoginUserKeytabPath()); |
||||||
|
hiveDataSourceParamDTO.setJavaSecurityKrb5Conf(hiveConnectionParam.getJavaSecurityKrb5Conf()); |
||||||
|
|
||||||
|
String[] tmpArray = hiveConnectionParam.getAddress().split(DOUBLE_SLASH); |
||||||
|
StringBuilder hosts = new StringBuilder(); |
||||||
|
String[] hostPortArray = tmpArray[tmpArray.length - 1].split(COMMA); |
||||||
|
for (String hostPort : hostPortArray) { |
||||||
|
hosts.append(hostPort.split(COLON)[0]).append(COMMA); |
||||||
|
} |
||||||
|
hosts.deleteCharAt(hosts.length() - 1); |
||||||
|
hiveDataSourceParamDTO.setHost(hosts.toString()); |
||||||
|
hiveDataSourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
|
||||||
|
return hiveDataSourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
HiveDataSourceParamDTO hiveParam = (HiveDataSourceParamDTO) datasourceParam; |
||||||
|
StringBuilder address = new StringBuilder(); |
||||||
|
address.append(JDBC_HIVE_2); |
||||||
|
for (String zkHost : hiveParam.getHost().split(",")) { |
||||||
|
address.append(String.format("%s:%s,", zkHost, hiveParam.getPort())); |
||||||
|
} |
||||||
|
address.deleteCharAt(address.length() - 1); |
||||||
|
String jdbcUrl = address.toString() + "/" + hiveParam.getDatabase(); |
||||||
|
if (CommonUtils.getKerberosStartupState()) { |
||||||
|
jdbcUrl += ";principal=" + hiveParam.getPrincipal(); |
||||||
|
} |
||||||
|
|
||||||
|
HiveConnectionParam hiveConnectionParam = new HiveConnectionParam(); |
||||||
|
hiveConnectionParam.setDatabase(hiveParam.getDatabase()); |
||||||
|
hiveConnectionParam.setAddress(address.toString()); |
||||||
|
hiveConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
hiveConnectionParam.setUser(hiveParam.getUserName()); |
||||||
|
hiveConnectionParam.setPassword(encodePassword(hiveParam.getPassword())); |
||||||
|
|
||||||
|
if (CommonUtils.getKerberosStartupState()) { |
||||||
|
hiveConnectionParam.setPrincipal(hiveParam.getPrincipal()); |
||||||
|
hiveConnectionParam.setJavaSecurityKrb5Conf(hiveParam.getJavaSecurityKrb5Conf()); |
||||||
|
hiveConnectionParam.setLoginUserKeytabPath(hiveParam.getLoginUserKeytabPath()); |
||||||
|
hiveConnectionParam.setLoginUserKeytabUsername(hiveParam.getLoginUserKeytabUsername()); |
||||||
|
} |
||||||
|
hiveConnectionParam.setOther(transformOther(hiveParam.getOther())); |
||||||
|
return hiveConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, HiveConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return ORG_APACHE_HIVE_JDBC_HIVE_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) connectionParam; |
||||||
|
String jdbcUrl = hiveConnectionParam.getJdbcUrl(); |
||||||
|
String otherParams = filterOther(hiveConnectionParam.getOther()); |
||||||
|
if (StringUtils.isNotEmpty(otherParams) && !"?".equals(otherParams.substring(0, 1))) { |
||||||
|
jdbcUrl += ";"; |
||||||
|
} |
||||||
|
return jdbcUrl + otherParams; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws IOException, ClassNotFoundException, SQLException { |
||||||
|
HiveConnectionParam hiveConnectionParam = (HiveConnectionParam) connectionParam; |
||||||
|
CommonUtils.loadKerberosConf(hiveConnectionParam.getJavaSecurityKrb5Conf(), |
||||||
|
hiveConnectionParam.getLoginUserKeytabUsername(), hiveConnectionParam.getLoginUserKeytabPath()); |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(connectionParam), |
||||||
|
hiveConnectionParam.getUser(), decodePassword(hiveConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.HIVE; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s;", key, value))); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private String filterOther(String otherParams) { |
||||||
|
if (StringUtils.isBlank(otherParams)) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
StringBuilder hiveConfListSb = new StringBuilder(); |
||||||
|
hiveConfListSb.append("?"); |
||||||
|
StringBuilder sessionVarListSb = new StringBuilder(); |
||||||
|
|
||||||
|
String[] otherArray = otherParams.split(";", -1); |
||||||
|
|
||||||
|
for (String conf : otherArray) { |
||||||
|
if (HiveConfUtils.isHiveConfVar(conf)) { |
||||||
|
hiveConfListSb.append(conf).append(";"); |
||||||
|
} else { |
||||||
|
sessionVarListSb.append(conf).append(";"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// remove the last ";"
|
||||||
|
if (sessionVarListSb.length() > 0) { |
||||||
|
sessionVarListSb.deleteCharAt(sessionVarListSb.length() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
if (hiveConfListSb.length() > 0) { |
||||||
|
hiveConfListSb.deleteCharAt(hiveConfListSb.length() - 1); |
||||||
|
} |
||||||
|
|
||||||
|
return sessionVarListSb.toString() + hiveConfListSb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (other == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
String[] configs = other.split(";"); |
||||||
|
for (String config : configs) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.mysql; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class MysqlConnectionParam extends BaseConnectionParam { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "MysqlConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.mysql; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class MysqlDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "MysqlDatasourceParamDTO{" |
||||||
|
+ "name='" + name + '\'' |
||||||
|
+ ", note='" + note + '\'' |
||||||
|
+ ", host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.MYSQL; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,176 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.mysql; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_MYSQL_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_MYSQL; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
public class MysqlDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(MysqlDatasourceProcessor.class); |
||||||
|
|
||||||
|
private static final String ALLOW_LOAD_LOCAL_IN_FILE_NAME = "allowLoadLocalInfile"; |
||||||
|
|
||||||
|
private static final String AUTO_DESERIALIZE = "autoDeserialize"; |
||||||
|
|
||||||
|
private static final String ALLOW_LOCAL_IN_FILE_NAME = "allowLocalInfile"; |
||||||
|
|
||||||
|
private static final String ALLOW_URL_IN_LOCAL_IN_FILE_NAME = "allowUrlInLocalInfile"; |
||||||
|
|
||||||
|
private static final String APPEND_PARAMS = "allowLoadLocalInfile=false&autoDeserialize=false&allowLocalInfile=false&allowUrlInLocalInfile=false"; |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
MysqlConnectionParam connectionParams = (MysqlConnectionParam) createConnectionParams(connectionJson); |
||||||
|
MysqlDatasourceParamDTO mysqlDatasourceParamDTO = new MysqlDatasourceParamDTO(); |
||||||
|
|
||||||
|
mysqlDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
mysqlDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
mysqlDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
|
||||||
|
String address = connectionParams.getAddress(); |
||||||
|
String[] hostSeperator = address.split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
mysqlDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
mysqlDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
|
||||||
|
return mysqlDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO dataSourceParam) { |
||||||
|
MysqlDatasourceParamDTO mysqlDatasourceParam = (MysqlDatasourceParamDTO) dataSourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_MYSQL, mysqlDatasourceParam.getHost(), mysqlDatasourceParam.getPort()); |
||||||
|
String jdbcUrl = String.format("%s/%s", address, mysqlDatasourceParam.getDatabase()); |
||||||
|
|
||||||
|
MysqlConnectionParam mysqlConnectionParam = new MysqlConnectionParam(); |
||||||
|
mysqlConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
mysqlConnectionParam.setDatabase(mysqlDatasourceParam.getDatabase()); |
||||||
|
mysqlConnectionParam.setAddress(address); |
||||||
|
mysqlConnectionParam.setUser(mysqlDatasourceParam.getUserName()); |
||||||
|
mysqlConnectionParam.setPassword(encodePassword(mysqlDatasourceParam.getPassword())); |
||||||
|
mysqlConnectionParam.setOther(transformOther(mysqlDatasourceParam.getOther())); |
||||||
|
|
||||||
|
return mysqlConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, MysqlConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_MYSQL_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
MysqlConnectionParam mysqlConnectionParam = (MysqlConnectionParam) connectionParam; |
||||||
|
String jdbcUrl = mysqlConnectionParam.getJdbcUrl(); |
||||||
|
if (StringUtils.isNotEmpty(mysqlConnectionParam.getOther())) { |
||||||
|
return String.format("%s?%s&%s", jdbcUrl, mysqlConnectionParam.getOther(), APPEND_PARAMS); |
||||||
|
} |
||||||
|
return String.format("%s?%s", jdbcUrl, APPEND_PARAMS); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
MysqlConnectionParam mysqlConnectionParam = (MysqlConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
String user = mysqlConnectionParam.getUser(); |
||||||
|
if (user.contains(AUTO_DESERIALIZE)) { |
||||||
|
logger.warn("sensitive param : {} in username field is filtered", AUTO_DESERIALIZE); |
||||||
|
user = user.replace(AUTO_DESERIALIZE, ""); |
||||||
|
} |
||||||
|
String password = decodePassword(mysqlConnectionParam.getPassword()); |
||||||
|
if (password.contains(AUTO_DESERIALIZE)) { |
||||||
|
logger.warn("sensitive param : {} in password field is filtered", AUTO_DESERIALIZE); |
||||||
|
password = password.replace(AUTO_DESERIALIZE, ""); |
||||||
|
} |
||||||
|
return DriverManager.getConnection(getJdbcUrl(connectionParam), user, password); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.MYSQL; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> paramMap) { |
||||||
|
if (MapUtils.isEmpty(paramMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new HashMap<>(); |
||||||
|
paramMap.forEach((k, v) -> { |
||||||
|
if (!checkKeyIsLegitimate(k)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
otherMap.put(k, v); |
||||||
|
}); |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s&", key, value))); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean checkKeyIsLegitimate(String key) { |
||||||
|
return !key.contains(ALLOW_LOAD_LOCAL_IN_FILE_NAME) |
||||||
|
&& !key.contains(AUTO_DESERIALIZE) |
||||||
|
&& !key.contains(ALLOW_LOCAL_IN_FILE_NAME) |
||||||
|
&& !key.contains(ALLOW_URL_IN_LOCAL_IN_FILE_NAME); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
for (String config : other.split("&")) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.oracle; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbConnectType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class OracleConnectionParam extends BaseConnectionParam { |
||||||
|
|
||||||
|
protected DbConnectType connectType; |
||||||
|
|
||||||
|
public DbConnectType getConnectType() { |
||||||
|
return connectType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setConnectType(DbConnectType connectType) { |
||||||
|
this.connectType = connectType; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "OracleConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ ", connectType=" + connectType |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.oracle; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbConnectType; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class OracleDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
private DbConnectType connectType; |
||||||
|
|
||||||
|
public DbConnectType getConnectType() { |
||||||
|
return connectType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setConnectType(DbConnectType connectType) { |
||||||
|
this.connectType = connectType; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "OracleDatasourceParamDTO{" |
||||||
|
+ "name='" + name + '\'' |
||||||
|
+ ", note='" + note + '\'' |
||||||
|
+ ", host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", connectType=" + connectType |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.ORACLE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,149 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.oracle; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.AT_SIGN; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_ORACLE_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_ORACLE_SERVICE_NAME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_ORACLE_SID; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbConnectType; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class OracleDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
OracleConnectionParam connectionParams = (OracleConnectionParam) createConnectionParams(connectionJson); |
||||||
|
OracleDatasourceParamDTO oracleDatasourceParamDTO = new OracleDatasourceParamDTO(); |
||||||
|
|
||||||
|
oracleDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
oracleDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
oracleDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
|
||||||
|
String hostSeperator = DOUBLE_SLASH; |
||||||
|
if (DbConnectType.ORACLE_SID.equals(connectionParams.connectType)) { |
||||||
|
hostSeperator = AT_SIGN; |
||||||
|
} |
||||||
|
String[] hostPort = connectionParams.getAddress().split(hostSeperator); |
||||||
|
String[] hostPortArray = hostPort[hostPort.length - 1].split(COMMA); |
||||||
|
oracleDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
oracleDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
|
||||||
|
return oracleDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
OracleDatasourceParamDTO oracleParam = (OracleDatasourceParamDTO) datasourceParam; |
||||||
|
String address; |
||||||
|
if (DbConnectType.ORACLE_SID.equals(oracleParam.getConnectType())) { |
||||||
|
address = String.format("%s%s:%s", |
||||||
|
JDBC_ORACLE_SID, oracleParam.getHost(), oracleParam.getPort()); |
||||||
|
} else { |
||||||
|
address = String.format("%s%s:%s", |
||||||
|
JDBC_ORACLE_SERVICE_NAME, oracleParam.getHost(), oracleParam.getPort()); |
||||||
|
} |
||||||
|
String jdbcUrl = address + "/" + oracleParam.getDatabase(); |
||||||
|
|
||||||
|
OracleConnectionParam oracleConnectionParam = new OracleConnectionParam(); |
||||||
|
oracleConnectionParam.setUser(oracleParam.getUserName()); |
||||||
|
oracleConnectionParam.setPassword(encodePassword(oracleParam.getPassword())); |
||||||
|
oracleConnectionParam.setAddress(address); |
||||||
|
oracleConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
oracleConnectionParam.setDatabase(oracleParam.getDatabase()); |
||||||
|
oracleConnectionParam.setConnectType(oracleParam.getConnectType()); |
||||||
|
oracleConnectionParam.setOther(transformOther(oracleParam.getOther())); |
||||||
|
|
||||||
|
return oracleConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, OracleConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_ORACLE_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
OracleConnectionParam oracleConnectionParam = (OracleConnectionParam) connectionParam; |
||||||
|
if (StringUtils.isNotEmpty(oracleConnectionParam.getOther())) { |
||||||
|
return String.format("%s?%s", oracleConnectionParam.getJdbcUrl(), oracleConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return oracleConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
OracleConnectionParam oracleConnectionParam = (OracleConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(connectionParam), |
||||||
|
oracleConnectionParam.getUser(), decodePassword(oracleConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.ORACLE; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
List<String> list = new ArrayList<>(); |
||||||
|
otherMap.forEach((key, value) -> list.add(String.format("%s=%s", key, value))); |
||||||
|
return String.join("&", list); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
String[] configs = other.split("&"); |
||||||
|
for (String config : configs) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.spi.task.datasource.postgresql; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class PostgreSqlConnectionParam extends BaseConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "PostgreSqlConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.postgresql; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class PostgreSqlDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "PostgreSqlDatasourceParamDTO{" |
||||||
|
+ "host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.POSTGRESQL; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.postgresql; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_POSTGRESQL; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_POSTGRESQL_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class PostgreSqlDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
PostgreSqlConnectionParam connectionParams = (PostgreSqlConnectionParam) createConnectionParams(connectionJson); |
||||||
|
PostgreSqlDatasourceParamDTO postgreSqlDatasourceParamDTO = new PostgreSqlDatasourceParamDTO(); |
||||||
|
postgreSqlDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
postgreSqlDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
postgreSqlDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
|
||||||
|
String address = connectionParams.getAddress(); |
||||||
|
String[] hostSeperator = address.split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
postgreSqlDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
postgreSqlDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
|
||||||
|
return postgreSqlDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
PostgreSqlDatasourceParamDTO postgreSqlParam = (PostgreSqlDatasourceParamDTO) datasourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_POSTGRESQL, postgreSqlParam.getHost(), postgreSqlParam.getPort()); |
||||||
|
String jdbcUrl = String.format("%s/%s", address, postgreSqlParam.getDatabase()); |
||||||
|
|
||||||
|
PostgreSqlConnectionParam postgreSqlConnectionParam = new PostgreSqlConnectionParam(); |
||||||
|
postgreSqlConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
postgreSqlConnectionParam.setAddress(address); |
||||||
|
postgreSqlConnectionParam.setDatabase(postgreSqlParam.getDatabase()); |
||||||
|
postgreSqlConnectionParam.setUser(postgreSqlParam.getUserName()); |
||||||
|
postgreSqlConnectionParam.setPassword(encodePassword(postgreSqlParam.getPassword())); |
||||||
|
postgreSqlConnectionParam.setOther(transformOther(postgreSqlParam.getOther())); |
||||||
|
|
||||||
|
return postgreSqlConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, PostgreSqlConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return ORG_POSTGRESQL_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
PostgreSqlConnectionParam postgreSqlConnectionParam = (PostgreSqlConnectionParam) connectionParam; |
||||||
|
if (StringUtils.isNotEmpty(postgreSqlConnectionParam.getOther())) { |
||||||
|
return String.format("%s?%s", postgreSqlConnectionParam.getJdbcUrl(), postgreSqlConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return postgreSqlConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
PostgreSqlConnectionParam postgreSqlConnectionParam = (PostgreSqlConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(postgreSqlConnectionParam), |
||||||
|
postgreSqlConnectionParam.getUser(), decodePassword(postgreSqlConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.POSTGRESQL; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s&", key, value))); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
for (String config : other.split("&")) { |
||||||
|
String[] split = config.split("="); |
||||||
|
otherMap.put(split[0], split[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.spi.task.datasource.presto; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class PrestoConnectionParam extends BaseConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "PrestoConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.presto; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class PrestoDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "PrestoDatasourceParamDTO{" |
||||||
|
+ "name='" + name + '\'' |
||||||
|
+ ", note='" + note + '\'' |
||||||
|
+ ", host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.PRESTO; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,134 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.presto; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_PRESTO_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_PRESTO; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class PrestoDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
PrestoConnectionParam connectionParams = (PrestoConnectionParam) createConnectionParams(connectionJson); |
||||||
|
|
||||||
|
String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
|
||||||
|
PrestoDatasourceParamDTO prestoDatasourceParamDTO = new PrestoDatasourceParamDTO(); |
||||||
|
prestoDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
prestoDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
prestoDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
prestoDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
prestoDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
|
||||||
|
return prestoDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
PrestoDatasourceParamDTO prestoParam = (PrestoDatasourceParamDTO) datasourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_PRESTO, prestoParam.getHost(), prestoParam.getPort()); |
||||||
|
String jdbcUrl = address + "/" + prestoParam.getDatabase(); |
||||||
|
|
||||||
|
PrestoConnectionParam prestoConnectionParam = new PrestoConnectionParam(); |
||||||
|
prestoConnectionParam.setUser(prestoParam.getUserName()); |
||||||
|
prestoConnectionParam.setPassword(encodePassword(prestoParam.getPassword())); |
||||||
|
prestoConnectionParam.setOther(transformOther(prestoParam.getOther())); |
||||||
|
prestoConnectionParam.setAddress(address); |
||||||
|
prestoConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
prestoConnectionParam.setDatabase(prestoParam.getDatabase()); |
||||||
|
|
||||||
|
return prestoConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, PrestoConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_PRESTO_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
PrestoConnectionParam prestoConnectionParam = (PrestoConnectionParam) connectionParam; |
||||||
|
if (StringUtils.isNotEmpty(prestoConnectionParam.getOther())) { |
||||||
|
return String.format("%s?%s", prestoConnectionParam.getJdbcUrl(), prestoConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return prestoConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
PrestoConnectionParam prestoConnectionParam = (PrestoConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(connectionParam), |
||||||
|
prestoConnectionParam.getUser(), decodePassword(prestoConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.PRESTO; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isNotEmpty(otherMap)) { |
||||||
|
List<String> list = new ArrayList<>(); |
||||||
|
otherMap.forEach((key, value) -> list.add(String.format("%s=%s", key, value))); |
||||||
|
return String.join("&", list); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
String[] configs = other.split("&"); |
||||||
|
for (String config : configs) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.spark; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsConnectionParam; |
||||||
|
|
||||||
|
public class SparkConnectionParam extends BaseHdfsConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SparkConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ ", principal='" + principal + '\'' |
||||||
|
+ ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\'' |
||||||
|
+ ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\'' |
||||||
|
+ ", loginUserKeytabPath='" + loginUserKeytabPath + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.spark; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseHdfsDatasourceParamDTO; |
||||||
|
|
||||||
|
public class SparkDatasourceParamDTO extends BaseHdfsDatasourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SparkDatasourceParamDTO{" |
||||||
|
+ "host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", principal='" + principal + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ ", javaSecurityKrb5Conf='" + javaSecurityKrb5Conf + '\'' |
||||||
|
+ ", loginUserKeytabUsername='" + loginUserKeytabUsername + '\'' |
||||||
|
+ ", loginUserKeytabPath='" + loginUserKeytabPath + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.SPARK; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,161 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.spark; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_HIVE_2; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ORG_APACHE_HIVE_JDBC_HIVE_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.CommonUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
public class SparkDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
SparkConnectionParam connectionParams = (SparkConnectionParam) createConnectionParams(connectionJson); |
||||||
|
|
||||||
|
SparkDatasourceParamDTO sparkDatasourceParamDTO = new SparkDatasourceParamDTO(); |
||||||
|
sparkDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
sparkDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
sparkDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
sparkDatasourceParamDTO.setJavaSecurityKrb5Conf(connectionParams.getJavaSecurityKrb5Conf()); |
||||||
|
sparkDatasourceParamDTO.setLoginUserKeytabPath(connectionParams.getLoginUserKeytabPath()); |
||||||
|
sparkDatasourceParamDTO.setLoginUserKeytabUsername(connectionParams.getLoginUserKeytabUsername()); |
||||||
|
|
||||||
|
StringBuilder hosts = new StringBuilder(); |
||||||
|
String[] tmpArray = connectionParams.getAddress().split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = tmpArray[tmpArray.length - 1].split(COMMA); |
||||||
|
Arrays.stream(hostPortArray).forEach(hostPort -> hosts.append(hostPort.split(COLON)[0]).append(COMMA)); |
||||||
|
hosts.deleteCharAt(hosts.length() - 1); |
||||||
|
|
||||||
|
sparkDatasourceParamDTO.setHost(hosts.toString()); |
||||||
|
sparkDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
|
||||||
|
return sparkDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO dataSourceParam) { |
||||||
|
StringBuilder address = new StringBuilder(); |
||||||
|
SparkDatasourceParamDTO sparkDatasourceParam = (SparkDatasourceParamDTO) dataSourceParam; |
||||||
|
address.append(JDBC_HIVE_2); |
||||||
|
for (String zkHost : sparkDatasourceParam.getHost().split(",")) { |
||||||
|
address.append(String.format("%s:%s,", zkHost, sparkDatasourceParam.getPort())); |
||||||
|
} |
||||||
|
address.deleteCharAt(address.length() - 1); |
||||||
|
|
||||||
|
String jdbcUrl = address + "/" + sparkDatasourceParam.getDatabase(); |
||||||
|
if (CommonUtils.getKerberosStartupState()) { |
||||||
|
jdbcUrl += ";principal=" + sparkDatasourceParam.getPrincipal(); |
||||||
|
} |
||||||
|
|
||||||
|
SparkConnectionParam sparkConnectionParam = new SparkConnectionParam(); |
||||||
|
sparkConnectionParam.setPassword(encodePassword(sparkDatasourceParam.getPassword())); |
||||||
|
sparkConnectionParam.setUser(sparkDatasourceParam.getUserName()); |
||||||
|
sparkConnectionParam.setOther(transformOther(sparkDatasourceParam.getOther())); |
||||||
|
sparkConnectionParam.setDatabase(sparkDatasourceParam.getDatabase()); |
||||||
|
sparkConnectionParam.setAddress(address.toString()); |
||||||
|
sparkConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
if (CommonUtils.getKerberosStartupState()) { |
||||||
|
sparkConnectionParam.setPrincipal(sparkDatasourceParam.getPrincipal()); |
||||||
|
sparkConnectionParam.setJavaSecurityKrb5Conf(sparkDatasourceParam.getJavaSecurityKrb5Conf()); |
||||||
|
sparkConnectionParam.setLoginUserKeytabPath(sparkDatasourceParam.getLoginUserKeytabPath()); |
||||||
|
sparkConnectionParam.setLoginUserKeytabUsername(sparkDatasourceParam.getLoginUserKeytabUsername()); |
||||||
|
} |
||||||
|
|
||||||
|
return sparkConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, SparkConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return ORG_APACHE_HIVE_JDBC_HIVE_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
SparkConnectionParam sparkConnectionParam = (SparkConnectionParam) connectionParam; |
||||||
|
if (StringUtils.isNotEmpty(sparkConnectionParam.getOther())) { |
||||||
|
return String.format("%s;%s", sparkConnectionParam.getJdbcUrl(), sparkConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return sparkConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws IOException, ClassNotFoundException, SQLException { |
||||||
|
SparkConnectionParam sparkConnectionParam = (SparkConnectionParam) connectionParam; |
||||||
|
CommonUtils.loadKerberosConf(sparkConnectionParam.getJavaSecurityKrb5Conf(), |
||||||
|
sparkConnectionParam.getLoginUserKeytabUsername(), sparkConnectionParam.getLoginUserKeytabPath()); |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(sparkConnectionParam), |
||||||
|
sparkConnectionParam.getUser(), decodePassword(sparkConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.SPARK; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
List<String> stringBuilder = otherMap.entrySet().stream() |
||||||
|
.map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue())).collect(Collectors.toList()); |
||||||
|
return String.join(";", stringBuilder); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
String[] configs = other.split(";"); |
||||||
|
for (String config : configs) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.spi.task.datasource.sqlserver; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
|
||||||
|
public class SqlServerConnectionParam extends BaseConnectionParam { |
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SqlServerConnectionParam{" |
||||||
|
+ "user='" + user + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", address='" + address + '\'' |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", jdbcUrl='" + jdbcUrl + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.sqlserver; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
|
||||||
|
public class SqlServerDatasourceParamDTO extends BaseDataSourceParamDTO { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SqlServerDatasourceParamDTO{" |
||||||
|
+ "name='" + name + '\'' |
||||||
|
+ ", note='" + note + '\'' |
||||||
|
+ ", host='" + host + '\'' |
||||||
|
+ ", port=" + port |
||||||
|
+ ", database='" + database + '\'' |
||||||
|
+ ", userName='" + userName + '\'' |
||||||
|
+ ", password='" + password + '\'' |
||||||
|
+ ", other='" + other + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getType() { |
||||||
|
return DbType.SQLSERVER; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.datasource.sqlserver; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COLON; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COM_SQLSERVER_JDBC_DRIVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DOUBLE_SLASH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JDBC_SQLSERVER; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.encodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.AbstractDatasourceProcessor; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseDataSourceParamDTO; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.ConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.collections4.MapUtils; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.DriverManager; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.LinkedHashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class SqlServerDatasourceProcessor extends AbstractDatasourceProcessor { |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseDataSourceParamDTO createDatasourceParamDTO(String connectionJson) { |
||||||
|
SqlServerConnectionParam connectionParams = (SqlServerConnectionParam) createConnectionParams(connectionJson); |
||||||
|
String[] hostSeperator = connectionParams.getAddress().split(DOUBLE_SLASH); |
||||||
|
String[] hostPortArray = hostSeperator[hostSeperator.length - 1].split(COMMA); |
||||||
|
|
||||||
|
SqlServerDatasourceParamDTO sqlServerDatasourceParamDTO = new SqlServerDatasourceParamDTO(); |
||||||
|
sqlServerDatasourceParamDTO.setDatabase(connectionParams.getDatabase()); |
||||||
|
sqlServerDatasourceParamDTO.setUserName(connectionParams.getUser()); |
||||||
|
sqlServerDatasourceParamDTO.setOther(parseOther(connectionParams.getOther())); |
||||||
|
sqlServerDatasourceParamDTO.setPort(Integer.parseInt(hostPortArray[0].split(COLON)[1])); |
||||||
|
sqlServerDatasourceParamDTO.setHost(hostPortArray[0].split(COLON)[0]); |
||||||
|
return sqlServerDatasourceParamDTO; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(BaseDataSourceParamDTO datasourceParam) { |
||||||
|
SqlServerDatasourceParamDTO sqlServerParam = (SqlServerDatasourceParamDTO) datasourceParam; |
||||||
|
String address = String.format("%s%s:%s", JDBC_SQLSERVER, sqlServerParam.getHost(), sqlServerParam.getPort()); |
||||||
|
String jdbcUrl = address + ";databaseName=" + sqlServerParam.getDatabase(); |
||||||
|
|
||||||
|
SqlServerConnectionParam sqlServerConnectionParam = new SqlServerConnectionParam(); |
||||||
|
sqlServerConnectionParam.setAddress(address); |
||||||
|
sqlServerConnectionParam.setDatabase(sqlServerParam.getDatabase()); |
||||||
|
sqlServerConnectionParam.setJdbcUrl(jdbcUrl); |
||||||
|
sqlServerConnectionParam.setOther(transformOther(sqlServerParam.getOther())); |
||||||
|
sqlServerConnectionParam.setUser(sqlServerParam.getUserName()); |
||||||
|
sqlServerConnectionParam.setPassword(encodePassword(sqlServerParam.getPassword())); |
||||||
|
return sqlServerConnectionParam; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public BaseConnectionParam createConnectionParams(String connectionJson) { |
||||||
|
return JSONUtils.parseObject(connectionJson, SqlServerConnectionParam.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getDatasourceDriver() { |
||||||
|
return COM_SQLSERVER_JDBC_DRIVER; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getJdbcUrl(ConnectionParam connectionParam) { |
||||||
|
SqlServerConnectionParam sqlServerConnectionParam = (SqlServerConnectionParam) connectionParam; |
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(sqlServerConnectionParam.getOther())) { |
||||||
|
return String.format("%s;%s", sqlServerConnectionParam.getJdbcUrl(), sqlServerConnectionParam.getOther()); |
||||||
|
} |
||||||
|
return sqlServerConnectionParam.getJdbcUrl(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Connection getConnection(ConnectionParam connectionParam) throws ClassNotFoundException, SQLException { |
||||||
|
SqlServerConnectionParam sqlServerConnectionParam = (SqlServerConnectionParam) connectionParam; |
||||||
|
Class.forName(getDatasourceDriver()); |
||||||
|
return DriverManager.getConnection(getJdbcUrl(connectionParam), sqlServerConnectionParam.getUser(), |
||||||
|
decodePassword(sqlServerConnectionParam.getPassword())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public DbType getDbType() { |
||||||
|
return DbType.SQLSERVER; |
||||||
|
} |
||||||
|
|
||||||
|
private String transformOther(Map<String, String> otherMap) { |
||||||
|
if (MapUtils.isEmpty(otherMap)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
StringBuilder stringBuilder = new StringBuilder(); |
||||||
|
otherMap.forEach((key, value) -> stringBuilder.append(String.format("%s=%s;", key, value))); |
||||||
|
return stringBuilder.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private Map<String, String> parseOther(String other) { |
||||||
|
if (StringUtils.isEmpty(other)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> otherMap = new LinkedHashMap<>(); |
||||||
|
for (String config : other.split(";")) { |
||||||
|
otherMap.put(config.split("=")[0], config.split("=")[1]); |
||||||
|
} |
||||||
|
return otherMap; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_BUSINESS_DATE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_CURRENT_DATE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_DATETIME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_DATE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME; |
||||||
|
import static org.apache.dolphinscheduler.spi.utils.DateUtils.addDays; |
||||||
|
import static org.apache.dolphinscheduler.spi.utils.DateUtils.format; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.CommandType; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* business time utils |
||||||
|
*/ |
||||||
|
public class BusinessTimeUtils { |
||||||
|
private BusinessTimeUtils() { |
||||||
|
throw new IllegalStateException("BusinessTimeUtils class"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get business time in parameters by different command types |
||||||
|
* |
||||||
|
* @param commandType command type |
||||||
|
* @param runTime run time or schedule time |
||||||
|
* @return business time |
||||||
|
*/ |
||||||
|
public static Map<String, String> getBusinessTime(CommandType commandType, Date runTime) { |
||||||
|
Date businessDate = runTime; |
||||||
|
switch (commandType) { |
||||||
|
case COMPLEMENT_DATA: |
||||||
|
break; |
||||||
|
case START_PROCESS: |
||||||
|
case START_CURRENT_TASK_PROCESS: |
||||||
|
case RECOVER_TOLERANCE_FAULT_PROCESS: |
||||||
|
case RECOVER_SUSPENDED_PROCESS: |
||||||
|
case START_FAILURE_TASK_PROCESS: |
||||||
|
case REPEAT_RUNNING: |
||||||
|
case SCHEDULER: |
||||||
|
default: |
||||||
|
businessDate = addDays(new Date(), -1); |
||||||
|
if (runTime != null) { |
||||||
|
/** |
||||||
|
* If there is a scheduled time, take the scheduling time. Recovery from failed nodes, suspension of recovery, re-run for scheduling |
||||||
|
*/ |
||||||
|
businessDate = addDays(runTime, -1); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
Date businessCurrentDate = addDays(businessDate, 1); |
||||||
|
Map<String, String> result = new HashMap<>(); |
||||||
|
result.put(PARAMETER_CURRENT_DATE, format(businessCurrentDate, PARAMETER_FORMAT_DATE)); |
||||||
|
result.put(PARAMETER_BUSINESS_DATE, format(businessDate, PARAMETER_FORMAT_DATE)); |
||||||
|
result.put(PARAMETER_DATETIME, format(businessCurrentDate, PARAMETER_FORMAT_TIME)); |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,158 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_TASK_EXECUTE_PATH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_TASK_INSTANCE_ID; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.CommandType; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.DataType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractParameters; |
||||||
|
import org.apache.dolphinscheduler.spi.task.Direct; |
||||||
|
import org.apache.dolphinscheduler.spi.task.Property; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.TaskRequest; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import com.google.common.base.Preconditions; |
||||||
|
|
||||||
|
/** |
||||||
|
* param utils |
||||||
|
*/ |
||||||
|
public class ParamUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* parameter conversion |
||||||
|
* Warning: |
||||||
|
* When you first invoke the function of convert, the variables of localParams and varPool in the ShellParameters will be modified. |
||||||
|
* But in the whole system the variables of localParams and varPool have been used in other functions. I'm not sure if this current |
||||||
|
* situation is wrong. So I cannot modify the original logic. |
||||||
|
* |
||||||
|
* @param taskExecutionContext the context of this task instance |
||||||
|
* @param parameters the parameters |
||||||
|
* @return global params |
||||||
|
* |
||||||
|
*/ |
||||||
|
public static Map<String, Property> convert(TaskRequest taskExecutionContext, AbstractParameters parameters) { |
||||||
|
Preconditions.checkNotNull(taskExecutionContext); |
||||||
|
Preconditions.checkNotNull(parameters); |
||||||
|
Map<String, Property> globalParams = getUserDefParamsMap(taskExecutionContext.getDefinedParams()); |
||||||
|
Map<String,String> globalParamsMap = taskExecutionContext.getDefinedParams(); |
||||||
|
CommandType commandType = CommandType.of(taskExecutionContext.getCmdTypeIfComplement()); |
||||||
|
Date scheduleTime = taskExecutionContext.getScheduleTime(); |
||||||
|
|
||||||
|
// combining local and global parameters
|
||||||
|
Map<String, Property> localParams = parameters.getLocalParametersMap(); |
||||||
|
|
||||||
|
Map<String, Property> varParams = parameters.getVarPoolMap(); |
||||||
|
|
||||||
|
if (globalParams == null && localParams == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
// if it is a complement,
|
||||||
|
// you need to pass in the task instance id to locate the time
|
||||||
|
// of the process instance complement
|
||||||
|
Map<String,String> params = BusinessTimeUtils |
||||||
|
.getBusinessTime(commandType, |
||||||
|
scheduleTime); |
||||||
|
|
||||||
|
if (globalParamsMap != null) { |
||||||
|
|
||||||
|
params.putAll(globalParamsMap); |
||||||
|
} |
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(taskExecutionContext.getExecutePath())) { |
||||||
|
params.put(PARAMETER_TASK_EXECUTE_PATH, taskExecutionContext.getExecutePath()); |
||||||
|
} |
||||||
|
params.put(PARAMETER_TASK_INSTANCE_ID, Integer.toString(taskExecutionContext.getTaskInstanceId())); |
||||||
|
|
||||||
|
if (globalParams != null && localParams != null) { |
||||||
|
globalParams.putAll(localParams); |
||||||
|
} else if (globalParams == null && localParams != null) { |
||||||
|
globalParams = localParams; |
||||||
|
} |
||||||
|
if (varParams != null) { |
||||||
|
varParams.putAll(globalParams); |
||||||
|
globalParams = varParams; |
||||||
|
} |
||||||
|
Iterator<Map.Entry<String, Property>> iter = globalParams.entrySet().iterator(); |
||||||
|
while (iter.hasNext()) { |
||||||
|
Map.Entry<String, Property> en = iter.next(); |
||||||
|
Property property = en.getValue(); |
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(property.getValue()) |
||||||
|
&& property.getValue().startsWith("$")) { |
||||||
|
/** |
||||||
|
* local parameter refers to global parameter with the same name |
||||||
|
* note: the global parameters of the process instance here are solidified parameters, |
||||||
|
* and there are no variables in them. |
||||||
|
*/ |
||||||
|
String val = property.getValue(); |
||||||
|
|
||||||
|
val = ParameterUtils.convertParameterPlaceholders(val, params); |
||||||
|
property.setValue(val); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return globalParams; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* format convert |
||||||
|
* |
||||||
|
* @param paramsMap params map |
||||||
|
* @return Map of converted |
||||||
|
*/ |
||||||
|
public static Map<String,String> convert(Map<String,Property> paramsMap) { |
||||||
|
if (paramsMap == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
Map<String, String> map = new HashMap<>(); |
||||||
|
Iterator<Map.Entry<String, Property>> iter = paramsMap.entrySet().iterator(); |
||||||
|
while (iter.hasNext()) { |
||||||
|
Map.Entry<String, Property> en = iter.next(); |
||||||
|
map.put(en.getKey(), en.getValue().getValue()); |
||||||
|
} |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get parameters map |
||||||
|
* |
||||||
|
* @param definedParams definedParams |
||||||
|
* @return parameters map |
||||||
|
*/ |
||||||
|
public static Map<String, Property> getUserDefParamsMap(Map<String, String> definedParams) { |
||||||
|
if (definedParams != null) { |
||||||
|
Map<String, Property> userDefParamsMaps = new HashMap<>(); |
||||||
|
Iterator<Map.Entry<String, String>> iter = definedParams.entrySet().iterator(); |
||||||
|
while (iter.hasNext()) { |
||||||
|
Map.Entry<String, String> en = iter.next(); |
||||||
|
Property property = new Property(en.getKey(), Direct.IN, DataType.VARCHAR, en.getValue()); |
||||||
|
userDefParamsMaps.put(property.getProp(),property); |
||||||
|
} |
||||||
|
return userDefParamsMaps; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,269 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_DATETIME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_SHECDULE_TIME; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.CommandType; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.DataType; |
||||||
|
import org.apache.dolphinscheduler.spi.task.Property; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.DateUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Iterator; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* parameter parse utils |
||||||
|
*/ |
||||||
|
public class ParameterUtils { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ParameterUtils.class); |
||||||
|
|
||||||
|
private static final String DATE_PARSE_PATTERN = "\\$\\[([^\\$\\]]+)]"; |
||||||
|
|
||||||
|
private static final String DATE_START_PATTERN = "^[0-9]"; |
||||||
|
|
||||||
|
private ParameterUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct ParameterUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* convert parameters place holders |
||||||
|
* |
||||||
|
* @param parameterString parameter |
||||||
|
* @param parameterMap parameter map |
||||||
|
* @return convert parameters place holders |
||||||
|
*/ |
||||||
|
public static String convertParameterPlaceholders(String parameterString, Map<String, String> parameterMap) { |
||||||
|
if (StringUtils.isEmpty(parameterString)) { |
||||||
|
return parameterString; |
||||||
|
} |
||||||
|
Date cronTime; |
||||||
|
if (parameterMap != null && !parameterMap.isEmpty()) { |
||||||
|
// replace variable ${} form,refers to the replacement of system variables and custom variables
|
||||||
|
parameterString = PlaceholderUtils.replacePlaceholders(parameterString, parameterMap, true); |
||||||
|
} |
||||||
|
if (parameterMap != null && null != parameterMap.get(PARAMETER_DATETIME)) { |
||||||
|
//Get current time, schedule execute time
|
||||||
|
String cronTimeStr = parameterMap.get(PARAMETER_DATETIME); |
||||||
|
cronTime = DateUtils.parse(cronTimeStr, PARAMETER_FORMAT_TIME); |
||||||
|
} else { |
||||||
|
cronTime = new Date(); |
||||||
|
} |
||||||
|
// replace time $[...] form, eg. $[yyyyMMdd]
|
||||||
|
if (cronTime != null) { |
||||||
|
return dateTemplateParse(parameterString, cronTime); |
||||||
|
} |
||||||
|
return parameterString; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* new |
||||||
|
* convert parameters place holders |
||||||
|
* |
||||||
|
* @param parameterString parameter |
||||||
|
* @param parameterMap parameter map |
||||||
|
* @return convert parameters place holders |
||||||
|
*/ |
||||||
|
public static String convertParameterPlaceholders2(String parameterString, Map<String, String> parameterMap) { |
||||||
|
if (StringUtils.isEmpty(parameterString)) { |
||||||
|
return parameterString; |
||||||
|
} |
||||||
|
//Get current time, schedule execute time
|
||||||
|
String cronTimeStr = parameterMap.get(PARAMETER_SHECDULE_TIME); |
||||||
|
Date cronTime = null; |
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(cronTimeStr)) { |
||||||
|
cronTime = DateUtils.parse(cronTimeStr, PARAMETER_FORMAT_TIME); |
||||||
|
|
||||||
|
} else { |
||||||
|
cronTime = new Date(); |
||||||
|
} |
||||||
|
|
||||||
|
// replace variable ${} form,refers to the replacement of system variables and custom variables
|
||||||
|
if (!parameterMap.isEmpty()) { |
||||||
|
parameterString = PlaceholderUtils.replacePlaceholders(parameterString, parameterMap, true); |
||||||
|
} |
||||||
|
|
||||||
|
// replace time $[...] form, eg. $[yyyyMMdd]
|
||||||
|
if (cronTime != null) { |
||||||
|
return dateTemplateParse(parameterString, cronTime); |
||||||
|
} |
||||||
|
return parameterString; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* set in parameter |
||||||
|
* |
||||||
|
* @param index index |
||||||
|
* @param stmt preparedstatement |
||||||
|
* @param dataType data type |
||||||
|
* @param value value |
||||||
|
* @throws Exception errors |
||||||
|
*/ |
||||||
|
public static void setInParameter(int index, PreparedStatement stmt, DataType dataType, String value) throws Exception { |
||||||
|
if (dataType.equals(DataType.VARCHAR)) { |
||||||
|
stmt.setString(index, value); |
||||||
|
} else if (dataType.equals(DataType.INTEGER)) { |
||||||
|
stmt.setInt(index, Integer.parseInt(value)); |
||||||
|
} else if (dataType.equals(DataType.LONG)) { |
||||||
|
stmt.setLong(index, Long.parseLong(value)); |
||||||
|
} else if (dataType.equals(DataType.FLOAT)) { |
||||||
|
stmt.setFloat(index, Float.parseFloat(value)); |
||||||
|
} else if (dataType.equals(DataType.DOUBLE)) { |
||||||
|
stmt.setDouble(index, Double.parseDouble(value)); |
||||||
|
} else if (dataType.equals(DataType.DATE)) { |
||||||
|
stmt.setDate(index, java.sql.Date.valueOf(value)); |
||||||
|
} else if (dataType.equals(DataType.TIME)) { |
||||||
|
stmt.setString(index, value); |
||||||
|
} else if (dataType.equals(DataType.TIMESTAMP)) { |
||||||
|
stmt.setTimestamp(index, java.sql.Timestamp.valueOf(value)); |
||||||
|
} else if (dataType.equals(DataType.BOOLEAN)) { |
||||||
|
stmt.setBoolean(index, Boolean.parseBoolean(value)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* curing user define parameters |
||||||
|
* |
||||||
|
* @param globalParamMap global param map |
||||||
|
* @param globalParamList global param list |
||||||
|
* @param commandType command type |
||||||
|
* @param scheduleTime schedule time |
||||||
|
* @return curing user define parameters |
||||||
|
*/ |
||||||
|
public static String curingGlobalParams(Map<String, String> globalParamMap, List<Property> globalParamList, |
||||||
|
CommandType commandType, Date scheduleTime) { |
||||||
|
|
||||||
|
if (globalParamList == null || globalParamList.isEmpty()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
Map<String, String> globalMap = new HashMap<>(); |
||||||
|
if (globalParamMap != null) { |
||||||
|
globalMap.putAll(globalParamMap); |
||||||
|
} |
||||||
|
Map<String, String> allParamMap = new HashMap<>(); |
||||||
|
//If it is a complement, a complement time needs to be passed in, according to the task type
|
||||||
|
Map<String, String> timeParams = BusinessTimeUtils |
||||||
|
.getBusinessTime(commandType, scheduleTime); |
||||||
|
|
||||||
|
if (timeParams != null) { |
||||||
|
allParamMap.putAll(timeParams); |
||||||
|
} |
||||||
|
|
||||||
|
allParamMap.putAll(globalMap); |
||||||
|
|
||||||
|
Set<Map.Entry<String, String>> entries = allParamMap.entrySet(); |
||||||
|
|
||||||
|
Map<String, String> resolveMap = new HashMap<>(); |
||||||
|
for (Map.Entry<String, String> entry : entries) { |
||||||
|
String val = entry.getValue(); |
||||||
|
if (val.startsWith("$")) { |
||||||
|
String str = ParameterUtils.convertParameterPlaceholders(val, allParamMap); |
||||||
|
resolveMap.put(entry.getKey(), str); |
||||||
|
} |
||||||
|
} |
||||||
|
globalMap.putAll(resolveMap); |
||||||
|
|
||||||
|
for (Property property : globalParamList) { |
||||||
|
String val = globalMap.get(property.getProp()); |
||||||
|
if (val != null) { |
||||||
|
property.setValue(val); |
||||||
|
} |
||||||
|
} |
||||||
|
return JSONUtils.toJsonString(globalParamList); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* $[yyyyMMdd] replace schedule time |
||||||
|
*/ |
||||||
|
public static String replaceScheduleTime(String text, Date scheduleTime) { |
||||||
|
Map<String, Property> paramsMap = new HashMap<>(); |
||||||
|
//if getScheduleTime null ,is current date
|
||||||
|
if (null == scheduleTime) { |
||||||
|
scheduleTime = new Date(); |
||||||
|
} |
||||||
|
|
||||||
|
String dateTime = DateUtils.format(scheduleTime, PARAMETER_FORMAT_TIME); |
||||||
|
Property p = new Property(); |
||||||
|
p.setValue(dateTime); |
||||||
|
p.setProp(PARAMETER_SHECDULE_TIME); |
||||||
|
paramsMap.put(PARAMETER_SHECDULE_TIME, p); |
||||||
|
text = ParameterUtils.convertParameterPlaceholders2(text, convert(paramsMap)); |
||||||
|
|
||||||
|
return text; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* format convert |
||||||
|
* |
||||||
|
* @param paramsMap params map |
||||||
|
* @return Map of converted |
||||||
|
* see org.apache.dolphinscheduler.server.utils.ParamUtils.convert |
||||||
|
*/ |
||||||
|
public static Map<String, String> convert(Map<String, Property> paramsMap) { |
||||||
|
Map<String, String> map = new HashMap<>(); |
||||||
|
Iterator<Map.Entry<String, Property>> iter = paramsMap.entrySet().iterator(); |
||||||
|
while (iter.hasNext()) { |
||||||
|
Map.Entry<String, Property> en = iter.next(); |
||||||
|
map.put(en.getKey(), en.getValue().getValue()); |
||||||
|
} |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
private static String dateTemplateParse(String templateStr, Date date) { |
||||||
|
if (templateStr == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Pattern pattern = Pattern.compile(DATE_PARSE_PATTERN); |
||||||
|
|
||||||
|
StringBuffer newValue = new StringBuffer(templateStr.length()); |
||||||
|
|
||||||
|
Matcher matcher = pattern.matcher(templateStr); |
||||||
|
|
||||||
|
while (matcher.find()) { |
||||||
|
String key = matcher.group(1); |
||||||
|
if (Pattern.matches(DATE_START_PATTERN, key)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
String value = TimePlaceholderUtils.getPlaceHolderTime(key, date); |
||||||
|
assert value != null; |
||||||
|
matcher.appendReplacement(newValue, value); |
||||||
|
} |
||||||
|
|
||||||
|
matcher.appendTail(newValue); |
||||||
|
|
||||||
|
return newValue.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,103 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* placeholder utils |
||||||
|
*/ |
||||||
|
public class PlaceholderUtils { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PlaceholderUtils.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* Prefix of the position to be replaced |
||||||
|
*/ |
||||||
|
public static final String PLACEHOLDER_PREFIX = "${"; |
||||||
|
|
||||||
|
/** |
||||||
|
* The suffix of the position to be replaced |
||||||
|
*/ |
||||||
|
|
||||||
|
public static final String PLACEHOLDER_SUFFIX = "}"; |
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces all placeholders of format {@code ${name}} with the value returned |
||||||
|
* from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}. |
||||||
|
* |
||||||
|
* @param value the value containing the placeholders to be replaced |
||||||
|
* @param paramsMap placeholder data dictionary |
||||||
|
* @param ignoreUnresolvablePlaceholders ignoreUnresolvablePlaceholders |
||||||
|
* @return the supplied value with placeholders replaced inline |
||||||
|
*/ |
||||||
|
public static String replacePlaceholders(String value, |
||||||
|
Map<String, String> paramsMap, |
||||||
|
boolean ignoreUnresolvablePlaceholders) { |
||||||
|
//replacement tool, parameter key will be replaced by value,if can't match , will throw an exception
|
||||||
|
PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false); |
||||||
|
|
||||||
|
//Non-strict replacement tool implementation, when the position to be replaced does not get the corresponding value, the current position is ignored, and the next position is replaced.
|
||||||
|
PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true); |
||||||
|
|
||||||
|
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper); |
||||||
|
|
||||||
|
//the PlaceholderResolver to use for replacement
|
||||||
|
return helper.replacePlaceholders(value, new PropertyPlaceholderResolver(value, paramsMap)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. |
||||||
|
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should |
||||||
|
* be ignored ({@code true}) or cause an exception ({@code false}) |
||||||
|
* @return PropertyPlaceholderHelper |
||||||
|
*/ |
||||||
|
public static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) { |
||||||
|
|
||||||
|
return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Placeholder replacement resolver |
||||||
|
*/ |
||||||
|
private static class PropertyPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver { |
||||||
|
|
||||||
|
private final String value; |
||||||
|
|
||||||
|
private final Map<String, String> paramsMap; |
||||||
|
|
||||||
|
public PropertyPlaceholderResolver(String value, Map<String, String> paramsMap) { |
||||||
|
this.value = value; |
||||||
|
this.paramsMap = paramsMap; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String resolvePlaceholder(String placeholderName) { |
||||||
|
try { |
||||||
|
return paramsMap.get(placeholderName); |
||||||
|
} catch (Exception ex) { |
||||||
|
logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex); |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,255 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Properties; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* Utility class for working with Strings that have placeholder values in them. A placeholder takes the form |
||||||
|
* {@code ${name}}. Using {@code PropertyPlaceholderHelper} these placeholders can be substituted for |
||||||
|
* user-supplied values. <p> Values for substitution can be supplied using a {@link Properties} instance or |
||||||
|
* using a {@link PlaceholderResolver}. |
||||||
|
* |
||||||
|
* @author Juergen Hoeller |
||||||
|
* @author Rob Harrop |
||||||
|
* @since 3.0 |
||||||
|
*/ |
||||||
|
public class PropertyPlaceholderHelper { |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PropertyPlaceholderHelper.class); |
||||||
|
|
||||||
|
private static final Map<String, String> wellKnownSimplePrefixes = new HashMap<String, String>(4); |
||||||
|
|
||||||
|
static { |
||||||
|
wellKnownSimplePrefixes.put("}", "{"); |
||||||
|
wellKnownSimplePrefixes.put("]", "["); |
||||||
|
wellKnownSimplePrefixes.put(")", "("); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private final String placeholderPrefix; |
||||||
|
|
||||||
|
private final String placeholderSuffix; |
||||||
|
|
||||||
|
private final String simplePrefix; |
||||||
|
|
||||||
|
private final String valueSeparator; |
||||||
|
|
||||||
|
private final boolean ignoreUnresolvablePlaceholders; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. |
||||||
|
* Unresolvable placeholders are ignored. |
||||||
|
* @param placeholderPrefix the prefix that denotes the start of a placeholder |
||||||
|
* @param placeholderSuffix the suffix that denotes the end of a placeholder |
||||||
|
*/ |
||||||
|
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix) { |
||||||
|
this(placeholderPrefix, placeholderSuffix, null, true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. |
||||||
|
* @param placeholderPrefix the prefix that denotes the start of a placeholder |
||||||
|
* @param placeholderSuffix the suffix that denotes the end of a placeholder |
||||||
|
* @param valueSeparator the separating character between the placeholder variable |
||||||
|
* and the associated default value, if any |
||||||
|
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should |
||||||
|
* be ignored ({@code true}) or cause an exception ({@code false}) |
||||||
|
*/ |
||||||
|
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix, |
||||||
|
String valueSeparator, boolean ignoreUnresolvablePlaceholders) { |
||||||
|
|
||||||
|
notNull(placeholderPrefix, "'placeholderPrefix' must not be null"); |
||||||
|
notNull(placeholderSuffix, "'placeholderSuffix' must not be null"); |
||||||
|
this.placeholderPrefix = placeholderPrefix; |
||||||
|
this.placeholderSuffix = placeholderSuffix; |
||||||
|
String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix); |
||||||
|
if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) { |
||||||
|
this.simplePrefix = simplePrefixForSuffix; |
||||||
|
} |
||||||
|
else { |
||||||
|
this.simplePrefix = this.placeholderPrefix; |
||||||
|
} |
||||||
|
this.valueSeparator = valueSeparator; |
||||||
|
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces all placeholders of format {@code ${name}} with the corresponding |
||||||
|
* property from the supplied {@link Properties}. |
||||||
|
* @param value the value containing the placeholders to be replaced |
||||||
|
* @param properties the {@code Properties} to use for replacement |
||||||
|
* @return the supplied value with placeholders replaced inline |
||||||
|
*/ |
||||||
|
public String replacePlaceholders(String value, final Properties properties) { |
||||||
|
notNull(properties, "'properties' must not be null"); |
||||||
|
return replacePlaceholders(value, new PlaceholderResolver() { |
||||||
|
@Override |
||||||
|
public String resolvePlaceholder(String placeholderName) { |
||||||
|
return properties.getProperty(placeholderName); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces all placeholders of format {@code ${name}} with the value returned |
||||||
|
* from the supplied {@link PlaceholderResolver}. |
||||||
|
* @param value the value containing the placeholders to be replaced |
||||||
|
* @param placeholderResolver the {@code PlaceholderResolver} to use for replacement |
||||||
|
* @return the supplied value with placeholders replaced inline |
||||||
|
*/ |
||||||
|
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) { |
||||||
|
notNull(value, "'value' must not be null"); |
||||||
|
return parseStringValue(value, placeholderResolver, new HashSet<String>()); |
||||||
|
} |
||||||
|
|
||||||
|
protected String parseStringValue( |
||||||
|
String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) { |
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder(value); |
||||||
|
|
||||||
|
int startIndex = value.indexOf(this.placeholderPrefix); |
||||||
|
while (startIndex != -1) { |
||||||
|
int endIndex = findPlaceholderEndIndex(result, startIndex); |
||||||
|
if (endIndex != -1) { |
||||||
|
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); |
||||||
|
String originalPlaceholder = placeholder; |
||||||
|
if (!visitedPlaceholders.add(originalPlaceholder)) { |
||||||
|
throw new IllegalArgumentException( |
||||||
|
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); |
||||||
|
} |
||||||
|
// Recursive invocation, parsing placeholders contained in the placeholder key.
|
||||||
|
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); |
||||||
|
// Now obtain the value for the fully resolved key...
|
||||||
|
String propVal = placeholderResolver.resolvePlaceholder(placeholder); |
||||||
|
if (propVal == null && this.valueSeparator != null) { |
||||||
|
int separatorIndex = placeholder.indexOf(this.valueSeparator); |
||||||
|
if (separatorIndex != -1) { |
||||||
|
String actualPlaceholder = placeholder.substring(0, separatorIndex); |
||||||
|
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); |
||||||
|
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); |
||||||
|
if (propVal == null) { |
||||||
|
propVal = defaultValue; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (propVal != null) { |
||||||
|
// Recursive invocation, parsing placeholders contained in the
|
||||||
|
// previously resolved placeholder value.
|
||||||
|
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); |
||||||
|
result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); |
||||||
|
if (logger.isTraceEnabled()) { |
||||||
|
logger.trace("Resolved placeholder '" + placeholder + "'"); |
||||||
|
} |
||||||
|
startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); |
||||||
|
} |
||||||
|
else if (this.ignoreUnresolvablePlaceholders) { |
||||||
|
// Proceed with unprocessed value.
|
||||||
|
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); |
||||||
|
} |
||||||
|
else { |
||||||
|
throw new IllegalArgumentException("Could not resolve placeholder '" |
||||||
|
+ placeholder + "'" + " in value \"" + value + "\""); |
||||||
|
} |
||||||
|
visitedPlaceholders.remove(originalPlaceholder); |
||||||
|
} |
||||||
|
else { |
||||||
|
startIndex = -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return result.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
private int findPlaceholderEndIndex(CharSequence buf, int startIndex) { |
||||||
|
int index = startIndex + this.placeholderPrefix.length(); |
||||||
|
int withinNestedPlaceholder = 0; |
||||||
|
while (index < buf.length()) { |
||||||
|
if (substringMatch(buf, index, this.placeholderSuffix)) { |
||||||
|
if (withinNestedPlaceholder > 0) { |
||||||
|
withinNestedPlaceholder--; |
||||||
|
index = index + this.placeholderSuffix.length(); |
||||||
|
} |
||||||
|
else { |
||||||
|
return index; |
||||||
|
} |
||||||
|
} |
||||||
|
else if (substringMatch(buf, index, this.simplePrefix)) { |
||||||
|
withinNestedPlaceholder++; |
||||||
|
index = index + this.simplePrefix.length(); |
||||||
|
} |
||||||
|
else { |
||||||
|
index++; |
||||||
|
} |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Strategy interface used to resolve replacement values for placeholders contained in Strings. |
||||||
|
*/ |
||||||
|
public interface PlaceholderResolver { |
||||||
|
|
||||||
|
/** |
||||||
|
* Resolve the supplied placeholder name to the replacement value. |
||||||
|
* @param placeholderName the name of the placeholder to resolve |
||||||
|
* @return the replacement value, or {@code null} if no replacement is to be made |
||||||
|
*/ |
||||||
|
String resolvePlaceholder(String placeholderName); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Test whether the given string matches the given substring |
||||||
|
* at the given index. |
||||||
|
* @param str the original string (or StringBuilder) |
||||||
|
* @param index the index in the original string to start matching against |
||||||
|
* @param substring the substring to match at the given index |
||||||
|
* @return whether the given string matches the given substring |
||||||
|
*/ |
||||||
|
public static boolean substringMatch(CharSequence str, int index, CharSequence substring) { |
||||||
|
for (int j = 0; j < substring.length(); j++) { |
||||||
|
int i = index + j; |
||||||
|
if (i >= str.length() || str.charAt(i) != substring.charAt(j)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Assert that an object is not {@code null}. |
||||||
|
* <pre class="code">Assert.notNull(clazz, "The class must not be null");</pre> |
||||||
|
* @param object the object to check |
||||||
|
* @param message the exception message to use if the assertion fails |
||||||
|
* @throws IllegalArgumentException if the object is {@code null} |
||||||
|
*/ |
||||||
|
public static void notNull(Object object, String message) { |
||||||
|
if (object == null) { |
||||||
|
throw new IllegalArgumentException(message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,570 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.paramparser; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_MONTHS; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.ADD_STRING; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.COMMA; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.DIVISION_STRING; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.LEFT_BRACE_STRING; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_BEGIN; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.MONTH_END; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.MULTIPLY_STRING; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.N; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.P; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.PARAMETER_FORMAT_TIME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.RIGHT_BRACE_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_CHAR; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.SUBTRACT_STRING; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.TIMESTAMP; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_BEGIN; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.WEEK_END; |
||||||
|
import static org.apache.dolphinscheduler.spi.utils.DateUtils.addDays; |
||||||
|
import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMinutes; |
||||||
|
import static org.apache.dolphinscheduler.spi.utils.DateUtils.addMonths; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.utils.DateUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.AbstractMap; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Stack; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* time place holder utils |
||||||
|
*/ |
||||||
|
public class TimePlaceholderUtils { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(TimePlaceholderUtils.class); |
||||||
|
|
||||||
|
/** |
||||||
|
* Prefix of the position to be replaced |
||||||
|
*/ |
||||||
|
public static final String PLACEHOLDER_PREFIX = "$["; |
||||||
|
|
||||||
|
/** |
||||||
|
* The suffix of the position to be replaced |
||||||
|
*/ |
||||||
|
public static final String PLACEHOLDER_SUFFIX = "]"; |
||||||
|
|
||||||
|
/** |
||||||
|
* Replaces all placeholders of format {@code ${name}} with the value returned |
||||||
|
* from the supplied {@link PropertyPlaceholderHelper.PlaceholderResolver}. |
||||||
|
* |
||||||
|
* @param value the value containing the placeholders to be replaced |
||||||
|
* @param date custom date |
||||||
|
* @param ignoreUnresolvablePlaceholders ignore unresolvable placeholders |
||||||
|
* @return the supplied value with placeholders replaced inline |
||||||
|
*/ |
||||||
|
public static String replacePlaceholders(String value, Date date, boolean ignoreUnresolvablePlaceholders) { |
||||||
|
PropertyPlaceholderHelper strictHelper = getPropertyPlaceholderHelper(false); |
||||||
|
PropertyPlaceholderHelper nonStrictHelper = getPropertyPlaceholderHelper(true); |
||||||
|
|
||||||
|
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper); |
||||||
|
return helper.replacePlaceholders(value, new TimePlaceholderResolver(value, date)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@code PropertyPlaceholderHelper} that uses the supplied prefix and suffix. |
||||||
|
* |
||||||
|
* @param ignoreUnresolvablePlaceholders indicates whether unresolvable placeholders should |
||||||
|
* be ignored ({@code true}) or cause an exception ({@code false}) |
||||||
|
*/ |
||||||
|
private static PropertyPlaceholderHelper getPropertyPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) { |
||||||
|
return new PropertyPlaceholderHelper(PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, null, ignoreUnresolvablePlaceholders); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calculate expression's value |
||||||
|
* |
||||||
|
* @param expression expression |
||||||
|
* @return expression's value |
||||||
|
*/ |
||||||
|
public static Integer calculate(String expression) { |
||||||
|
expression = StringUtils.trim(expression); |
||||||
|
expression = convert(expression); |
||||||
|
|
||||||
|
List<String> result = string2List(expression); |
||||||
|
result = convert2SuffixList(result); |
||||||
|
|
||||||
|
return calculate(result); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Change the sign in the expression to P (positive) N (negative) |
||||||
|
* |
||||||
|
* @param expression |
||||||
|
* @return eg. "-3+-6*(+8)-(-5) -> S3+S6*(P8)-(S5)" |
||||||
|
*/ |
||||||
|
private static String convert(String expression) { |
||||||
|
char[] arr = expression.toCharArray(); |
||||||
|
|
||||||
|
for (int i = 0; i < arr.length; i++) { |
||||||
|
if (arr[i] == SUBTRACT_CHAR) { |
||||||
|
if (i == 0) { |
||||||
|
arr[i] = N; |
||||||
|
} else { |
||||||
|
char c = arr[i - 1]; |
||||||
|
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) { |
||||||
|
arr[i] = N; |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (arr[i] == ADD_CHAR) { |
||||||
|
if (i == 0) { |
||||||
|
arr[i] = P; |
||||||
|
} else { |
||||||
|
char c = arr[i - 1]; |
||||||
|
if (c == ADD_CHAR || c == SUBTRACT_CHAR || c == MULTIPLY_CHAR || c == DIVISION_CHAR || c == LEFT_BRACE_CHAR) { |
||||||
|
arr[i] = P; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return new String(arr); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* to suffix expression |
||||||
|
* |
||||||
|
* @param srcList |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private static List<String> convert2SuffixList(List<String> srcList) { |
||||||
|
List<String> result = new ArrayList<>(); |
||||||
|
Stack<String> stack = new Stack<>(); |
||||||
|
|
||||||
|
for (int i = 0; i < srcList.size(); i++) { |
||||||
|
if (Character.isDigit(srcList.get(i).charAt(0))) { |
||||||
|
result.add(srcList.get(i)); |
||||||
|
} else { |
||||||
|
switch (srcList.get(i).charAt(0)) { |
||||||
|
case LEFT_BRACE_CHAR: |
||||||
|
stack.push(srcList.get(i)); |
||||||
|
break; |
||||||
|
case RIGHT_BRACE_CHAR: |
||||||
|
while (!LEFT_BRACE_STRING.equals(stack.peek())) { |
||||||
|
result.add(stack.pop()); |
||||||
|
} |
||||||
|
stack.pop(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
while (!stack.isEmpty() && compare(stack.peek(), srcList.get(i))) { |
||||||
|
result.add(stack.pop()); |
||||||
|
} |
||||||
|
stack.push(srcList.get(i)); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
while (!stack.isEmpty()) { |
||||||
|
result.add(stack.pop()); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Calculate the suffix expression |
||||||
|
* |
||||||
|
* @param result |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private static Integer calculate(List<String> result) { |
||||||
|
Stack<Integer> stack = new Stack<>(); |
||||||
|
for (int i = 0; i < result.size(); i++) { |
||||||
|
if (Character.isDigit(result.get(i).charAt(0))) { |
||||||
|
stack.push(Integer.parseInt(result.get(i))); |
||||||
|
} else { |
||||||
|
Integer backInt = stack.pop(); |
||||||
|
Integer frontInt = 0; |
||||||
|
char op = result.get(i).charAt(0); |
||||||
|
|
||||||
|
if (!(op == P || op == N)) { |
||||||
|
frontInt = stack.pop(); |
||||||
|
} |
||||||
|
|
||||||
|
Integer res = 0; |
||||||
|
switch (result.get(i).charAt(0)) { |
||||||
|
case P: |
||||||
|
res = frontInt + backInt; |
||||||
|
break; |
||||||
|
case N: |
||||||
|
res = frontInt - backInt; |
||||||
|
break; |
||||||
|
case ADD_CHAR: |
||||||
|
res = frontInt + backInt; |
||||||
|
break; |
||||||
|
case SUBTRACT_CHAR: |
||||||
|
res = frontInt - backInt; |
||||||
|
break; |
||||||
|
case MULTIPLY_CHAR: |
||||||
|
res = frontInt * backInt; |
||||||
|
break; |
||||||
|
case DIVISION_CHAR: |
||||||
|
res = frontInt / backInt; |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
stack.push(res); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return stack.pop(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* string to list |
||||||
|
* |
||||||
|
* @param expression |
||||||
|
* @return list |
||||||
|
*/ |
||||||
|
private static List<String> string2List(String expression) { |
||||||
|
List<String> result = new ArrayList<>(); |
||||||
|
String num = ""; |
||||||
|
for (int i = 0; i < expression.length(); i++) { |
||||||
|
if (Character.isDigit(expression.charAt(i))) { |
||||||
|
num = num + expression.charAt(i); |
||||||
|
} else { |
||||||
|
if (!num.isEmpty()) { |
||||||
|
result.add(num); |
||||||
|
} |
||||||
|
result.add(expression.charAt(i) + ""); |
||||||
|
num = ""; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!num.isEmpty()) { |
||||||
|
result.add(num); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* compare loginUser level |
||||||
|
* |
||||||
|
* @param peek |
||||||
|
* @param cur |
||||||
|
* @return true or false |
||||||
|
*/ |
||||||
|
private static boolean compare(String peek, String cur) { |
||||||
|
if (MULTIPLY_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) { |
||||||
|
return true; |
||||||
|
} else if (DIVISION_STRING.equals(peek) && (DIVISION_STRING.equals(cur) || MULTIPLY_STRING.equals(cur) || ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) { |
||||||
|
return true; |
||||||
|
} else if (ADD_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur))) { |
||||||
|
return true; |
||||||
|
} else { |
||||||
|
return SUBTRACT_STRING.equals(peek) && (ADD_STRING.equals(cur) || SUBTRACT_STRING.equals(cur)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Placeholder replacement resolver |
||||||
|
*/ |
||||||
|
private static class TimePlaceholderResolver implements |
||||||
|
PropertyPlaceholderHelper.PlaceholderResolver { |
||||||
|
|
||||||
|
private final String value; |
||||||
|
|
||||||
|
private final Date date; |
||||||
|
|
||||||
|
public TimePlaceholderResolver(String value, Date date) { |
||||||
|
this.value = value; |
||||||
|
this.date = date; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String resolvePlaceholder(String placeholderName) { |
||||||
|
try { |
||||||
|
return calculateTime(placeholderName, date); |
||||||
|
} catch (Exception ex) { |
||||||
|
logger.error("resolve placeholder '{}' in [ {} ]", placeholderName, value, ex); |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return the formatted date according to the corresponding date format |
||||||
|
* |
||||||
|
* @param expression date expression |
||||||
|
* @param date date |
||||||
|
* @return reformat date |
||||||
|
*/ |
||||||
|
public static String getPlaceHolderTime(String expression, Date date) { |
||||||
|
if (StringUtils.isBlank(expression)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
if (null == date) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return calculateTime(expression, date); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calculate time |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return calculate time |
||||||
|
*/ |
||||||
|
private static String calculateTime(String expression, Date date) { |
||||||
|
// After N years: $[add_months(yyyyMMdd,12*N)], the first N months: $[add_months(yyyyMMdd,-N)], etc
|
||||||
|
String value; |
||||||
|
|
||||||
|
try { |
||||||
|
if (expression.startsWith(TIMESTAMP)) { |
||||||
|
String timeExpression = expression.substring(TIMESTAMP.length() + 1, expression.length() - 1); |
||||||
|
|
||||||
|
Map.Entry<Date, String> entry = calcTimeExpression(timeExpression, date); |
||||||
|
|
||||||
|
String dateStr = DateUtils.format(entry.getKey(), entry.getValue()); |
||||||
|
|
||||||
|
Date timestamp = DateUtils.parse(dateStr, PARAMETER_FORMAT_TIME); |
||||||
|
|
||||||
|
value = String.valueOf(timestamp.getTime() / 1000); |
||||||
|
} else { |
||||||
|
Map.Entry<Date, String> entry = calcTimeExpression(expression, date); |
||||||
|
value = DateUtils.format(entry.getKey(), entry.getValue()); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
logger.error(e.getMessage(), e); |
||||||
|
throw e; |
||||||
|
} |
||||||
|
|
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calculate time expresstion |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return map with date, date format |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcTimeExpression(String expression, Date date) { |
||||||
|
Map.Entry<Date, String> resultEntry; |
||||||
|
|
||||||
|
if (expression.startsWith(ADD_MONTHS)) { |
||||||
|
resultEntry = calcMonths(expression, date); |
||||||
|
} else if (expression.startsWith(MONTH_BEGIN)) { |
||||||
|
resultEntry = calcMonthBegin(expression, date); |
||||||
|
} else if (expression.startsWith(MONTH_END)) { |
||||||
|
resultEntry = calcMonthEnd(expression, date); |
||||||
|
} else if (expression.startsWith(WEEK_BEGIN)) { |
||||||
|
resultEntry = calcWeekStart(expression, date); |
||||||
|
} else if (expression.startsWith(WEEK_END)) { |
||||||
|
resultEntry = calcWeekEnd(expression, date); |
||||||
|
} else { |
||||||
|
resultEntry = calcMinutes(expression, date); |
||||||
|
} |
||||||
|
|
||||||
|
return resultEntry; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get first day of month |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return first day of month |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcMonthBegin(String expression, Date date) { |
||||||
|
String addMonthExpr = expression.substring(MONTH_BEGIN.length() + 1, expression.length() - 1); |
||||||
|
String[] params = addMonthExpr.split(COMMA); |
||||||
|
|
||||||
|
if (params.length == 2) { |
||||||
|
String dateFormat = params[0]; |
||||||
|
String dayExpr = params[1]; |
||||||
|
Integer day = calculate(dayExpr); |
||||||
|
Date targetDate = DateUtils.getFirstDayOfMonth(date); |
||||||
|
targetDate = addDays(targetDate, day); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
throw new RuntimeException("expression not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get last day of month |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return last day of month |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcMonthEnd(String expression, Date date) { |
||||||
|
String addMonthExpr = expression.substring(MONTH_END.length() + 1, expression.length() - 1); |
||||||
|
String[] params = addMonthExpr.split(COMMA); |
||||||
|
|
||||||
|
if (params.length == 2) { |
||||||
|
String dateFormat = params[0]; |
||||||
|
String dayExpr = params[1]; |
||||||
|
Integer day = calculate(dayExpr); |
||||||
|
Date targetDate = DateUtils.getLastDayOfMonth(date); |
||||||
|
targetDate = addDays(targetDate, day); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
throw new RuntimeException("expression not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get first day of week |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return monday |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcWeekStart(String expression, Date date) { |
||||||
|
String addMonthExpr = expression.substring(WEEK_BEGIN.length() + 1, expression.length() - 1); |
||||||
|
String[] params = addMonthExpr.split(COMMA); |
||||||
|
|
||||||
|
if (params.length == 2) { |
||||||
|
String dateFormat = params[0]; |
||||||
|
String dayExpr = params[1]; |
||||||
|
Integer day = calculate(dayExpr); |
||||||
|
Date targetDate = DateUtils.getMonday(date); |
||||||
|
targetDate = addDays(targetDate, day); |
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
throw new RuntimeException("expression not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get last day of week |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return last day of week |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcWeekEnd(String expression, Date date) { |
||||||
|
String addMonthExpr = expression.substring(WEEK_END.length() + 1, expression.length() - 1); |
||||||
|
String[] params = addMonthExpr.split(COMMA); |
||||||
|
|
||||||
|
if (params.length == 2) { |
||||||
|
String dateFormat = params[0]; |
||||||
|
String dayExpr = params[1]; |
||||||
|
Integer day = calculate(dayExpr); |
||||||
|
Date targetDate = DateUtils.getSunday(date); |
||||||
|
targetDate = addDays(targetDate, day); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
throw new RuntimeException("Expression not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calc months expression |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return calc months |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcMonths(String expression, Date date) { |
||||||
|
String addMonthExpr = expression.substring(ADD_MONTHS.length() + 1, expression.length() - 1); |
||||||
|
String[] params = addMonthExpr.split(COMMA); |
||||||
|
|
||||||
|
if (params.length == 2) { |
||||||
|
String dateFormat = params[0]; |
||||||
|
String monthExpr = params[1]; |
||||||
|
Integer addMonth = calculate(monthExpr); |
||||||
|
Date targetDate = addMonths(date, addMonth); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
throw new RuntimeException("expression not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calculate time expression |
||||||
|
* |
||||||
|
* @param expression expresstion |
||||||
|
* @param date date |
||||||
|
* @return calculate time expression with date,format |
||||||
|
*/ |
||||||
|
public static Map.Entry<Date, String> calcMinutes(String expression, Date date) { |
||||||
|
if (expression.contains("+")) { |
||||||
|
int index = expression.lastIndexOf('+'); |
||||||
|
|
||||||
|
if (Character.isDigit(expression.charAt(index + 1))) { |
||||||
|
String addMinuteExpr = expression.substring(index + 1); |
||||||
|
Date targetDate = addMinutes(date, calcMinutes(addMinuteExpr)); |
||||||
|
String dateFormat = expression.substring(0, index); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
} else if (expression.contains("-")) { |
||||||
|
int index = expression.lastIndexOf('-'); |
||||||
|
|
||||||
|
if (Character.isDigit(expression.charAt(index + 1))) { |
||||||
|
String addMinuteExpr = expression.substring(index + 1); |
||||||
|
Date targetDate = addMinutes(date, 0 - calcMinutes(addMinuteExpr)); |
||||||
|
String dateFormat = expression.substring(0, index); |
||||||
|
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(targetDate, dateFormat); |
||||||
|
} |
||||||
|
|
||||||
|
// yyyy-MM-dd/HH:mm:ss
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(date, expression); |
||||||
|
} |
||||||
|
|
||||||
|
// $[HHmmss]
|
||||||
|
return new AbstractMap.SimpleImmutableEntry<>(date, expression); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* calculate need minutes |
||||||
|
* |
||||||
|
* @param minuteExpression minute expression |
||||||
|
* @return calculate need minutes |
||||||
|
*/ |
||||||
|
public static Integer calcMinutes(String minuteExpression) { |
||||||
|
int index = minuteExpression.indexOf('/'); |
||||||
|
|
||||||
|
String calcExpression; |
||||||
|
|
||||||
|
if (index == -1) { |
||||||
|
calcExpression = String.format("60*24*(%s)", minuteExpression); |
||||||
|
} else { |
||||||
|
|
||||||
|
calcExpression = String.format("60*24*(%s)%s", minuteExpression.substring(0, index), |
||||||
|
minuteExpression.substring(index)); |
||||||
|
} |
||||||
|
|
||||||
|
return calculate(calcExpression); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.request; |
||||||
|
|
||||||
|
/** |
||||||
|
* DataX Task ExecutionContext |
||||||
|
* to master/worker task transport |
||||||
|
*/ |
||||||
|
public class DataxTaskRequest extends TaskRequest { |
||||||
|
|
||||||
|
/** |
||||||
|
* dataSourceId |
||||||
|
*/ |
||||||
|
private int dataSourceId; |
||||||
|
|
||||||
|
/** |
||||||
|
* sourcetype |
||||||
|
*/ |
||||||
|
private int sourcetype; |
||||||
|
|
||||||
|
/** |
||||||
|
* sourceConnectionParams |
||||||
|
*/ |
||||||
|
private String sourceConnectionParams; |
||||||
|
|
||||||
|
/** |
||||||
|
* dataTargetId |
||||||
|
*/ |
||||||
|
private int dataTargetId; |
||||||
|
|
||||||
|
/** |
||||||
|
* targetType |
||||||
|
*/ |
||||||
|
private int targetType; |
||||||
|
|
||||||
|
/** |
||||||
|
* targetConnectionParams |
||||||
|
*/ |
||||||
|
private String targetConnectionParams; |
||||||
|
|
||||||
|
public int getDataSourceId() { |
||||||
|
return dataSourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataSourceId(int dataSourceId) { |
||||||
|
this.dataSourceId = dataSourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSourcetype() { |
||||||
|
return sourcetype; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSourcetype(int sourcetype) { |
||||||
|
this.sourcetype = sourcetype; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSourceConnectionParams() { |
||||||
|
return sourceConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSourceConnectionParams(String sourceConnectionParams) { |
||||||
|
this.sourceConnectionParams = sourceConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDataTargetId() { |
||||||
|
return dataTargetId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataTargetId(int dataTargetId) { |
||||||
|
this.dataTargetId = dataTargetId; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTargetType() { |
||||||
|
return targetType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTargetType(int targetType) { |
||||||
|
this.targetType = targetType; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTargetConnectionParams() { |
||||||
|
return targetConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTargetConnectionParams(String targetConnectionParams) { |
||||||
|
this.targetConnectionParams = targetConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "DataxTaskExecutionContext{" |
||||||
|
+ "dataSourceId=" + dataSourceId |
||||||
|
+ ", sourcetype=" + sourcetype |
||||||
|
+ ", sourceConnectionParams='" + sourceConnectionParams + '\'' |
||||||
|
+ ", dataTargetId=" + dataTargetId |
||||||
|
+ ", targetType=" + targetType |
||||||
|
+ ", targetConnectionParams='" + targetConnectionParams + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.request; |
||||||
|
|
||||||
|
/** |
||||||
|
* Procedure Task ExecutionContext |
||||||
|
* to master/worker task transport |
||||||
|
*/ |
||||||
|
public class ProcedureTaskRequest extends TaskRequest { |
||||||
|
|
||||||
|
/** |
||||||
|
* connectionParams |
||||||
|
*/ |
||||||
|
private String connectionParams; |
||||||
|
|
||||||
|
public String getConnectionParams() { |
||||||
|
return connectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setConnectionParams(String connectionParams) { |
||||||
|
this.connectionParams = connectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "ProcedureTaskExecutionContext{" |
||||||
|
+ "connectionParams='" + connectionParams + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.request; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.UdfFuncBean; |
||||||
|
import org.apache.dolphinscheduler.spi.task.UdfFuncBean.UdfFuncDeserializer; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; |
||||||
|
|
||||||
|
/** |
||||||
|
* SQL Task ExecutionContext |
||||||
|
* to master/worker task transport |
||||||
|
*/ |
||||||
|
public class SQLTaskRequest extends TaskRequest { |
||||||
|
|
||||||
|
/** |
||||||
|
* warningGroupId |
||||||
|
*/ |
||||||
|
private int warningGroupId; |
||||||
|
|
||||||
|
/** |
||||||
|
* connectionParams |
||||||
|
*/ |
||||||
|
private String connectionParams; |
||||||
|
/** |
||||||
|
* udf function tenant code map |
||||||
|
*/ |
||||||
|
@JsonDeserialize(keyUsing = UdfFuncDeserializer.class) |
||||||
|
private Map<UdfFuncBean,String> udfFuncTenantCodeMap; |
||||||
|
|
||||||
|
public int getWarningGroupId() { |
||||||
|
return warningGroupId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWarningGroupId(int warningGroupId) { |
||||||
|
this.warningGroupId = warningGroupId; |
||||||
|
} |
||||||
|
|
||||||
|
public Map<UdfFuncBean, String> getUdfFuncTenantCodeMap() { |
||||||
|
return udfFuncTenantCodeMap; |
||||||
|
} |
||||||
|
|
||||||
|
public void setUdfFuncTenantCodeMap(Map<UdfFuncBean, String> udfFuncTenantCodeMap) { |
||||||
|
this.udfFuncTenantCodeMap = udfFuncTenantCodeMap; |
||||||
|
} |
||||||
|
|
||||||
|
public String getConnectionParams() { |
||||||
|
return connectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setConnectionParams(String connectionParams) { |
||||||
|
this.connectionParams = connectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SQLTaskExecutionContext{" |
||||||
|
+ "warningGroupId=" + warningGroupId |
||||||
|
+ ", connectionParams='" + connectionParams + '\'' |
||||||
|
+ ", udfFuncTenantCodeMap=" + udfFuncTenantCodeMap |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.task.request; |
||||||
|
|
||||||
|
/** |
||||||
|
* Sqoop Task ExecutionContext |
||||||
|
* to master/worker task transport |
||||||
|
*/ |
||||||
|
public class SqoopTaskRequest extends TaskRequest { |
||||||
|
|
||||||
|
/** |
||||||
|
* dataSourceId |
||||||
|
*/ |
||||||
|
private int dataSourceId; |
||||||
|
|
||||||
|
/** |
||||||
|
* sourcetype |
||||||
|
*/ |
||||||
|
private int sourcetype; |
||||||
|
|
||||||
|
/** |
||||||
|
* sourceConnectionParams |
||||||
|
*/ |
||||||
|
private String sourceConnectionParams; |
||||||
|
|
||||||
|
/** |
||||||
|
* dataTargetId |
||||||
|
*/ |
||||||
|
private int dataTargetId; |
||||||
|
|
||||||
|
/** |
||||||
|
* targetType |
||||||
|
*/ |
||||||
|
private int targetType; |
||||||
|
|
||||||
|
/** |
||||||
|
* targetConnectionParams |
||||||
|
*/ |
||||||
|
private String targetConnectionParams; |
||||||
|
|
||||||
|
public int getDataSourceId() { |
||||||
|
return dataSourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataSourceId(int dataSourceId) { |
||||||
|
this.dataSourceId = dataSourceId; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSourcetype() { |
||||||
|
return sourcetype; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSourcetype(int sourcetype) { |
||||||
|
this.sourcetype = sourcetype; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSourceConnectionParams() { |
||||||
|
return sourceConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSourceConnectionParams(String sourceConnectionParams) { |
||||||
|
this.sourceConnectionParams = sourceConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDataTargetId() { |
||||||
|
return dataTargetId; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataTargetId(int dataTargetId) { |
||||||
|
this.dataTargetId = dataTargetId; |
||||||
|
} |
||||||
|
|
||||||
|
public int getTargetType() { |
||||||
|
return targetType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTargetType(int targetType) { |
||||||
|
this.targetType = targetType; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTargetConnectionParams() { |
||||||
|
return targetConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTargetConnectionParams(String targetConnectionParams) { |
||||||
|
this.targetConnectionParams = targetConnectionParams; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "SqoopTaskExecutionContext{" |
||||||
|
+ "dataSourceId=" + dataSourceId |
||||||
|
+ ", sourcetype=" + sourcetype |
||||||
|
+ ", sourceConnectionParams='" + sourceConnectionParams + '\'' |
||||||
|
+ ", dataTargetId=" + dataTargetId |
||||||
|
+ ", targetType=" + targetType |
||||||
|
+ ", targetConnectionParams='" + targetConnectionParams + '\'' |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,104 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.utils; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.HADOOP_SECURITY_AUTHENTICATION; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JAVA_SECURITY_KRB5_CONF; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JAVA_SECURITY_KRB5_CONF_PATH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.KERBEROS; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.LOGIN_USER_KEY_TAB_PATH; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.LOGIN_USER_KEY_TAB_USERNAME; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.RESOURCE_STORAGE_TYPE; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.ResUploadType; |
||||||
|
|
||||||
|
import org.apache.hadoop.conf.Configuration; |
||||||
|
import org.apache.hadoop.security.UserGroupInformation; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* common utils |
||||||
|
*/ |
||||||
|
public class CommonUtils { |
||||||
|
|
||||||
|
private CommonUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct CommonUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* if upload resource is HDFS and kerberos startup is true , else false |
||||||
|
* |
||||||
|
* @return true if upload resource is HDFS and kerberos startup |
||||||
|
*/ |
||||||
|
public static boolean getKerberosStartupState() { |
||||||
|
String resUploadStartupType = PropertyUtils.getUpperCaseString(RESOURCE_STORAGE_TYPE); |
||||||
|
ResUploadType resUploadType = ResUploadType.valueOf(resUploadStartupType); |
||||||
|
Boolean kerberosStartupState = PropertyUtils.getBoolean(HADOOP_SECURITY_AUTHENTICATION_STARTUP_STATE, false); |
||||||
|
return resUploadType == ResUploadType.HDFS && kerberosStartupState; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* load kerberos configuration |
||||||
|
* |
||||||
|
* @param configuration |
||||||
|
* @return load kerberos config return true |
||||||
|
* @throws IOException errors |
||||||
|
*/ |
||||||
|
public static boolean loadKerberosConf(Configuration configuration) throws IOException { |
||||||
|
return loadKerberosConf(PropertyUtils.getString(JAVA_SECURITY_KRB5_CONF_PATH), |
||||||
|
PropertyUtils.getString(LOGIN_USER_KEY_TAB_USERNAME), |
||||||
|
PropertyUtils.getString(LOGIN_USER_KEY_TAB_PATH), configuration); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* load kerberos configuration |
||||||
|
* |
||||||
|
* @param javaSecurityKrb5Conf javaSecurityKrb5Conf |
||||||
|
* @param loginUserKeytabUsername loginUserKeytabUsername |
||||||
|
* @param loginUserKeytabPath loginUserKeytabPath |
||||||
|
* @throws IOException errors |
||||||
|
*/ |
||||||
|
public static void loadKerberosConf(String javaSecurityKrb5Conf, String loginUserKeytabUsername, String loginUserKeytabPath) throws IOException { |
||||||
|
loadKerberosConf(javaSecurityKrb5Conf, loginUserKeytabUsername, loginUserKeytabPath, new Configuration()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* load kerberos configuration |
||||||
|
* |
||||||
|
* @param javaSecurityKrb5Conf javaSecurityKrb5Conf |
||||||
|
* @param loginUserKeytabUsername loginUserKeytabUsername |
||||||
|
* @param loginUserKeytabPath loginUserKeytabPath |
||||||
|
* @param configuration configuration |
||||||
|
* @return load kerberos config return true |
||||||
|
* @throws IOException errors |
||||||
|
*/ |
||||||
|
public static boolean loadKerberosConf(String javaSecurityKrb5Conf, String loginUserKeytabUsername, String loginUserKeytabPath, Configuration configuration) throws IOException { |
||||||
|
if (CommonUtils.getKerberosStartupState()) { |
||||||
|
System.setProperty(JAVA_SECURITY_KRB5_CONF, StringUtils.defaultIfBlank(javaSecurityKrb5Conf, PropertyUtils.getString(JAVA_SECURITY_KRB5_CONF_PATH))); |
||||||
|
configuration.set(HADOOP_SECURITY_AUTHENTICATION, KERBEROS); |
||||||
|
UserGroupInformation.setConfiguration(configuration); |
||||||
|
UserGroupInformation.loginUserFromKeytab(StringUtils.defaultIfBlank(loginUserKeytabUsername, PropertyUtils.getString(LOGIN_USER_KEY_TAB_USERNAME)), |
||||||
|
StringUtils.defaultIfBlank(loginUserKeytabPath, PropertyUtils.getString(LOGIN_USER_KEY_TAB_PATH))); |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,622 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.utils; |
||||||
|
|
||||||
|
import java.time.Instant; |
||||||
|
import java.time.LocalDateTime; |
||||||
|
import java.time.ZoneId; |
||||||
|
import java.time.ZonedDateTime; |
||||||
|
import java.time.format.DateTimeFormatter; |
||||||
|
import java.util.Calendar; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.Objects; |
||||||
|
import java.util.TimeZone; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
/** |
||||||
|
* date utils |
||||||
|
*/ |
||||||
|
public class DateUtils { |
||||||
|
|
||||||
|
static final long C0 = 1L; |
||||||
|
static final long C1 = C0 * 1000L; |
||||||
|
static final long C2 = C1 * 1000L; |
||||||
|
static final long C3 = C2 * 1000L; |
||||||
|
static final long C4 = C3 * 60L; |
||||||
|
static final long C5 = C4 * 60L; |
||||||
|
static final long C6 = C5 * 24L; |
||||||
|
|
||||||
|
/** |
||||||
|
* a default datetime formatter for the timestamp |
||||||
|
*/ |
||||||
|
private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DateUtils.class); |
||||||
|
|
||||||
|
private DateUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct DateUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param timeMillis timeMillis like System.currentTimeMillis() |
||||||
|
* @return string formatted as yyyy-MM-dd HH:mm:ss |
||||||
|
*/ |
||||||
|
public static String formatTimeStamp(long timeMillis) { |
||||||
|
return formatTimeStamp(timeMillis, DEFAULT_DATETIME_FORMATTER); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param timeMillis timeMillis like System.currentTimeMillis() |
||||||
|
* @param dateTimeFormatter expect formatter, like yyyy-MM-dd HH:mm:ss |
||||||
|
* @return formatted string |
||||||
|
*/ |
||||||
|
public static String formatTimeStamp(long timeMillis, DateTimeFormatter dateTimeFormatter) { |
||||||
|
Objects.requireNonNull(dateTimeFormatter); |
||||||
|
return dateTimeFormatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(timeMillis), |
||||||
|
ZoneId.systemDefault())); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* date to local datetime |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return local datetime |
||||||
|
*/ |
||||||
|
private static LocalDateTime date2LocalDateTime(Date date) { |
||||||
|
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* local datetime to date |
||||||
|
* |
||||||
|
* @param localDateTime local datetime |
||||||
|
* @return date |
||||||
|
*/ |
||||||
|
private static Date localDateTime2Date(LocalDateTime localDateTime) { |
||||||
|
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); |
||||||
|
return Date.from(instant); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get current date str |
||||||
|
* |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String getCurrentTime() { |
||||||
|
return getCurrentTime(Constants.YYYY_MM_DD_HH_MM_SS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get the date string in the specified format of the current time |
||||||
|
* |
||||||
|
* @param format date format |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String getCurrentTime(String format) { |
||||||
|
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(format)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get the formatted date string |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @param format e.g. yyyy-MM-dd HH:mm:ss |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String format(Date date, String format) { |
||||||
|
return format(date2LocalDateTime(date), format); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get the formatted date string |
||||||
|
* |
||||||
|
* @param localDateTime local data time |
||||||
|
* @param format yyyy-MM-dd HH:mm:ss |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String format(LocalDateTime localDateTime, String format) { |
||||||
|
return localDateTime.format(DateTimeFormatter.ofPattern(format)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* convert time to yyyy-MM-dd HH:mm:ss format |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String dateToString(Date date) { |
||||||
|
return format(date, Constants.YYYY_MM_DD_HH_MM_SS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* convert string to date and time |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @param format format |
||||||
|
* @return date |
||||||
|
*/ |
||||||
|
public static Date parse(String date, String format) { |
||||||
|
try { |
||||||
|
LocalDateTime ldt = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(format)); |
||||||
|
return localDateTime2Date(ldt); |
||||||
|
} catch (Exception e) { |
||||||
|
logger.error("error while parse date:" + date, e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* convert date str to yyyy-MM-dd HH:mm:ss format |
||||||
|
* |
||||||
|
* @param str date string |
||||||
|
* @return yyyy-MM-dd HH:mm:ss format |
||||||
|
*/ |
||||||
|
public static Date stringToDate(String str) { |
||||||
|
return parse(str, Constants.YYYY_MM_DD_HH_MM_SS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get seconds between two dates |
||||||
|
* |
||||||
|
* @param d1 date1 |
||||||
|
* @param d2 date2 |
||||||
|
* @return differ seconds |
||||||
|
*/ |
||||||
|
public static long differSec(Date d1, Date d2) { |
||||||
|
if (d1 == null || d2 == null) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
return (long) Math.ceil(differMs(d1, d2) / 1000.0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get ms between two dates |
||||||
|
* |
||||||
|
* @param d1 date1 |
||||||
|
* @param d2 date2 |
||||||
|
* @return differ ms |
||||||
|
*/ |
||||||
|
public static long differMs(Date d1, Date d2) { |
||||||
|
return Math.abs(d1.getTime() - d2.getTime()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get hours between two dates |
||||||
|
* |
||||||
|
* @param d1 date1 |
||||||
|
* @param d2 date2 |
||||||
|
* @return differ hours |
||||||
|
*/ |
||||||
|
public static long diffHours(Date d1, Date d2) { |
||||||
|
return (long) Math.ceil(diffMin(d1, d2) / 60.0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get minutes between two dates |
||||||
|
* |
||||||
|
* @param d1 date1 |
||||||
|
* @param d2 date2 |
||||||
|
* @return differ minutes |
||||||
|
*/ |
||||||
|
public static long diffMin(Date d1, Date d2) { |
||||||
|
return (long) Math.ceil(differSec(d1, d2) / 60.0); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get the date of the specified date in the days before and after |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @param day day |
||||||
|
* @return the date of the specified date in the days before and after |
||||||
|
*/ |
||||||
|
public static Date getSomeDay(Date date, int day) { |
||||||
|
Calendar calendar = Calendar.getInstance(); |
||||||
|
calendar.setTime(date); |
||||||
|
calendar.add(Calendar.DATE, day); |
||||||
|
return calendar.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get the hour of day. |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return hour of day |
||||||
|
*/ |
||||||
|
public static int getHourIndex(Date date) { |
||||||
|
Calendar calendar = Calendar.getInstance(); |
||||||
|
calendar.setTime(date); |
||||||
|
return calendar.get(Calendar.HOUR_OF_DAY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* compare two dates |
||||||
|
* |
||||||
|
* @param future future date |
||||||
|
* @param old old date |
||||||
|
* @return true if future time greater than old time |
||||||
|
*/ |
||||||
|
public static boolean compare(Date future, Date old) { |
||||||
|
return future.getTime() > old.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* convert schedule string to date |
||||||
|
* |
||||||
|
* @param schedule schedule |
||||||
|
* @return convert schedule string to date |
||||||
|
*/ |
||||||
|
public static Date getScheduleDate(String schedule) { |
||||||
|
return stringToDate(schedule); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* format time to readable |
||||||
|
* |
||||||
|
* @param ms ms |
||||||
|
* @return format time |
||||||
|
*/ |
||||||
|
public static String format2Readable(long ms) { |
||||||
|
|
||||||
|
long days = MILLISECONDS.toDays(ms); |
||||||
|
long hours = MILLISECONDS.toDurationHours(ms); |
||||||
|
long minutes = MILLISECONDS.toDurationMinutes(ms); |
||||||
|
long seconds = MILLISECONDS.toDurationSeconds(ms); |
||||||
|
|
||||||
|
return String.format("%02d %02d:%02d:%02d", days, hours, minutes, seconds); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* format time to duration |
||||||
|
* |
||||||
|
* @param d1 d1 |
||||||
|
* @param d2 d2 |
||||||
|
* @return format time |
||||||
|
*/ |
||||||
|
public static String format2Duration(Date d1, Date d2) { |
||||||
|
if (d1 == null || d2 == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return format2Duration(differMs(d1, d2)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* format time to duration |
||||||
|
* |
||||||
|
* @param ms ms |
||||||
|
* @return format time |
||||||
|
*/ |
||||||
|
public static String format2Duration(long ms) { |
||||||
|
|
||||||
|
long days = MILLISECONDS.toDays(ms); |
||||||
|
long hours = MILLISECONDS.toDurationHours(ms); |
||||||
|
long minutes = MILLISECONDS.toDurationMinutes(ms); |
||||||
|
long seconds = MILLISECONDS.toDurationSeconds(ms); |
||||||
|
|
||||||
|
StringBuilder strBuilder = new StringBuilder(); |
||||||
|
strBuilder = days > 0 ? strBuilder.append(days).append("d").append(" ") : strBuilder; |
||||||
|
strBuilder = hours > 0 ? strBuilder.append(hours).append("h").append(" ") : strBuilder; |
||||||
|
strBuilder = minutes > 0 ? strBuilder.append(minutes).append("m").append(" ") : strBuilder; |
||||||
|
strBuilder = seconds > 0 ? strBuilder.append(seconds).append("s") : strBuilder; |
||||||
|
|
||||||
|
return strBuilder.toString(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get monday |
||||||
|
* <p> |
||||||
|
* note: Set the first day of the week to Monday, the default is Sunday |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return get monday |
||||||
|
*/ |
||||||
|
public static Date getMonday(Date date) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
|
||||||
|
cal.setTime(date); |
||||||
|
|
||||||
|
cal.setFirstDayOfWeek(Calendar.MONDAY); |
||||||
|
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); |
||||||
|
|
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get sunday |
||||||
|
* <p> |
||||||
|
* note: Set the first day of the week to Monday, the default is Sunday |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return get sunday |
||||||
|
*/ |
||||||
|
public static Date getSunday(Date date) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
cal.setTime(date); |
||||||
|
|
||||||
|
cal.setFirstDayOfWeek(Calendar.MONDAY); |
||||||
|
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); |
||||||
|
|
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get first day of month |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return first day of month |
||||||
|
*/ |
||||||
|
public static Date getFirstDayOfMonth(Date date) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
|
||||||
|
cal.setTime(date); |
||||||
|
cal.set(Calendar.DAY_OF_MONTH, 1); |
||||||
|
|
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get some hour of day |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @param offsetHour hours |
||||||
|
* @return some hour of day |
||||||
|
*/ |
||||||
|
public static Date getSomeHourOfDay(Date date, int offsetHour) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
|
||||||
|
cal.setTime(date); |
||||||
|
cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + offsetHour); |
||||||
|
cal.set(Calendar.MINUTE, 0); |
||||||
|
cal.set(Calendar.SECOND, 0); |
||||||
|
cal.set(Calendar.MILLISECOND, 0); |
||||||
|
|
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get last day of month |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @return get last day of month |
||||||
|
*/ |
||||||
|
public static Date getLastDayOfMonth(Date date) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
|
||||||
|
cal.setTime(date); |
||||||
|
|
||||||
|
cal.add(Calendar.MONTH, 1); |
||||||
|
cal.set(Calendar.DAY_OF_MONTH, 1); |
||||||
|
cal.add(Calendar.DAY_OF_MONTH, -1); |
||||||
|
|
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return YYYY-MM-DD 00:00:00 |
||||||
|
* |
||||||
|
* @param inputDay date |
||||||
|
* @return start day |
||||||
|
*/ |
||||||
|
public static Date getStartOfDay(Date inputDay) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
cal.setTime(inputDay); |
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0); |
||||||
|
cal.set(Calendar.MINUTE, 0); |
||||||
|
cal.set(Calendar.SECOND, 0); |
||||||
|
cal.set(Calendar.MILLISECOND, 0); |
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return YYYY-MM-DD 23:59:59 |
||||||
|
* |
||||||
|
* @param inputDay day |
||||||
|
* @return end of day |
||||||
|
*/ |
||||||
|
public static Date getEndOfDay(Date inputDay) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
cal.setTime(inputDay); |
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 23); |
||||||
|
cal.set(Calendar.MINUTE, 59); |
||||||
|
cal.set(Calendar.SECOND, 59); |
||||||
|
cal.set(Calendar.MILLISECOND, 999); |
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return YYYY-MM-DD 00:00:00 |
||||||
|
* |
||||||
|
* @param inputDay day |
||||||
|
* @return start of hour |
||||||
|
*/ |
||||||
|
public static Date getStartOfHour(Date inputDay) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
cal.setTime(inputDay); |
||||||
|
cal.set(Calendar.MINUTE, 0); |
||||||
|
cal.set(Calendar.SECOND, 0); |
||||||
|
cal.set(Calendar.MILLISECOND, 0); |
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* return YYYY-MM-DD 23:59:59 |
||||||
|
* |
||||||
|
* @param inputDay day |
||||||
|
* @return end of hour |
||||||
|
*/ |
||||||
|
public static Date getEndOfHour(Date inputDay) { |
||||||
|
Calendar cal = Calendar.getInstance(); |
||||||
|
cal.setTime(inputDay); |
||||||
|
cal.set(Calendar.MINUTE, 59); |
||||||
|
cal.set(Calendar.SECOND, 59); |
||||||
|
cal.set(Calendar.MILLISECOND, 999); |
||||||
|
return cal.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get current date |
||||||
|
* |
||||||
|
* @return current date |
||||||
|
*/ |
||||||
|
public static Date getCurrentDate() { |
||||||
|
return DateUtils.parse(DateUtils.getCurrentTime(), |
||||||
|
Constants.YYYY_MM_DD_HH_MM_SS); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addYears(Date date, int amount) { |
||||||
|
return add(date, 1, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addMonths(Date date, int amount) { |
||||||
|
return add(date, 2, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addWeeks(Date date, int amount) { |
||||||
|
return add(date, 3, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addDays(Date date, int amount) { |
||||||
|
return add(date, 5, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addHours(Date date, int amount) { |
||||||
|
return add(date, 11, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addMinutes(Date date, int amount) { |
||||||
|
return add(date, 12, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addSeconds(Date date, int amount) { |
||||||
|
return add(date, 13, amount); |
||||||
|
} |
||||||
|
|
||||||
|
public static Date addMilliseconds(Date date, int amount) { |
||||||
|
return add(date, 14, amount); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get date |
||||||
|
* |
||||||
|
* @param date date |
||||||
|
* @param calendarField calendarField |
||||||
|
* @param amount amount |
||||||
|
* @return date |
||||||
|
*/ |
||||||
|
public static Date add(final Date date, final int calendarField, final int amount) { |
||||||
|
if (date == null) { |
||||||
|
throw new IllegalArgumentException("The date must not be null"); |
||||||
|
} |
||||||
|
final Calendar c = Calendar.getInstance(); |
||||||
|
c.setTime(date); |
||||||
|
c.add(calendarField, amount); |
||||||
|
return c.getTime(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* starting from the current time, get how many seconds are left before the target time. |
||||||
|
* targetTime = baseTime + intervalSeconds |
||||||
|
* |
||||||
|
* @param baseTime base time |
||||||
|
* @param intervalSeconds a period of time |
||||||
|
* @return the number of seconds |
||||||
|
*/ |
||||||
|
public static long getRemainTime(Date baseTime, long intervalSeconds) { |
||||||
|
if (baseTime == null) { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
long usedTime = (System.currentTimeMillis() - baseTime.getTime()) / 1000; |
||||||
|
return intervalSeconds - usedTime; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get current time stamp : yyyyMMddHHmmssSSS |
||||||
|
* |
||||||
|
* @return date string |
||||||
|
*/ |
||||||
|
public static String getCurrentTimeStamp() { |
||||||
|
return getCurrentTime(Constants.YYYYMMDDHHMMSSSSS); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* transform date to target timezone date |
||||||
|
* <p>e.g. |
||||||
|
* <p> if input date is 2020-01-01 00:00:00 current timezone is CST |
||||||
|
* <p>targetTimezoneId is MST |
||||||
|
* <p>this method will return 2020-01-01 15:00:00 |
||||||
|
*/ |
||||||
|
public static Date getTimezoneDate(Date date, String targetTimezoneId) { |
||||||
|
if (StringUtils.isEmpty(targetTimezoneId)) { |
||||||
|
return date; |
||||||
|
} |
||||||
|
|
||||||
|
String dateToString = dateToString(date); |
||||||
|
LocalDateTime localDateTime = LocalDateTime.parse(dateToString, DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS)); |
||||||
|
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, TimeZone.getTimeZone(targetTimezoneId).toZoneId()); |
||||||
|
return Date.from(zonedDateTime.toInstant()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get timezone by timezoneId |
||||||
|
*/ |
||||||
|
public static TimeZone getTimezone(String timezoneId) { |
||||||
|
if (StringUtils.isEmpty(timezoneId)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return TimeZone.getTimeZone(timezoneId); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Time unit representing one thousandth of a second |
||||||
|
*/ |
||||||
|
public static class MILLISECONDS { |
||||||
|
|
||||||
|
public static long toSeconds(long d) { |
||||||
|
return d / (C3 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toMinutes(long d) { |
||||||
|
return d / (C4 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toHours(long d) { |
||||||
|
return d / (C5 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toDays(long d) { |
||||||
|
return d / (C6 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toDurationSeconds(long d) { |
||||||
|
return (d % (C4 / C2)) / (C3 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toDurationMinutes(long d) { |
||||||
|
return (d % (C5 / C2)) / (C4 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
public static long toDurationHours(long d) { |
||||||
|
return (d % (C6 / C2)) / (C5 / C2); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,260 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.spi.utils; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.utils.Constants.COMMON_PROPERTIES_PATH; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Properties; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
public class PropertyUtils { |
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PropertyUtils.class); |
||||||
|
|
||||||
|
private static final Properties properties = new Properties(); |
||||||
|
|
||||||
|
private PropertyUtils() { |
||||||
|
throw new UnsupportedOperationException("Construct PropertyUtils"); |
||||||
|
} |
||||||
|
|
||||||
|
static { |
||||||
|
loadPropertyFile(COMMON_PROPERTIES_PATH); |
||||||
|
} |
||||||
|
|
||||||
|
public static synchronized void loadPropertyFile(String... propertyFiles) { |
||||||
|
for (String fileName : propertyFiles) { |
||||||
|
try (InputStream fis = PropertyUtils.class.getResourceAsStream(fileName);) { |
||||||
|
properties.load(fis); |
||||||
|
|
||||||
|
} catch (IOException e) { |
||||||
|
logger.error(e.getMessage(), e); |
||||||
|
System.exit(1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Override from system properties
|
||||||
|
System.getProperties().forEach((k, v) -> { |
||||||
|
final String key = String.valueOf(k); |
||||||
|
logger.info("Overriding property from system property: {}", key); |
||||||
|
PropertyUtils.setValue(key, String.valueOf(v)); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static String getString(String key) { |
||||||
|
return properties.getProperty(key.trim()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value with upper case |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @return property value with upper case |
||||||
|
*/ |
||||||
|
public static String getUpperCaseString(String key) { |
||||||
|
return properties.getProperty(key.trim()).toUpperCase(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @param defaultVal default value |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static String getString(String key, String defaultVal) { |
||||||
|
String val = properties.getProperty(key.trim()); |
||||||
|
return val == null ? defaultVal : val; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @return get property int value , if key == null, then return -1 |
||||||
|
*/ |
||||||
|
public static int getInt(String key) { |
||||||
|
return getInt(key, -1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param key key |
||||||
|
* @param defaultValue default value |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static int getInt(String key, int defaultValue) { |
||||||
|
String value = getString(key); |
||||||
|
if (value == null) { |
||||||
|
return defaultValue; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
return Integer.parseInt(value); |
||||||
|
} catch (NumberFormatException e) { |
||||||
|
logger.info(e.getMessage(), e); |
||||||
|
} |
||||||
|
return defaultValue; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static boolean getBoolean(String key) { |
||||||
|
String value = properties.getProperty(key.trim()); |
||||||
|
if (null != value) { |
||||||
|
return Boolean.parseBoolean(value); |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property value |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @param defaultValue default value |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static Boolean getBoolean(String key, boolean defaultValue) { |
||||||
|
String value = properties.getProperty(key.trim()); |
||||||
|
if (null != value) { |
||||||
|
return Boolean.parseBoolean(value); |
||||||
|
} |
||||||
|
|
||||||
|
return defaultValue; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get property long value |
||||||
|
* |
||||||
|
* @param key key |
||||||
|
* @param defaultVal default value |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static long getLong(String key, long defaultVal) { |
||||||
|
String val = getString(key); |
||||||
|
return val == null ? defaultVal : Long.parseLong(val); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param key key |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static long getLong(String key) { |
||||||
|
return getLong(key, -1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param key key |
||||||
|
* @param defaultVal default value |
||||||
|
* @return property value |
||||||
|
*/ |
||||||
|
public static double getDouble(String key, double defaultVal) { |
||||||
|
String val = getString(key); |
||||||
|
return val == null ? defaultVal : Double.parseDouble(val); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get array |
||||||
|
* |
||||||
|
* @param key property name |
||||||
|
* @param splitStr separator |
||||||
|
* @return property value through array |
||||||
|
*/ |
||||||
|
public static String[] getArray(String key, String splitStr) { |
||||||
|
String value = getString(key); |
||||||
|
if (value == null) { |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
try { |
||||||
|
String[] propertyArray = value.split(splitStr); |
||||||
|
return propertyArray; |
||||||
|
} catch (NumberFormatException e) { |
||||||
|
logger.info(e.getMessage(), e); |
||||||
|
} |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param key key |
||||||
|
* @param type type |
||||||
|
* @param defaultValue default value |
||||||
|
* @param <T> T |
||||||
|
* @return get enum value |
||||||
|
*/ |
||||||
|
public static <T extends Enum<T>> T getEnum(String key, Class<T> type, |
||||||
|
T defaultValue) { |
||||||
|
String val = getString(key); |
||||||
|
return val == null ? defaultValue : Enum.valueOf(type, val); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* get all properties with specified prefix, like: fs. |
||||||
|
* |
||||||
|
* @param prefix prefix to search |
||||||
|
* @return all properties with specified prefix |
||||||
|
*/ |
||||||
|
public static Map<String, String> getPrefixedProperties(String prefix) { |
||||||
|
Map<String, String> matchedProperties = new HashMap<>(); |
||||||
|
for (String propName : properties.stringPropertyNames()) { |
||||||
|
if (propName.startsWith(prefix)) { |
||||||
|
matchedProperties.put(propName, properties.getProperty(propName)); |
||||||
|
} |
||||||
|
} |
||||||
|
return matchedProperties; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
*/ |
||||||
|
public static void setValue(String key, String value) { |
||||||
|
properties.setProperty(key, value); |
||||||
|
} |
||||||
|
|
||||||
|
public static Map<String, String> getPropertiesByPrefix(String prefix) { |
||||||
|
if (StringUtils.isEmpty(prefix)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Set<Object> keys = properties.keySet(); |
||||||
|
if (keys.isEmpty()) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
Map<String, String> propertiesMap = new HashMap<>(); |
||||||
|
keys.forEach(k -> { |
||||||
|
if (k.toString().contains(prefix)) { |
||||||
|
propertiesMap.put(k.toString().replaceFirst(prefix + ".", ""), properties.getProperty((String) k)); |
||||||
|
} |
||||||
|
}); |
||||||
|
return propertiesMap; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,251 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.Flag; |
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractParameters; |
||||||
|
import org.apache.dolphinscheduler.spi.task.ResourceInfo; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* DataX parameter |
||||||
|
*/ |
||||||
|
public class DataxParameters extends AbstractParameters { |
||||||
|
|
||||||
|
/** |
||||||
|
* if custom json config,eg 0, 1 |
||||||
|
*/ |
||||||
|
private int customConfig; |
||||||
|
|
||||||
|
/** |
||||||
|
* if customConfig eq 1 ,then json is usable |
||||||
|
*/ |
||||||
|
private String json; |
||||||
|
|
||||||
|
/** |
||||||
|
* data source type,eg MYSQL, POSTGRES ... |
||||||
|
*/ |
||||||
|
private String dsType; |
||||||
|
|
||||||
|
/** |
||||||
|
* datasource id |
||||||
|
*/ |
||||||
|
private int dataSource; |
||||||
|
|
||||||
|
/** |
||||||
|
* data target type,eg MYSQL, POSTGRES ... |
||||||
|
*/ |
||||||
|
private String dtType; |
||||||
|
|
||||||
|
/** |
||||||
|
* datatarget id |
||||||
|
*/ |
||||||
|
private int dataTarget; |
||||||
|
|
||||||
|
/** |
||||||
|
* sql |
||||||
|
*/ |
||||||
|
private String sql; |
||||||
|
|
||||||
|
/** |
||||||
|
* target table |
||||||
|
*/ |
||||||
|
private String targetTable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Pre Statements |
||||||
|
*/ |
||||||
|
private List<String> preStatements; |
||||||
|
|
||||||
|
/** |
||||||
|
* Post Statements |
||||||
|
*/ |
||||||
|
private List<String> postStatements; |
||||||
|
|
||||||
|
/** |
||||||
|
* speed byte num |
||||||
|
*/ |
||||||
|
private int jobSpeedByte; |
||||||
|
|
||||||
|
/** |
||||||
|
* speed record count |
||||||
|
*/ |
||||||
|
private int jobSpeedRecord; |
||||||
|
|
||||||
|
/** |
||||||
|
* Xms memory |
||||||
|
*/ |
||||||
|
private int xms; |
||||||
|
|
||||||
|
/** |
||||||
|
* Xmx memory |
||||||
|
*/ |
||||||
|
private int xmx; |
||||||
|
|
||||||
|
public int getCustomConfig() { |
||||||
|
return customConfig; |
||||||
|
} |
||||||
|
|
||||||
|
public void setCustomConfig(int customConfig) { |
||||||
|
this.customConfig = customConfig; |
||||||
|
} |
||||||
|
|
||||||
|
public String getJson() { |
||||||
|
return json; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJson(String json) { |
||||||
|
this.json = json; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDsType() { |
||||||
|
return dsType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDsType(String dsType) { |
||||||
|
this.dsType = dsType; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDataSource() { |
||||||
|
return dataSource; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataSource(int dataSource) { |
||||||
|
this.dataSource = dataSource; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDtType() { |
||||||
|
return dtType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDtType(String dtType) { |
||||||
|
this.dtType = dtType; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDataTarget() { |
||||||
|
return dataTarget; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDataTarget(int dataTarget) { |
||||||
|
this.dataTarget = dataTarget; |
||||||
|
} |
||||||
|
|
||||||
|
public String getSql() { |
||||||
|
return sql; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSql(String sql) { |
||||||
|
this.sql = sql; |
||||||
|
} |
||||||
|
|
||||||
|
public String getTargetTable() { |
||||||
|
return targetTable; |
||||||
|
} |
||||||
|
|
||||||
|
public void setTargetTable(String targetTable) { |
||||||
|
this.targetTable = targetTable; |
||||||
|
} |
||||||
|
|
||||||
|
public List<String> getPreStatements() { |
||||||
|
return preStatements; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPreStatements(List<String> preStatements) { |
||||||
|
this.preStatements = preStatements; |
||||||
|
} |
||||||
|
|
||||||
|
public List<String> getPostStatements() { |
||||||
|
return postStatements; |
||||||
|
} |
||||||
|
|
||||||
|
public void setPostStatements(List<String> postStatements) { |
||||||
|
this.postStatements = postStatements; |
||||||
|
} |
||||||
|
|
||||||
|
public int getJobSpeedByte() { |
||||||
|
return jobSpeedByte; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJobSpeedByte(int jobSpeedByte) { |
||||||
|
this.jobSpeedByte = jobSpeedByte; |
||||||
|
} |
||||||
|
|
||||||
|
public int getJobSpeedRecord() { |
||||||
|
return jobSpeedRecord; |
||||||
|
} |
||||||
|
|
||||||
|
public void setJobSpeedRecord(int jobSpeedRecord) { |
||||||
|
this.jobSpeedRecord = jobSpeedRecord; |
||||||
|
} |
||||||
|
|
||||||
|
public int getXms() { |
||||||
|
return xms; |
||||||
|
} |
||||||
|
|
||||||
|
public void setXms(int xms) { |
||||||
|
this.xms = xms; |
||||||
|
} |
||||||
|
|
||||||
|
public int getXmx() { |
||||||
|
return xmx; |
||||||
|
} |
||||||
|
|
||||||
|
public void setXmx(int xmx) { |
||||||
|
this.xmx = xmx; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean checkParameters() { |
||||||
|
if (customConfig == Flag.NO.ordinal()) { |
||||||
|
return dataSource != 0 |
||||||
|
&& dataTarget != 0 |
||||||
|
&& StringUtils.isNotEmpty(sql) |
||||||
|
&& StringUtils.isNotEmpty(targetTable); |
||||||
|
} else { |
||||||
|
return StringUtils.isNotEmpty(json); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<ResourceInfo> getResourceFilesList() { |
||||||
|
return new ArrayList<>(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "DataxParameters{" |
||||||
|
+ "customConfig=" + customConfig |
||||||
|
+ ", json='" + json + '\'' |
||||||
|
+ ", dsType='" + dsType + '\'' |
||||||
|
+ ", dataSource=" + dataSource |
||||||
|
+ ", dtType='" + dtType + '\'' |
||||||
|
+ ", dataTarget=" + dataTarget |
||||||
|
+ ", sql='" + sql + '\'' |
||||||
|
+ ", targetTable='" + targetTable + '\'' |
||||||
|
+ ", preStatements=" + preStatements |
||||||
|
+ ", postStatements=" + postStatements |
||||||
|
+ ", jobSpeedByte=" + jobSpeedByte |
||||||
|
+ ", jobSpeedRecord=" + jobSpeedRecord |
||||||
|
+ ", xms=" + xms |
||||||
|
+ ", xmx=" + xmx |
||||||
|
+ '}'; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,570 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.EXIT_CODE_FAILURE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.RWXR_XR_X; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.datasource.PasswordUtils.decodePassword; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.plugin.task.api.AbstractTaskExecutor; |
||||||
|
import org.apache.dolphinscheduler.plugin.task.api.ShellCommandExecutor; |
||||||
|
import org.apache.dolphinscheduler.plugin.task.api.TaskResponse; |
||||||
|
import org.apache.dolphinscheduler.plugin.task.util.OSUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
import org.apache.dolphinscheduler.spi.enums.Flag; |
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractParameters; |
||||||
|
import org.apache.dolphinscheduler.spi.task.Property; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.BaseConnectionParam; |
||||||
|
import org.apache.dolphinscheduler.spi.task.datasource.DatasourceUtil; |
||||||
|
import org.apache.dolphinscheduler.spi.task.paramparser.ParamUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.task.paramparser.ParameterUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.DataxTaskRequest; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.CollectionUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.nio.file.Files; |
||||||
|
import java.nio.file.Path; |
||||||
|
import java.nio.file.Paths; |
||||||
|
import java.nio.file.StandardOpenOption; |
||||||
|
import java.nio.file.attribute.FileAttribute; |
||||||
|
import java.nio.file.attribute.PosixFilePermission; |
||||||
|
import java.nio.file.attribute.PosixFilePermissions; |
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.sql.ResultSet; |
||||||
|
import java.sql.ResultSetMetaData; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
import com.alibaba.druid.sql.ast.SQLStatement; |
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr; |
||||||
|
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr; |
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLSelect; |
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLSelectItem; |
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; |
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; |
||||||
|
import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; |
||||||
|
import com.alibaba.druid.sql.parser.SQLStatementParser; |
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode; |
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode; |
||||||
|
|
||||||
|
public class DataxTask extends AbstractTaskExecutor { |
||||||
|
/** |
||||||
|
* jvm parameters |
||||||
|
*/ |
||||||
|
public static final String JVM_PARAM = " --jvm=\"-Xms%sG -Xmx%sG\" "; |
||||||
|
/** |
||||||
|
* python process(datax only supports version 2.7 by default) |
||||||
|
*/ |
||||||
|
private static final String DATAX_PYTHON = "python2.7"; |
||||||
|
private static final Pattern PYTHON_PATH_PATTERN = Pattern.compile("/bin/python[\\d.]*$"); |
||||||
|
/** |
||||||
|
* datax path |
||||||
|
*/ |
||||||
|
private static final String DATAX_PATH = "${DATAX_HOME}/bin/datax.py"; |
||||||
|
/** |
||||||
|
* datax channel count |
||||||
|
*/ |
||||||
|
private static final int DATAX_CHANNEL_COUNT = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* datax parameters |
||||||
|
*/ |
||||||
|
private DataxParameters dataXParameters; |
||||||
|
|
||||||
|
/** |
||||||
|
* shell command executor |
||||||
|
*/ |
||||||
|
private ShellCommandExecutor shellCommandExecutor; |
||||||
|
|
||||||
|
/** |
||||||
|
* taskExecutionContext |
||||||
|
*/ |
||||||
|
private DataxTaskRequest taskExecutionContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* constructor |
||||||
|
* |
||||||
|
* @param taskExecutionContext taskExecutionContext |
||||||
|
*/ |
||||||
|
public DataxTask(DataxTaskRequest taskExecutionContext) { |
||||||
|
super(taskExecutionContext); |
||||||
|
this.taskExecutionContext = taskExecutionContext; |
||||||
|
|
||||||
|
this.shellCommandExecutor = new ShellCommandExecutor(this::logHandle, |
||||||
|
taskExecutionContext, logger); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* init DataX config |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
logger.info("datax task params {}", taskExecutionContext.getTaskParams()); |
||||||
|
dataXParameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), DataxParameters.class); |
||||||
|
|
||||||
|
if (!dataXParameters.checkParameters()) { |
||||||
|
throw new RuntimeException("datax task params is not valid"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* run DataX process |
||||||
|
* |
||||||
|
* @throws Exception if error throws Exception |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void handle() throws Exception { |
||||||
|
try { |
||||||
|
// set the name of the current thread
|
||||||
|
String threadLoggerInfoName = String.format("TaskLogInfo-%s", taskExecutionContext.getTaskAppId()); |
||||||
|
Thread.currentThread().setName(threadLoggerInfoName); |
||||||
|
|
||||||
|
// replace placeholder,and combine local and global parameters
|
||||||
|
Map<String, Property> paramsMap = ParamUtils.convert(taskExecutionContext,getParameters()); |
||||||
|
|
||||||
|
// run datax procesDataSourceService.s
|
||||||
|
String jsonFilePath = buildDataxJsonFile(paramsMap); |
||||||
|
String shellCommandFilePath = buildShellCommandFile(jsonFilePath, paramsMap); |
||||||
|
TaskResponse commandExecuteResult = shellCommandExecutor.run(shellCommandFilePath); |
||||||
|
|
||||||
|
setExitStatusCode(commandExecuteResult.getExitStatusCode()); |
||||||
|
setAppIds(commandExecuteResult.getAppIds()); |
||||||
|
setProcessId(commandExecuteResult.getProcessId()); |
||||||
|
} catch (Exception e) { |
||||||
|
setExitStatusCode(EXIT_CODE_FAILURE); |
||||||
|
throw e; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* cancel DataX process |
||||||
|
* |
||||||
|
* @param cancelApplication cancelApplication |
||||||
|
* @throws Exception if error throws Exception |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void cancelApplication(boolean cancelApplication) |
||||||
|
throws Exception { |
||||||
|
// cancel process
|
||||||
|
shellCommandExecutor.cancelApplication(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build datax configuration file |
||||||
|
* |
||||||
|
* @return datax json file name |
||||||
|
* @throws Exception if error throws Exception |
||||||
|
*/ |
||||||
|
private String buildDataxJsonFile(Map<String, Property> paramsMap) |
||||||
|
throws Exception { |
||||||
|
// generate json
|
||||||
|
String fileName = String.format("%s/%s_job.json", |
||||||
|
taskExecutionContext.getExecutePath(), |
||||||
|
taskExecutionContext.getTaskAppId()); |
||||||
|
String json; |
||||||
|
|
||||||
|
Path path = new File(fileName).toPath(); |
||||||
|
if (Files.exists(path)) { |
||||||
|
return fileName; |
||||||
|
} |
||||||
|
|
||||||
|
if (dataXParameters.getCustomConfig() == Flag.YES.ordinal()) { |
||||||
|
json = dataXParameters.getJson().replaceAll("\\r\\n", "\n"); |
||||||
|
} else { |
||||||
|
ObjectNode job = JSONUtils.createObjectNode(); |
||||||
|
job.putArray("content").addAll(buildDataxJobContentJson()); |
||||||
|
job.set("setting", buildDataxJobSettingJson()); |
||||||
|
|
||||||
|
ObjectNode root = JSONUtils.createObjectNode(); |
||||||
|
root.set("job", job); |
||||||
|
root.set("core", buildDataxCoreJson()); |
||||||
|
json = root.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
// replace placeholder
|
||||||
|
json = ParameterUtils.convertParameterPlaceholders(json, ParamUtils.convert(paramsMap)); |
||||||
|
|
||||||
|
logger.debug("datax job json : {}", json); |
||||||
|
|
||||||
|
// create datax json file
|
||||||
|
FileUtils.writeStringToFile(new File(fileName), json, StandardCharsets.UTF_8); |
||||||
|
return fileName; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build datax job config |
||||||
|
* |
||||||
|
* @return collection of datax job config JSONObject |
||||||
|
* @throws SQLException if error throws SQLException |
||||||
|
*/ |
||||||
|
private List<ObjectNode> buildDataxJobContentJson() { |
||||||
|
|
||||||
|
BaseConnectionParam dataSourceCfg = (BaseConnectionParam) DatasourceUtil.buildConnectionParams( |
||||||
|
DbType.of(taskExecutionContext.getSourcetype()), |
||||||
|
taskExecutionContext.getSourceConnectionParams()); |
||||||
|
|
||||||
|
BaseConnectionParam dataTargetCfg = (BaseConnectionParam) DatasourceUtil.buildConnectionParams( |
||||||
|
DbType.of(taskExecutionContext.getTargetType()), |
||||||
|
taskExecutionContext.getTargetConnectionParams()); |
||||||
|
|
||||||
|
List<ObjectNode> readerConnArr = new ArrayList<>(); |
||||||
|
ObjectNode readerConn = JSONUtils.createObjectNode(); |
||||||
|
|
||||||
|
ArrayNode sqlArr = readerConn.putArray("querySql"); |
||||||
|
for (String sql : new String[]{dataXParameters.getSql()}) { |
||||||
|
sqlArr.add(sql); |
||||||
|
} |
||||||
|
|
||||||
|
ArrayNode urlArr = readerConn.putArray("jdbcUrl"); |
||||||
|
urlArr.add(DatasourceUtil.getJdbcUrl(DbType.valueOf(dataXParameters.getDsType()), dataSourceCfg)); |
||||||
|
|
||||||
|
readerConnArr.add(readerConn); |
||||||
|
|
||||||
|
ObjectNode readerParam = JSONUtils.createObjectNode(); |
||||||
|
readerParam.put("username", dataSourceCfg.getUser()); |
||||||
|
readerParam.put("password", decodePassword(dataSourceCfg.getPassword())); |
||||||
|
readerParam.putArray("connection").addAll(readerConnArr); |
||||||
|
|
||||||
|
ObjectNode reader = JSONUtils.createObjectNode(); |
||||||
|
reader.put("name", DataxUtils.getReaderPluginName(DbType.of(taskExecutionContext.getSourcetype()))); |
||||||
|
reader.set("parameter", readerParam); |
||||||
|
|
||||||
|
List<ObjectNode> writerConnArr = new ArrayList<>(); |
||||||
|
ObjectNode writerConn = JSONUtils.createObjectNode(); |
||||||
|
ArrayNode tableArr = writerConn.putArray("table"); |
||||||
|
tableArr.add(dataXParameters.getTargetTable()); |
||||||
|
|
||||||
|
writerConn.put("jdbcUrl", DatasourceUtil.getJdbcUrl(DbType.valueOf(dataXParameters.getDtType()), dataTargetCfg)); |
||||||
|
writerConnArr.add(writerConn); |
||||||
|
|
||||||
|
ObjectNode writerParam = JSONUtils.createObjectNode(); |
||||||
|
writerParam.put("username", dataTargetCfg.getUser()); |
||||||
|
writerParam.put("password", decodePassword(dataTargetCfg.getPassword())); |
||||||
|
|
||||||
|
String[] columns = parsingSqlColumnNames(DbType.of(taskExecutionContext.getSourcetype()), |
||||||
|
DbType.of(taskExecutionContext.getTargetType()), |
||||||
|
dataSourceCfg, dataXParameters.getSql()); |
||||||
|
|
||||||
|
ArrayNode columnArr = writerParam.putArray("column"); |
||||||
|
for (String column : columns) { |
||||||
|
columnArr.add(column); |
||||||
|
} |
||||||
|
writerParam.putArray("connection").addAll(writerConnArr); |
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(dataXParameters.getPreStatements())) { |
||||||
|
ArrayNode preSqlArr = writerParam.putArray("preSql"); |
||||||
|
for (String preSql : dataXParameters.getPreStatements()) { |
||||||
|
preSqlArr.add(preSql); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(dataXParameters.getPostStatements())) { |
||||||
|
ArrayNode postSqlArr = writerParam.putArray("postSql"); |
||||||
|
for (String postSql : dataXParameters.getPostStatements()) { |
||||||
|
postSqlArr.add(postSql); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ObjectNode writer = JSONUtils.createObjectNode(); |
||||||
|
writer.put("name", DataxUtils.getWriterPluginName(DbType.of(taskExecutionContext.getTargetType()))); |
||||||
|
writer.set("parameter", writerParam); |
||||||
|
|
||||||
|
List<ObjectNode> contentList = new ArrayList<>(); |
||||||
|
ObjectNode content = JSONUtils.createObjectNode(); |
||||||
|
content.set("reader", reader); |
||||||
|
content.set("writer", writer); |
||||||
|
contentList.add(content); |
||||||
|
|
||||||
|
return contentList; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build datax setting config |
||||||
|
* |
||||||
|
* @return datax setting config JSONObject |
||||||
|
*/ |
||||||
|
private ObjectNode buildDataxJobSettingJson() { |
||||||
|
|
||||||
|
ObjectNode speed = JSONUtils.createObjectNode(); |
||||||
|
|
||||||
|
speed.put("channel", DATAX_CHANNEL_COUNT); |
||||||
|
|
||||||
|
if (dataXParameters.getJobSpeedByte() > 0) { |
||||||
|
speed.put("byte", dataXParameters.getJobSpeedByte()); |
||||||
|
} |
||||||
|
|
||||||
|
if (dataXParameters.getJobSpeedRecord() > 0) { |
||||||
|
speed.put("record", dataXParameters.getJobSpeedRecord()); |
||||||
|
} |
||||||
|
|
||||||
|
ObjectNode errorLimit = JSONUtils.createObjectNode(); |
||||||
|
errorLimit.put("record", 0); |
||||||
|
errorLimit.put("percentage", 0); |
||||||
|
|
||||||
|
ObjectNode setting = JSONUtils.createObjectNode(); |
||||||
|
setting.set("speed", speed); |
||||||
|
setting.set("errorLimit", errorLimit); |
||||||
|
|
||||||
|
return setting; |
||||||
|
} |
||||||
|
|
||||||
|
private ObjectNode buildDataxCoreJson() { |
||||||
|
|
||||||
|
ObjectNode speed = JSONUtils.createObjectNode(); |
||||||
|
speed.put("channel", DATAX_CHANNEL_COUNT); |
||||||
|
|
||||||
|
if (dataXParameters.getJobSpeedByte() > 0) { |
||||||
|
speed.put("byte", dataXParameters.getJobSpeedByte()); |
||||||
|
} |
||||||
|
|
||||||
|
if (dataXParameters.getJobSpeedRecord() > 0) { |
||||||
|
speed.put("record", dataXParameters.getJobSpeedRecord()); |
||||||
|
} |
||||||
|
|
||||||
|
ObjectNode channel = JSONUtils.createObjectNode(); |
||||||
|
channel.set("speed", speed); |
||||||
|
|
||||||
|
ObjectNode transport = JSONUtils.createObjectNode(); |
||||||
|
transport.set("channel", channel); |
||||||
|
|
||||||
|
ObjectNode core = JSONUtils.createObjectNode(); |
||||||
|
core.set("transport", transport); |
||||||
|
|
||||||
|
return core; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* create command |
||||||
|
* |
||||||
|
* @return shell command file name |
||||||
|
* @throws Exception if error throws Exception |
||||||
|
*/ |
||||||
|
private String buildShellCommandFile(String jobConfigFilePath, Map<String, Property> paramsMap) |
||||||
|
throws Exception { |
||||||
|
// generate scripts
|
||||||
|
String fileName = String.format("%s/%s_node.%s", |
||||||
|
taskExecutionContext.getExecutePath(), |
||||||
|
taskExecutionContext.getTaskAppId(), |
||||||
|
OSUtils.isWindows() ? "bat" : "sh"); |
||||||
|
|
||||||
|
Path path = new File(fileName).toPath(); |
||||||
|
|
||||||
|
if (Files.exists(path)) { |
||||||
|
return fileName; |
||||||
|
} |
||||||
|
|
||||||
|
// datax python command
|
||||||
|
StringBuilder sbr = new StringBuilder(); |
||||||
|
sbr.append(getPythonCommand()); |
||||||
|
sbr.append(" "); |
||||||
|
sbr.append(DATAX_PATH); |
||||||
|
sbr.append(" "); |
||||||
|
sbr.append(loadJvmEnv(dataXParameters)); |
||||||
|
sbr.append(jobConfigFilePath); |
||||||
|
|
||||||
|
// replace placeholder
|
||||||
|
String dataxCommand = ParameterUtils.convertParameterPlaceholders(sbr.toString(), ParamUtils.convert(paramsMap)); |
||||||
|
|
||||||
|
logger.debug("raw script : {}", dataxCommand); |
||||||
|
|
||||||
|
// create shell command file
|
||||||
|
Set<PosixFilePermission> perms = PosixFilePermissions.fromString(RWXR_XR_X); |
||||||
|
FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms); |
||||||
|
|
||||||
|
if (OSUtils.isWindows()) { |
||||||
|
Files.createFile(path); |
||||||
|
} else { |
||||||
|
Files.createFile(path, attr); |
||||||
|
} |
||||||
|
|
||||||
|
Files.write(path, dataxCommand.getBytes(), StandardOpenOption.APPEND); |
||||||
|
|
||||||
|
return fileName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPythonCommand() { |
||||||
|
String pythonHome = System.getenv("PYTHON_HOME"); |
||||||
|
return getPythonCommand(pythonHome); |
||||||
|
} |
||||||
|
|
||||||
|
public String getPythonCommand(String pythonHome) { |
||||||
|
if (StringUtils.isEmpty(pythonHome)) { |
||||||
|
return DATAX_PYTHON; |
||||||
|
} |
||||||
|
String pythonBinPath = "/bin/" + DATAX_PYTHON; |
||||||
|
Matcher matcher = PYTHON_PATH_PATTERN.matcher(pythonHome); |
||||||
|
if (matcher.find()) { |
||||||
|
return matcher.replaceAll(pythonBinPath); |
||||||
|
} |
||||||
|
return Paths.get(pythonHome, pythonBinPath).toString(); |
||||||
|
} |
||||||
|
|
||||||
|
public String loadJvmEnv(DataxParameters dataXParameters) { |
||||||
|
int xms = Math.max(dataXParameters.getXms(), 1); |
||||||
|
int xmx = Math.max(dataXParameters.getXmx(), 1); |
||||||
|
return String.format(JVM_PARAM, xms, xmx); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* parsing synchronized column names in SQL statements |
||||||
|
* |
||||||
|
* @param sourceType the database type of the data source |
||||||
|
* @param targetType the database type of the data target |
||||||
|
* @param dataSourceCfg the database connection parameters of the data source |
||||||
|
* @param sql sql for data synchronization |
||||||
|
* @return Keyword converted column names |
||||||
|
*/ |
||||||
|
private String[] parsingSqlColumnNames(DbType sourceType, DbType targetType, BaseConnectionParam dataSourceCfg, String sql) { |
||||||
|
String[] columnNames = tryGrammaticalAnalysisSqlColumnNames(sourceType, sql); |
||||||
|
|
||||||
|
if (columnNames == null || columnNames.length == 0) { |
||||||
|
logger.info("try to execute sql analysis query column name"); |
||||||
|
columnNames = tryExecuteSqlResolveColumnNames(sourceType, dataSourceCfg, sql); |
||||||
|
} |
||||||
|
|
||||||
|
notNull(columnNames, String.format("parsing sql columns failed : %s", sql)); |
||||||
|
|
||||||
|
return DataxUtils.convertKeywordsColumns(targetType, columnNames); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* try grammatical parsing column |
||||||
|
* |
||||||
|
* @param dbType database type |
||||||
|
* @param sql sql for data synchronization |
||||||
|
* @return column name array |
||||||
|
* @throws RuntimeException if error throws RuntimeException |
||||||
|
*/ |
||||||
|
private String[] tryGrammaticalAnalysisSqlColumnNames(DbType dbType, String sql) { |
||||||
|
String[] columnNames; |
||||||
|
|
||||||
|
try { |
||||||
|
SQLStatementParser parser = DataxUtils.getSqlStatementParser(dbType, sql); |
||||||
|
if (parser == null) { |
||||||
|
logger.warn("database driver [{}] is not support grammatical analysis sql", dbType); |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
|
||||||
|
SQLStatement sqlStatement = parser.parseStatement(); |
||||||
|
SQLSelectStatement sqlSelectStatement = (SQLSelectStatement) sqlStatement; |
||||||
|
SQLSelect sqlSelect = sqlSelectStatement.getSelect(); |
||||||
|
|
||||||
|
List<SQLSelectItem> selectItemList = null; |
||||||
|
if (sqlSelect.getQuery() instanceof SQLSelectQueryBlock) { |
||||||
|
SQLSelectQueryBlock block = (SQLSelectQueryBlock) sqlSelect.getQuery(); |
||||||
|
selectItemList = block.getSelectList(); |
||||||
|
} else if (sqlSelect.getQuery() instanceof SQLUnionQuery) { |
||||||
|
SQLUnionQuery unionQuery = (SQLUnionQuery) sqlSelect.getQuery(); |
||||||
|
SQLSelectQueryBlock block = (SQLSelectQueryBlock) unionQuery.getRight(); |
||||||
|
selectItemList = block.getSelectList(); |
||||||
|
} |
||||||
|
|
||||||
|
notNull(selectItemList, |
||||||
|
String.format("select query type [%s] is not support", sqlSelect.getQuery().toString())); |
||||||
|
|
||||||
|
columnNames = new String[selectItemList.size()]; |
||||||
|
for (int i = 0; i < selectItemList.size(); i++) { |
||||||
|
SQLSelectItem item = selectItemList.get(i); |
||||||
|
|
||||||
|
String columnName = null; |
||||||
|
|
||||||
|
if (item.getAlias() != null) { |
||||||
|
columnName = item.getAlias(); |
||||||
|
} else if (item.getExpr() != null) { |
||||||
|
if (item.getExpr() instanceof SQLPropertyExpr) { |
||||||
|
SQLPropertyExpr expr = (SQLPropertyExpr) item.getExpr(); |
||||||
|
columnName = expr.getName(); |
||||||
|
} else if (item.getExpr() instanceof SQLIdentifierExpr) { |
||||||
|
SQLIdentifierExpr expr = (SQLIdentifierExpr) item.getExpr(); |
||||||
|
columnName = expr.getName(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
throw new RuntimeException( |
||||||
|
String.format("grammatical analysis sql column [ %s ] failed", item.toString())); |
||||||
|
} |
||||||
|
|
||||||
|
if (columnName == null) { |
||||||
|
throw new RuntimeException( |
||||||
|
String.format("grammatical analysis sql column [ %s ] failed", item.toString())); |
||||||
|
} |
||||||
|
|
||||||
|
columnNames[i] = columnName; |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
logger.warn(e.getMessage(), e); |
||||||
|
return new String[0]; |
||||||
|
} |
||||||
|
|
||||||
|
return columnNames; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* try to execute sql to resolve column names |
||||||
|
* |
||||||
|
* @param baseDataSource the database connection parameters |
||||||
|
* @param sql sql for data synchronization |
||||||
|
* @return column name array |
||||||
|
*/ |
||||||
|
public String[] tryExecuteSqlResolveColumnNames(DbType sourceType, BaseConnectionParam baseDataSource, String sql) { |
||||||
|
String[] columnNames; |
||||||
|
sql = String.format("SELECT t.* FROM ( %s ) t WHERE 0 = 1", sql); |
||||||
|
sql = sql.replace(";", ""); |
||||||
|
|
||||||
|
try ( |
||||||
|
Connection connection = DatasourceUtil.getConnection(sourceType, baseDataSource); |
||||||
|
PreparedStatement stmt = connection.prepareStatement(sql); |
||||||
|
ResultSet resultSet = stmt.executeQuery()) { |
||||||
|
|
||||||
|
ResultSetMetaData md = resultSet.getMetaData(); |
||||||
|
int num = md.getColumnCount(); |
||||||
|
columnNames = new String[num]; |
||||||
|
for (int i = 1; i <= num; i++) { |
||||||
|
columnNames[i - 1] = md.getColumnName(i); |
||||||
|
} |
||||||
|
} catch (SQLException e) { |
||||||
|
logger.warn(e.getMessage(), e); |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return columnNames; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractParameters getParameters() { |
||||||
|
return dataXParameters; |
||||||
|
} |
||||||
|
|
||||||
|
private void notNull(Object obj, String message) { |
||||||
|
if (obj == null) { |
||||||
|
throw new RuntimeException(message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractTask; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannel; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.DataxTaskRequest; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.TaskRequest; |
||||||
|
|
||||||
|
public class DataxTaskChannel implements TaskChannel { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void cancelApplication(boolean status) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractTask createTask(TaskRequest taskRequest) { |
||||||
|
return new DataxTask((DataxTaskRequest) taskRequest); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannel; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannelFactory; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class DataxTaskChannelFactory implements TaskChannelFactory { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getName() { |
||||||
|
return "DATAX"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<PluginParams> getParams() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TaskChannel create() { |
||||||
|
return new DataxTaskChannel(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.DolphinSchedulerPlugin; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannelFactory; |
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList; |
||||||
|
|
||||||
|
public class DataxTaskPlugin implements DolphinSchedulerPlugin { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Iterable<TaskChannelFactory> getTaskChannelFactorys() { |
||||||
|
return ImmutableList.of(new DataxTaskChannelFactory()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.datax; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.enums.DbType; |
||||||
|
|
||||||
|
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; |
||||||
|
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; |
||||||
|
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser; |
||||||
|
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser; |
||||||
|
import com.alibaba.druid.sql.parser.SQLStatementParser; |
||||||
|
|
||||||
|
public class DataxUtils { |
||||||
|
|
||||||
|
public static final String DATAX_READER_PLUGIN_MYSQL = "mysqlreader"; |
||||||
|
|
||||||
|
public static final String DATAX_READER_PLUGIN_POSTGRESQL = "postgresqlreader"; |
||||||
|
|
||||||
|
public static final String DATAX_READER_PLUGIN_ORACLE = "oraclereader"; |
||||||
|
|
||||||
|
public static final String DATAX_READER_PLUGIN_SQLSERVER = "sqlserverreader"; |
||||||
|
|
||||||
|
public static final String DATAX_READER_PLUGIN_CLICKHOUSE = "clickhousereader"; |
||||||
|
|
||||||
|
public static final String DATAX_WRITER_PLUGIN_MYSQL = "mysqlwriter"; |
||||||
|
|
||||||
|
public static final String DATAX_WRITER_PLUGIN_POSTGRESQL = "postgresqlwriter"; |
||||||
|
|
||||||
|
public static final String DATAX_WRITER_PLUGIN_ORACLE = "oraclewriter"; |
||||||
|
|
||||||
|
public static final String DATAX_WRITER_PLUGIN_SQLSERVER = "sqlserverwriter"; |
||||||
|
|
||||||
|
public static final String DATAX_WRITER_PLUGIN_CLICKHOUSE = "clickhousewriter"; |
||||||
|
|
||||||
|
public static String getReaderPluginName(DbType dbType) { |
||||||
|
switch (dbType) { |
||||||
|
case MYSQL: |
||||||
|
return DATAX_READER_PLUGIN_MYSQL; |
||||||
|
case POSTGRESQL: |
||||||
|
return DATAX_READER_PLUGIN_POSTGRESQL; |
||||||
|
case ORACLE: |
||||||
|
return DATAX_READER_PLUGIN_ORACLE; |
||||||
|
case SQLSERVER: |
||||||
|
return DATAX_READER_PLUGIN_SQLSERVER; |
||||||
|
case CLICKHOUSE: |
||||||
|
return DATAX_READER_PLUGIN_CLICKHOUSE; |
||||||
|
default: |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static String getWriterPluginName(DbType dbType) { |
||||||
|
switch (dbType) { |
||||||
|
case MYSQL: |
||||||
|
return DATAX_WRITER_PLUGIN_MYSQL; |
||||||
|
case POSTGRESQL: |
||||||
|
return DATAX_WRITER_PLUGIN_POSTGRESQL; |
||||||
|
case ORACLE: |
||||||
|
return DATAX_WRITER_PLUGIN_ORACLE; |
||||||
|
case SQLSERVER: |
||||||
|
return DATAX_WRITER_PLUGIN_SQLSERVER; |
||||||
|
case CLICKHOUSE: |
||||||
|
return DATAX_WRITER_PLUGIN_CLICKHOUSE; |
||||||
|
default: |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static SQLStatementParser getSqlStatementParser(DbType dbType, String sql) { |
||||||
|
switch (dbType) { |
||||||
|
case MYSQL: |
||||||
|
return new MySqlStatementParser(sql); |
||||||
|
case POSTGRESQL: |
||||||
|
return new PGSQLStatementParser(sql); |
||||||
|
case ORACLE: |
||||||
|
return new OracleStatementParser(sql); |
||||||
|
case SQLSERVER: |
||||||
|
return new SQLServerStatementParser(sql); |
||||||
|
default: |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static String[] convertKeywordsColumns(DbType dbType, String[] columns) { |
||||||
|
if (columns == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
String[] toColumns = new String[columns.length]; |
||||||
|
for (int i = 0; i < columns.length; i++) { |
||||||
|
toColumns[i] = doConvertKeywordsColumn(dbType, columns[i]); |
||||||
|
} |
||||||
|
|
||||||
|
return toColumns; |
||||||
|
} |
||||||
|
|
||||||
|
public static String doConvertKeywordsColumn(DbType dbType, String column) { |
||||||
|
if (column == null) { |
||||||
|
return column; |
||||||
|
} |
||||||
|
|
||||||
|
column = column.trim(); |
||||||
|
column = column.replace("`", ""); |
||||||
|
column = column.replace("\"", ""); |
||||||
|
column = column.replace("'", ""); |
||||||
|
|
||||||
|
switch (dbType) { |
||||||
|
case MYSQL: |
||||||
|
return String.format("`%s`", column); |
||||||
|
case POSTGRESQL: |
||||||
|
return String.format("\"%s\"", column); |
||||||
|
case ORACLE: |
||||||
|
return String.format("\"%s\"", column); |
||||||
|
case SQLSERVER: |
||||||
|
return String.format("`%s`", column); |
||||||
|
default: |
||||||
|
return column; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
import static org.apache.dolphinscheduler.plugin.task.mr.MapReduceTaskConstants.MR_NAME; |
||||||
|
import static org.apache.dolphinscheduler.plugin.task.mr.MapReduceTaskConstants.MR_QUEUE; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.D; |
||||||
|
import static org.apache.dolphinscheduler.spi.task.TaskConstants.JAR; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.plugin.task.util.ArgsUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.task.ResourceInfo; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.StringUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* mapreduce args utils |
||||||
|
*/ |
||||||
|
public class MapReduceArgsUtils { |
||||||
|
|
||||||
|
private MapReduceArgsUtils() { |
||||||
|
throw new IllegalStateException("Utility class"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build args |
||||||
|
* |
||||||
|
* @param param param |
||||||
|
* @return argument list |
||||||
|
*/ |
||||||
|
public static List<String> buildArgs(MapReduceParameters param) { |
||||||
|
List<String> args = new ArrayList<>(); |
||||||
|
|
||||||
|
ResourceInfo mainJar = param.getMainJar(); |
||||||
|
if (mainJar != null) { |
||||||
|
args.add(JAR); |
||||||
|
args.add(mainJar.getRes()); |
||||||
|
} |
||||||
|
|
||||||
|
ProgramType programType = param.getProgramType(); |
||||||
|
String mainClass = param.getMainClass(); |
||||||
|
if (programType != null && programType != ProgramType.PYTHON && StringUtils.isNotEmpty(mainClass)) { |
||||||
|
args.add(mainClass); |
||||||
|
} |
||||||
|
|
||||||
|
String appName = param.getAppName(); |
||||||
|
if (StringUtils.isNotEmpty(appName)) { |
||||||
|
args.add(String.format("%s%s=%s", D, MR_NAME, ArgsUtils.escape(appName))); |
||||||
|
} |
||||||
|
|
||||||
|
String others = param.getOthers(); |
||||||
|
if (StringUtils.isEmpty(others) || !others.contains(MR_QUEUE)) { |
||||||
|
String queue = param.getQueue(); |
||||||
|
if (StringUtils.isNotEmpty(queue)) { |
||||||
|
args.add(String.format("%s%s=%s", D, MR_QUEUE, queue)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// -conf -archives -files -libjars -D
|
||||||
|
if (StringUtils.isNotEmpty(others)) { |
||||||
|
args.add(others); |
||||||
|
} |
||||||
|
|
||||||
|
String mainArgs = param.getMainArgs(); |
||||||
|
if (StringUtils.isNotEmpty(mainArgs)) { |
||||||
|
args.add(mainArgs); |
||||||
|
} |
||||||
|
|
||||||
|
return args; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,159 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractParameters; |
||||||
|
import org.apache.dolphinscheduler.spi.task.ResourceInfo; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* mapreduce parameters |
||||||
|
*/ |
||||||
|
public class MapReduceParameters extends AbstractParameters { |
||||||
|
|
||||||
|
/** |
||||||
|
* major jar |
||||||
|
*/ |
||||||
|
private ResourceInfo mainJar; |
||||||
|
|
||||||
|
/** |
||||||
|
* major class
|
||||||
|
*/ |
||||||
|
private String mainClass; |
||||||
|
|
||||||
|
/** |
||||||
|
* arguments |
||||||
|
*/ |
||||||
|
private String mainArgs; |
||||||
|
|
||||||
|
/** |
||||||
|
* other arguments |
||||||
|
*/ |
||||||
|
private String others; |
||||||
|
|
||||||
|
/** |
||||||
|
* app name |
||||||
|
*/ |
||||||
|
private String appName; |
||||||
|
|
||||||
|
/** |
||||||
|
* queue |
||||||
|
*/ |
||||||
|
private String queue; |
||||||
|
|
||||||
|
/** |
||||||
|
* resource list |
||||||
|
*/ |
||||||
|
private List<ResourceInfo> resourceList = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* program type |
||||||
|
* 0 JAVA,1 SCALA,2 PYTHON |
||||||
|
*/ |
||||||
|
private ProgramType programType; |
||||||
|
|
||||||
|
public String getMainClass() { |
||||||
|
return mainClass; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMainClass(String mainClass) { |
||||||
|
this.mainClass = mainClass; |
||||||
|
} |
||||||
|
|
||||||
|
public String getMainArgs() { |
||||||
|
return mainArgs; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMainArgs(String mainArgs) { |
||||||
|
this.mainArgs = mainArgs; |
||||||
|
} |
||||||
|
|
||||||
|
public String getOthers() { |
||||||
|
return others; |
||||||
|
} |
||||||
|
|
||||||
|
public void setOthers(String others) { |
||||||
|
this.others = others; |
||||||
|
} |
||||||
|
|
||||||
|
public String getAppName() { |
||||||
|
return appName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setAppName(String appName) { |
||||||
|
this.appName = appName; |
||||||
|
} |
||||||
|
|
||||||
|
public String getQueue() { |
||||||
|
return queue; |
||||||
|
} |
||||||
|
|
||||||
|
public void setQueue(String queue) { |
||||||
|
this.queue = queue; |
||||||
|
} |
||||||
|
|
||||||
|
public List<ResourceInfo> getResourceList() { |
||||||
|
return this.resourceList; |
||||||
|
} |
||||||
|
|
||||||
|
public void setResourceList(List<ResourceInfo> resourceList) { |
||||||
|
this.resourceList = resourceList; |
||||||
|
} |
||||||
|
|
||||||
|
public void setMainJar(ResourceInfo mainJar) { |
||||||
|
this.mainJar = mainJar; |
||||||
|
} |
||||||
|
|
||||||
|
public ResourceInfo getMainJar() { |
||||||
|
return mainJar; |
||||||
|
} |
||||||
|
|
||||||
|
public ProgramType getProgramType() { |
||||||
|
return programType; |
||||||
|
} |
||||||
|
|
||||||
|
public void setProgramType(ProgramType programType) { |
||||||
|
this.programType = programType; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean checkParameters() { |
||||||
|
return this.mainJar != null && this.programType != null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<ResourceInfo> getResourceFilesList() { |
||||||
|
if (mainJar != null && !resourceList.contains(mainJar)) { |
||||||
|
resourceList.add(mainJar); |
||||||
|
} |
||||||
|
|
||||||
|
return resourceList; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "mainJar= " + mainJar |
||||||
|
+ "mainClass=" + mainClass |
||||||
|
+ "mainArgs=" + mainArgs |
||||||
|
+ "queue=" + queue |
||||||
|
+ "other mainArgs=" + others |
||||||
|
; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,134 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.plugin.task.api.AbstractYarnTask; |
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractParameters; |
||||||
|
import org.apache.dolphinscheduler.spi.task.Property; |
||||||
|
import org.apache.dolphinscheduler.spi.task.ResourceInfo; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskConstants; |
||||||
|
import org.apache.dolphinscheduler.spi.task.paramparser.ParamUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.task.paramparser.ParameterUtils; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.TaskRequest; |
||||||
|
import org.apache.dolphinscheduler.spi.utils.JSONUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* mapreduce task |
||||||
|
*/ |
||||||
|
public class MapReduceTask extends AbstractYarnTask { |
||||||
|
|
||||||
|
/** |
||||||
|
* mapreduce command |
||||||
|
* usage: hadoop jar <jar> [mainClass] [GENERIC_OPTIONS] args... |
||||||
|
*/ |
||||||
|
private static final String MAPREDUCE_COMMAND = TaskConstants.HADOOP; |
||||||
|
|
||||||
|
/** |
||||||
|
* mapreduce parameters |
||||||
|
*/ |
||||||
|
private MapReduceParameters mapreduceParameters; |
||||||
|
|
||||||
|
/** |
||||||
|
* taskExecutionContext |
||||||
|
*/ |
||||||
|
private TaskRequest taskExecutionContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* constructor |
||||||
|
* @param taskExecutionContext taskExecutionContext |
||||||
|
*/ |
||||||
|
public MapReduceTask(TaskRequest taskExecutionContext) { |
||||||
|
super(taskExecutionContext); |
||||||
|
this.taskExecutionContext = taskExecutionContext; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void init() { |
||||||
|
|
||||||
|
logger.info("mapreduce task params {}", taskExecutionContext.getTaskParams()); |
||||||
|
|
||||||
|
this.mapreduceParameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), MapReduceParameters.class); |
||||||
|
|
||||||
|
// check parameters
|
||||||
|
if (mapreduceParameters == null || !mapreduceParameters.checkParameters()) { |
||||||
|
throw new RuntimeException("mapreduce task params is not valid"); |
||||||
|
} |
||||||
|
|
||||||
|
mapreduceParameters.setQueue(taskExecutionContext.getQueue()); |
||||||
|
setMainJarName(); |
||||||
|
|
||||||
|
// replace placeholder,and combine local and global parameters
|
||||||
|
Map<String, Property> paramsMap = ParamUtils.convert(taskExecutionContext,getParameters()); |
||||||
|
|
||||||
|
if (paramsMap != null) { |
||||||
|
String args = ParameterUtils.convertParameterPlaceholders(mapreduceParameters.getMainArgs(), ParamUtils.convert(paramsMap)); |
||||||
|
mapreduceParameters.setMainArgs(args); |
||||||
|
if (mapreduceParameters.getProgramType() != null && mapreduceParameters.getProgramType() == ProgramType.PYTHON) { |
||||||
|
String others = ParameterUtils.convertParameterPlaceholders(mapreduceParameters.getOthers(), ParamUtils.convert(paramsMap)); |
||||||
|
mapreduceParameters.setOthers(others); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* build command |
||||||
|
* @return command |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
protected String buildCommand() { |
||||||
|
// hadoop jar <jar> [mainClass] [GENERIC_OPTIONS] args...
|
||||||
|
List<String> args = new ArrayList<>(); |
||||||
|
args.add(MAPREDUCE_COMMAND); |
||||||
|
|
||||||
|
// other parameters
|
||||||
|
args.addAll(MapReduceArgsUtils.buildArgs(mapreduceParameters)); |
||||||
|
|
||||||
|
String command = ParameterUtils.convertParameterPlaceholders(String.join(" ", args), |
||||||
|
taskExecutionContext.getDefinedParams()); |
||||||
|
logger.info("mapreduce task command: {}", command); |
||||||
|
|
||||||
|
return command; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void setMainJarName() { |
||||||
|
// main jar
|
||||||
|
ResourceInfo mainJar = mapreduceParameters.getMainJar(); |
||||||
|
if (mainJar != null) { |
||||||
|
int resourceId = mainJar.getId(); |
||||||
|
String resourceName; |
||||||
|
if (resourceId == 0) { |
||||||
|
resourceName = mainJar.getRes(); |
||||||
|
} else { |
||||||
|
//when update resource maybe has error ,也许也可以交给上层去做控制 需要看资源是否可以抽象为共性 目前来讲我认为是可以的
|
||||||
|
resourceName = mainJar.getResourceName().replaceFirst("/", ""); |
||||||
|
} |
||||||
|
mainJar.setRes(resourceName); |
||||||
|
mapreduceParameters.setMainJar(mainJar); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractParameters getParameters() { |
||||||
|
return mapreduceParameters; |
||||||
|
} |
||||||
|
} |
@ -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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.task.AbstractTask; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannel; |
||||||
|
import org.apache.dolphinscheduler.spi.task.request.TaskRequest; |
||||||
|
|
||||||
|
public class MapReduceTaskChannel implements TaskChannel { |
||||||
|
@Override |
||||||
|
public void cancelApplication(boolean status) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public AbstractTask createTask(TaskRequest taskRequest) { |
||||||
|
return new MapReduceTask(taskRequest); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.spi.params.base.PluginParams; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannel; |
||||||
|
import org.apache.dolphinscheduler.spi.task.TaskChannelFactory; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class MapReduceTaskChannelFactory implements TaskChannelFactory { |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getName() { |
||||||
|
return "MR"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<PluginParams> getParams() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public TaskChannel create() { |
||||||
|
return new MapReduceTaskChannel(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.dolphinscheduler.plugin.task.mr; |
||||||
|
|
||||||
|
public class MapReduceTaskConstants { |
||||||
|
|
||||||
|
private MapReduceTaskConstants() { |
||||||
|
throw new UnsupportedOperationException("Construct Constants"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* -D mapreduce.job.name=name |
||||||
|
*/ |
||||||
|
public static final String MR_NAME = "mapreduce.job.name"; |
||||||
|
|
||||||
|
/** |
||||||
|
* -D mapreduce.job.queuename=queuename |
||||||
|
*/ |
||||||
|
public static final String MR_QUEUE = "mapreduce.job.queuename"; |
||||||
|
|
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue