Kaynağa Gözat

升级大版本V1.3.x

xueli.xue 9 yıl önce
ebeveyn
işleme
510b397ca7
21 değiştirilmiş dosya ile 587 ekleme ve 18 silme
  1. 8 1
      xxl-job-admin/src/main/java/com/xxl/job/service/job/RemoteHttpJobBean.java
  2. 24 0
      xxl-job-client-demo/pom.xml
  3. 13 0
      xxl-job-client-demo/src/main/java/com/xxl/job/dao/IXxlJobInfoDao.java
  4. 32 0
      xxl-job-client-demo/src/main/java/com/xxl/job/dao/impl/XxlJobInfoDaoImpl.java
  5. 38 0
      xxl-job-client-demo/src/main/java/com/xxl/job/dao/model/XxlJobInfo.java
  6. 3 2
      xxl-job-client-demo/src/main/java/com/xxl/job/service/handler/DemoJobHandler.java
  7. 23 0
      xxl-job-client-demo/src/main/java/com/xxl/job/service/loader/DbGlueLoader.java
  8. 50 0
      xxl-job-client-demo/src/main/resources/applicationcontext-database.xml
  9. 5 0
      xxl-job-client-demo/src/main/resources/applicationcontext-xxl-job.xml
  10. 4 0
      xxl-job-client-demo/src/main/resources/jdbc.properties
  11. 26 0
      xxl-job-client-demo/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
  12. 7 0
      xxl-job-client/pom.xml
  13. 187 0
      xxl-job-client/src/main/java/com/xxl/job/client/glue/GlueFactory.java
  14. 17 0
      xxl-job-client/src/main/java/com/xxl/job/client/glue/cache/ICache.java
  15. 71 0
      xxl-job-client/src/main/java/com/xxl/job/client/glue/cache/LocalCache.java
  16. 16 0
      xxl-job-client/src/main/java/com/xxl/job/client/glue/loader/GlueLoader.java
  17. 36 12
      xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerRepository.java
  18. 1 1
      xxl-job-client/src/main/java/com/xxl/job/client/handler/IJobHandler.java
  19. 1 1
      xxl-job-client/src/main/java/com/xxl/job/client/handler/annotation/JobHander.java
  20. 24 0
      xxl-job-client/src/main/java/com/xxl/job/client/handler/impl/GlueJobHandler.java
  21. 1 1
      xxl-job-client/src/main/java/com/xxl/job/client/netcom/jetty/XxlJobJettyServer.java

+ 8 - 1
xxl-job-admin/src/main/java/com/xxl/job/service/job/RemoteHttpJobBean.java Dosyayı Görüntüle

@@ -55,12 +55,19 @@ public class RemoteHttpJobBean extends QuartzJobBean {
55 55
 		
56 56
 		// trigger request
57 57
 		HashMap<String, String> params = new HashMap<String, String>();
58
+		params.put(HandlerRepository.TRIGGER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
58 59
 		params.put(HandlerRepository.NAMESPACE, HandlerRepository.NameSpaceEnum.RUN.name());
60
+		
59 61
 		params.put(HandlerRepository.TRIGGER_LOG_URL, PropertiesUtil.getString(HandlerRepository.TRIGGER_LOG_URL));
60 62
 		params.put(HandlerRepository.TRIGGER_LOG_ID, String.valueOf(jobLog.getId()));
61
-		params.put(HandlerRepository.TRIGGER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
63
+		
62 64
 		params.put(HandlerRepository.HANDLER_NAME, jobDataMap.get(HandlerRepository.HANDLER_NAME));
63 65
 		params.put(HandlerRepository.HANDLER_PARAMS, jobDataMap.get(HandlerRepository.HANDLER_PARAMS));
66
+		
67
+		params.put(HandlerRepository.HANDLER_GLUE_SWITCH, String.valueOf(jobInfo.getGlueSwitch()));
68
+		params.put(HandlerRepository.HANDLER_JOB_GROUP, jobInfo.getJobGroup());
69
+		params.put(HandlerRepository.HANDLER_JOB_NAME, jobInfo.getJobName());
70
+		
64 71
 
65 72
 		// handler address, jetty (servlet dead)
66 73
 		String handler_address = jobDataMap.get(HandlerRepository.HANDLER_ADDRESS);

+ 24 - 0
xxl-job-client-demo/pom.xml Dosyayı Görüntüle

@@ -51,6 +51,30 @@
51 51
 			<version>1.7.5</version>
52 52
 		</dependency>
53 53
 		
54
+		<!-- c3p0 -->
55
+		<dependency>
56
+			<groupId>c3p0</groupId>
57
+			<artifactId>c3p0</artifactId>
58
+			<version>0.9.1.2</version>
59
+		</dependency>
60
+		<!-- mybatis-spring -->
61
+		<dependency>
62
+			<groupId>org.mybatis</groupId>
63
+			<artifactId>mybatis-spring</artifactId>
64
+			<version>1.2.2</version>
65
+		</dependency>
66
+		<dependency>
67
+			<groupId>org.mybatis</groupId>
68
+			<artifactId>mybatis</artifactId>
69
+			<version>3.2.8</version>
70
+		</dependency>
71
+		<!-- mysql-connector -->
72
+		<dependency>
73
+			<groupId>mysql</groupId>
74
+			<artifactId>mysql-connector-java</artifactId>
75
+			<version>5.1.29</version>
76
+		</dependency>
77
+		
54 78
 		<!-- xxl-job-client -->
55 79
 		<dependency>
56 80
 			<groupId>com.xxl</groupId>

+ 13 - 0
xxl-job-client-demo/src/main/java/com/xxl/job/dao/IXxlJobInfoDao.java Dosyayı Görüntüle

@@ -0,0 +1,13 @@
1
+package com.xxl.job.dao;
2
+
3
+import com.xxl.job.dao.model.XxlJobInfo;
4
+
5
+/**
6
+ * job log for glue
7
+ * @author xuxueli 2016-5-19 18:04:56
8
+ */
9
+public interface IXxlJobInfoDao {
10
+	
11
+	public XxlJobInfo load(String jobGroup, String jobName);
12
+
13
+}

+ 32 - 0
xxl-job-client-demo/src/main/java/com/xxl/job/dao/impl/XxlJobInfoDaoImpl.java Dosyayı Görüntüle

@@ -0,0 +1,32 @@
1
+package com.xxl.job.dao.impl;
2
+
3
+import java.util.HashMap;
4
+
5
+import javax.annotation.Resource;
6
+
7
+import org.mybatis.spring.SqlSessionTemplate;
8
+import org.springframework.stereotype.Repository;
9
+
10
+import com.xxl.job.dao.IXxlJobInfoDao;
11
+import com.xxl.job.dao.model.XxlJobInfo;
12
+
13
+/**
14
+ * job log for glue
15
+ * @author xuxueli 2016-5-19 18:17:52
16
+ */
17
+@Repository
18
+public class XxlJobInfoDaoImpl implements IXxlJobInfoDao {
19
+
20
+	@Resource
21
+	public SqlSessionTemplate sqlSessionTemplate;
22
+
23
+	@Override
24
+	public XxlJobInfo load(String jobGroup, String jobName) {
25
+		HashMap<String, Object> params = new HashMap<String, Object>();
26
+		params.put("jobGroup", jobGroup);
27
+		params.put("jobName", jobName);
28
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.load", params);
29
+	}
30
+	
31
+	
32
+}

+ 38 - 0
xxl-job-client-demo/src/main/java/com/xxl/job/dao/model/XxlJobInfo.java Dosyayı Görüntüle

@@ -0,0 +1,38 @@
1
+package com.xxl.job.dao.model;
2
+
3
+/**
4
+ * xxl-job info
5
+ * @author xuxueli 2016-5-19 17:57:46
6
+ */
7
+public class XxlJobInfo {
8
+	
9
+	private String jobGroup;
10
+	private String jobName;
11
+	
12
+	private String glueSource;
13
+
14
+	public String getJobGroup() {
15
+		return jobGroup;
16
+	}
17
+
18
+	public void setJobGroup(String jobGroup) {
19
+		this.jobGroup = jobGroup;
20
+	}
21
+
22
+	public String getJobName() {
23
+		return jobName;
24
+	}
25
+
26
+	public void setJobName(String jobName) {
27
+		this.jobName = jobName;
28
+	}
29
+
30
+	public String getGlueSource() {
31
+		return glueSource;
32
+	}
33
+
34
+	public void setGlueSource(String glueSource) {
35
+		this.glueSource = glueSource;
36
+	}
37
+	
38
+}

+ 3 - 2
xxl-job-client-demo/src/main/java/com/xxl/job/service/handler/DemoJobHandler.java Dosyayı Görüntüle

@@ -7,7 +7,8 @@ import org.slf4j.LoggerFactory;
7 7
 import org.springframework.stereotype.Service;
8 8
 
9 9
 import com.xxl.job.client.handler.IJobHandler;
10
-import com.xxl.job.client.handler.JobHander;
10
+import com.xxl.job.client.handler.IJobHandler.JobHandleStatus;
11
+import com.xxl.job.client.handler.annotation.JobHander;
11 12
 
12 13
 /**
13 14
  * demo job handler
@@ -30,7 +31,7 @@ public class DemoJobHandler extends IJobHandler {
30 31
 	
31 32
 	public static void main(String[] args) {
32 33
 		System.out.println(DemoJobHandler.class.getName());
33
-		System.out.println(DemoJobHandler.class);
34
+		System.out.println(JobHandleStatus.class);
34 35
 	}
35 36
 	
36 37
 }

+ 23 - 0
xxl-job-client-demo/src/main/java/com/xxl/job/service/loader/DbGlueLoader.java Dosyayı Görüntüle

@@ -0,0 +1,23 @@
1
+package com.xxl.job.service.loader;
2
+
3
+import javax.annotation.Resource;
4
+
5
+import org.springframework.stereotype.Service;
6
+
7
+import com.xxl.job.client.glue.loader.GlueLoader;
8
+import com.xxl.job.dao.IXxlJobInfoDao;
9
+import com.xxl.job.dao.model.XxlJobInfo;
10
+
11
+@Service("dbGlueLoader")
12
+public class DbGlueLoader implements GlueLoader {
13
+
14
+	@Resource
15
+	private IXxlJobInfoDao xxlJobInfoDao;
16
+	
17
+	@Override
18
+	public String load(String job_group, String job_name) {
19
+		XxlJobInfo glue = xxlJobInfoDao.load(job_group, job_name);
20
+		return glue!=null?glue.getGlueSource():null;
21
+	}
22
+
23
+}

+ 50 - 0
xxl-job-client-demo/src/main/resources/applicationcontext-database.xml Dosyayı Görüntüle

@@ -0,0 +1,50 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<beans xmlns="http://www.springframework.org/schema/beans"
3
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4
+	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
5
+	xsi:schemaLocation="
6
+		http://www.springframework.org/schema/beans 
7
+		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
8
+		http://www.springframework.org/schema/context 
9
+		http://www.springframework.org/schema/context/spring-context-3.0.xsd 
10
+		http://www.springframework.org/schema/aop 
11
+		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
12
+		http://www.springframework.org/schema/tx 
13
+		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
14
+		
15
+	<context:component-scan base-package="com.xxl.job.service, com.xxl.job.dao" />
16
+	
17
+	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
18
+		<property name="fileEncoding" value="utf-8" />
19
+		<property name="locations">
20
+			<list>
21
+				<value>classpath*:jdbc.properties</value>
22
+			</list>
23
+		</property>
24
+	</bean>
25
+
26
+	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  destroy-method="close">  
27
+	    <property name="driverClass" value="${c3p0.driverClass}" />  
28
+	    <property name="jdbcUrl" value="${c3p0.url}" />  
29
+	    <property name="user" value="${c3p0.user}" />  
30
+	    <property name="password" value="${c3p0.password}" />  
31
+	    <property name="initialPoolSize" value="3" />  
32
+	    <property name="minPoolSize" value="2" />  
33
+	    <property name="maxPoolSize" value="10" />  
34
+	    <property name="maxIdleTime" value="60" />
35
+	    <property name="acquireRetryDelay" value="1000" />
36
+	    <property name="acquireRetryAttempts" value="10" />
37
+	    <property name="preferredTestQuery" value="SELECT 1" />
38
+	</bean>
39
+	
40
+	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
41
+		<property name="dataSource" ref="dataSource" />
42
+		<property name="mapperLocations" value="classpath*:mybatis-mapper/*.xml"/>
43
+	</bean>
44
+    
45
+    <!-- scope must be "prototype" when junit -->
46
+    <bean id="sqlSessionTemplate"  class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">  
47
+          <constructor-arg index="0" ref="sqlSessionFactory" />  
48
+    </bean> 
49
+	
50
+</beans>

+ 5 - 0
xxl-job-client-demo/src/main/resources/applicationcontext-xxl-job.xml Dosyayı Görüntüle

@@ -15,5 +15,10 @@
15 15
 	<bean id="xxlJobJettyServer" class="com.xxl.job.client.netcom.jetty.XxlJobJettyServer" init-method="start">
16 16
 		<property name="port" value="9999" />
17 17
 	</bean>
18
+	
19
+	<bean id="glueFactory" class="com.xxl.job.client.glue.GlueFactory">
20
+		<property name="cacheTimeout" value="5000" />
21
+		<property name="glueLoader" ref="dbGlueLoader" />
22
+	</bean>
18 23
 
19 24
 </beans>

+ 4 - 0
xxl-job-client-demo/src/main/resources/jdbc.properties Dosyayı Görüntüle

@@ -0,0 +1,4 @@
1
+c3p0.driverClass=com.mysql.jdbc.Driver
2
+c3p0.url=jdbc:mysql://localhost:3306/xxl-job?Unicode=true&amp;characterEncoding=UTF-8
3
+c3p0.user=root
4
+c3p0.password=root_pwd

+ 26 - 0
xxl-job-client-demo/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml Dosyayı Görüntüle

@@ -0,0 +1,26 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
3
+	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
4
+<mapper namespace="XxlJobInfoMapper">
5
+	
6
+	<resultMap id="XxlJobInfo" type="com.xxl.job.dao.model.XxlJobInfo" >
7
+		<result column="job_group" property="jobGroup" />
8
+	    <result column="job_name" property="jobName" />
9
+	    <result column="glue_source" property="glueSource" />
10
+	</resultMap>
11
+
12
+	<sql id="Base_Column_List">
13
+		t.job_group,
14
+		t.job_name,
15
+		t.glue_source
16
+	</sql>
17
+	
18
+	<select id="load" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
19
+		SELECT <include refid="Base_Column_List" />
20
+		FROM xxl_job_qrtz_trigger_info AS t
21
+		WHERE t.job_group = #{jobGroup}
22
+			AND t.job_name = #{jobName}
23
+	</select>
24
+	
25
+	
26
+</mapper>

+ 7 - 0
xxl-job-client/pom.xml Dosyayı Görüntüle

@@ -60,6 +60,13 @@
60 60
 			<version>3.2.14.RELEASE</version>
61 61
 			<scope>compile</scope>
62 62
 		</dependency>
63
+		
64
+		<!-- groovy-all -->
65
+		<dependency>
66
+			<groupId>org.codehaus.groovy</groupId>
67
+			<artifactId>groovy-all</artifactId>
68
+			<version>2.4.5</version>
69
+		</dependency>
63 70
 
64 71
 	</dependencies>
65 72
 

+ 187 - 0
xxl-job-client/src/main/java/com/xxl/job/client/glue/GlueFactory.java Dosyayı Görüntüle

@@ -0,0 +1,187 @@
1
+package com.xxl.job.client.glue;
2
+
3
+import java.lang.reflect.Field;
4
+import java.lang.reflect.Modifier;
5
+
6
+import javax.annotation.Resource;
7
+
8
+import org.slf4j.Logger;
9
+import org.slf4j.LoggerFactory;
10
+import org.springframework.beans.BeansException;
11
+import org.springframework.beans.factory.annotation.Autowired;
12
+import org.springframework.context.ApplicationContext;
13
+import org.springframework.context.ApplicationContextAware;
14
+import org.springframework.core.annotation.AnnotationUtils;
15
+
16
+import com.xxl.job.client.glue.cache.LocalCache;
17
+import com.xxl.job.client.glue.loader.GlueLoader;
18
+import com.xxl.job.client.handler.IJobHandler;
19
+import com.xxl.job.client.handler.IJobHandler.JobHandleStatus;
20
+
21
+import groovy.lang.GroovyClassLoader;
22
+
23
+/**
24
+ * glue factory, product class/object by name
25
+ * @author xuxueli 2016-1-2 20:02:27
26
+ */
27
+public class GlueFactory implements ApplicationContextAware {
28
+	private static Logger logger = LoggerFactory.getLogger(GlueFactory.class);
29
+	
30
+	/**
31
+	 * groovy class loader
32
+	 */
33
+	private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
34
+	
35
+	/**
36
+	 * glue cache timeout / second
37
+	 */
38
+	private long cacheTimeout = 5000;
39
+	public void setCacheTimeout(long cacheTimeout) {
40
+		this.cacheTimeout = cacheTimeout;
41
+	}
42
+	
43
+	/**
44
+	 * code source loader
45
+	 */
46
+	private GlueLoader glueLoader;
47
+	public void setGlueLoader(GlueLoader glueLoader) {
48
+		this.glueLoader = glueLoader;
49
+	}
50
+	
51
+	// ----------------------------- spring support -----------------------------
52
+	private static ApplicationContext applicationContext;
53
+	private static GlueFactory glueFactory;
54
+	
55
+	@Override
56
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
57
+		GlueFactory.applicationContext = applicationContext;
58
+		GlueFactory.glueFactory = (GlueFactory) applicationContext.getBean("glueFactory");
59
+	}
60
+	
61
+	/**
62
+	 * inject service of spring
63
+	 * @param instance
64
+	 */
65
+	public void injectService(Object instance){
66
+		if (instance==null) {
67
+			return;
68
+		}
69
+	    
70
+		Field[] fields = instance.getClass().getDeclaredFields();
71
+		for (Field field : fields) {
72
+			if (Modifier.isStatic(field.getModifiers())) {
73
+				continue;
74
+			}
75
+			
76
+			Object fieldBean = null;
77
+			// with bean-id, bean could be found by both @Resource and @Autowired, or bean could only be found by @Autowired
78
+			if (AnnotationUtils.getAnnotation(field, Resource.class) != null) {
79
+				try {
80
+					fieldBean = applicationContext.getBean(field.getName());
81
+				} catch (Exception e) {
82
+				}
83
+				if (fieldBean==null ) {
84
+					fieldBean = applicationContext.getBean(field.getType());
85
+				}
86
+			} else if (AnnotationUtils.getAnnotation(field, Autowired.class) != null) {
87
+				fieldBean = applicationContext.getBean(field.getType());		
88
+			}
89
+			
90
+			if (fieldBean!=null) {
91
+				field.setAccessible(true);
92
+				try {
93
+					field.set(instance, fieldBean);
94
+				} catch (IllegalArgumentException e) {
95
+					e.printStackTrace();
96
+				} catch (IllegalAccessException e) {
97
+					e.printStackTrace();
98
+				}
99
+			}
100
+		}
101
+	}
102
+	
103
+	// ----------------------------- load instance -----------------------------
104
+	
105
+	// load class, 
106
+	public static String generateClassCacheKey(String job_group, String job_name){
107
+		return job_group.concat("_").concat(job_name).concat("_class");
108
+	}
109
+	public Class<?> loadClass(String job_group, String job_name) throws Exception{
110
+		if (job_group==null || job_group.trim().length()==0 || job_name==null || job_name.trim().length()==0) {
111
+			return null;
112
+		}
113
+		String cacheClassKey = generateClassCacheKey(job_group, job_name);
114
+		Object cacheClass = LocalCache.getInstance().get(cacheClassKey);
115
+		if (cacheClass != null) {
116
+			return (Class<?>) cacheClass;
117
+		}
118
+		String codeSource = glueLoader.load(job_group, job_name);
119
+		if (codeSource!=null && codeSource.trim().length()>0) {
120
+			Class<?> clazz = groovyClassLoader.parseClass(codeSource);
121
+			if (clazz!=null) {
122
+				LocalCache.getInstance().set(cacheClassKey, clazz, cacheTimeout);
123
+				logger.info(">>>>>>>>>>>> xxl-glue, fresh class, cacheClassKey:{}", cacheClassKey);
124
+				return clazz;
125
+			}
126
+		}
127
+		return null;
128
+	}
129
+	
130
+	// load new instance, prototype
131
+	public IJobHandler loadNewInstance(String job_group, String job_name) throws Exception{
132
+		if (job_group==null || job_group.trim().length()==0 || job_name==null || job_name.trim().length()==0) {
133
+			return null;
134
+		}
135
+		Class<?> clazz = loadClass(job_group, job_name);
136
+		if (clazz!=null) {
137
+			Object instance = clazz.newInstance();
138
+			if (instance!=null) {
139
+				if (!(instance instanceof IJobHandler)) {
140
+					throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadNewInstance error, "
141
+							+ "cannot convert from instance["+ instance.getClass() +"] to IJobHandler");
142
+				}
143
+				
144
+				this.injectService(instance);
145
+				return (IJobHandler) instance;
146
+			}
147
+		}
148
+		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadNewInstance error, instance is null");
149
+	}
150
+	
151
+	// // load instance, singleton
152
+	public static String generateInstanceCacheKey(String job_group, String job_name){
153
+		return job_group.concat("_").concat(job_name).concat("_instance");
154
+	}
155
+	public IJobHandler loadInstance(String job_group, String job_name) throws Exception{
156
+		if (job_group==null || job_group.trim().length()==0 || job_name==null || job_name.trim().length()==0) {
157
+			return null;
158
+		}
159
+		String cacheInstanceKey = generateInstanceCacheKey(job_group, job_name);
160
+		Object cacheInstance = LocalCache.getInstance().get(cacheInstanceKey);
161
+		if (cacheInstance!=null) {
162
+			if (!(cacheInstance instanceof IJobHandler)) {
163
+				throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, "
164
+						+ "cannot convert from cacheClass["+ cacheInstance.getClass() +"] to IJobHandler");
165
+			}
166
+			return (IJobHandler) cacheInstance;
167
+		}
168
+		Object instance = loadNewInstance(job_group, job_name);
169
+		if (instance!=null) {
170
+			if (!(instance instanceof IJobHandler)) {
171
+				throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, "
172
+						+ "cannot convert from instance["+ instance.getClass() +"] to IJobHandler");
173
+			}
174
+			
175
+			LocalCache.getInstance().set(cacheInstanceKey, instance, cacheTimeout);
176
+			logger.info(">>>>>>>>>>>> xxl-glue, fresh instance, cacheInstanceKey:{}", cacheInstanceKey);
177
+			return (IJobHandler) instance;
178
+		}
179
+		throw new IllegalArgumentException(">>>>>>>>>>> xxl-glue, loadInstance error, instance is null");
180
+	}
181
+	
182
+	// ----------------------------- util -----------------------------
183
+	public static JobHandleStatus glue(String job_group, String job_name, String... params) throws Exception{
184
+		return GlueFactory.glueFactory.loadInstance(job_group, job_name).handle(params);
185
+	}
186
+	
187
+}

