|
|
|
@ -16,32 +16,50 @@
|
|
|
|
|
*/ |
|
|
|
|
package org.apache.dolphinscheduler.server.worker.task.processdure; |
|
|
|
|
|
|
|
|
|
import com.cronutils.utils.StringUtils; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.BOOLEAN; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.DATE; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.DOUBLE; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.FLOAT; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.INTEGER; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.LONG; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.TIME; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.TIMESTAMP; |
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.VARCHAR; |
|
|
|
|
|
|
|
|
|
import org.apache.dolphinscheduler.common.Constants; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.*; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.CommandType; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.DataType; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.DbType; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.Direct; |
|
|
|
|
import org.apache.dolphinscheduler.common.enums.TaskTimeoutStrategy; |
|
|
|
|
import org.apache.dolphinscheduler.common.process.Property; |
|
|
|
|
import org.apache.dolphinscheduler.common.task.AbstractParameters; |
|
|
|
|
import org.apache.dolphinscheduler.common.task.procedure.ProcedureParameters; |
|
|
|
|
import org.apache.dolphinscheduler.common.utils.CollectionUtils; |
|
|
|
|
import org.apache.dolphinscheduler.common.utils.*; |
|
|
|
|
import org.apache.dolphinscheduler.common.utils.JSONUtils; |
|
|
|
|
import org.apache.dolphinscheduler.common.utils.ParameterUtils; |
|
|
|
|
import org.apache.dolphinscheduler.common.utils.StringUtils; |
|
|
|
|
import org.apache.dolphinscheduler.dao.datasource.BaseDataSource; |
|
|
|
|
import org.apache.dolphinscheduler.dao.datasource.DataSourceFactory; |
|
|
|
|
import org.apache.dolphinscheduler.server.entity.TaskExecutionContext; |
|
|
|
|
import org.apache.dolphinscheduler.server.utils.ParamUtils; |
|
|
|
|
import org.apache.dolphinscheduler.server.worker.task.AbstractTask; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
|
|
|
|
|
import java.sql.*; |
|
|
|
|
import java.sql.CallableStatement; |
|
|
|
|
import java.sql.Connection; |
|
|
|
|
import java.sql.DriverManager; |
|
|
|
|
import java.sql.PreparedStatement; |
|
|
|
|
import java.sql.SQLException; |
|
|
|
|
import java.sql.Types; |
|
|
|
|
import java.util.Collection; |
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.Iterator; |
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
import static org.apache.dolphinscheduler.common.enums.DataType.*; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* procedure task |
|
|
|
|
* procedure task |
|
|
|
|
*/ |
|
|
|
|
public class ProcedureTask extends AbstractTask { |
|
|
|
|
|
|
|
|
@ -63,8 +81,9 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* constructor |
|
|
|
|
* |
|
|
|
|
* @param taskExecutionContext taskExecutionContext |
|
|
|
|
* @param logger logger |
|
|
|
|
* @param logger logger |
|
|
|
|
*/ |
|
|
|
|
public ProcedureTask(TaskExecutionContext taskExecutionContext, Logger logger) { |
|
|
|
|
super(taskExecutionContext, logger); |
|
|
|
@ -111,7 +130,6 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
baseDataSource.getPassword()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// combining local and global parameters
|
|
|
|
|
Map<String, Property> paramsMap = ParamUtils.convert(ParamUtils.getUserDefParamsMap(taskExecutionContext.getDefinedParams()), |
|
|
|
|
taskExecutionContext.getDefinedParams(), |
|
|
|
@ -122,13 +140,13 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
|
|
|
|
|
Collection<Property> userDefParamsList = null; |
|
|
|
|
|
|
|
|
|
if (procedureParameters.getLocalParametersMap() != null){ |
|
|
|
|
if (procedureParameters.getLocalParametersMap() != null) { |
|
|
|
|
userDefParamsList = procedureParameters.getLocalParametersMap().values(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
String method = getCallMethod(userDefParamsList); |
|
|
|
|
|
|
|
|
|
logger.info("call method : {}",method); |
|
|
|
|
logger.info("call method : {}", method); |
|
|
|
|
|
|
|
|
|
// call method
|
|
|
|
|
stmt = connection.prepareCall(method); |
|
|
|
@ -148,48 +166,48 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
printOutParameter(stmt, outParameterMap); |
|
|
|
|
|
|
|
|
|
setExitStatusCode(Constants.EXIT_CODE_SUCCESS); |
|
|
|
|
}catch (Exception e){ |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
setExitStatusCode(Constants.EXIT_CODE_FAILURE); |
|
|
|
|
logger.error("procedure task error",e); |
|
|
|
|
logger.error("procedure task error", e); |
|
|
|
|
throw e; |
|
|
|
|
} |
|
|
|
|
finally { |
|
|
|
|
close(stmt,connection); |
|
|
|
|
} finally { |
|
|
|
|
close(stmt, connection); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* get call method |
|
|
|
|
* |
|
|
|
|
* @param userDefParamsList userDefParamsList |
|
|
|
|
* @return method |
|
|
|
|
*/ |
|
|
|
|
private String getCallMethod(Collection<Property> userDefParamsList) { |
|
|
|
|
String method;// no parameters
|
|
|
|
|
if (CollectionUtils.isEmpty(userDefParamsList)){ |
|
|
|
|
if (CollectionUtils.isEmpty(userDefParamsList)) { |
|
|
|
|
method = "{call " + procedureParameters.getMethod() + "}"; |
|
|
|
|
}else { // exists parameters
|
|
|
|
|
} else { // exists parameters
|
|
|
|
|
int size = userDefParamsList.size(); |
|
|
|
|
StringBuilder parameter = new StringBuilder(); |
|
|
|
|
parameter.append("("); |
|
|
|
|
for (int i = 0 ;i < size - 1; i++){ |
|
|
|
|
for (int i = 0; i < size - 1; i++) { |
|
|
|
|
parameter.append("?,"); |
|
|
|
|
} |
|
|
|
|
parameter.append("?)"); |
|
|
|
|
method = "{call " + procedureParameters.getMethod() + parameter.toString()+ "}"; |
|
|
|
|
method = "{call " + procedureParameters.getMethod() + parameter.toString() + "}"; |
|
|
|
|
} |
|
|
|
|
return method; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* print outParameter |
|
|
|
|
* |
|
|
|
|
* @param stmt CallableStatement |
|
|
|
|
* @param outParameterMap outParameterMap |
|
|
|
|
* @throws SQLException |
|
|
|
|
*/ |
|
|
|
|
private void printOutParameter(CallableStatement stmt, |
|
|
|
|
Map<Integer, Property> outParameterMap) throws SQLException { |
|
|
|
|
Iterator<Map.Entry<Integer, Property>> iter = outParameterMap.entrySet().iterator(); |
|
|
|
|
while (iter.hasNext()){ |
|
|
|
|
while (iter.hasNext()) { |
|
|
|
|
Map.Entry<Integer, Property> en = iter.next(); |
|
|
|
|
|
|
|
|
|
int index = en.getKey(); |
|
|
|
@ -208,27 +226,26 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
* @param paramsMap paramsMap |
|
|
|
|
* @param userDefParamsList userDefParamsList |
|
|
|
|
* @return outParameterMap |
|
|
|
|
* @throws Exception |
|
|
|
|
*/ |
|
|
|
|
private Map<Integer, Property> getOutParameterMap(CallableStatement stmt, |
|
|
|
|
Map<String, Property> paramsMap, |
|
|
|
|
Collection<Property> userDefParamsList) throws Exception { |
|
|
|
|
Map<Integer,Property> outParameterMap = new HashMap<>(); |
|
|
|
|
if (userDefParamsList != null && userDefParamsList.size() > 0){ |
|
|
|
|
Map<Integer, Property> outParameterMap = new HashMap<>(); |
|
|
|
|
if (userDefParamsList != null && userDefParamsList.size() > 0) { |
|
|
|
|
int index = 1; |
|
|
|
|
for (Property property : userDefParamsList){ |
|
|
|
|
for (Property property : userDefParamsList) { |
|
|
|
|
logger.info("localParams : prop : {} , dirct : {} , type : {} , value : {}" |
|
|
|
|
,property.getProp(), |
|
|
|
|
, property.getProp(), |
|
|
|
|
property.getDirect(), |
|
|
|
|
property.getType(), |
|
|
|
|
property.getValue()); |
|
|
|
|
// set parameters
|
|
|
|
|
if (property.getDirect().equals(Direct.IN)){ |
|
|
|
|
if (property.getDirect().equals(Direct.IN)) { |
|
|
|
|
ParameterUtils.setInParameter(index, stmt, property.getType(), paramsMap.get(property.getProp()).getValue()); |
|
|
|
|
}else if (property.getDirect().equals(Direct.OUT)){ |
|
|
|
|
setOutParameter(index,stmt,property.getType(),paramsMap.get(property.getProp()).getValue()); |
|
|
|
|
} else if (property.getDirect().equals(Direct.OUT)) { |
|
|
|
|
setOutParameter(index, stmt, property.getType(), paramsMap.get(property.getProp()).getValue()); |
|
|
|
|
property.setValue(paramsMap.get(property.getProp()).getValue()); |
|
|
|
|
outParameterMap.put(index,property); |
|
|
|
|
outParameterMap.put(index, property); |
|
|
|
|
} |
|
|
|
|
index++; |
|
|
|
|
} |
|
|
|
@ -237,26 +254,22 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* set timtou |
|
|
|
|
* set timeout |
|
|
|
|
* |
|
|
|
|
* @param stmt CallableStatement |
|
|
|
|
* @throws SQLException |
|
|
|
|
*/ |
|
|
|
|
private void setTimeout(CallableStatement stmt) throws SQLException { |
|
|
|
|
Boolean failed = TaskTimeoutStrategy.of(taskExecutionContext.getTaskTimeoutStrategy()) == TaskTimeoutStrategy.FAILED; |
|
|
|
|
Boolean warnfailed = TaskTimeoutStrategy.of(taskExecutionContext.getTaskTimeoutStrategy()) == TaskTimeoutStrategy.WARNFAILED; |
|
|
|
|
if(failed || warnfailed){ |
|
|
|
|
Boolean failed = taskExecutionContext.getTaskTimeoutStrategy() == TaskTimeoutStrategy.FAILED; |
|
|
|
|
Boolean warnFailed = taskExecutionContext.getTaskTimeoutStrategy() == TaskTimeoutStrategy.WARNFAILED; |
|
|
|
|
if (failed || warnFailed) { |
|
|
|
|
stmt.setQueryTimeout(taskExecutionContext.getTaskTimeout()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* close jdbc resource |
|
|
|
|
* |
|
|
|
|
* @param stmt |
|
|
|
|
* @param connection |
|
|
|
|
*/ |
|
|
|
|
private void close(PreparedStatement stmt, |
|
|
|
|
Connection connection){ |
|
|
|
|
private void close(PreparedStatement stmt, Connection connection) { |
|
|
|
|
if (stmt != null) { |
|
|
|
|
try { |
|
|
|
|
stmt.close(); |
|
|
|
@ -275,40 +288,35 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* get output parameter |
|
|
|
|
* @param stmt |
|
|
|
|
* @param index |
|
|
|
|
* @param prop |
|
|
|
|
* @param dataType |
|
|
|
|
* @throws SQLException |
|
|
|
|
*/ |
|
|
|
|
private void getOutputParameter(CallableStatement stmt, int index, String prop, DataType dataType) throws SQLException { |
|
|
|
|
switch (dataType){ |
|
|
|
|
switch (dataType) { |
|
|
|
|
case VARCHAR: |
|
|
|
|
logger.info("out prameter varchar key : {} , value : {}",prop,stmt.getString(index)); |
|
|
|
|
logger.info("out prameter varchar key : {} , value : {}", prop, stmt.getString(index)); |
|
|
|
|
break; |
|
|
|
|
case INTEGER: |
|
|
|
|
logger.info("out prameter integer key : {} , value : {}", prop, stmt.getInt(index)); |
|
|
|
|
break; |
|
|
|
|
case LONG: |
|
|
|
|
logger.info("out prameter long key : {} , value : {}",prop,stmt.getLong(index)); |
|
|
|
|
logger.info("out prameter long key : {} , value : {}", prop, stmt.getLong(index)); |
|
|
|
|
break; |
|
|
|
|
case FLOAT: |
|
|
|
|
logger.info("out prameter float key : {} , value : {}",prop,stmt.getFloat(index)); |
|
|
|
|
logger.info("out prameter float key : {} , value : {}", prop, stmt.getFloat(index)); |
|
|
|
|
break; |
|
|
|
|
case DOUBLE: |
|
|
|
|
logger.info("out prameter double key : {} , value : {}",prop,stmt.getDouble(index)); |
|
|
|
|
logger.info("out prameter double key : {} , value : {}", prop, stmt.getDouble(index)); |
|
|
|
|
break; |
|
|
|
|
case DATE: |
|
|
|
|
logger.info("out prameter date key : {} , value : {}",prop,stmt.getDate(index)); |
|
|
|
|
logger.info("out prameter date key : {} , value : {}", prop, stmt.getDate(index)); |
|
|
|
|
break; |
|
|
|
|
case TIME: |
|
|
|
|
logger.info("out prameter time key : {} , value : {}",prop,stmt.getTime(index)); |
|
|
|
|
logger.info("out prameter time key : {} , value : {}", prop, stmt.getTime(index)); |
|
|
|
|
break; |
|
|
|
|
case TIMESTAMP: |
|
|
|
|
logger.info("out prameter timestamp key : {} , value : {}",prop,stmt.getTimestamp(index)); |
|
|
|
|
logger.info("out prameter timestamp key : {} , value : {}", prop, stmt.getTimestamp(index)); |
|
|
|
|
break; |
|
|
|
|
case BOOLEAN: |
|
|
|
|
logger.info("out prameter boolean key : {} , value : {}",prop, stmt.getBoolean(index)); |
|
|
|
|
logger.info("out prameter boolean key : {} , value : {}", prop, stmt.getBoolean(index)); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
@ -322,72 +330,73 @@ public class ProcedureTask extends AbstractTask {
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* set out parameter |
|
|
|
|
* @param index index |
|
|
|
|
* @param stmt stmt |
|
|
|
|
* @param dataType dataType |
|
|
|
|
* @param value value |
|
|
|
|
* |
|
|
|
|
* @param index index |
|
|
|
|
* @param stmt stmt |
|
|
|
|
* @param dataType dataType |
|
|
|
|
* @param value value |
|
|
|
|
* @throws Exception exception |
|
|
|
|
*/ |
|
|
|
|
private void setOutParameter(int index,CallableStatement stmt,DataType dataType,String value)throws Exception{ |
|
|
|
|
if (dataType.equals(VARCHAR)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
private void setOutParameter(int index, CallableStatement stmt, DataType dataType, String value) throws Exception { |
|
|
|
|
if (dataType.equals(VARCHAR)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.VARCHAR); |
|
|
|
|
}else { |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.VARCHAR, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(INTEGER)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(INTEGER)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.INTEGER); |
|
|
|
|
}else { |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.INTEGER, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(LONG)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
stmt.registerOutParameter(index,Types.INTEGER); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index,Types.INTEGER ,value); |
|
|
|
|
} else if (dataType.equals(LONG)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.INTEGER); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.INTEGER, value); |
|
|
|
|
} |
|
|
|
|
}else if (dataType.equals(FLOAT)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(FLOAT)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.FLOAT); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.FLOAT,value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.FLOAT, value); |
|
|
|
|
} |
|
|
|
|
}else if (dataType.equals(DOUBLE)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(DOUBLE)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.DOUBLE); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.DOUBLE , value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.DOUBLE, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(DATE)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(DATE)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.DATE); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.DATE , value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.DATE, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(TIME)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(TIME)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIME); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIME , value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIME, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(TIMESTAMP)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(TIMESTAMP)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIMESTAMP); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIMESTAMP , value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.TIMESTAMP, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}else if (dataType.equals(BOOLEAN)){ |
|
|
|
|
if (StringUtils.isEmpty(value)){ |
|
|
|
|
} else if (dataType.equals(BOOLEAN)) { |
|
|
|
|
if (StringUtils.isEmpty(value)) { |
|
|
|
|
stmt.registerOutParameter(index, Types.BOOLEAN); |
|
|
|
|
}else { |
|
|
|
|
stmt.registerOutParameter(index, Types.BOOLEAN , value); |
|
|
|
|
} else { |
|
|
|
|
stmt.registerOutParameter(index, Types.BOOLEAN, value); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|