commit
94eeade64c
Binary file not shown.
@ -0,0 +1,81 @@
|
||||
package com.xxl.job.admin.core.conf;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* xxl-job config
|
||||
*
|
||||
* @author xuxueli 2017-04-28
|
||||
*/
|
||||
@Configuration
|
||||
public class XxlJobAdminConfig implements InitializingBean{
|
||||
private static XxlJobAdminConfig adminConfig = null;
|
||||
public static XxlJobAdminConfig getAdminConfig() {
|
||||
return adminConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
adminConfig = this;
|
||||
}
|
||||
|
||||
@Value("${xxl.job.mail.host}")
|
||||
private String mailHost;
|
||||
|
||||
@Value("${xxl.job.mail.port}")
|
||||
private String mailPort;
|
||||
|
||||
@Value("${xxl.job.mail.username}")
|
||||
private String mailUsername;
|
||||
|
||||
@Value("${xxl.job.mail.password}")
|
||||
private String mailPassword;
|
||||
|
||||
@Value("${xxl.job.mail.sendNick}")
|
||||
private String mailSendNick;
|
||||
|
||||
@Value("${xxl.job.login.username}")
|
||||
private String loginUsername;
|
||||
|
||||
@Value("${xxl.job.login.password}")
|
||||
private String loginPassword;
|
||||
|
||||
@Value("${xxl.job.i18n}")
|
||||
private String i18n;
|
||||
|
||||
|
||||
public String getMailHost() {
|
||||
return mailHost;
|
||||
}
|
||||
|
||||
public String getMailPort() {
|
||||
return mailPort;
|
||||
}
|
||||
|
||||
public String getMailUsername() {
|
||||
return mailUsername;
|
||||
}
|
||||
|
||||
public String getMailPassword() {
|
||||
return mailPassword;
|
||||
}
|
||||
|
||||
public String getMailSendNick() {
|
||||
return mailSendNick;
|
||||
}
|
||||
|
||||
public String getLoginUsername() {
|
||||
return loginUsername;
|
||||
}
|
||||
|
||||
public String getLoginPassword() {
|
||||
return loginPassword;
|
||||
}
|
||||
|
||||
public String getI18n() {
|
||||
return i18n;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.xxl.job.admin.core.util;
|
||||
|
||||
import freemarker.ext.beans.BeansWrapper;
|
||||
import freemarker.template.TemplateHashModel;
|
||||
|
||||
/**
|
||||
* ftl util
|
||||
*
|
||||
* @author xuxueli 2018-01-17 20:37:48
|
||||
*/
|
||||
public class FtlUtil {
|
||||
|
||||
public static TemplateHashModel generateStaticModel(String packageName) {
|
||||
try {
|
||||
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
|
||||
TemplateHashModel staticModels = wrapper.getStaticModels();
|
||||
TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName);
|
||||
return fileStatics;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.xxl.job.admin.core.util;
|
||||
|
||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
||||
import com.xxl.job.core.util.JacksonUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* i18n util
|
||||
*
|
||||
* @author xuxueli 2018-01-17 20:39:06
|
||||
*/
|
||||
public class I18nUtil {
|
||||
private static Logger logger = LoggerFactory.getLogger(I18nUtil.class);
|
||||
|
||||
private static Properties prop = null;
|
||||
public static Properties loadI18nProp(){
|
||||
if (prop != null) {
|
||||
return prop;
|
||||
}
|
||||
try {
|
||||
// bild i18n prop
|
||||
String i18n = XxlJobAdminConfig.getAdminConfig().getI18n();
|
||||
i18n = StringUtils.isNotBlank(i18n)?("_"+i18n):i18n;
|
||||
String i18nFile = MessageFormat.format("i18n/message{0}.properties", i18n);
|
||||
|
||||
// load prop
|
||||
Resource resource = new ClassPathResource(i18nFile);
|
||||
EncodedResource encodedResource = new EncodedResource(resource,"UTF-8");
|
||||
prop = PropertiesLoaderUtils.loadProperties(encodedResource);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* get val of i18n key
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getString(String key) {
|
||||
return loadI18nProp().getProperty(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* get mult val of i18n mult key, as json
|
||||
*
|
||||
* @param keys
|
||||
* @return
|
||||
*/
|
||||
public static String getMultString(String... keys) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
Properties prop = loadI18nProp();
|
||||
if (keys!=null && keys.length>0) {
|
||||
for (String key: keys) {
|
||||
map.put(key, prop.getProperty(key));
|
||||
}
|
||||
} else {
|
||||
for (String key: prop.stringPropertyNames()) {
|
||||
map.put(key, prop.getProperty(key));
|
||||
}
|
||||
}
|
||||
|
||||
String json = JacksonUtil.writeValueAsString(map);
|
||||
return json;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
package com.xxl.job.admin.core.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* local cache tool
|
||||
*
|
||||
* @author xuxueli 2018-01-22 21:37:34
|
||||
*/
|
||||
public class LocalCacheUtil {
|
||||
|
||||
private static ConcurrentHashMap<String, LocalCacheData> cacheRepository = new ConcurrentHashMap<>();
|
||||
private static class LocalCacheData{
|
||||
private String key;
|
||||
private Object val;
|
||||
private long timeoutTime;
|
||||
|
||||
public LocalCacheData() {
|
||||
}
|
||||
|
||||
public LocalCacheData(String key, Object val, long timeoutTime) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
this.timeoutTime = timeoutTime;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Object getVal() {
|
||||
return val;
|
||||
}
|
||||
|
||||
public void setVal(Object val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public long getTimeoutTime() {
|
||||
return timeoutTime;
|
||||
}
|
||||
|
||||
public void setTimeoutTime(long timeoutTime) {
|
||||
this.timeoutTime = timeoutTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set cache
|
||||
*
|
||||
* @param key
|
||||
* @param val
|
||||
* @param cacheTime
|
||||
* @return
|
||||
*/
|
||||
public static boolean set(String key, Object val, long cacheTime){
|
||||
|
||||
// clean timeout cache, before set new cache (avoid cache too much)
|
||||
cleanTimeutCache();
|
||||
|
||||
// set new cache
|
||||
if (StringUtils.isBlank(key)) {
|
||||
return false;
|
||||
}
|
||||
if (val == null) {
|
||||
remove(key);
|
||||
}
|
||||
if (cacheTime <= 0) {
|
||||
remove(key);
|
||||
}
|
||||
long timeoutTime = System.currentTimeMillis() + cacheTime;
|
||||
LocalCacheData localCacheData = new LocalCacheData(key, val, timeoutTime);
|
||||
cacheRepository.put(localCacheData.getKey(), localCacheData);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove cache
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static boolean remove(String key){
|
||||
if (StringUtils.isBlank(key)) {
|
||||
return false;
|
||||
}
|
||||
cacheRepository.remove(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* get cache
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Object get(String key){
|
||||
if (StringUtils.isBlank(key)) {
|
||||
return null;
|
||||
}
|
||||
LocalCacheData localCacheData = cacheRepository.get(key);
|
||||
if (localCacheData!=null && System.currentTimeMillis()<localCacheData.getTimeoutTime()) {
|
||||
return localCacheData.getVal();
|
||||
} else {
|
||||
remove(key);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean timeout cache
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean cleanTimeutCache(){
|
||||
if (!cacheRepository.keySet().isEmpty()) {
|
||||
for (String key: cacheRepository.keySet()) {
|
||||
LocalCacheData localCacheData = cacheRepository.get(key);
|
||||
if (localCacheData!=null && System.currentTimeMillis()>=localCacheData.getTimeoutTime()) {
|
||||
cacheRepository.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.xxl.job.admin.core.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.EncodedResource;
|
||||
import org.springframework.core.io.support.PropertiesLoaderUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* properties util
|
||||
*
|
||||
* @author xuxueli 2015-8-28 10:35:53
|
||||
*/
|
||||
public class PropertiesUtil {
|
||||
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
|
||||
private static final String file_name = "xxl-job-admin.properties";
|
||||
|
||||
|
||||
public static String getString(String key) {
|
||||
Properties prop = null;
|
||||
try {
|
||||
Resource resource = new ClassPathResource(file_name);
|
||||
EncodedResource encodedResource = new EncodedResource(resource,"UTF-8");
|
||||
prop = PropertiesLoaderUtils.loadProperties(encodedResource);
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
if (prop!=null) {
|
||||
return prop.getProperty(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
${result?if_exists}
|
@ -1,2 +0,0 @@
|
||||
/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */
|
||||
;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'<h3 style="'+(e?n.title[1]:"")+'">'+(e?n.title[0]:n.title)+"</h3>":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e='<span yes type="1">'+n.btn[0]+"</span>",2===t&&(e='<span no type="0">'+n.btn[1]+"</span>"+e),'<div class="layui-m-layerbtn">'+e+"</div>"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='<i></i><i class="layui-m-layerload"></i><i></i><p>'+(n.content||"")+"</p>"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"<div "+("string"==typeof n.shade?'style="'+n.shade+'"':"")+' class="layui-m-layershade"></div>':"")+'<div class="layui-m-layermain" '+(n.fixed?"":'style="position:static;"')+'><div class="layui-m-layersection"><div class="layui-m-layerchild '+(n.skin?"layui-m-layer-"+n.skin+" ":"")+(n.className?n.className:"")+" "+(n.anim?"layui-m-anim-"+n.anim:"")+'" '+(n.style?'style="'+n.style+'"':"")+">"+l+'<div class="layui-m-layercont">'+n.content+"</div>"+c+"</div></div></div>",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;o<r;o++)l.touch(s[o],a);if(e.shade&&e.shadeClose){var c=t[i]("layui-m-layershade")[0];l.touch(c,function(){layer.close(n.index,e.end)})}e.end&&(l.end[n.index]=e.end)},e.layer={v:"2.0",index:r,open:function(e){var t=new c(e||{});return t.index},close:function(e){var n=a("#"+o[0]+e)[0];n&&(n.innerHTML="",t.body.removeChild(n),clearTimeout(l.timer[e]),delete l.timer[e],"function"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[i](o[0]),n=0,a=e.length;n<a;n++)layer.close(0|e[0].getAttribute("index"))}},"function"==typeof define?define(function(){return layer}):function(){var e=document.scripts,n=e[e.length-1],i=n.src,a=i.substring(0,i.lastIndexOf("/")+1);n.getAttribute("merge")||document.head.appendChild(function(){var e=t.createElement("link");return e.href=a+"need/layer.css?2.0",e.type="text/css",e.rel="styleSheet",e.id="layermcss",e}())}()}(window);
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,25 @@
|
||||
package com.xxl.job.admin.util;
|
||||
|
||||
import com.xxl.job.admin.core.util.I18nUtil;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* email util test
|
||||
*
|
||||
* @author xuxueli 2017-12-22 17:16:23
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath*:spring/applicationcontext-*.xml")
|
||||
public class I18nUtilTest {
|
||||
|
||||
@Test
|
||||
public void test(){
|
||||
System.out.println(I18nUtil.getString("admin_name"));
|
||||
System.out.println(I18nUtil.getMultString("admin_name", "admin_name_full"));
|
||||
System.out.println(I18nUtil.getMultString());
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.xxl.job.admin.util;
|
||||
|
||||
import com.xxl.job.admin.core.util.PropertiesUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* prop util test
|
||||
*
|
||||
* @author xuxueli 2017-12-25 15:17:36
|
||||
*/
|
||||
public class PropertiesUtilTest {
|
||||
|
||||
@Test
|
||||
public void registryTest() throws Exception {
|
||||
System.out.println(PropertiesUtil.getString("xxl.job.login.username"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.xxl.job.core.thread;
|
||||
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
import com.xxl.job.core.util.FileUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* job file clean thread
|
||||
*
|
||||
* @author xuxueli 2017-12-29 16:23:43
|
||||
*/
|
||||
public class JobLogFileCleanThread extends Thread {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobLogFileCleanThread.class);
|
||||
|
||||
private static JobLogFileCleanThread instance = new JobLogFileCleanThread();
|
||||
public static JobLogFileCleanThread getInstance(){
|
||||
return instance;
|
||||
}
|
||||
|
||||
private Thread localThread;
|
||||
private volatile boolean toStop = false;
|
||||
public void start(final long logRetentionDays){
|
||||
|
||||
// limit min value
|
||||
if (logRetentionDays < 3 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
localThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (!toStop) {
|
||||
try {
|
||||
// clean log dir, over logRetentionDays
|
||||
File[] childDirs = new File(XxlJobFileAppender.getLogPath()).listFiles();
|
||||
if (childDirs!=null && childDirs.length>0) {
|
||||
|
||||
// today
|
||||
Calendar todayCal = Calendar.getInstance();
|
||||
todayCal.set(Calendar.HOUR_OF_DAY,0);
|
||||
todayCal.set(Calendar.MINUTE,0);
|
||||
todayCal.set(Calendar.SECOND,0);
|
||||
todayCal.set(Calendar.MILLISECOND,0);
|
||||
|
||||
Date todayDate = todayCal.getTime();
|
||||
|
||||
for (File childFile: childDirs) {
|
||||
|
||||
// valid
|
||||
if (!childFile.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
if (childFile.getName().indexOf("-") == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// file create date
|
||||
Date logFileCreateDate = null;
|
||||
try {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
logFileCreateDate = simpleDateFormat.parse(childFile.getName());
|
||||
} catch (ParseException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
if (logFileCreateDate == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((todayDate.getTime()-logFileCreateDate.getTime()) >= logRetentionDays * (24 * 60 * 60 * 1000) ) {
|
||||
FileUtil.deleteRecursively(childFile);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
TimeUnit.DAYS.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
logger.info(">>>>>>>>>>> xxl-job, executor JobLogFileCleanThread thread destory.");
|
||||
|
||||
}
|
||||
});
|
||||
localThread.setDaemon(true);
|
||||
localThread.start();
|
||||
}
|
||||
|
||||
public void toStop() {
|
||||
toStop = true;
|
||||
|
||||
if (localThread == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// interrupt and wait
|
||||
localThread.interrupt();
|
||||
try {
|
||||
localThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.xxl.job.core.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* file tool
|
||||
*
|
||||
* @author xuxueli 2017-12-29 17:56:48
|
||||
*/
|
||||
public class FileUtil {
|
||||
|
||||
public static boolean deleteRecursively(File root) {
|
||||
if (root != null && root.exists()) {
|
||||
if (root.isDirectory()) {
|
||||
File[] children = root.listFiles();
|
||||
if (children != null) {
|
||||
for (File child : children) {
|
||||
deleteRecursively(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
return root.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue