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