+ 17 - 0
xxl-job-client/src/main/java/com/xxl/job/client/glue/cache/ICache.java Dosyayı Görüntüle

@@ -0,0 +1,17 @@
1
+package com.xxl.job.client.glue.cache;
2
+
3
+/**
4
+ * chche interface
5
+ * @author xuxueli 2016-1-8 15:57:27
6
+ */
7
+public interface ICache {
8
+	
9
+	public boolean set(String key, Object value);
10
+	
11
+	public boolean set(String key, Object value, long timeout);
12
+	
13
+	public Object get(String key);
14
+	
15
+	public boolean remove(String key);
16
+	
17
+}

+ 71 - 0
xxl-job-client/src/main/java/com/xxl/job/client/glue/cache/LocalCache.java Dosyayı Görüntüle

@@ -0,0 +1,71 @@
1
+package com.xxl.job.client.glue.cache;
2
+
3
+import java.util.concurrent.ConcurrentHashMap;
4
+
5
+/**
6
+ * local interface
7
+ * @author Administrator
8
+ */
9
+public class LocalCache implements ICache{
10
+	
11
+	private static final LocalCache instance = new LocalCache();
12
+	public static LocalCache getInstance(){
13
+		return instance;
14
+	} 
15
+	
16
+	private static final ConcurrentHashMap<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();
17
+	private static final long CACHE_TIMEOUT = 5000;
18
+	
19
+	private static String makeTimKey(String key){
20
+		return key.concat("_tim");
21
+	}
22
+	private static String makeDataKey(String key){
23
+		return key.concat("_data");
24
+	}
25
+	
26
+	@Override
27
+	public boolean set(String key, Object value) {
28
+		cacheMap.put(makeTimKey(key), System.currentTimeMillis() + CACHE_TIMEOUT);
29
+		cacheMap.put(makeDataKey(key), value);
30
+		return true;
31
+	}
32
+	
33
+	@Override
34
+	public boolean set(String key, Object value, long timeout) {
35
+		cacheMap.put(makeTimKey(key), System.currentTimeMillis() + timeout);
36
+		cacheMap.put(makeDataKey(key), value);
37
+		return true;
38
+	}
39
+
40
+	@Override
41
+	public Object get(String key) {
42
+		Object tim = cacheMap.get(makeTimKey(key));
43
+		if (tim != null && System.currentTimeMillis() < Long.parseLong(tim.toString())) {
44
+			return cacheMap.get(makeDataKey(key));
45
+		}
46
+		return null;
47
+	}
48
+
49
+	@Override
50
+	public boolean remove(String key) {
51
+		cacheMap.remove(makeTimKey(key));
52
+		cacheMap.remove(makeDataKey(key));
53
+		return true;
54
+	}
55
+	
56
+	public static void main(String[] args) {
57
+		String key = "key01";
58
+		System.out.println(LocalCache.getInstance().get(key));
59
+		
60
+		LocalCache.getInstance().set(key, "v1");
61
+		System.out.println(LocalCache.getInstance().get(key));
62
+		
63
+		LocalCache.getInstance().set(key, "v2");
64
+		System.out.println(LocalCache.getInstance().get(key));
65
+		
66
+		LocalCache.getInstance().remove(key);
67
+		System.out.println(LocalCache.getInstance().get(key));
68
+		
69
+	}
70
+	
71
+}

