刘力
3 years ago
24 changed files with 1454 additions and 1 deletions
-
8APIService/pom.xml
-
26APIService/src/main/java/com/storeroom/controller/TestApiServiceController.java
-
10APIService/src/main/java/com/storeroom/service/ApiService.java
-
19APIService/src/main/java/com/storeroom/service/dto/ResultDto.java
-
44APIService/src/main/java/com/storeroom/service/impl/ApiServiceImpl.java
-
10common/pom.xml
-
33common/src/main/java/com/storeroom/config/RestTempleConfig.java
-
115common/src/main/java/com/storeroom/utils/FastjsonUtils.java
-
318common/src/main/java/com/storeroom/utils/HttpUtils.java
-
34common/src/test/java/TestHttp.java
-
1storeroom/src/main/java/com/storeroom/modules/device/service/dto/DeviceSpecParamDto.java
-
36system/src/main/java/com/storeroom/modules/quartz/config/JobRunner.java
-
33system/src/main/java/com/storeroom/modules/quartz/config/QuartzConfig.java
-
68system/src/main/java/com/storeroom/modules/quartz/domain/QuartzJob.java
-
50system/src/main/java/com/storeroom/modules/quartz/domain/QuartzLog.java
-
16system/src/main/java/com/storeroom/modules/quartz/repository/QuartzJobRepository.java
-
8system/src/main/java/com/storeroom/modules/quartz/repository/QuartzLogRepository.java
-
104system/src/main/java/com/storeroom/modules/quartz/service/QuartzJobService.java
-
21system/src/main/java/com/storeroom/modules/quartz/service/dto/JobQueryCriteria.java
-
180system/src/main/java/com/storeroom/modules/quartz/service/impl/QuartzJobServiceImpl.java
-
24system/src/main/java/com/storeroom/modules/quartz/task/TestTask.java
-
99system/src/main/java/com/storeroom/modules/quartz/utils/ExecutionJob.java
-
157system/src/main/java/com/storeroom/modules/quartz/utils/QuartzManage.java
-
41system/src/main/java/com/storeroom/modules/quartz/utils/QuartzRunnable.java
@ -0,0 +1,26 @@ |
|||
package com.storeroom.controller; |
|||
|
|||
|
|||
import com.storeroom.annotaion.rest.AnonymousGetMapping; |
|||
import com.storeroom.service.ApiService; |
|||
import com.storeroom.utils.ApiResponse; |
|||
import io.swagger.annotations.Api; |
|||
import io.swagger.annotations.ApiOperation; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
@RestController |
|||
@RequestMapping("/api/service/") |
|||
@Api(tags = "测试第三方接口") |
|||
@RequiredArgsConstructor |
|||
public class TestApiServiceController { |
|||
|
|||
private final ApiService apiService; |
|||
|
|||
@ApiOperation("获取库房token") |
|||
@AnonymousGetMapping("token") |
|||
public ApiResponse<Object> getToken() { |
|||
return ApiResponse.success(apiService.getToken()); |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
package com.storeroom.service; |
|||
|
|||
public interface ApiService { |
|||
|
|||
/** |
|||
* 获取环控token |
|||
* @return / |
|||
*/ |
|||
String getToken(); |
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.storeroom.service.dto; |
|||
|
|||
|
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.List; |
|||
|
|||
@Getter |
|||
@Setter |
|||
public class ResultDto implements Serializable { |
|||
|
|||
private String Status; |
|||
|
|||
private String Message; |
|||
|
|||
private List<Object> Data; |
|||
} |
@ -0,0 +1,44 @@ |
|||
package com.storeroom.service.impl; |
|||
|
|||
import com.storeroom.exception.BaseException; |
|||
import com.storeroom.service.ApiService; |
|||
import com.storeroom.utils.FastjsonUtils; |
|||
import com.storeroom.utils.HttpUtils; |
|||
import lombok.SneakyThrows; |
|||
import org.apache.http.HttpResponse; |
|||
import org.apache.http.util.EntityUtils; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
|
|||
@Service |
|||
public class ApiServiceImpl implements ApiService { |
|||
|
|||
String access_token = ""; |
|||
|
|||
@SneakyThrows |
|||
@Override |
|||
public String getToken() { |
|||
|
|||
//根据code 换取access token |
|||
HashMap<String, String> map = new HashMap<>(); |
|||
map.put("Content-type", "application/json"); |
|||
HttpResponse response = HttpUtils.doGet("http://jiton.8800.org:800", "/Api/Third/GetToken", "GET", map, null); |
|||
if (response.getStatusLine().getStatusCode() == 200) { |
|||
String s = EntityUtils.toString(response.getEntity()); |
|||
Map<String, Object> dateMap = FastjsonUtils.toJavaMap(s); |
|||
dateMap.forEach((k, v) -> { |
|||
if (k.equals("Data")) { |
|||
Map<String, Object> Data = FastjsonUtils.toJavaMap(v.toString()); |
|||
access_token = Data.get("access_token").toString(); |
|||
} |
|||
}); |
|||
return access_token; |
|||
} else { |
|||
throw new BaseException("访问失败" + response.getStatusLine().getStatusCode() + ""); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
package com.storeroom.config; |
|||
|
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.boot.web.client.RestTemplateBuilder; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; |
|||
import org.springframework.web.client.RestTemplate; |
|||
|
|||
|
|||
@Configuration |
|||
public class RestTempleConfig { |
|||
// 启动的时候要注意,由于我们在controller中注入了RestTemplate,所以启动的时候需要实例化该类的一个实例 |
|||
@Autowired |
|||
private RestTemplateBuilder builder; |
|||
|
|||
// 使用RestTemplateBuilder来实例化RestTemplate对象,spring默认已经注入了RestTemplateBuilder实例 |
|||
@Bean |
|||
public RestTemplate restTemplate() { |
|||
return builder.build(); |
|||
} |
|||
|
|||
@Bean |
|||
public RestTemplate customRestTemplate() { |
|||
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); |
|||
httpRequestFactory.setConnectionRequestTimeout(3000); |
|||
httpRequestFactory.setConnectTimeout(3000); |
|||
httpRequestFactory.setReadTimeout(3000); |
|||
return new RestTemplate(httpRequestFactory); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,115 @@ |
|||
package com.storeroom.utils; |
|||
|
|||
import com.alibaba.fastjson.*; |
|||
import com.alibaba.fastjson.serializer.SerializerFeature; |
|||
import com.alibaba.fastjson.util.ParameterizedTypeImpl; |
|||
|
|||
import java.lang.reflect.ParameterizedType; |
|||
import java.lang.reflect.Type; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Objects; |
|||
|
|||
public class FastjsonUtils { |
|||
|
|||
public static ParameterizedType makeJavaType(Type rawType, Type... typeArguments) { |
|||
return new ParameterizedTypeImpl(typeArguments, null, rawType); |
|||
} |
|||
|
|||
public static String toString(Object value) { |
|||
if (Objects.isNull(value)) { |
|||
return null; |
|||
} |
|||
if (value instanceof String) { |
|||
return (String) value; |
|||
} |
|||
return toJSONString(value); |
|||
} |
|||
|
|||
public static String toJSONString(Object value) { |
|||
return JSON.toJSONString(value, SerializerFeature.DisableCircularReferenceDetect); |
|||
} |
|||
|
|||
public static String toPrettyString(Object value) { |
|||
return JSON.toJSONString(value, SerializerFeature.DisableCircularReferenceDetect |
|||
, SerializerFeature.PrettyFormat); |
|||
} |
|||
|
|||
public static Object fromJavaObject(Object value) { |
|||
Object result = null; |
|||
if (Objects.nonNull(value) && (value instanceof String)) { |
|||
result = parseObject((String) value); |
|||
} else { |
|||
result = JSON.toJSON(value); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
public static Object parseObject(String content) { |
|||
return JSON.parseObject(content, Object.class); |
|||
} |
|||
|
|||
public static Object getJsonElement(JSONObject node, String name) { |
|||
return node.get(name); |
|||
} |
|||
|
|||
public static Object getJsonElement(JSONArray node, int index) { |
|||
return node.get(index); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(JSON node, Class<T> clazz) { |
|||
return node.toJavaObject(clazz); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(JSON node, Type type) { |
|||
return node.toJavaObject(type); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(JSON node, TypeReference<T> typeReference) { |
|||
return node.toJavaObject(typeReference); |
|||
} |
|||
|
|||
public static <E> List<E> toJavaList(JSON node, Class<E> clazz) { |
|||
return node.toJavaObject(new TypeReference<List<E>>(clazz){}); |
|||
} |
|||
|
|||
public static List<Object> toJavaList(JSON node) { |
|||
return node.toJavaObject(new TypeReference<List<Object>>(){}); |
|||
} |
|||
|
|||
public static <V> Map<String, V> toJavaMap(JSON node, Class<V> clazz) { |
|||
return node.toJavaObject(new TypeReference<Map<String, V>>(clazz){}); |
|||
} |
|||
|
|||
public static Map<String, Object> toJavaMap(JSON node) { |
|||
return node.toJavaObject(new TypeReference<Map<String, Object>>(){}); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(String content, Class<T> clazz) { |
|||
return JSON.parseObject(content, clazz); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(String content, Type type) { |
|||
return JSON.parseObject(content, type); |
|||
} |
|||
|
|||
public static <T> T toJavaObject(String content, TypeReference<T> typeReference) { |
|||
return JSON.parseObject(content, typeReference); |
|||
} |
|||
|
|||
public static <E> List<E> toJavaList(String content, Class<E> clazz) { |
|||
return JSON.parseObject(content, new TypeReference<List<E>>(clazz){}); |
|||
} |
|||
|
|||
public static List<Object> toJavaList(String content) { |
|||
return JSON.parseObject(content, new TypeReference<List<Object>>(){}); |
|||
} |
|||
|
|||
public static <V> Map<String, V> toJavaMap(String content, Class<V> clazz) { |
|||
return JSON.parseObject(content, new TypeReference<Map<String, V>>(clazz){}); |
|||
} |
|||
|
|||
public static Map<String, Object> toJavaMap(String content) { |
|||
return JSON.parseObject(content, new TypeReference<Map<String, Object>>(){}); |
|||
} |
|||
} |
@ -0,0 +1,318 @@ |
|||
package com.storeroom.utils; |
|||
|
|||
|
|||
import org.apache.http.HttpResponse; |
|||
import org.apache.http.NameValuePair; |
|||
import org.apache.http.client.HttpClient; |
|||
import org.apache.http.client.entity.UrlEncodedFormEntity; |
|||
import org.apache.http.client.methods.HttpDelete; |
|||
import org.apache.http.client.methods.HttpGet; |
|||
import org.apache.http.client.methods.HttpPost; |
|||
import org.apache.http.client.methods.HttpPut; |
|||
import org.apache.http.conn.ClientConnectionManager; |
|||
import org.apache.http.conn.scheme.Scheme; |
|||
import org.apache.http.conn.scheme.SchemeRegistry; |
|||
import org.apache.http.conn.ssl.SSLSocketFactory; |
|||
import org.apache.http.entity.ByteArrayEntity; |
|||
import org.apache.http.entity.StringEntity; |
|||
import org.apache.http.impl.client.DefaultHttpClient; |
|||
import org.apache.http.message.BasicNameValuePair; |
|||
|
|||
import java.security.KeyManagementException; |
|||
import java.security.NoSuchAlgorithmException; |
|||
import javax.net.ssl.SSLContext; |
|||
import javax.net.ssl.TrustManager; |
|||
import javax.net.ssl.X509TrustManager; |
|||
import java.io.UnsupportedEncodingException; |
|||
import java.net.URLEncoder; |
|||
import java.security.cert.X509Certificate; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
|
|||
public class HttpUtils { |
|||
/** |
|||
* get |
|||
* 发送get请求 |
|||
* |
|||
* @param host 主机地址 |
|||
* @param path 请求路径 |
|||
* @param method 请求方法 get |
|||
* @param headers 请求头数据,使用map封装 |
|||
* @param querys 请求参数,使用map封装 |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doGet(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpGet request = new HttpGet(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* post form |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @param bodys 请求体,使用map封装 |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doPost(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys, |
|||
Map<String, String> bodys) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpPost request = new HttpPost(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
if (bodys != null) { |
|||
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(); |
|||
|
|||
for (String key : bodys.keySet()) { |
|||
nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key))); |
|||
} |
|||
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8"); |
|||
formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8"); |
|||
request.setEntity(formEntity); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* Post String |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @param body |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doPost(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys, |
|||
String body) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpPost request = new HttpPost(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
if (StringUtils.isNotBlank(body)) { |
|||
request.setEntity(new StringEntity(body, "utf-8")); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* Post stream |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @param body |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doPost(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys, |
|||
byte[] body) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpPost request = new HttpPost(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
if (body != null) { |
|||
request.setEntity(new ByteArrayEntity(body)); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* Put String |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @param body |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doPut(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys, |
|||
String body) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpPut request = new HttpPut(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
if (StringUtils.isNotBlank(body)) { |
|||
request.setEntity(new StringEntity(body, "utf-8")); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* Put stream |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @param body |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doPut(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys, |
|||
byte[] body) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpPut request = new HttpPut(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
if (body != null) { |
|||
request.setEntity(new ByteArrayEntity(body)); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
/** |
|||
* Delete |
|||
* |
|||
* @param host |
|||
* @param path |
|||
* @param method |
|||
* @param headers |
|||
* @param querys |
|||
* @return |
|||
* @throws Exception |
|||
*/ |
|||
public static HttpResponse doDelete(String host, String path, String method, |
|||
Map<String, String> headers, |
|||
Map<String, String> querys) |
|||
throws Exception { |
|||
HttpClient httpClient = wrapClient(host); |
|||
|
|||
HttpDelete request = new HttpDelete(buildUrl(host, path, querys)); |
|||
for (Map.Entry<String, String> e : headers.entrySet()) { |
|||
request.addHeader(e.getKey(), e.getValue()); |
|||
} |
|||
|
|||
return httpClient.execute(request); |
|||
} |
|||
|
|||
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException { |
|||
StringBuilder sbUrl = new StringBuilder(); |
|||
sbUrl.append(host); |
|||
if (!StringUtils.isBlank(path)) { |
|||
sbUrl.append(path); |
|||
} |
|||
if (null != querys) { |
|||
StringBuilder sbQuery = new StringBuilder(); |
|||
for (Map.Entry<String, String> query : querys.entrySet()) { |
|||
if (0 < sbQuery.length()) { |
|||
sbQuery.append("&"); |
|||
} |
|||
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { |
|||
sbQuery.append(query.getValue()); |
|||
} |
|||
if (!StringUtils.isBlank(query.getKey())) { |
|||
sbQuery.append(query.getKey()); |
|||
if (!StringUtils.isBlank(query.getValue())) { |
|||
sbQuery.append("="); |
|||
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); |
|||
} |
|||
} |
|||
} |
|||
if (0 < sbQuery.length()) { |
|||
sbUrl.append("?").append(sbQuery); |
|||
} |
|||
} |
|||
|
|||
return sbUrl.toString(); |
|||
} |
|||
|
|||
private static HttpClient wrapClient(String host) { |
|||
HttpClient httpClient = new DefaultHttpClient(); |
|||
if (host.startsWith("https://")) { |
|||
sslClient(httpClient); |
|||
} |
|||
|
|||
return httpClient; |
|||
} |
|||
|
|||
private static void sslClient(HttpClient httpClient) { |
|||
try { |
|||
SSLContext ctx = SSLContext.getInstance("TLS"); |
|||
X509TrustManager tm = new X509TrustManager() { |
|||
public X509Certificate[] getAcceptedIssuers() { |
|||
return null; |
|||
} |
|||
|
|||
public void checkClientTrusted(X509Certificate[] xcs, String str) { |
|||
|
|||
} |
|||
|
|||
public void checkServerTrusted(X509Certificate[] xcs, String str) { |
|||
|
|||
} |
|||
}; |
|||
ctx.init(null, new TrustManager[]{tm}, null); |
|||
SSLSocketFactory ssf = new SSLSocketFactory(ctx); |
|||
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); |
|||
ClientConnectionManager ccm = httpClient.getConnectionManager(); |
|||
SchemeRegistry registry = ccm.getSchemeRegistry(); |
|||
registry.register(new Scheme("https", 443, ssf)); |
|||
} catch (KeyManagementException ex) { |
|||
throw new RuntimeException(ex); |
|||
} catch (NoSuchAlgorithmException ex) { |
|||
throw new RuntimeException(ex); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
@ -0,0 +1,34 @@ |
|||
import com.storeroom.utils.FastjsonUtils; |
|||
import com.storeroom.utils.HttpUtils; |
|||
import org.apache.http.HttpResponse; |
|||
import org.apache.http.util.EntityUtils; |
|||
import org.junit.jupiter.api.Test; |
|||
|
|||
|
|||
import java.util.HashMap; |
|||
|
|||
public class TestHttp { |
|||
|
|||
@Test |
|||
void test1() throws Exception { |
|||
//根据code 换取access token |
|||
HashMap<String, String> map = new HashMap<>(); |
|||
map.put("Content-type", "application/json"); |
|||
|
|||
HttpResponse response = HttpUtils.doGet("http://jiton.8800.org:800", "/Api/Third/GetToken", "GET", map, null); |
|||
if (response.getStatusLine().getStatusCode() == 200) { |
|||
System.out.println("访问成功"); |
|||
//将获取的结果转换为json字符串形式 |
|||
String s = EntityUtils.toString(response.getEntity()); |
|||
Object a = FastjsonUtils.toJavaMap(s); |
|||
System.out.println(a); |
|||
//使用fastjson将字符串转换为需要的对象 |
|||
// JSON.parseObject() |
|||
// public static JSONObject parseObject(String text, Feature... features) |
|||
} else { |
|||
System.out.println("访问失败" + response.getStatusLine().getStatusCode()); |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,36 @@ |
|||
package com.storeroom.modules.quartz.config; |
|||
|
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import com.storeroom.modules.quartz.repository.QuartzJobRepository; |
|||
import com.storeroom.modules.quartz.utils.QuartzManage; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.boot.ApplicationArguments; |
|||
import org.springframework.boot.ApplicationRunner; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.List; |
|||
|
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class JobRunner implements ApplicationRunner { |
|||
|
|||
private static final Logger log = LoggerFactory.getLogger(JobRunner.class); |
|||
private final QuartzJobRepository quartzJobRepository; |
|||
private final QuartzManage quartzManage; |
|||
|
|||
/** |
|||
* 项目启动时重新激活启用的定时任务 |
|||
* |
|||
* @param applicationArguments / |
|||
*/ |
|||
@Override |
|||
public void run(ApplicationArguments applicationArguments) { |
|||
log.info("--------------------注入系统定时任务------------------"); |
|||
List<QuartzJob> quartzJobs = quartzJobRepository.findByIsPauseIsFalse(); |
|||
quartzJobs.forEach(quartzManage::addJob); |
|||
log.info("--------------------定时任务注入完成------------------"); |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
package com.storeroom.modules.quartz.config; |
|||
|
|||
|
|||
import org.quartz.spi.TriggerFiredBundle; |
|||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.scheduling.quartz.AdaptableJobFactory; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Configuration |
|||
public class QuartzConfig { |
|||
|
|||
/** |
|||
* 解决Job中注入Spring Bean为null的问题 |
|||
*/ |
|||
@Component("quartzJobFactory") |
|||
public static class QuartzJobFactory extends AdaptableJobFactory { |
|||
|
|||
private final AutowireCapableBeanFactory capableBeanFactory; |
|||
|
|||
public QuartzJobFactory(AutowireCapableBeanFactory capableBeanFactory) { |
|||
this.capableBeanFactory = capableBeanFactory; |
|||
} |
|||
|
|||
@Override |
|||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { |
|||
//调用父类的方法,把Job注入到spring中 |
|||
Object jobInstance = super.createJobInstance(bundle); |
|||
capableBeanFactory.autowireBean(jobInstance); |
|||
return jobInstance; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,68 @@ |
|||
package com.storeroom.modules.quartz.domain; |
|||
|
|||
import com.storeroom.base.BaseEntity; |
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Getter; |
|||
import lombok.Setter; |
|||
|
|||
import javax.persistence.*; |
|||
import javax.validation.constraints.NotBlank; |
|||
import javax.validation.constraints.NotNull; |
|||
import java.io.Serializable; |
|||
|
|||
|
|||
@Getter |
|||
@Setter |
|||
@Entity |
|||
@Table(name = "sys_quartz_job") |
|||
public class QuartzJob extends BaseEntity implements Serializable { |
|||
|
|||
public static final String JOB_KEY = "JOB_KEY"; |
|||
|
|||
@Id |
|||
@Column(name = "job_id") |
|||
@NotNull(groups = {Update.class}) |
|||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
|||
private Long id; |
|||
|
|||
@Transient |
|||
@ApiModelProperty(value = "用于子任务唯一标识", hidden = true) |
|||
private String uuid; |
|||
|
|||
@ApiModelProperty(value = "定时器名称") |
|||
private String jobName; |
|||
|
|||
@NotBlank |
|||
@ApiModelProperty(value = "Bean名称") |
|||
private String beanName; |
|||
|
|||
@NotBlank |
|||
@ApiModelProperty(value = "方法名称") |
|||
private String methodName; |
|||
|
|||
@ApiModelProperty(value = "参数") |
|||
private String params; |
|||
|
|||
@NotBlank |
|||
@ApiModelProperty(value = "cron表达式") |
|||
private String cronExpression; |
|||
|
|||
@ApiModelProperty(value = "状态,暂时或启动") |
|||
private Boolean isPause = false; |
|||
|
|||
@ApiModelProperty(value = "负责人") |
|||
private String personInCharge; |
|||
|
|||
@ApiModelProperty(value = "报警邮箱") |
|||
private String email; |
|||
|
|||
@ApiModelProperty(value = "子任务") |
|||
private String subTask; |
|||
|
|||
@ApiModelProperty(value = "失败后暂停") |
|||
private Boolean pauseAfterFailure; |
|||
|
|||
@NotBlank |
|||
@ApiModelProperty(value = "备注") |
|||
private String description; |
|||
} |
@ -0,0 +1,50 @@ |
|||
package com.storeroom.modules.quartz.domain; |
|||
|
|||
|
|||
import io.swagger.annotations.ApiModelProperty; |
|||
import lombok.Data; |
|||
import org.hibernate.annotations.CreationTimestamp; |
|||
|
|||
import javax.persistence.*; |
|||
import java.io.Serializable; |
|||
import java.sql.Timestamp; |
|||
|
|||
@Entity |
|||
@Data |
|||
@Table(name = "sys_quartz_log") |
|||
public class QuartzLog implements Serializable { |
|||
|
|||
@Id |
|||
@Column(name = "log_id") |
|||
@ApiModelProperty(value = "ID", hidden = true) |
|||
@GeneratedValue(strategy = GenerationType.IDENTITY) |
|||
private Long id; |
|||
|
|||
@ApiModelProperty(value = "任务名称", hidden = true) |
|||
private String jobName; |
|||
|
|||
@ApiModelProperty(value = "bean名称", hidden = true) |
|||
private String beanName; |
|||
|
|||
@ApiModelProperty(value = "方法名称", hidden = true) |
|||
private String methodName; |
|||
|
|||
@ApiModelProperty(value = "参数", hidden = true) |
|||
private String params; |
|||
|
|||
@ApiModelProperty(value = "cron表达式", hidden = true) |
|||
private String cronExpression; |
|||
|
|||
@ApiModelProperty(value = "状态", hidden = true) |
|||
private Boolean isSuccess; |
|||
|
|||
@ApiModelProperty(value = "异常详情", hidden = true) |
|||
private String exceptionDetail; |
|||
|
|||
@ApiModelProperty(value = "执行耗时", hidden = true) |
|||
private Long time; |
|||
|
|||
@CreationTimestamp |
|||
@ApiModelProperty(value = "创建时间", hidden = true) |
|||
private Timestamp createTime; |
|||
} |
@ -0,0 +1,16 @@ |
|||
package com.storeroom.modules.quartz.repository; |
|||
|
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface QuartzJobRepository extends JpaRepository<QuartzJob,Long>, JpaSpecificationExecutor<QuartzJob> { |
|||
|
|||
/** |
|||
* 查询启用的任务 |
|||
* @return List |
|||
*/ |
|||
List<QuartzJob> findByIsPauseIsFalse(); |
|||
} |
@ -0,0 +1,8 @@ |
|||
package com.storeroom.modules.quartz.repository; |
|||
|
|||
import com.storeroom.modules.quartz.domain.QuartzLog; |
|||
import org.springframework.data.jpa.repository.JpaRepository; |
|||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; |
|||
|
|||
public interface QuartzLogRepository extends JpaRepository<QuartzLog,Long>, JpaSpecificationExecutor<QuartzLog> { |
|||
} |
@ -0,0 +1,104 @@ |
|||
package com.storeroom.modules.quartz.service; |
|||
|
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import com.storeroom.modules.quartz.domain.QuartzLog; |
|||
import com.storeroom.modules.system.service.dto.JobQueryCriteria; |
|||
import org.springframework.data.domain.Pageable; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
import java.util.List; |
|||
import java.util.Set; |
|||
|
|||
public interface QuartzJobService { |
|||
|
|||
/** |
|||
* 分页查询 |
|||
* @param criteria 条件 |
|||
* @param pageable 分页参数 |
|||
* @return / |
|||
*/ |
|||
Object queryAll(JobQueryCriteria criteria, Pageable pageable); |
|||
|
|||
/** |
|||
* 查询全部 |
|||
* @param criteria 条件 |
|||
* @return / |
|||
*/ |
|||
List<QuartzJob> queryAll(JobQueryCriteria criteria); |
|||
|
|||
/** |
|||
* 分页查询日志 |
|||
* @param criteria 条件 |
|||
* @param pageable 分页参数 |
|||
* @return / |
|||
*/ |
|||
Object queryAllLog(JobQueryCriteria criteria, Pageable pageable); |
|||
|
|||
/** |
|||
* 查询全部 |
|||
* @param criteria 条件 |
|||
* @return / |
|||
*/ |
|||
List<QuartzLog> queryAllLog(JobQueryCriteria criteria); |
|||
|
|||
/** |
|||
* 创建 |
|||
* @param resources / |
|||
*/ |
|||
void create(QuartzJob resources); |
|||
|
|||
/** |
|||
* 编辑 |
|||
* @param resources / |
|||
*/ |
|||
void update(QuartzJob resources); |
|||
|
|||
/** |
|||
* 删除任务 |
|||
* @param ids / |
|||
*/ |
|||
void delete(Set<Long> ids); |
|||
|
|||
/** |
|||
* 根据ID查询 |
|||
* @param id ID |
|||
* @return / |
|||
*/ |
|||
QuartzJob findById(Long id); |
|||
|
|||
/** |
|||
* 更改定时任务状态 |
|||
* @param quartzJob / |
|||
*/ |
|||
void updateIsPause(QuartzJob quartzJob); |
|||
|
|||
/** |
|||
* 立即执行定时任务 |
|||
* @param quartzJob / |
|||
*/ |
|||
void execution(QuartzJob quartzJob); |
|||
|
|||
/** |
|||
* 导出定时任务 |
|||
* @param queryAll 待导出的数据 |
|||
* @param response / |
|||
* @throws IOException / |
|||
*/ |
|||
void download(List<QuartzJob> queryAll, HttpServletResponse response) throws IOException; |
|||
|
|||
/** |
|||
* 导出定时任务日志 |
|||
* @param queryAllLog 待导出的数据 |
|||
* @param response / |
|||
* @throws IOException / |
|||
*/ |
|||
void downloadLog(List<QuartzLog> queryAllLog, HttpServletResponse response) throws IOException; |
|||
|
|||
/** |
|||
* 执行子任务 |
|||
* @param tasks / |
|||
* @throws InterruptedException / |
|||
*/ |
|||
void executionSubJob(String[] tasks) throws InterruptedException; |
|||
} |
@ -0,0 +1,21 @@ |
|||
package com.storeroom.modules.quartz.service.dto; |
|||
|
|||
|
|||
import com.storeroom.annotaion.Query; |
|||
import lombok.Data; |
|||
|
|||
import java.sql.Timestamp; |
|||
import java.util.List; |
|||
|
|||
@Data |
|||
public class JobQueryCriteria { |
|||
|
|||
@Query(type = Query.Type.INNER_LIKE) |
|||
private String jobName; |
|||
|
|||
@Query |
|||
private Boolean isSuccess; |
|||
|
|||
@Query(type = Query.Type.BETWEEN) |
|||
private List<Timestamp> createTime; |
|||
} |
@ -0,0 +1,180 @@ |
|||
package com.storeroom.modules.quartz.service.impl; |
|||
|
|||
import cn.hutool.core.util.IdUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.storeroom.exception.BaseException; |
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import com.storeroom.modules.quartz.domain.QuartzLog; |
|||
import com.storeroom.modules.quartz.repository.QuartzJobRepository; |
|||
import com.storeroom.modules.quartz.repository.QuartzLogRepository; |
|||
import com.storeroom.modules.quartz.service.QuartzJobService; |
|||
import com.storeroom.modules.quartz.utils.QuartzManage; |
|||
import com.storeroom.modules.system.service.dto.JobQueryCriteria; |
|||
import com.storeroom.utils.*; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.quartz.CronExpression; |
|||
import org.springframework.data.domain.Pageable; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import javax.servlet.http.HttpServletResponse; |
|||
import java.io.IOException; |
|||
import java.util.*; |
|||
|
|||
|
|||
@RequiredArgsConstructor |
|||
@Service(value = "quartzJobService") |
|||
public class QuartzJobServiceImpl implements QuartzJobService { |
|||
|
|||
private final QuartzJobRepository quartzJobRepository; |
|||
private final QuartzLogRepository quartzLogRepository; |
|||
private final QuartzManage quartzManage; |
|||
private final RedisUtils redisUtils; |
|||
|
|||
@Override |
|||
public Object queryAll(JobQueryCriteria criteria, Pageable pageable){ |
|||
return PageUtil.toPage(quartzJobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); |
|||
} |
|||
|
|||
@Override |
|||
public Object queryAllLog(JobQueryCriteria criteria, Pageable pageable){ |
|||
return PageUtil.toPage(quartzLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable)); |
|||
} |
|||
|
|||
@Override |
|||
public List<QuartzJob> queryAll(JobQueryCriteria criteria) { |
|||
return quartzJobRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); |
|||
} |
|||
|
|||
@Override |
|||
public List<QuartzLog> queryAllLog(JobQueryCriteria criteria) { |
|||
return quartzLogRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)); |
|||
} |
|||
|
|||
@Override |
|||
public QuartzJob findById(Long id) { |
|||
QuartzJob quartzJob = quartzJobRepository.findById(id).orElseGet(QuartzJob::new); |
|||
ValidationUtil.isNull(quartzJob.getId(),"QuartzJob","id",id); |
|||
return quartzJob; |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void create(QuartzJob resources) { |
|||
if (!CronExpression.isValidExpression(resources.getCronExpression())){ |
|||
throw new BaseException("cron表达式格式错误"); |
|||
} |
|||
resources = quartzJobRepository.save(resources); |
|||
quartzManage.addJob(resources); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void update(QuartzJob resources) { |
|||
if (!CronExpression.isValidExpression(resources.getCronExpression())){ |
|||
throw new BaseException("cron表达式格式错误"); |
|||
} |
|||
if(StringUtils.isNotBlank(resources.getSubTask())){ |
|||
List<String> tasks = Arrays.asList(resources.getSubTask().split("[,,]")); |
|||
if (tasks.contains(resources.getId().toString())) { |
|||
throw new BaseException("子任务中不能添加当前任务ID"); |
|||
} |
|||
} |
|||
resources = quartzJobRepository.save(resources); |
|||
quartzManage.updateJobCron(resources); |
|||
} |
|||
|
|||
@Override |
|||
public void updateIsPause(QuartzJob quartzJob) { |
|||
if (quartzJob.getIsPause()) { |
|||
quartzManage.resumeJob(quartzJob); |
|||
quartzJob.setIsPause(false); |
|||
} else { |
|||
quartzManage.pauseJob(quartzJob); |
|||
quartzJob.setIsPause(true); |
|||
} |
|||
quartzJobRepository.save(quartzJob); |
|||
} |
|||
|
|||
@Override |
|||
public void execution(QuartzJob quartzJob) { |
|||
quartzManage.runJobNow(quartzJob); |
|||
} |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void delete(Set<Long> ids) { |
|||
for (Long id : ids) { |
|||
QuartzJob quartzJob = findById(id); |
|||
quartzManage.deleteJob(quartzJob); |
|||
quartzJobRepository.delete(quartzJob); |
|||
} |
|||
} |
|||
|
|||
@Async |
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void executionSubJob(String[] tasks) throws InterruptedException { |
|||
for (String id : tasks) { |
|||
if (StrUtil.isBlank(id)) { |
|||
// 如果是手动清除子任务id,会出现id为空字符串的问题 |
|||
continue; |
|||
} |
|||
QuartzJob quartzJob = findById(Long.parseLong(id)); |
|||
// 执行任务 |
|||
String uuid = NanoIdUtils.randomNanoId(); |
|||
quartzJob.setUuid(uuid); |
|||
// 执行任务 |
|||
execution(quartzJob); |
|||
// 获取执行状态,如果执行失败则停止后面的子任务执行 |
|||
Boolean result = (Boolean) redisUtils.get(uuid); |
|||
while (result == null) { |
|||
// 休眠5秒,再次获取子任务执行情况 |
|||
Thread.sleep(5000); |
|||
result = (Boolean) redisUtils.get(uuid); |
|||
} |
|||
if(!result){ |
|||
redisUtils.del(uuid); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void download(List<QuartzJob> quartzJobs, HttpServletResponse response) throws IOException { |
|||
List<Map<String, Object>> list = new ArrayList<>(); |
|||
for (QuartzJob quartzJob : quartzJobs) { |
|||
Map<String,Object> map = new LinkedHashMap<>(); |
|||
map.put("任务名称", quartzJob.getJobName()); |
|||
map.put("Bean名称", quartzJob.getBeanName()); |
|||
map.put("执行方法", quartzJob.getMethodName()); |
|||
map.put("参数", quartzJob.getParams()); |
|||
map.put("表达式", quartzJob.getCronExpression()); |
|||
map.put("状态", quartzJob.getIsPause() ? "暂停中" : "运行中"); |
|||
map.put("描述", quartzJob.getDescription()); |
|||
map.put("创建日期", quartzJob.getCreateTime()); |
|||
list.add(map); |
|||
} |
|||
FileUtil.downloadExcel(list, response); |
|||
} |
|||
|
|||
@Override |
|||
public void downloadLog(List<QuartzLog> queryAllLog, HttpServletResponse response) throws IOException { |
|||
List<Map<String, Object>> list = new ArrayList<>(); |
|||
for (QuartzLog quartzLog : queryAllLog) { |
|||
Map<String,Object> map = new LinkedHashMap<>(); |
|||
map.put("任务名称", quartzLog.getJobName()); |
|||
map.put("Bean名称", quartzLog.getBeanName()); |
|||
map.put("执行方法", quartzLog.getMethodName()); |
|||
map.put("参数", quartzLog.getParams()); |
|||
map.put("表达式", quartzLog.getCronExpression()); |
|||
map.put("异常详情", quartzLog.getExceptionDetail()); |
|||
map.put("耗时/毫秒", quartzLog.getTime()); |
|||
map.put("状态", quartzLog.getIsSuccess() ? "成功" : "失败"); |
|||
map.put("创建日期", quartzLog.getCreateTime()); |
|||
list.add(map); |
|||
} |
|||
FileUtil.downloadExcel(list, response); |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
package com.storeroom.modules.quartz.task; |
|||
|
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
@Slf4j |
|||
@Async |
|||
@Component |
|||
public class TestTask { |
|||
|
|||
public void run(){ |
|||
log.info("run 执行成功"); |
|||
} |
|||
|
|||
public void run1(String str){ |
|||
log.info("run1 执行成功,参数为: {}" + str); |
|||
} |
|||
|
|||
public void run2(){ |
|||
log.info("run2 执行成功"); |
|||
} |
|||
} |
@ -0,0 +1,99 @@ |
|||
package com.storeroom.modules.quartz.utils; |
|||
|
|||
import cn.hutool.extra.template.Template; |
|||
import cn.hutool.extra.template.TemplateConfig; |
|||
import cn.hutool.extra.template.TemplateEngine; |
|||
import cn.hutool.extra.template.TemplateUtil; |
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import com.storeroom.modules.quartz.domain.QuartzLog; |
|||
import com.storeroom.modules.quartz.repository.QuartzLogRepository; |
|||
import com.storeroom.modules.quartz.service.QuartzJobService; |
|||
import com.storeroom.utils.RedisUtils; |
|||
import com.storeroom.utils.SpringContextHolder; |
|||
import com.storeroom.utils.StringUtils; |
|||
import com.storeroom.utils.ThrowableUtil; |
|||
import org.quartz.JobExecutionContext; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.scheduling.annotation.Async; |
|||
import org.springframework.scheduling.quartz.QuartzJobBean; |
|||
|
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.Executors; |
|||
import java.util.concurrent.Future; |
|||
|
|||
|
|||
@Async |
|||
public class ExecutionJob extends QuartzJobBean { |
|||
|
|||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); |
|||
|
|||
|
|||
@Override |
|||
public void executeInternal(JobExecutionContext context) { |
|||
// 创建单个线程 |
|||
ExecutorService executor = Executors.newSingleThreadExecutor(); |
|||
// 获取任务 |
|||
QuartzJob quartzJob = (QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY); |
|||
// 获取spring bean |
|||
QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class); |
|||
QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class); |
|||
RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class); |
|||
|
|||
String uuid = quartzJob.getUuid(); |
|||
|
|||
QuartzLog log = new QuartzLog(); |
|||
log.setJobName(quartzJob.getJobName()); |
|||
log.setBeanName(quartzJob.getBeanName()); |
|||
log.setMethodName(quartzJob.getMethodName()); |
|||
log.setParams(quartzJob.getParams()); |
|||
long startTime = System.currentTimeMillis(); |
|||
log.setCronExpression(quartzJob.getCronExpression()); |
|||
try { |
|||
// 执行任务 |
|||
QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams()); |
|||
Future<?> future = executor.submit(task); |
|||
future.get(); |
|||
long times = System.currentTimeMillis() - startTime; |
|||
log.setTime(times); |
|||
if(StringUtils.isNotBlank(uuid)) { |
|||
redisUtils.set(uuid, true); |
|||
} |
|||
// 任务状态 |
|||
log.setIsSuccess(true); |
|||
logger.info("任务执行成功,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒"); |
|||
// 判断是否存在子任务 |
|||
if(StringUtils.isNotBlank(quartzJob.getSubTask())){ |
|||
String[] tasks = quartzJob.getSubTask().split("[,,]"); |
|||
// 执行子任务 |
|||
quartzJobService.executionSubJob(tasks); |
|||
} |
|||
} catch (Exception e) { |
|||
if(StringUtils.isNotBlank(uuid)) { |
|||
redisUtils.set(uuid, false); |
|||
} |
|||
logger.error("任务执行失败,任务名称:" + quartzJob.getJobName()); |
|||
long times = System.currentTimeMillis() - startTime; |
|||
log.setTime(times); |
|||
// 任务状态 0:成功 1:失败 |
|||
log.setIsSuccess(false); |
|||
log.setExceptionDetail(ThrowableUtil.getStackTrace(e)); |
|||
// 任务如果失败了则暂停 |
|||
if(quartzJob.getPauseAfterFailure() != null && quartzJob.getPauseAfterFailure()){ |
|||
quartzJob.setIsPause(false); |
|||
//更新状态 |
|||
quartzJobService.updateIsPause(quartzJob); |
|||
} |
|||
|
|||
} finally { |
|||
quartzLogRepository.save(log); |
|||
executor.shutdown(); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,157 @@ |
|||
package com.storeroom.modules.quartz.utils; |
|||
|
|||
|
|||
import com.storeroom.exception.BaseException; |
|||
import com.storeroom.modules.quartz.domain.QuartzJob; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.quartz.*; |
|||
import org.quartz.impl.triggers.CronTriggerImpl; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.annotation.Resource; |
|||
import java.util.Date; |
|||
|
|||
import static org.quartz.TriggerBuilder.newTrigger; |
|||
|
|||
@Slf4j |
|||
@Component |
|||
public class QuartzManage { |
|||
|
|||
private static final String JOB_NAME = "TASK_"; |
|||
|
|||
@Resource |
|||
private Scheduler scheduler; |
|||
|
|||
public void addJob(QuartzJob quartzJob){ |
|||
try { |
|||
// 构建job信息 |
|||
JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class). |
|||
withIdentity(JOB_NAME + quartzJob.getId()).build(); |
|||
|
|||
//通过触发器名和cron 表达式创建 Trigger |
|||
Trigger cronTrigger = newTrigger() |
|||
.withIdentity(JOB_NAME + quartzJob.getId()) |
|||
.startNow() |
|||
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression())) |
|||
.build(); |
|||
|
|||
cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob); |
|||
|
|||
//重置启动时间 |
|||
((CronTriggerImpl)cronTrigger).setStartTime(new Date()); |
|||
|
|||
//执行定时任务 |
|||
scheduler.scheduleJob(jobDetail,cronTrigger); |
|||
|
|||
// 暂停任务 |
|||
if (quartzJob.getIsPause()) { |
|||
pauseJob(quartzJob); |
|||
} |
|||
} catch (Exception e){ |
|||
log.error("创建定时任务失败", e); |
|||
throw new BaseException("创建定时任务失败"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 更新job cron表达式 |
|||
* @param quartzJob / |
|||
*/ |
|||
public void updateJobCron(QuartzJob quartzJob){ |
|||
try { |
|||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); |
|||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); |
|||
// 如果不存在则创建一个定时任务 |
|||
if(trigger == null){ |
|||
addJob(quartzJob); |
|||
trigger = (CronTrigger) scheduler.getTrigger(triggerKey); |
|||
} |
|||
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzJob.getCronExpression()); |
|||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); |
|||
//重置启动时间 |
|||
((CronTriggerImpl)trigger).setStartTime(new Date()); |
|||
trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob); |
|||
|
|||
scheduler.rescheduleJob(triggerKey, trigger); |
|||
// 暂停任务 |
|||
if (quartzJob.getIsPause()) { |
|||
pauseJob(quartzJob); |
|||
} |
|||
} catch (Exception e){ |
|||
log.error("更新定时任务失败", e); |
|||
throw new BaseException("更新定时任务失败"); |
|||
} |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 删除一个job |
|||
* @param quartzJob / |
|||
*/ |
|||
public void deleteJob(QuartzJob quartzJob){ |
|||
try { |
|||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); |
|||
scheduler.pauseJob(jobKey); |
|||
scheduler.deleteJob(jobKey); |
|||
} catch (Exception e){ |
|||
log.error("删除定时任务失败", e); |
|||
throw new BaseException("删除定时任务失败"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 恢复一个job |
|||
* @param quartzJob / |
|||
*/ |
|||
public void resumeJob(QuartzJob quartzJob){ |
|||
try { |
|||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); |
|||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); |
|||
// 如果不存在则创建一个定时任务 |
|||
if(trigger == null) { |
|||
addJob(quartzJob); |
|||
} |
|||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); |
|||
scheduler.resumeJob(jobKey); |
|||
} catch (Exception e){ |
|||
log.error("恢复定时任务失败", e); |
|||
throw new BaseException("恢复定时任务失败"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 立即执行job |
|||
* @param quartzJob / |
|||
*/ |
|||
public void runJobNow(QuartzJob quartzJob){ |
|||
try { |
|||
TriggerKey triggerKey = TriggerKey.triggerKey(JOB_NAME + quartzJob.getId()); |
|||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); |
|||
// 如果不存在则创建一个定时任务 |
|||
if(trigger == null) { |
|||
addJob(quartzJob); |
|||
} |
|||
JobDataMap dataMap = new JobDataMap(); |
|||
dataMap.put(QuartzJob.JOB_KEY, quartzJob); |
|||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); |
|||
scheduler.triggerJob(jobKey,dataMap); |
|||
} catch (Exception e){ |
|||
log.error("定时任务执行失败", e); |
|||
throw new BaseException("定时任务执行失败"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 暂停一个job |
|||
* @param quartzJob / |
|||
*/ |
|||
public void pauseJob(QuartzJob quartzJob){ |
|||
try { |
|||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId()); |
|||
scheduler.pauseJob(jobKey); |
|||
} catch (Exception e){ |
|||
log.error("定时任务暂停失败", e); |
|||
throw new BaseException("定时任务暂停失败"); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
package com.storeroom.modules.quartz.utils; |
|||
|
|||
import com.storeroom.utils.SpringContextHolder; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.util.ReflectionUtils; |
|||
|
|||
import java.lang.reflect.Method; |
|||
import java.util.concurrent.Callable; |
|||
|
|||
|
|||
@Slf4j |
|||
public class QuartzRunnable implements Callable<Object> { |
|||
|
|||
private final Object target; |
|||
private final Method method; |
|||
private final String params; |
|||
|
|||
QuartzRunnable(String beanName, String methodName, String params) |
|||
throws NoSuchMethodException, SecurityException { |
|||
this.target = SpringContextHolder.getBean(beanName); |
|||
this.params = params; |
|||
if (StringUtils.isNotBlank(params)) { |
|||
this.method = target.getClass().getDeclaredMethod(methodName, String.class); |
|||
} else { |
|||
this.method = target.getClass().getDeclaredMethod(methodName); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
@SuppressWarnings("all") |
|||
public Object call() throws Exception { |
|||
ReflectionUtils.makeAccessible(method); |
|||
if (StringUtils.isNotBlank(params)) { |
|||
method.invoke(target, params); |
|||
} else { |
|||
method.invoke(target); |
|||
} |
|||
return null; |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue