diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java index 5bf24493..efc44eb3 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java @@ -1,6 +1,5 @@ package com.xxl.job.admin.core.callback; -import com.xxl.job.admin.core.model.ReturnT; import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.util.DynamicSchedulerUtil; @@ -35,65 +34,80 @@ public class XxlJobLogCallbackServerHandler extends AbstractHandler { // parse hex-json to request model String requestHex = httpServletRequest.getParameter(XxlJobNetCommUtil.HEX); + + // do biz + ResponseModel responseModel = dobiz(requestHex); + + // format response model to hex-json + String responseHex = XxlJobNetCommUtil.formatObj2HexJson(responseModel); + + // response + httpServletResponse.setContentType("text/html;charset=utf-8"); + httpServletResponse.setStatus(HttpServletResponse.SC_OK); + baseRequest.setHandled(true); + httpServletResponse.getWriter().println(responseHex); + } + + private ResponseModel dobiz(String requestHex){ + + // valid hex + if (requestHex==null || requestHex.trim().length()==0) { + return new ResponseModel(ResponseModel.FAIL, "request hex is null."); + } + + // valid request model RequestModel requestModel = XxlJobNetCommUtil.parseHexJson2Obj(requestHex, RequestModel.class); + if (requestModel==null) { + return new ResponseModel(ResponseModel.FAIL, "request hex parse fail."); + } - // process - ResponseModel responseModel = null; + // valid log item XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(requestModel.getLogId()); - if (log!=null) { - - // trigger success, to trigger child job, and avoid repeat trigger child job - String childTriggerMsg = null; - if (ResponseModel.SUCCESS.equals(requestModel.getStatus()) && !ResponseModel.SUCCESS.equals(log.getHandleStatus())) { - XxlJobInfo xxlJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName()); - if (xxlJobInfo!=null && StringUtils.isNotBlank(xxlJobInfo.getChildJobKey())) { - childTriggerMsg = "
"; - String[] childJobKeys = xxlJobInfo.getChildJobKey().split(","); - for (int i = 0; i < childJobKeys.length; i++) { - String[] jobKeyArr = childJobKeys[i].split("_"); - if (jobKeyArr!=null && jobKeyArr.length==2) { - XxlJobInfo childJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKeyArr[0], jobKeyArr[1]); - if (childJobInfo!=null) { - try { - boolean ret = DynamicSchedulerUtil.triggerJob(childJobInfo.getJobName(), childJobInfo.getJobGroup()); - - // add msg - childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务成功, 子任务Key: {2}, status: {3}, 子任务描述: {4}", - (i+1), childJobKeys.length, childJobKeys[i], ret, childJobInfo.getJobDesc()); - } catch (SchedulerException e) { - logger.error("", e); - } - } else { - childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务失败, 子任务xxlJobInfo不存在, 子任务Key: {2}", - (i+1), childJobKeys.length, childJobKeys[i]); + if (log == null) { + return new ResponseModel(ResponseModel.FAIL, "log item not found."); + } + + // trigger success, to trigger child job, and avoid repeat trigger child job + String childTriggerMsg = null; + if (ResponseModel.SUCCESS.equals(requestModel.getStatus()) && !ResponseModel.SUCCESS.equals(log.getHandleStatus())) { + XxlJobInfo xxlJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName()); + if (xxlJobInfo!=null && StringUtils.isNotBlank(xxlJobInfo.getChildJobKey())) { + childTriggerMsg = "
"; + String[] childJobKeys = xxlJobInfo.getChildJobKey().split(","); + for (int i = 0; i < childJobKeys.length; i++) { + String[] jobKeyArr = childJobKeys[i].split("_"); + if (jobKeyArr!=null && jobKeyArr.length==2) { + XxlJobInfo childJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKeyArr[0], jobKeyArr[1]); + if (childJobInfo!=null) { + try { + boolean ret = DynamicSchedulerUtil.triggerJob(childJobInfo.getJobName(), childJobInfo.getJobGroup()); + + // add msg + childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务成功, 子任务Key: {2}, status: {3}, 子任务描述: {4}", + (i+1), childJobKeys.length, childJobKeys[i], ret, childJobInfo.getJobDesc()); + } catch (SchedulerException e) { + logger.error("", e); } } else { - childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务失败, 子任务Key格式错误, 子任务Key: {2}", + childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务失败, 子任务xxlJobInfo不存在, 子任务Key: {2}", (i+1), childJobKeys.length, childJobKeys[i]); } + } else { + childTriggerMsg += MessageFormat.format("
{0}/{1} 触发子任务失败, 子任务Key格式错误, 子任务Key: {2}", + (i+1), childJobKeys.length, childJobKeys[i]); } - } - } - // save log - log.setHandleTime(new Date()); - log.setHandleStatus(requestModel.getStatus()); - log.setHandleMsg(requestModel.getMsg() + childTriggerMsg); - DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(log); - responseModel = new ResponseModel(ResponseModel.SUCCESS, null); - } else { - responseModel = new ResponseModel(ResponseModel.FAIL, "log item not found."); + } } - // format response model to hex-json - String responseHex = XxlJobNetCommUtil.formatObj2HexJson(responseModel); + // success, save log + log.setHandleTime(new Date()); + log.setHandleStatus(requestModel.getStatus()); + log.setHandleMsg(requestModel.getMsg() + childTriggerMsg); + DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(log); - // response - httpServletResponse.setContentType("text/html;charset=utf-8"); - httpServletResponse.setStatus(HttpServletResponse.SC_OK); - baseRequest.setHandled(true); - httpServletResponse.getWriter().println(responseHex); + return new ResponseModel(ResponseModel.SUCCESS, null); } } diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/glue/loader/impl/DbGlueLoader.java b/xxl-job-core/src/main/java/com/xxl/job/core/glue/loader/impl/DbGlueLoader.java new file mode 100644 index 00000000..303eb2fb --- /dev/null +++ b/xxl-job-core/src/main/java/com/xxl/job/core/glue/loader/impl/DbGlueLoader.java @@ -0,0 +1,30 @@ +package com.xxl.job.core.glue.loader.impl; + +import com.xxl.job.core.glue.loader.GlueLoader; +import com.xxl.job.core.util.DBUtil; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; + +/** + * Created by xuxueli on 16/9/30. + */ +public class DbGlueLoader implements GlueLoader { + + private DataSource dataSource; + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public String load(String job_group, String job_name) { + String sql = "SELECT glue_source FROM XXL_JOB_QRTZ_TRIGGER_INFO WHERE job_group = ? AND job_name = ?"; + List> result = DBUtil.query(dataSource, sql, new String[]{job_group, job_name}); + if (result!=null && result.size()==1 && result.get(0)!=null && result.get(0).get("glue_source")!=null ) { + return (String) result.get(0).get("glue_source"); + } + return null; + } + +} diff --git a/xxl-job-core/src/main/java/com/xxl/job/core/util/DBUtil.java b/xxl-job-core/src/main/java/com/xxl/job/core/util/DBUtil.java new file mode 100644 index 00000000..da522b8c --- /dev/null +++ b/xxl-job-core/src/main/java/com/xxl/job/core/util/DBUtil.java @@ -0,0 +1,128 @@ +package com.xxl.job.core.util; + +import javax.sql.DataSource; +import java.sql.*; +import java.util.*; + +/** + * Created by xuxueli on 16/9/30. + */ +public class DBUtil { + + private static Connection getConn(DataSource dataSource) { + try { + return dataSource.getConnection(); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + /** + * update + * + * @param dataSource + * @param sql + * @param params + */ + public static int update(DataSource dataSource, String sql, Object params[]) { + Connection connection = getConn(dataSource); + PreparedStatement preparedStatement = null; + int ret = 0; + try { + preparedStatement = connection.prepareStatement(sql); + if (params != null) { + for (int i = 0; i < params.length; i++) { + preparedStatement.setObject(i + 1, params[i]); + } + } + ret = preparedStatement.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } finally { + release(connection, preparedStatement, null); + } + return ret; + } + + /** + * query + * + * @param dataSource + * @param sql + * @param params + * @return + */ + public static List> query(DataSource dataSource, String sql, Object[] params) { + Connection connection = getConn(dataSource); + PreparedStatement preparedStatement = null; + ResultSet resultSet = null; + try { + preparedStatement = connection.prepareStatement(sql); + if (params != null) { + for (int i = 0; i < params.length; i++) { + preparedStatement.setObject(i + 1, params[i]); + } + } + resultSet = preparedStatement.executeQuery(); + + List> ret = resultSetToList(resultSet); + return ret; + } catch (SQLException e) { + e.printStackTrace(); + } finally { + release(connection, preparedStatement, resultSet); + } + return null; + } + + private static List> resultSetToList(ResultSet resultSet) throws SQLException { + if (resultSet == null) { + return Collections.EMPTY_LIST; + } + + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); // 得到结果集(rs)的结构信息,比如字段数、字段名等 + int columnCount = resultSetMetaData.getColumnCount(); // 返回此 ResultSet 对象中的列数 + + List> list = new ArrayList>(); + while (resultSet.next()) { + Map rowData = new HashMap(columnCount); + for (int i = 1; i <= columnCount; i++) { + rowData.put(resultSetMetaData.getColumnName(i), resultSet.getObject(i)); + } + list.add(rowData); + } + return list; + } + + /** + * release + * @param connection + * @param preparedStatement + * @param resultSet + */ + public static void release(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) { + if (resultSet != null) { + try { + resultSet.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + if (preparedStatement != null) { + try { + preparedStatement.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + +} diff --git a/xxl-job-executor-example/pom.xml b/xxl-job-executor-example/pom.xml index fcefe3e1..964b444b 100644 --- a/xxl-job-executor-example/pom.xml +++ b/xxl-job-executor-example/pom.xml @@ -21,29 +21,7 @@ spring-webmvc ${spring.version} - - org.springframework - spring-context-support - ${spring.version} - - - org.springframework - spring-orm - ${spring.version} - - - org.springframework - spring-test - ${spring.version} - - - - - org.aspectj - aspectjweaver - 1.8.7 - - + org.slf4j @@ -57,17 +35,6 @@ c3p0 0.9.1.2 - - - org.mybatis - mybatis-spring - 1.2.2 - - - org.mybatis - mybatis - 3.2.8 - mysql diff --git a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/DbGlueLoader.java b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/DbGlueLoader.java deleted file mode 100644 index 46408387..00000000 --- a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/DbGlueLoader.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.xxl.job.executor.loader; - -import javax.annotation.Resource; - -import org.springframework.stereotype.Service; - -import com.xxl.job.core.glue.loader.GlueLoader; -import com.xxl.job.executor.loader.dao.IXxlJobInfoDao; -import com.xxl.job.executor.loader.dao.model.XxlJobInfo; - -/** - * GLUE 代码加载器,推荐将该服务配置成RPC服务 - * @author xuxueli - */ -@Service("dbGlueLoader") -public class DbGlueLoader implements GlueLoader { - - @Resource - private IXxlJobInfoDao xxlJobInfoDao; - - @Override - public String load(String job_group, String job_name) { - XxlJobInfo glue = xxlJobInfoDao.load(job_group, job_name); - return glue!=null?glue.getGlueSource():null; - } - -} diff --git a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/IXxlJobInfoDao.java b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/IXxlJobInfoDao.java deleted file mode 100644 index a93b7648..00000000 --- a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/IXxlJobInfoDao.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.xxl.job.executor.loader.dao; - -import com.xxl.job.executor.loader.dao.model.XxlJobInfo; - -/** - * job log for glue - * @author xuxueli 2016-5-19 18:04:56 - */ -public interface IXxlJobInfoDao { - - public XxlJobInfo load(String jobGroup, String jobName); - -} diff --git a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/impl/XxlJobInfoDaoImpl.java b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/impl/XxlJobInfoDaoImpl.java deleted file mode 100644 index 3aba909f..00000000 --- a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/impl/XxlJobInfoDaoImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.xxl.job.executor.loader.dao.impl; - -import java.util.HashMap; - -import javax.annotation.Resource; - -import org.mybatis.spring.SqlSessionTemplate; -import org.springframework.stereotype.Repository; - -import com.xxl.job.executor.loader.dao.IXxlJobInfoDao; -import com.xxl.job.executor.loader.dao.model.XxlJobInfo; - - -/** - * job log for glue - * @author xuxueli 2016-5-19 18:17:52 - */ -@Repository -public class XxlJobInfoDaoImpl implements IXxlJobInfoDao { - - @Resource - public SqlSessionTemplate sqlSessionTemplate; - - @Override - public XxlJobInfo load(String jobGroup, String jobName) { - HashMap params = new HashMap(); - params.put("jobGroup", jobGroup); - params.put("jobName", jobName); - return sqlSessionTemplate.selectOne("XxlJobInfoMapper.load", params); - } - - -} diff --git a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/model/XxlJobInfo.java b/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/model/XxlJobInfo.java deleted file mode 100644 index ccab5767..00000000 --- a/xxl-job-executor-example/src/main/java/com/xxl/job/executor/loader/dao/model/XxlJobInfo.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.xxl.job.executor.loader.dao.model; - -/** - * xxl-job info - * @author xuxueli 2016-5-19 17:57:46 - */ -public class XxlJobInfo { - - private String jobGroup; - private String jobName; - - private String glueSource; - - public String getJobGroup() { - return jobGroup; - } - - public void setJobGroup(String jobGroup) { - this.jobGroup = jobGroup; - } - - public String getJobName() { - return jobName; - } - - public void setJobName(String jobName) { - this.jobName = jobName; - } - - public String getGlueSource() { - return glueSource; - } - - public void setGlueSource(String glueSource) { - this.glueSource = glueSource; - } - -} diff --git a/xxl-job-executor-example/src/main/resources/applicationcontext-database.xml b/xxl-job-executor-example/src/main/resources/applicationcontext-database.xml deleted file mode 100644 index 93a93df6..00000000 --- a/xxl-job-executor-example/src/main/resources/applicationcontext-database.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - classpath*:jdbc.properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml b/xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml index 581c10fd..d571f061 100644 --- a/xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml +++ b/xxl-job-executor-example/src/main/resources/applicationcontext-xxl-job.xml @@ -7,17 +7,51 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + classpath:jdbc.properties + \ No newline at end of file diff --git a/xxl-job-executor-example/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-executor-example/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml deleted file mode 100644 index 35160b61..00000000 --- a/xxl-job-executor-example/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - t.job_group, - t.job_name, - t.glue_source - - - - - - \ No newline at end of file