+ 16 - 0
xxl-job-client/src/main/java/com/xxl/job/client/glue/loader/GlueLoader.java Dosyayı Görüntüle

@@ -0,0 +1,16 @@
1
+package com.xxl.job.client.glue.loader;
2
+
3
+/**
4
+ * code source loader
5
+ * @author xuxueli 2016-1-2 20:01:39
6
+ */
7
+public interface GlueLoader {
8
+
9
+	/**
10
+	 * load code source by name, ensure every load is the latest.
11
+	 * @param name
12
+	 * @return
13
+	 */
14
+	public String load(String job_group, String job_name);
15
+	
16
+}

+ 36 - 12
xxl-job-client/src/main/java/com/xxl/job/client/handler/HandlerRepository.java Dosyayı Görüntüle

@@ -7,8 +7,9 @@ import java.util.concurrent.ConcurrentHashMap;
7 7
 import org.slf4j.Logger;
8 8
 import org.slf4j.LoggerFactory;
9 9
 
10
-import com.xxl.job.client.util.HttpUtil.RemoteCallBack;
10
+import com.xxl.job.client.handler.impl.GlueJobHandler;
11 11
 import com.xxl.job.client.log.XxlJobFileAppender;
12
+import com.xxl.job.client.util.HttpUtil.RemoteCallBack;
12 13
 import com.xxl.job.client.util.JacksonUtil;
13 14
 
14 15
 /**
@@ -22,9 +23,13 @@ public class HandlerRepository {
22 23
 	public enum NameSpaceEnum{RUN, KILL, LOG}
23 24
 	
24 25
 	public static final String HANDLER_ADDRESS = "handler_address";
25
-	public static final String HANDLER_NAME = "handler_name";
26 26
 	public static final String HANDLER_PARAMS = "handler_params";
27 27
 	
28
+	public static final String HANDLER_GLUE_SWITCH = "handler_glue_switch";
29
+	public static final String HANDLER_NAME = "handler_name";
30
+	public static final String HANDLER_JOB_GROUP = "handler_job_group";
31
+	public static final String HANDLER_JOB_NAME = "handler_job_name";
32
+	
28 33
 	public static final String TRIGGER_LOG_ID = "trigger_log_id";
29 34
 	public static final String TRIGGER_LOG_URL = "trigger_log_url";
30 35
 	public static final String TRIGGER_TIMESTAMP = "trigger_timestamp";
@@ -64,19 +69,38 @@ public class HandlerRepository {
64 69
 			}
65 70
 					
66 71
 			// push data to queue
67
-			String handler_name = _param.get(HandlerRepository.HANDLER_NAME);
68
-			if (handler_name!=null && handler_name.trim().length()>0) {
69
-				HandlerThread handlerThread = handlerTreadMap.get(handler_name);
70
-				if (handlerThread != null) {
71
-					handlerThread.pushData(_param);
72
-					callback.setStatus(RemoteCallBack.SUCCESS);
73
-				} else {
72
+			String handler_glue_switch = _param.get(HandlerRepository.HANDLER_GLUE_SWITCH);
73
+			HandlerThread handlerThread = null;
74
+			if ("0".equals(handler_glue_switch)) {
75
+				// bean model
76
+				String handler_name = _param.get(HandlerRepository.HANDLER_NAME);
77
+				if (handler_name == null || handler_name.trim().length()==0) {
78
+					callback.setMsg("bean model handler[HANDLER_NAME] not found.");
79
+					return JacksonUtil.writeValueAsString(callback);
80
+				}
81
+				handlerThread = handlerTreadMap.get(handler_name);
82
+				if (handlerThread == null) {
74 83
 					callback.setMsg("handler[" + handler_name + "] not found.");
84
+					return JacksonUtil.writeValueAsString(callback);
75 85
 				}
76
-			}else{
77
-				callback.setMsg("param[HANDLER_NAME] can not be null.");
86
+			} else {
87
+				// glue
88
+				String handler_job_group = _param.get(HandlerRepository.HANDLER_JOB_GROUP);
89
+				String handler_job_name = _param.get(HandlerRepository.HANDLER_JOB_NAME);
90
+				if (handler_job_group == null || handler_job_group.trim().length()==0 || handler_job_name == null || handler_job_name.trim().length()==0) {
91
+					callback.setMsg("glue model handler[job group or name] is null.");
92
+					return JacksonUtil.writeValueAsString(callback);
93
+				}
94
+				String glueHandleName = "glue_".concat(handler_job_group).concat("_").concat(handler_job_name);
95
+				handlerThread = handlerTreadMap.get(glueHandleName);
96
+				if (handlerThread==null) {
97
+					HandlerRepository.regist(glueHandleName, new GlueJobHandler(handler_job_group, handler_job_name));
98
+				}
99
+				handlerThread = handlerTreadMap.get(glueHandleName);
78 100
 			}
79 101
 			
102
+			handlerThread.pushData(_param);
103
+			callback.setStatus(RemoteCallBack.SUCCESS);
80 104
 		} else if (namespace.equals(HandlerRepository.NameSpaceEnum.LOG.name())) {
81 105
 			String trigger_log_id = _param.get(HandlerRepository.TRIGGER_LOG_ID);
82 106
 			String trigger_timestamp = _param.get(HandlerRepository.TRIGGER_TIMESTAMP);
@@ -128,7 +152,7 @@ public class HandlerRepository {
128 152
 			return JacksonUtil.writeValueAsString(callback);
129 153
 		}
130 154
 		
131
-		logger.info(">>>>>>>>>>> xxl-job service end, triggerData:{}", new Object[]{callback});
155
+		logger.info(">>>>>>>>>>> xxl-job service end, triggerData:{}");
132 156
 		return JacksonUtil.writeValueAsString(callback); 
133 157
 	}
134 158
 	

+ 1 - 1
xxl-job-client/src/main/java/com/xxl/job/client/handler/IJobHandler.java Dosyayı Görüntüle

@@ -15,7 +15,7 @@ public abstract class IJobHandler extends HandlerRepository{
15 15
 	 */
16 16
 	public abstract JobHandleStatus handle(String... params) throws Exception;
17 17
 	
18
-	public enum JobHandleStatus{
18
+	public static enum JobHandleStatus{
19 19
 		/**
20 20
 		 * handle success
21 21
 		 */

xxl-job-client/src/main/java/com/xxl/job/client/handler/JobHander.java → xxl-job-client/src/main/java/com/xxl/job/client/handler/annotation/JobHander.java Dosyayı Görüntüle

@@ -1,4 +1,4 @@
1
-package com.xxl.job.client.handler;
1
+package com.xxl.job.client.handler.annotation;
2 2
 
3 3
 import java.lang.annotation.ElementType;
4 4
 import java.lang.annotation.Retention;

+ 24 - 0
xxl-job-client/src/main/java/com/xxl/job/client/handler/impl/GlueJobHandler.java Dosyayı Görüntüle

@@ -0,0 +1,24 @@
1
+package com.xxl.job.client.handler.impl;
2
+
3
+import com.xxl.job.client.glue.GlueFactory;
4
+import com.xxl.job.client.handler.IJobHandler;
5
+
6
+/**
7
+ * glue job handler
8
+ * @author xuxueli 2016-5-19 21:05:45
9
+ */
10
+public class GlueJobHandler extends IJobHandler {
11
+	
12
+	private String job_group;
13
+	private String job_name;
14
+	public GlueJobHandler(String job_group, String job_name) {
15
+		this.job_group = job_group;
16
+		this.job_name = job_name;
17
+	}
18
+
19
+	@Override
20
+	public JobHandleStatus handle(String... params) throws Exception {
21
+		return GlueFactory.glue(job_group, job_name, params);
22
+	}
23
+
24
+}

+ 1 - 1
xxl-job-client/src/main/java/com/xxl/job/client/netcom/jetty/XxlJobJettyServer.java Dosyayı Görüntüle

@@ -16,7 +16,7 @@ import org.springframework.context.ApplicationContextAware;
16 16
 
17 17
 import com.xxl.job.client.handler.HandlerRepository;
18 18
 import com.xxl.job.client.handler.IJobHandler;
19
-import com.xxl.job.client.handler.JobHander;
19
+import com.xxl.job.client.handler.annotation.JobHander;
20 20
 
21 21
 /**
22 22
  * Created by xuxueli on 2016/3/2 21:14.