Commit 44f3c95a by liyuan

init project

parents
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>byit-myth-job</artifactId>
<groupId>myth-job</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>byit-myth-admin</artifactId>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>byit-myth-job</artifactId>
<groupId>myth-job</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>byit-myth-core</artifactId>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>byit-myth-job</artifactId>
<groupId>myth-job</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>byit-myth-executor</artifactId>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>byit-myth-register</artifactId>
<groupId>myth-job</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>myth-register-client</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-api.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.byit.registry.client;
import com.byit.registry.client.model.RegistryDataParamVO;
import com.byit.registry.client.model.RegistryParamVO;
import com.byit.registry.client.util.BasicHttpUtil;
import com.byit.registry.client.util.json.BasicJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* base util for registry
*
*/
public class RegistryBaseClient {
private static Logger logger = LoggerFactory.getLogger(RegistryBaseClient.class);
private String adminAddress;
private String accessToken;
private String biz;
private String env;
private List<String> adminAddressArr;
public RegistryBaseClient(String adminAddress, String accessToken, String biz, String env) {
this.adminAddress = adminAddress;
this.accessToken = accessToken;
this.biz = biz;
this.env = env;
// valid
if (adminAddress==null || adminAddress.trim().length()==0) {
throw new RuntimeException("registry adminAddress empty");
}
if (biz==null || biz.trim().length()<4 || biz.trim().length()>255) {
throw new RuntimeException("registry biz empty Invalid[4~255]");
}
if (env==null || env.trim().length()<2 || env.trim().length()>255) {
throw new RuntimeException("registry biz env Invalid[2~255]");
}
// parse
adminAddressArr = new ArrayList<>();
if (adminAddress.contains(",")) {
adminAddressArr.addAll(Arrays.asList(adminAddress.split(",")));
} else {
adminAddressArr.add(adminAddress);
}
}
/**
* registry
*
* @param registryDataList
* @return
*/
public boolean registry(List<RegistryDataParamVO> registryDataList){
// valid
if (registryDataList==null || registryDataList.size()==0) {
throw new RuntimeException("registry registryDataList empty");
}
for (RegistryDataParamVO registryParam: registryDataList) {
if (registryParam.getKey()==null || registryParam.getKey().trim().length()<4 || registryParam.getKey().trim().length()>255) {
throw new RuntimeException("registry registryDataList#key Invalid[4~255]");
}
if (registryParam.getValue()==null || registryParam.getValue().trim().length()<4 || registryParam.getValue().trim().length()>255) {
throw new RuntimeException("registry registryDataList#value Invalid[4~255]");
}
}
// pathUrl
String pathUrl = "/api/registry";
// param
RegistryParamVO registryParamVO = new RegistryParamVO();
registryParamVO.setAccessToken(this.accessToken);
registryParamVO.setBiz(this.biz);
registryParamVO.setEnv(this.env);
registryParamVO.setRegistryDataList(registryDataList);
String paramsJson = BasicJson.toJson(registryParamVO);
// result
Map<String, Object> respObj = requestAndValid(pathUrl, paramsJson, 5);
return respObj!=null?true:false;
}
private Map<String, Object> requestAndValid(String pathUrl, String requestBody, int timeout){
for (String adminAddressUrl: adminAddressArr) {
String finalUrl = adminAddressUrl + pathUrl;
// request
String responseData = BasicHttpUtil.postBody(finalUrl, requestBody, timeout);
if (responseData == null) {
return null;
}
// parse resopnse
Map<String, Object> resopnseMap = null;
try {
resopnseMap = BasicJson.parseMap(responseData);
} catch (Exception e) { }
// valid resopnse
if (resopnseMap==null
|| !resopnseMap.containsKey("code")
|| !"200".equals(String.valueOf(resopnseMap.get("code")))
) {
logger.warn("RegistryBaseClient response fail, responseData={}", responseData);
return null;
}
return resopnseMap;
}
return null;
}
/**
* remove
*
* @param registryDataList
* @return
*/
public boolean remove(List<RegistryDataParamVO> registryDataList) {
// valid
if (registryDataList==null || registryDataList.size()==0) {
throw new RuntimeException("registry registryDataList empty");
}
for (RegistryDataParamVO registryParam: registryDataList) {
if (registryParam.getKey()==null || registryParam.getKey().trim().length()<4 || registryParam.getKey().trim().length()>255) {
throw new RuntimeException("registry registryDataList#key Invalid[4~255]");
}
if (registryParam.getValue()==null || registryParam.getValue().trim().length()<4 || registryParam.getValue().trim().length()>255) {
throw new RuntimeException("registry registryDataList#value Invalid[4~255]");
}
}
// pathUrl
String pathUrl = "/api/remove";
// param
RegistryParamVO registryParamVO = new RegistryParamVO();
registryParamVO.setAccessToken(this.accessToken);
registryParamVO.setBiz(this.biz);
registryParamVO.setEnv(this.env);
registryParamVO.setRegistryDataList(registryDataList);
String paramsJson = BasicJson.toJson(registryParamVO);
// result
Map<String, Object> respObj = requestAndValid(pathUrl, paramsJson, 5);
return respObj!=null?true:false;
}
/**
* discovery
*
* @param keys
* @return
*/
public Map<String, TreeSet<String>> discovery(Set<String> keys) {
// valid
if (keys==null || keys.size()==0) {
throw new RuntimeException("registry keys empty");
}
// pathUrl
String pathUrl = "/api/discovery";
// param
RegistryParamVO registryParamVO = new RegistryParamVO();
registryParamVO.setAccessToken(this.accessToken);
registryParamVO.setBiz(this.biz);
registryParamVO.setEnv(this.env);
registryParamVO.setKeys(new ArrayList<String>(keys));
String paramsJson = BasicJson.toJson(registryParamVO);
// result
Map<String, Object> respObj = requestAndValid(pathUrl, paramsJson, 5);
// parse
if (respObj!=null && respObj.containsKey("data")) {
Map<String, TreeSet<String>> data = (Map<String, TreeSet<String>>) respObj.get("data");
return data;
}
return null;
}
/**
* discovery
*
* @param keys
* @return
*/
public boolean monitor(Set<String> keys) {
// valid
if (keys==null || keys.size()==0) {
throw new RuntimeException("registry keys empty");
}
// pathUrl
String pathUrl = "/api/monitor";
// param
RegistryParamVO registryParamVO = new RegistryParamVO();
registryParamVO.setAccessToken(this.accessToken);
registryParamVO.setBiz(this.biz);
registryParamVO.setEnv(this.env);
registryParamVO.setKeys(new ArrayList<String>(keys));
String paramsJson = BasicJson.toJson(registryParamVO);
// result
Map<String, Object> respObj = requestAndValid(pathUrl, paramsJson, 60);
return respObj!=null?true:false;
}
}
package com.byit.registry.client;
import com.byit.registry.client.model.RegistryDataParamVO;
import com.byit.registry.client.util.json.BasicJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* registry client, auto heatbeat registry info, auto monitor discovery info
*
*/
public class RegistryClient {
private static Logger logger = LoggerFactory.getLogger(RegistryClient.class);
private volatile Set<RegistryDataParamVO> registryData = new HashSet<>();
private volatile ConcurrentMap<String, TreeSet<String>> discoveryData = new ConcurrentHashMap<>();
private Thread registryThread;
private Thread discoveryThread;
private volatile boolean registryThreadStop = false;
private RegistryBaseClient registryBaseClient;
public RegistryClient(String adminAddress, String accessToken, String biz, String env) {
registryBaseClient = new RegistryBaseClient(adminAddress, accessToken, biz, env);
logger.info(">>>>>>>>>>> registry, RegistryClient init .... [adminAddress={}, accessToken={}, biz={}, env={}]", adminAddress, accessToken, biz, env);
// registry thread
registryThread = new Thread(new Runnable() {
@Override
public void run() {
while (!registryThreadStop) {
try {
if (registryData.size() > 0) {
boolean ret = registryBaseClient.registry(new ArrayList<RegistryDataParamVO>(registryData));
logger.debug(">>>>>>>>>>> registry, refresh registry data {}, registryData = {}", ret?"success":"fail",registryData);
}
} catch (Exception e) {
if (!registryThreadStop) {
logger.error(">>>>>>>>>>> registry, registryThread error.", e);
}
}
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
if (!registryThreadStop) {
logger.error(">>>>>>>>>>> registry, registryThread error.", e);
}
}
}
logger.info(">>>>>>>>>>> registry, registryThread stoped.");
}
});
registryThread.setName("registry, RegistryClient registryThread.");
registryThread.setDaemon(true);
registryThread.start();
// discovery thread
discoveryThread = new Thread(new Runnable() {
@Override
public void run() {
while (!registryThreadStop) {
if (discoveryData.size() == 0) {
try {
TimeUnit.SECONDS.sleep(3);
} catch (Exception e) {
if (!registryThreadStop) {
logger.error(">>>>>>>>>>> registry, discoveryThread error.", e);
}
}
} else {
try {
// monitor
boolean monitorRet = registryBaseClient.monitor(discoveryData.keySet());
// avoid fail-retry request too quick
if (!monitorRet){
TimeUnit.SECONDS.sleep(10);
}
// refreshDiscoveryData, all
refreshDiscoveryData(discoveryData.keySet());
} catch (Exception e) {
if (!registryThreadStop) {
logger.error(">>>>>>>>>>> registry, discoveryThread error.", e);
}
}
}
}
logger.info(">>>>>>>>>>> registry, discoveryThread stoped.");
}
});
discoveryThread.setName("registry, RegistryClient discoveryThread.");
discoveryThread.setDaemon(true);
discoveryThread.start();
logger.info(">>>>>>>>>>> registry, RegistryClient init success.");
}
public void stop() {
registryThreadStop = true;
if (registryThread != null) {
registryThread.interrupt();
}
if (discoveryThread != null) {
discoveryThread.interrupt();
}
}
/**
* registry
*
* @param registryDataList
* @return
*/
public boolean registry(List<RegistryDataParamVO> registryDataList){
// valid
if (registryDataList==null || registryDataList.size()==0) {
throw new RuntimeException("registry registryDataList empty");
}
for (RegistryDataParamVO registryParam: registryDataList) {
if (registryParam.getKey()==null || registryParam.getKey().trim().length()<4 || registryParam.getKey().trim().length()>255) {
throw new RuntimeException("registry registryDataList#key Invalid[4~255]");
}
if (registryParam.getValue()==null || registryParam.getValue().trim().length()<4 || registryParam.getValue().trim().length()>255) {
throw new RuntimeException("registry registryDataList#value Invalid[4~255]");
}
}
// cache
registryData.addAll(registryDataList);
// remote
registryBaseClient.registry(registryDataList);
return true;
}
/**
* remove
*
* @param registryDataList
* @return
*/
public boolean remove(List<RegistryDataParamVO> registryDataList) {
// valid
if (registryDataList==null || registryDataList.size()==0) {
throw new RuntimeException("registry registryDataList empty");
}
for (RegistryDataParamVO registryParam: registryDataList) {
if (registryParam.getKey()==null || registryParam.getKey().trim().length()<4 || registryParam.getKey().trim().length()>255) {
throw new RuntimeException("registry registryDataList#key Invalid[4~255]");
}
if (registryParam.getValue()==null || registryParam.getValue().trim().length()<4 || registryParam.getValue().trim().length()>255) {
throw new RuntimeException("registry registryDataList#value Invalid[4~255]");
}
}
// cache
registryData.removeAll(registryDataList);
// remote
registryBaseClient.remove(registryDataList);
return true;
}
/**
* discovery
*
* @param keys
* @return
*/
public Map<String, TreeSet<String>> discovery(Set<String> keys) {
if (keys==null || keys.size() == 0) {
return null;
}
// find from local
Map<String, TreeSet<String>> registryDataTmp = new HashMap<String, TreeSet<String>>();
for (String key : keys) {
TreeSet<String> valueSet = discoveryData.get(key);
if (valueSet != null) {
registryDataTmp.put(key, valueSet);
}
}
// not find all, find from remote
if (keys.size() != registryDataTmp.size()) {
// refreshDiscoveryData, some, first use
refreshDiscoveryData(keys);
// find from local
for (String key : keys) {
TreeSet<String> valueSet = discoveryData.get(key);
if (valueSet != null) {
registryDataTmp.put(key, valueSet);
}
}
}
return registryDataTmp;
}
/**
* refreshDiscoveryData, some or all
*/
private void refreshDiscoveryData(Set<String> keys){
if (keys==null || keys.size() == 0) {
return;
}
// discovery mult
Map<String, TreeSet<String>> updatedData = new HashMap<>();
Map<String, TreeSet<String>> keyValueListData = registryBaseClient.discovery(keys);
if (keyValueListData!=null) {
for (String keyItem: keyValueListData.keySet()) {
// list > set
TreeSet<String> valueSet = new TreeSet<>();
valueSet.addAll(keyValueListData.get(keyItem));
// valid if updated
boolean updated = true;
TreeSet<String> oldValSet = discoveryData.get(keyItem);
if (oldValSet!=null && BasicJson.toJson(oldValSet).equals(BasicJson.toJson(valueSet))) {
updated = false;
}
// set
if (updated) {
discoveryData.put(keyItem, valueSet);
updatedData.put(keyItem, valueSet);
}
}
}
if (updatedData.size() > 0) {
logger.info(">>>>>>>>>>> registry, refresh discovery data finish, discoveryData(updated) = {}", updatedData);
}
logger.debug(">>>>>>>>>>> registry, refresh discovery data finish, discoveryData = {}", discoveryData);
}
public TreeSet<String> discovery(String key) {
if (key==null) {
return null;
}
Map<String, TreeSet<String>> keyValueSetTmp = discovery(new HashSet<String>(Arrays.asList(key)));
if (keyValueSetTmp != null) {
return keyValueSetTmp.get(key);
}
return null;
}
}
package com.byit.registry.client.model;
import java.util.Objects;
public class RegistryDataParamVO {
private String key;
private String value;
public RegistryDataParamVO() {
}
public RegistryDataParamVO(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RegistryDataParamVO that = (RegistryDataParamVO) o;
return Objects.equals(key, that.key) &&
Objects.equals(value, that.value);
}
@Override
public int hashCode() {
return Objects.hash(key, value);
}
@Override
public String toString() {
return "RegistryDataParamVO{" +
"key='" + key + '\'' +
", value='" + value + '\'' +
'}';
}
}
package com.byit.registry.client.model;
import java.util.List;
public class RegistryParamVO {
private String accessToken;
private String biz;
private String env;
private List<RegistryDataParamVO> registryDataList;
private List<String> keys;
public String getBiz() {
return biz;
}
public void setBiz(String biz) {
this.biz = biz;
}
public String getEnv() {
return env;
}
public void setEnv(String env) {
this.env = env;
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public List<RegistryDataParamVO> getRegistryDataList() {
return registryDataList;
}
public void setRegistryDataList(List<RegistryDataParamVO> registryDataList) {
this.registryDataList = registryDataList;
}
public List<String> getKeys() {
return keys;
}
public void setKeys(List<String> keys) {
this.keys = keys;
}
}
package com.byit.registry.client.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class BasicHttpUtil {
private static Logger logger = LoggerFactory.getLogger(BasicHttpUtil.class);
/**
* post
*
* @param url
* @param requestBody
* @param timeout
* @return
*/
public static String postBody(String url, String requestBody, int timeout) {
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
try {
// connection
URL realUrl = new URL(url);
connection = (HttpURLConnection) realUrl.openConnection();
// connection setting
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setReadTimeout(timeout * 1000);
connection.setConnectTimeout(3 * 1000);
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
// do connection
connection.connect();
// write requestBody
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
dataOutputStream.writeBytes(requestBody);
dataOutputStream.flush();
dataOutputStream.close();
/*byte[] requestBodyBytes = requestBody.getBytes("UTF-8");
connection.setRequestProperty("Content-Length", String.valueOf(requestBodyBytes.length));
OutputStream outwritestream = connection.getOutputStream();
outwritestream.write(requestBodyBytes);
outwritestream.flush();
outwritestream.close();*/
// valid StatusCode
int statusCode = connection.getResponseCode();
if (statusCode != 200) {
throw new RuntimeException("http request StatusCode("+ statusCode +") invalid. for url : " + url);
}
// result
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
return result.toString();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (connection != null) {
connection.disconnect();
}
} catch (Exception e2) {
logger.error(e2.getMessage(), e2);
}
}
return null;
}
/**
* get
*
* @param url
* @param timeout second
* @return
*/
public static String get(String url, int timeout) {
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
try {
// connection
URL realUrl = new URL(url);
connection = (HttpURLConnection) realUrl.openConnection();
// connection setting
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setReadTimeout(timeout * 1000);
connection.setConnectTimeout(3 * 1000);
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
// do connection
connection.connect();
//Map<String, List<String>> map = connection.getHeaderFields();
// valid StatusCode
int statusCode = connection.getResponseCode();
if (statusCode != 200) {
throw new RuntimeException("Http Request StatusCode("+ statusCode +") Invalid.");
}
// result
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
return result.toString();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (connection != null) {
connection.disconnect();
}
} catch (Exception e2) {
logger.error(e2.getMessage(), e2);
}
}
return null;
}
}
package com.byit.registry.client.util.json;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BasicJson {
private static final BasicJsonReader basicJsonReader = new BasicJsonReader();
private static final BasicJsonwriter basicJsonwriter = new BasicJsonwriter();
/**
* object to json
*
* @param object
* @return
*/
public static String toJson(Object object) {
return basicJsonwriter.toJson(object);
}
/**
* parse json to map
*
* @param json
* @return only for filed type "null、ArrayList、LinkedHashMap、String、Long、Double、..."
*/
public static Map<String, Object> parseMap(String json) {
return basicJsonReader.parseMap(json);
}
/**
* json to List
*
* @param json
* @return
*/
public static List<Object> parseList(String json) {
return basicJsonReader.parseList(json);
}
public static void main(String[] args) {
Map<String, Object> result = new HashMap<>();
result.put("code", 200);
result.put("msg", "success");
result.put("arr", Arrays.asList("111","222"));
result.put("float", 1.11f);
result.put("temp", null);
String json = toJson(result);
System.out.println(json);
Map<String, Object> mapObj = parseMap(json);
System.out.println(mapObj);
List<Object> listInt = parseList("[111,222,33]");
System.out.println(listInt);
}
}
package com.byit.registry.client.util.json;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class BasicJsonReader {
public Map<String, Object> parseMap(String json) {
if (json != null) {
json = json.trim();
if (json.startsWith("{")) {
return parseMapInternal(json);
}
}
throw new IllegalArgumentException("Cannot parse JSON");
}
public List<Object> parseList(String json) {
if (json != null) {
json = json.trim();
if (json.startsWith("[")) {
return parseListInternal(json);
}
}
throw new IllegalArgumentException("Cannot parse JSON");
}
private List<Object> parseListInternal(String json) {
List<Object> list = new ArrayList<Object>();
json = trimLeadingCharacter(trimTrailingCharacter(json, ']'), '[');
for (String value : tokenize(json)) {
list.add(parseInternal(value));
}
return list;
}
private Object parseInternal(String json) {
if (json.equals("null")) {
return null;
}
if (json.startsWith("[")) {
return parseListInternal(json);
}
if (json.startsWith("{")) {
return parseMapInternal(json);
}
if (json.startsWith("\"")) {
return trimTrailingCharacter(trimLeadingCharacter(json, '"'), '"');
}
try {
return Long.valueOf(json);
}
catch (NumberFormatException ex) {
// ignore
}
try {
return Double.valueOf(json);
}
catch (NumberFormatException ex) {
// ignore
}
return json;
}
private Map<String, Object> parseMapInternal(String json) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
json = trimLeadingCharacter(trimTrailingCharacter(json, '}'), '{');
for (String pair : tokenize(json)) {
String[] values = trimArrayElements(split(pair, ":"));
String key = trimLeadingCharacter(trimTrailingCharacter(values[0], '"'), '"');
Object value = parseInternal(values[1]);
map.put(key, value);
}
return map;
}
// append start
private static String[] split(String toSplit, String delimiter) {
if (toSplit!=null && !toSplit.isEmpty() && delimiter!=null && !delimiter.isEmpty()) {
int offset = toSplit.indexOf(delimiter);
if (offset < 0) {
return null;
} else {
String beforeDelimiter = toSplit.substring(0, offset);
String afterDelimiter = toSplit.substring(offset + delimiter.length());
return new String[]{beforeDelimiter, afterDelimiter};
}
} else {
return null;
}
}
private static String[] trimArrayElements(String[] array) {
if (array == null || array.length == 0) {
return new String[0];
} else {
String[] result = new String[array.length];
for(int i = 0; i < array.length; ++i) {
String element = array[i];
result[i] = element != null ? element.trim() : null;
}
return result;
}
}
// append end
private List<String> tokenize(String json) {
List<String> list = new ArrayList<String>();
int index = 0;
int inObject = 0;
int inList = 0;
boolean inValue = false;
boolean inEscape = false;
StringBuilder build = new StringBuilder();
while (index < json.length()) {
char current = json.charAt(index);
if (inEscape) {
build.append(current);
index++;
inEscape = false;
continue;
}
if (current == '{') {
inObject++;
}
if (current == '}') {
inObject--;
}
if (current == '[') {
inList++;
}
if (current == ']') {
inList--;
}
if (current == '"') {
inValue = !inValue;
}
if (current == ',' && inObject == 0 && inList == 0 && !inValue) {
list.add(build.toString());
build.setLength(0);
}
else if (current == '\\') {
inEscape = true;
}
else {
build.append(current);
}
index++;
}
if (build.length() > 0) {
list.add(build.toString());
}
return list;
}
// plugin util
private static String trimTrailingCharacter(String string, char c) {
if (string.length() > 0 && string.charAt(string.length() - 1) == c) {
return string.substring(0, string.length() - 1);
}
return string;
}
private static String trimLeadingCharacter(String string, char c) {
if (string.length() > 0 && string.charAt(0) == c) {
return string.substring(1);
}
return string;
}
}
package com.byit.registry.client.util.json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
public class BasicJsonwriter {
private static Logger logger = LoggerFactory.getLogger(BasicJsonwriter.class);
private static final String STR_SLASH = "\"";
private static final String STR_SLASH_STR = "\":";
private static final String STR_COMMA = ",";
private static final String STR_OBJECT_LEFT = "{";
private static final String STR_OBJECT_RIGHT = "}";
private static final String STR_ARRAY_LEFT = "[";
private static final String STR_ARRAY_RIGHT = "]";
private static final Map<String, Field[]> cacheFields = new HashMap<>();
/**
* write object to json
*
* @param object
* @return
*/
public String toJson(Object object) {
StringBuilder json = new StringBuilder();
try {
writeObjItem(null, object, json);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
// replace
String str = json.toString();
if (str.contains("\n")) {
str = str.replaceAll("\\n", "\\\\n");
}
if (str.contains("\t")) {
str = str.replaceAll("\\t", "\\\\t");
}
if (str.contains("\r")) {
str = str.replaceAll("\\r", "\\\\r");
}
return str;
}
/**
* append Obj
*
* @param key
* @param value
* @param json "key":value or value
*/
private void writeObjItem(String key, Object value, StringBuilder json) {
/*if ("serialVersionUID".equals(key)
|| value instanceof Logger) {
// pass
return;
}*/
// "key:"
if (key != null) {
json.append(STR_SLASH).append(key).append(STR_SLASH_STR);
}
// val
if (value == null) {
json.append("null");
} else if (value instanceof String
|| value instanceof Byte
|| value instanceof CharSequence) {
// string
json.append(STR_SLASH).append(value.toString()).append(STR_SLASH);
} else if ( value instanceof Boolean
|| value instanceof Short
|| value instanceof Integer
|| value instanceof Long
|| value instanceof Float
|| value instanceof Double
) {
// number
json.append(value);
} else if (value instanceof Object[] || value instanceof Collection) {
// collection | array // Array.getLength(array); // Array.get(array, i);
Collection valueColl = null;
if (value instanceof Object[]) {
Object[] valueArr = (Object[]) value;
valueColl = Arrays.asList(valueArr);
} else if (value instanceof Collection) {
valueColl = (Collection) value;
}
json.append(STR_ARRAY_LEFT);
if (valueColl.size() > 0) {
for (Object obj : valueColl) {
writeObjItem(null, obj, json);
json.append(STR_COMMA);
}
json.delete(json.length() - 1, json.length());
}
json.append(STR_ARRAY_RIGHT);
} else if (value instanceof Map) {
// map
Map<?, ?> valueMap = (Map<?, ?>) value;
json.append(STR_OBJECT_LEFT);
if (!valueMap.isEmpty()) {
Set<?> keys = valueMap.keySet();
for (Object valueMapItemKey : keys) {
writeObjItem(valueMapItemKey.toString(), valueMap.get(valueMapItemKey), json);
json.append(STR_COMMA);
}
json.delete(json.length() - 1, json.length());
}
json.append(STR_OBJECT_RIGHT);
} else {
// bean
json.append(STR_OBJECT_LEFT);
Field[] fields = getDeclaredFields(value.getClass());
if (fields.length > 0) {
for (Field field : fields) {
Object fieldObj = getFieldObject(field, value);
writeObjItem(field.getName(), fieldObj, json);
json.append(STR_COMMA);
}
json.delete(json.length() - 1, json.length());
}
json.append(STR_OBJECT_RIGHT);
}
}
public synchronized Field[] getDeclaredFields(Class<?> clazz) {
String cacheKey = clazz.getName();
if (cacheFields.containsKey(cacheKey)) {
return cacheFields.get(cacheKey);
}
Field[] fields = getAllDeclaredFields(clazz); //clazz.getDeclaredFields();
cacheFields.put(cacheKey, fields);
return fields;
}
private Field[] getAllDeclaredFields(Class<?> clazz) {
List<Field> list = new ArrayList<Field>();
Class<?> current = clazz;
while (current != null && current != Object.class) {
Field[] fields = current.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
continue;
}
list.add(field);
}
current = current.getSuperclass();
}
return list.toArray(new Field[list.size()]);
}
private synchronized Object getFieldObject(Field field, Object obj) {
try {
field.setAccessible(true);
return field.get(obj);
} catch (IllegalArgumentException | IllegalAccessException e) {
logger.error(e.getMessage(), e);
return null;
} finally {
field.setAccessible(false);
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>byit-myth-register</artifactId>
<groupId>myth-job</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>myth-register-server</artifactId>
<packaging>jar</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- starter-web:spring-webmvc + autoconfigure + logback + yaml + tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- starter-test:junit + spring-test + mockito -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- freemarker-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- mybatis-starter:mybatis + mybatis-spring + tomcat-jdbc(default) -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
<dependency>
<groupId>myth-job</groupId>
<artifactId>myth-register-client</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- docker -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<!-- made of '[a-z0-9-_.]' -->
<imageName>${project.artifactId}:${project.version}</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.byit.registry.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RegistryAdminApplication {
public static void main(String[] args) {
SpringApplication.run(RegistryAdminApplication.class, args);
}
}
\ No newline at end of file
package com.byit.registry.admin.controller;
import com.byit.registry.admin.controller.annotation.PermessionLimit;
import com.byit.registry.admin.core.model.RegistryData;
import com.byit.registry.admin.core.result.ReturnT;
import com.byit.registry.admin.core.util.JacksonUtil;
import com.byit.registry.admin.service.IRegistryService;
import com.byit.registry.client.model.RegistryDataParamVO;
import com.byit.registry.client.model.RegistryParamVO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/api")
public class ApiController {
@Resource
private IRegistryService registryService;
/**
* 服务注册 & 续约 API
*
* 说明:新服务注册上线1s内广播通知接入方;需要接入方循环续约,否则服务将会过期(三倍于注册中心心跳时间)下线;
*
* ------
* 地址格式:{服务注册中心跟地址}/registry
*
* 请求参数说明:
* 1、accessToken:请求令牌;
* 2、biz:业务标识
* 2、env:环境标识
* 3、registryDataList:服务注册信息
*
* 请求数据格式如下,放置在 RequestBody 中,JSON格式:
*
* {
* "accessToken" : "xx",
* "biz" : "xx",
* "env" : "xx",
* "registryDataList" : [{
* "key" : "service01",
* "value" : "address01"
* }]
* }
*
* @param data
* @return
*/
@RequestMapping("/registry")
@ResponseBody
@PermessionLimit(limit=false)
public ReturnT<String> registry(@RequestBody(required = false) String data){
// parse data
RegistryParamVO registryParamVO = null;
try {
registryParamVO = JacksonUtil.readValue(data, RegistryParamVO.class);
} catch (Exception e) {
System.out.print(e);
}
// parse param
String accessToken = null;
String biz = null;
String env = null;
List<RegistryData> registryDataList = null;
if (registryParamVO != null) {
accessToken = registryParamVO.getAccessToken();
biz = registryParamVO.getBiz();
env = registryParamVO.getEnv();
if (registryParamVO.getRegistryDataList()!=null) {
registryDataList = new ArrayList<>();
for (RegistryDataParamVO dataParamVO: registryParamVO.getRegistryDataList()) {
RegistryData dateItem = new RegistryData();
dateItem.setKey(dataParamVO.getKey());
dateItem.setValue(dataParamVO.getValue());
registryDataList.add(dateItem);
}
}
}
return registryService.registry(accessToken, biz, env, registryDataList);
}
/**
* 服务摘除 API
*
* 说明:新服务摘除下线1s内广播通知接入方;
*
* ------
* 地址格式:{服务注册中心跟地址}/remove
*
* 请求参数说明:
* 1、accessToken:请求令牌;
* 2、biz:业务标识
* 2、env:环境标识
* 3、registryDataList:服务注册信息
*
* 请求数据格式如下,放置在 RequestBody 中,JSON格式:
*
* {
* "accessToken" : "xx",
* "biz" : "xx",
* "env" : "xx",
* "registryDataList" : [{
* "key" : "service01",
* "value" : "address01"
* }]
* }
*
* @param data
* @return
*/
@RequestMapping("/remove")
@ResponseBody
@PermessionLimit(limit=false)
public ReturnT<String> remove(@RequestBody(required = false) String data){
// parse data
RegistryParamVO registryParamVO = null;
try {
registryParamVO = JacksonUtil.readValue(data, RegistryParamVO.class);
} catch (Exception e) { }
// parse param
String accessToken = null;
String biz = null;
String env = null;
List<RegistryData> registryDataList = null;
if (registryParamVO != null) {
accessToken = registryParamVO.getAccessToken();
biz = registryParamVO.getBiz();
env = registryParamVO.getEnv();
if (registryParamVO.getRegistryDataList()!=null) {
registryDataList = new ArrayList<>();
for (RegistryDataParamVO dataParamVO: registryParamVO.getRegistryDataList()) {
RegistryData dateItem = new RegistryData();
dateItem.setKey(dataParamVO.getKey());
dateItem.setValue(dataParamVO.getValue());
registryDataList.add(dateItem);
}
}
}
return registryService.remove(accessToken, biz, env, registryDataList);
}
/**
* 服务发现 API
*
* 说明:查询在线服务地址列表;
*
* ------
* 地址格式:{服务注册中心跟地址}/discovery
*
* 请求参数说明:
* 1、accessToken:请求令牌;
* 2、biz:业务标识
* 2、env:环境标识
* 3、keys:服务注册Key列表
*
* 请求数据格式如下,放置在 RequestBody 中,JSON格式:
*
* {
* "accessToken" : "xx",
* "biz" : "xx",
* "env" : "xx",
* "keys" : [
* "service01",
* "service02"
* ]
* }
*
* @param data
* @return
*/
@RequestMapping("/discovery")
@ResponseBody
@PermessionLimit(limit=false)
public ReturnT<Map<String, List<String>>> discovery(@RequestBody(required = false) String data) {
// parse data
RegistryParamVO registryParamVO = null;
try {
registryParamVO = JacksonUtil.readValue(data, RegistryParamVO.class);
} catch (Exception e) {
System.out.println(e);
}
// parse param
String accessToken = null;
String biz = null;
String env = null;
List<String> keys = null;
if (registryParamVO != null) {
accessToken = registryParamVO.getAccessToken();
biz = registryParamVO.getBiz();
env = registryParamVO.getEnv();
keys = registryParamVO.getKeys();
}
return registryService.discovery(accessToken, biz, env, keys);
}
/**
* 服务监控 API
*
* 说明:long-polling 接口,主动阻塞一段时间(三倍于注册中心心跳时间);直至阻塞超时或服务注册信息变动时响应;
*
* ------
* 地址格式:{服务注册中心跟地址}/monitor
*
* 请求参数说明:
* 1、accessToken:请求令牌;
* 2、biz:业务标识
* 2、env:环境标识
* 3、keys:服务注册Key列表
*
* 请求数据格式如下,放置在 RequestBody 中,JSON格式:
*
* {
* "accessToken" : "xx",
* "biz" : "xx",
* "env" : "xx",
* "keys" : [
* "service01",
* "service02"
* ]
* }
*
* @param data
* @return
*/
@RequestMapping("/monitor")
@ResponseBody
@PermessionLimit(limit=false)
public DeferredResult monitor(@RequestBody(required = false) String data) {
// parse data
RegistryParamVO registryParamVO = null;
try {
registryParamVO = JacksonUtil.readValue(data, RegistryParamVO.class);
} catch (Exception e) {
System.out.println(e);
}
// parse param
String accessToken = null;
String biz = null;
String env = null;
List<String> keys = null;
if (registryParamVO != null) {
accessToken = registryParamVO.getAccessToken();
biz = registryParamVO.getBiz();
env = registryParamVO.getEnv();
keys = registryParamVO.getKeys();
}
return registryService.monitor(accessToken, biz, env, keys);
}
}
package com.byit.registry.admin.controller;
import com.byit.registry.admin.controller.annotation.PermessionLimit;
import com.byit.registry.admin.controller.interceptor.PermissionInterceptor;
import com.byit.registry.admin.core.result.ReturnT;
import com.byit.registry.admin.dao.IRegistryDao;
import com.byit.registry.admin.dao.IRegistryDataDao;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class IndexController {
@Resource
private IRegistryDao registryDao;
@Resource
private IRegistryDataDao registryDataDao;
@RequestMapping("/")
public String index(Model model, HttpServletRequest request) {
int registryNum = registryDao.pageListCount(0, 1, null, null, null);
int registryDataNum = registryDataDao.count();
model.addAttribute("registryNum", registryNum);
model.addAttribute("registryDataNum", registryDataNum);
return "index";
}
@RequestMapping("/toLogin")
@PermessionLimit(limit=false)
public String toLogin(Model model, HttpServletRequest request) {
if (PermissionInterceptor.ifLogin(request)) {
return "redirect:/";
}
return "login";
}
@RequestMapping(value="login", method=RequestMethod.POST)
@ResponseBody
@PermessionLimit(limit=false)
public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){
// valid
if (PermissionInterceptor.ifLogin(request)) {
return ReturnT.SUCCESS;
}
// param
if (userName==null || userName.trim().length()==0 || password==null || password.trim().length()==0){
return new ReturnT<>(500, "请输入账号密码");
}
boolean ifRem = (ifRemember!=null && "on".equals(ifRemember))?true:false;
// do login
boolean loginRet = PermissionInterceptor.login(response, userName, password, ifRem);
if (!loginRet) {
return new ReturnT<>(500, "账号密码错误");
}
return ReturnT.SUCCESS;
}
@RequestMapping(value="logout", method=RequestMethod.POST)
@ResponseBody
@PermessionLimit(limit=false)
public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){
if (PermissionInterceptor.ifLogin(request)) {
PermissionInterceptor.logout(request, response);
}
return ReturnT.SUCCESS;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
}
package com.byit.registry.admin.controller;
import com.byit.registry.admin.core.model.Registry;
import com.byit.registry.admin.core.result.ReturnT;
import com.byit.registry.admin.service.IRegistryService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.Map;
@Controller
@RequestMapping("/registry")
public class RegistryController {
@Resource
private IRegistryService registryService;
@RequestMapping("")
public String index(Model model){
return "registry/registry.index";
}
@RequestMapping("/pageList")
@ResponseBody
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length,
String biz,
String env,
String key){
return registryService.pageList(start, length, biz, env, key);
}
@RequestMapping("/delete")
@ResponseBody
public ReturnT<String> delete(int id){
return registryService.delete(id);
}
@RequestMapping("/update")
@ResponseBody
public ReturnT<String> update(Registry registry){
return registryService.update(registry);
}
@RequestMapping("/add")
@ResponseBody
public ReturnT<String> add(Registry registry){
return registryService.add(registry);
}
}
package com.byit.registry.admin.controller.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限限制
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermessionLimit {
/**
* 登陆拦截 (默认拦截)
*/
boolean limit() default true;
}
\ No newline at end of file
package com.byit.registry.admin.controller.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
/**
* push cookies to model as cookieMap
*
*/
@Component
public class CookieInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
if (modelAndView!=null && request.getCookies()!=null && request.getCookies().length>0) {
HashMap<String, Cookie> cookieMap = new HashMap<String, Cookie>();
for (Cookie ck : request.getCookies()) {
cookieMap.put(ck.getName(), ck);
}
modelAndView.addObject("cookieMap", cookieMap);
}
super.postHandle(request, response, handler, modelAndView);
}
}
package com.byit.registry.admin.controller.interceptor;
import com.byit.registry.admin.controller.annotation.PermessionLimit;
import com.byit.registry.admin.core.util.CookieUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigInteger;
/**
* 权限拦截, 简易版
*
*/
@Component
public class PermissionInterceptor extends HandlerInterceptorAdapter implements InitializingBean {
// ---------------------- init ----------------------
@Value("${byit.registry.login.username}")
private String username;
@Value("${byit.registry.login.password}")
private String password;
@Override
public void afterPropertiesSet() throws Exception {
// valid
if (username==null || username.trim().length()==0 || password==null || password.trim().length()==0) {
throw new RuntimeException("权限账号密码不可为空");
}
// login token
String tokenTmp = DigestUtils.md5DigestAsHex(String.valueOf(username + "_" + password).getBytes()); //.getBytes("UTF-8")
tokenTmp = new BigInteger(1, tokenTmp.getBytes()).toString(16);
LOGIN_IDENTITY_TOKEN = tokenTmp;
}
// ---------------------- tool ----------------------
public static final String LOGIN_IDENTITY_KEY = "MQ_LOGIN_IDENTITY";
private static String LOGIN_IDENTITY_TOKEN;
public static String getLoginIdentityToken() {
return LOGIN_IDENTITY_TOKEN;
}
public static boolean login(HttpServletResponse response, String username, String password, boolean ifRemember){
// login token
String tokenTmp = DigestUtils.md5DigestAsHex(String.valueOf(username + "_" + password).getBytes());
tokenTmp = new BigInteger(1, tokenTmp.getBytes()).toString(16);
if (!getLoginIdentityToken().equals(tokenTmp)){
return false;
}
// do login
CookieUtil.set(response, LOGIN_IDENTITY_KEY, getLoginIdentityToken(), ifRemember);
return true;
}
public static void logout(HttpServletRequest request, HttpServletResponse response){
CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
}
public static boolean ifLogin(HttpServletRequest request){
String indentityInfo = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
if (indentityInfo==null || !getLoginIdentityToken().equals(indentityInfo.trim())) {
return false;
}
return true;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return super.preHandle(request, response, handler);
}
if (!ifLogin(request)) {
HandlerMethod method = (HandlerMethod)handler;
PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
if (permission == null || permission.limit()) {
response.sendRedirect(request.getContextPath() + "/toLogin");
//request.getRequestDispatcher("/toLogin").forward(request, response);
return false;
}
}
return super.preHandle(request, response, handler);
}
}
package com.byit.registry.admin.controller.interceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.annotation.Resource;
/**
* web mvc config
*
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Resource
private PermissionInterceptor permissionInterceptor;
@Resource
private CookieInterceptor cookieInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(permissionInterceptor).addPathPatterns("/**");
registry.addInterceptor(cookieInterceptor).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
\ No newline at end of file
package com.byit.registry.admin.controller.resolver;
import com.byit.registry.admin.core.result.ReturnT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* common exception resolver
*
*/
@Component
public class MqExceptionResolver implements HandlerExceptionResolver {
private static transient Logger logger = LoggerFactory.getLogger(MqExceptionResolver.class);
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
logger.error("MqExceptionResolver:", ex);
// if json
boolean isJson = false;
HandlerMethod method = (HandlerMethod)handler;
ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
if (responseBody != null) {
isJson = true;
}
// error result
ReturnT<String> errorResult = new ReturnT<String>(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "<br/>"));
// response
ModelAndView mv = new ModelAndView();
if (isJson) {
try {
response.setContentType("application/json;charset=utf-8");
response.getWriter().print("{\"code\":"+errorResult.getCode()+", \"msg\":\""+ errorResult.getMsg() +"\"}");
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return mv;
} else {
mv.addObject("exceptionMsg", errorResult.getMsg());
mv.setViewName("/common/common.exception");
return mv;
}
}
}
\ No newline at end of file
package com.byit.registry.admin.core.model;
import java.util.List;
public class Registry {
private int id;
private String biz; // 业务标识
private String env; // 环境标识
private String key; // 注册Key
private String data; // 注册Value有效数据
private int status; // 状态:0-正常、1-锁定、2-禁用
// plugin
private List<String> dataList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBiz() {
return biz;
}
public void setBiz(String biz) {
this.biz = biz;
}
public String getEnv() {
return env;
}
public void setEnv(String env) {
this.env = env;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public List<String> getDataList() {
return dataList;
}
public void setDataList(List<String> dataList) {
this.dataList = dataList;
}
}
package com.byit.registry.admin.core.model;
import java.util.Date;
public class RegistryData {
private int id;
private String biz; // 业务标识
private String env; // 环境标识
private String key; // 注册Key
private String value; // 注册Value
private Date updateTime; // 更新时间
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBiz() {
return biz;
}
public void setBiz(String biz) {
this.biz = biz;
}
public String getEnv() {
return env;
}
public void setEnv(String env) {
this.env = env;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
package com.byit.registry.admin.core.model;
import java.util.Date;
public class RegistryMessage {
private int id;
private int type; // 消息类型:0-注册更新
private String data; // 消息内容
private Date addTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Date getAddTime() {
return addTime;
}
public void setAddTime(Date addTime) {
this.addTime = addTime;
}
}
package com.byit.registry.admin.core.result;
import java.io.Serializable;
/**
* 封装返回
*
* @param <T>
*/
public class ReturnT<T> implements Serializable {
public static final long serialVersionUID = 42L;
public static final int SUCCESS_CODE = 200;
public static final int FAIL_CODE = 500;
public static final ReturnT<String> SUCCESS = new ReturnT<String>(null);
public static final ReturnT<String> FAIL = new ReturnT<String>(FAIL_CODE, null);
private int code;
private String msg;
private T data;
public ReturnT(){}
public ReturnT(int code, String msg) {
this.code = code;
this.msg = msg;
}
public ReturnT(T data) {
this.code = SUCCESS_CODE;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "ReturnT [code=" + code + ", msg=" + msg + ", data=" + data + "]";
}
}
package com.byit.registry.admin.core.util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie.Util
*
*/
public class CookieUtil {
// 默认缓存时间,单位/秒, 2H
private static final int COOKIE_MAX_AGE = Integer.MAX_VALUE;
// 保存路径,根路径
private static final String COOKIE_PATH = "/";
/**
* 保存
*
* @param response
* @param key
* @param value
* @param ifRemember
*/
public static void set(HttpServletResponse response, String key, String value, boolean ifRemember) {
int age = ifRemember?COOKIE_MAX_AGE:-1;
set(response, key, value, null, COOKIE_PATH, age, true);
}
/**
* 保存
*
* @param response
* @param key
* @param value
* @param maxAge
*/
private static void set(HttpServletResponse response, String key, String value, String domain, String path, int maxAge, boolean isHttpOnly) {
Cookie cookie = new Cookie(key, value);
if (domain != null) {
cookie.setDomain(domain);
}
cookie.setPath(path);
cookie.setMaxAge(maxAge);
cookie.setHttpOnly(isHttpOnly);
response.addCookie(cookie);
}
/**
* 查询value
*
* @param request
* @param key
* @return
*/
public static String getValue(HttpServletRequest request, String key) {
Cookie cookie = get(request, key);
if (cookie != null) {
return cookie.getValue();
}
return null;
}
/**
* 查询Cookie
*
* @param request
* @param key
*/
private static Cookie get(HttpServletRequest request, String key) {
Cookie[] arr_cookie = request.getCookies();
if (arr_cookie != null && arr_cookie.length > 0) {
for (Cookie cookie : arr_cookie) {
if (cookie.getName().equals(key)) {
return cookie;
}
}
}
return null;
}
/**
* 删除Cookie
*
* @param request
* @param response
* @param key
*/
public static void remove(HttpServletRequest request, HttpServletResponse response, String key) {
Cookie cookie = get(request, key);
if (cookie != null) {
set(response, key, "", null, COOKIE_PATH, 0, true);
}
}
}
\ No newline at end of file
package com.byit.registry.admin.core.util;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Jackson util
*
* 1、obj need private and set/get;
* 2、do not support inner class;
*
*/
public class JacksonUtil {
private static Logger logger = LoggerFactory.getLogger(JacksonUtil.class);
private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() {
return objectMapper;
}
/**
* bean、array、List、Map --> json
*
* @param obj
* @return json string
* @throws Exception
*/
public static String writeValueAsString(Object obj) {
try {
return getInstance().writeValueAsString(obj);
} catch (JsonGenerationException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/**
* string --> bean、Map、List(array)
*
* @param jsonStr
* @param clazz
* @return obj
* @throws Exception
*/
public static <T> T readValue(String jsonStr, Class<T> clazz) {
try {
return getInstance().readValue(jsonStr, clazz);
} catch (JsonParseException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/**
* string --> List<Bean>...
*
* @param jsonStr
* @param parametrized
* @param parameterClasses
* @param <T>
* @return
*/
public static <T> T readValue(String jsonStr, Class<?> parametrized, Class<?>... parameterClasses) {
try {
JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses);
return getInstance().readValue(jsonStr, javaType);
} catch (JsonParseException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/*public static <T> T readValueRefer(String jsonStr, Class<T> clazz) {
try {
return getInstance().readValue(jsonStr, new TypeReference<T>() { });
} catch (JsonParseException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}*/
public static void main(String[] args) {
try {
Map<String, String> map = new HashMap<String, String>();
map.put("aaa", "111");
map.put("bbb", "222");
String json = writeValueAsString(map);
System.out.println(json);
System.out.println(readValue(json, Map.class));
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
package com.byit.registry.admin.core.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URL;
import java.util.Properties;
/**
* prop util
*
*/
public class PropUtil {
private static Logger logger = LoggerFactory.getLogger(PropUtil.class);
/**
* load prop
*
* @param propertyFileName disk path when start with "file:", other classpath
* @return
*/
public static Properties loadProp(String propertyFileName) {
InputStream in = null;
try {
// load file location, disk
File file = new File(propertyFileName);
if (!file.exists()) {
return null;
}
URL url = new File(propertyFileName).toURI().toURL();
in = new FileInputStream(url.getPath());
if (in == null) {
return null;
}
Properties prop = new Properties();
prop.load(new InputStreamReader(in, "utf-8"));
return prop;
} catch (IOException e) {
logger.error(e.getMessage(), e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
return null;
}
/**
* write prop to disk
*
* @param properties
* @param filePathName
* @return
*/
public static boolean writeProp(Properties properties, String filePathName){
FileOutputStream fileOutputStream = null;
try {
// mk file
File file = new File(filePathName);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
// write data
fileOutputStream = new FileOutputStream(file, false);
properties.store(new OutputStreamWriter(fileOutputStream, "utf-8"), null);
//properties.store(new FileWriter(filePathName), null);
return true;
} catch (IOException e) {
logger.error(e.getMessage(), e);
return false;
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
}
}
package com.byit.registry.admin.dao;
import com.byit.registry.admin.core.model.Registry;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface IRegistryDao {
List<Registry> pageList(@Param("offset") int offset,
@Param("pagesize") int pagesize,
@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key);
int pageListCount(@Param("offset") int offset,
@Param("pagesize") int pagesize,
@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key);
Registry load(@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key);
Registry loadById(@Param("id") int id);
int add(@Param("registry") Registry registry);
int update(@Param("registry") Registry registry);
int delete(@Param("id") int id);
}
package com.byit.registry.admin.dao;
import com.byit.registry.admin.core.model.RegistryData;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface IRegistryDataDao {
int refresh(@Param("registryData") RegistryData registryData);
int add(@Param("registryData") RegistryData registryData);
List<RegistryData> findData(@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key);
int cleanData(@Param("timeout") int timeout);
int deleteData(@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key);
int deleteDataValue(@Param("biz") String biz,
@Param("env") String env,
@Param("key") String key,
@Param("value") String value);
int count();
}
package com.byit.registry.admin.dao;
import com.byit.registry.admin.core.model.RegistryMessage;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface IRegistryMessageDao {
int add(@Param("registryMessage") RegistryMessage registryMessage);
List<RegistryMessage> findMessage(@Param("excludeIds") List<Integer> excludeIds);
int cleanMessage(@Param("messageTimeout") int messageTimeout);
}
package com.byit.registry.admin.service;
import com.byit.registry.admin.core.model.Registry;
import com.byit.registry.admin.core.model.RegistryData;
import com.byit.registry.admin.core.result.ReturnT;
import org.springframework.web.context.request.async.DeferredResult;
import java.util.List;
import java.util.Map;
public interface IRegistryService {
// admin
Map<String,Object> pageList(int start, int length, String biz, String env, String key);
ReturnT<String> delete(int id);
ReturnT<String> update(Registry registry);
ReturnT<String> add(Registry registry);
// ------------------------ remote registry ------------------------
/**
* refresh registry-value, check update and broacase
*/
ReturnT<String> registry(String accessToken, String biz, String env, List<RegistryData> registryDataList);
/**
* remove registry-value, check update and broacase
*/
ReturnT<String> remove(String accessToken, String biz, String env, List<RegistryData> registryDataList);
/**
* discovery registry-data, read file
*/
ReturnT<Map<String, List<String>>> discovery(String accessToken, String biz, String env, List<String> keys);
/**
* monitor update
*/
DeferredResult<ReturnT<String>> monitor(String accessToken, String biz, String env, List<String> keys);
}
### web
server.port=8080
server.context-path=/myth-register
### resources
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
### myth-registry, datasource
spring.datasource.url=jdbc:mysql://cdb-29txkq14.bj.tencentcdb.com:10044/myth-registry?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=ly@$19890325
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=30
spring.datasource.tomcat.test-on-borrow=true
### myth-registry, registry data filepath
byit.registry.data.filepath=/Users/liyuan/codes/open/rpc/data/applogs/myth-registry/registrydata
### myth-registry, access token
byit.registry.accessToken=
### myth-registry, login conf
byit.registry.login.username=admin
byit.registry.login.password=123456
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="/Users/liyuan/codes/open/rpc/data/applogs/myth-registry/myth-registry-admin.log"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byit.registry.admin.dao.IRegistryDataDao" >
<resultMap id="registryData" type="com.byit.registry.admin.core.model.RegistryData" >
<result column="id" property="id" />
<result column="biz" property="biz" />
<result column="env" property="env" />
<result column="key" property="key" />
<result column="value" property="value" />
<result column="updateTime" property="updateTime" />
</resultMap>
<sql id="Base_Column_List">
t.`id`,
t.`biz`,
t.`env`,
t.`key`,
t.`value`,
t.`updateTime`
</sql>
<update id="refresh" parameterType="com.byit.registry.admin.core.model.RegistryData" >
UPDATE myth_registry_data AS t
SET
t.`updateTime` = now()
WHERE t.`biz` = #{registryData.biz}
and t.`env` = #{registryData.env}
and t.`key` = #{registryData.key}
and t.`value` = #{registryData.value}
</update>
<insert id="add" parameterType="com.byit.registry.admin.core.model.RegistryData" >
INSERT INTO myth_registry_data (
`biz`,
`env`,
`key`,
`value`,
`updateTime`
) VALUES
(
#{registryData.biz},
#{registryData.env},
#{registryData.key},
#{registryData.value},
now()
)
</insert>
<select id="findData" parameterType="java.util.HashMap" resultMap="registryData">
SELECT <include refid="Base_Column_List" />
FROM myth_registry_data AS t
where t.biz = #{biz}
and t.env = #{env}
and t.key = #{key}
ORDER BY t.value ASC
</select>
<delete id="cleanData" parameterType="java.util.HashMap" >
DELETE FROM myth_registry_data
WHERE NOW() <![CDATA[ > ]]> DATE_ADD(updateTime, Interval #{timeout} SECOND)
</delete>
<delete id="deleteData" parameterType="java.util.HashMap" >
DELETE FROM myth_registry_data
WHERE `biz` = #{biz}
and `env` = #{env}
and `key` = #{key}
</delete>
<delete id="deleteDataValue" parameterType="java.util.HashMap" >
DELETE FROM myth_registry_data
WHERE `biz` = #{biz}
and `env` = #{env}
and `key` = #{key}
and `value` = #{value}
</delete>
<select id="count" resultType="java.lang.Integer" >
SELECT count(1)
FROM myth_registry_data
</select>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byit.registry.admin.dao.IRegistryDao" >
<resultMap id="registry" type="com.byit.registry.admin.core.model.Registry" >
<result column="id" property="id" />
<result column="biz" property="biz" />
<result column="env" property="env" />
<result column="key" property="key" />
<result column="data" property="data" />
<result column="status" property="status" />
</resultMap>
<sql id="Base_Column_List">
t.`id`,
t.`biz`,
t.`env`,
t.`key`,
t.`data`,
t.`status`
</sql>
<select id="pageList" parameterType="java.util.HashMap" resultMap="registry">
SELECT <include refid="Base_Column_List" />
FROM myth_registry AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="biz != null and biz != ''">
AND t.biz = #{biz}
</if>
<if test="env != null and env != ''">
AND t.env = #{env}
</if>
<if test="key != null and key != ''">
AND t.key like CONCAT(CONCAT('%', #{key}), '%')
</if>
</trim>
ORDER BY t.biz ASC, t.env ASC, t.key ASC
LIMIT #{offset}, #{pagesize}
</select>
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
SELECT count(1)
FROM myth_registry AS t
<trim prefix="WHERE" prefixOverrides="AND | OR" >
<if test="biz != null and biz != ''">
AND t.biz = #{biz}
</if>
<if test="env != null and env != ''">
AND t.env = #{env}
</if>
<if test="key != null and key != ''">
AND t.key like CONCAT(CONCAT('%', #{key}), '%')
</if>
</trim>
</select>
<select id="load" parameterType="java.util.HashMap" resultMap="registry">
SELECT <include refid="Base_Column_List" />
FROM myth_registry AS t
WHERE t.`biz` = #{biz}
and t.`env` = #{env}
and t.`key` = #{key}
</select>
<select id="loadById" parameterType="java.util.HashMap" resultMap="registry">
SELECT <include refid="Base_Column_List" />
FROM myth_registry AS t
WHERE id = #{id}
</select>
<insert id="add" parameterType="com.byit.registry.admin.core.model.Registry" >
INSERT INTO myth_registry (
`biz`,
`env`,
`key`,
`data`,
`status`
) VALUES
(
#{registry.biz},
#{registry.env},
#{registry.key},
#{registry.data},
#{registry.status}
)
</insert>
<update id="update" parameterType="com.byit.registry.admin.core.model.Registry" >
UPDATE myth_registry AS t
SET
t.`data` = #{registry.data},
t.`status` = #{registry.status}
WHERE t.`id` = #{registry.id}
</update>
<delete id="delete" parameterType="java.util.HashMap" >
DELETE FROM myth_registry
WHERE id = #{id}
</delete>
</mapper>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byit.registry.admin.dao.IRegistryMessageDao" >
<resultMap id="registryMessage" type="com.byit.registry.admin.core.model.RegistryMessage" >
<result column="id" property="id" />
<result column="type" property="type" />
<result column="data" property="data" />
<result column="addTime" property="addTime" />
</resultMap>
<sql id="Base_Column_List">
t.`id`,
t.`type`,
t.`data`,
t.`addTime`
</sql>
<insert id="add" parameterType="com.byit.registry.admin.core.model.RegistryMessage" >
INSERT INTO myth_registry_message (
`type`,
`data`,
`addTime`
) VALUES
(
#{registryMessage.type},
#{registryMessage.data},
NOW()
)
</insert>
<select id="findMessage" parameterType="java.util.HashMap" resultMap="registryMessage" >
SELECT <include refid="Base_Column_List" />
FROM myth_registry_message AS t
<if test="excludeIds != null and excludeIds.size() > 0" >
where t.id not in
<foreach collection="excludeIds" item="idItem" index="index" separator="," open="(" close=")">
#{idItem}
</foreach>
</if>
ORDER BY t.id ASC
</select>
<delete id="cleanMessage" parameterType="java.util.HashMap" >
DELETE FROM myth_registry_message
WHERE NOW() <![CDATA[ > ]]> DATE_ADD(addTime, Interval #{messageTimeout} SECOND)
</delete>
</mapper>
\ No newline at end of file
/* This is a compiled file, you should be editing the file in the templates directory */
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.pace-inactive {
display: none;
}
.pace .pace-progress {
background: #2299dd;
position: fixed;
z-index: 2000;
top: 0;
right: 100%;
width: 100%;
height: 2px;
}
.pace .pace-progress-inner {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #2299dd, 0 0 5px #2299dd;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-moz-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
-o-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
.pace .pace-activity {
display: block;
position: fixed;
z-index: 2000;
top: 15px;
right: 15px;
width: 14px;
height: 14px;
border: solid 2px transparent;
border-top-color: #2299dd;
border-left-color: #2299dd;
border-radius: 10px;
-webkit-animation: pace-spinner 400ms linear infinite;
-moz-animation: pace-spinner 400ms linear infinite;
-ms-animation: pace-spinner 400ms linear infinite;
-o-animation: pace-spinner 400ms linear infinite;
animation: pace-spinner 400ms linear infinite;
}
@-webkit-keyframes pace-spinner {
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes pace-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes pace-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes pace-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes pace-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}
.daterangepicker {
position: absolute;
color: inherit;
background-color: #fff;
border-radius: 4px;
width: 278px;
padding: 4px;
margin-top: 1px;
top: 100px;
left: 20px;
/* Calendars */ }
.daterangepicker:before, .daterangepicker:after {
position: absolute;
display: inline-block;
border-bottom-color: rgba(0, 0, 0, 0.2);
content: ''; }
.daterangepicker:before {
top: -7px;
border-right: 7px solid transparent;
border-left: 7px solid transparent;
border-bottom: 7px solid #ccc; }
.daterangepicker:after {
top: -6px;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-left: 6px solid transparent; }
.daterangepicker.opensleft:before {
right: 9px; }
.daterangepicker.opensleft:after {
right: 10px; }
.daterangepicker.openscenter:before {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto; }
.daterangepicker.openscenter:after {
left: 0;
right: 0;
width: 0;
margin-left: auto;
margin-right: auto; }
.daterangepicker.opensright:before {
left: 9px; }
.daterangepicker.opensright:after {
left: 10px; }
.daterangepicker.dropup {
margin-top: -5px; }
.daterangepicker.dropup:before {
top: initial;
bottom: -7px;
border-bottom: initial;
border-top: 7px solid #ccc; }
.daterangepicker.dropup:after {
top: initial;
bottom: -6px;
border-bottom: initial;
border-top: 6px solid #fff; }
.daterangepicker.dropdown-menu {
max-width: none;
z-index: 3001; }
.daterangepicker.single .ranges, .daterangepicker.single .calendar {
float: none; }
.daterangepicker.show-calendar .calendar {
display: block; }
.daterangepicker .calendar {
display: none;
max-width: 270px;
margin: 4px; }
.daterangepicker .calendar.single .calendar-table {
border: none; }
.daterangepicker .calendar th, .daterangepicker .calendar td {
white-space: nowrap;
text-align: center;
min-width: 32px; }
.daterangepicker .calendar-table {
border: 1px solid #fff;
padding: 4px;
border-radius: 4px;
background-color: #fff; }
.daterangepicker table {
width: 100%;
margin: 0; }
.daterangepicker td, .daterangepicker th {
text-align: center;
width: 20px;
height: 20px;
border-radius: 4px;
border: 1px solid transparent;
white-space: nowrap;
cursor: pointer; }
.daterangepicker td.available:hover, .daterangepicker th.available:hover {
background-color: #eee;
border-color: transparent;
color: inherit; }
.daterangepicker td.week, .daterangepicker th.week {
font-size: 80%;
color: #ccc; }
.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date {
background-color: #fff;
border-color: transparent;
color: #999; }
.daterangepicker td.in-range {
background-color: #ebf4f8;
border-color: transparent;
color: #000;
border-radius: 0; }
.daterangepicker td.start-date {
border-radius: 4px 0 0 4px; }
.daterangepicker td.end-date {
border-radius: 0 4px 4px 0; }
.daterangepicker td.start-date.end-date {
border-radius: 4px; }
.daterangepicker td.active, .daterangepicker td.active:hover {
background-color: #357ebd;
border-color: transparent;
color: #fff; }
.daterangepicker th.month {
width: auto; }
.daterangepicker td.disabled, .daterangepicker option.disabled {
color: #999;
cursor: not-allowed;
text-decoration: line-through; }
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
font-size: 12px;
padding: 1px;
height: auto;
margin: 0;
cursor: default; }
.daterangepicker select.monthselect {
margin-right: 2%;
width: 56%; }
.daterangepicker select.yearselect {
width: 40%; }
.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {
width: 50px;
margin-bottom: 0; }
.daterangepicker .input-mini {
border: 1px solid #ccc;
border-radius: 4px;
color: #555;
height: 30px;
line-height: 30px;
display: block;
vertical-align: middle;
margin: 0 0 5px 0;
padding: 0 6px 0 28px;
width: 100%; }
.daterangepicker .input-mini.active {
border: 1px solid #08c;
border-radius: 4px; }
.daterangepicker .daterangepicker_input {
position: relative; }
.daterangepicker .daterangepicker_input i {
position: absolute;
left: 8px;
top: 8px; }
.daterangepicker.rtl .input-mini {
padding-right: 28px;
padding-left: 6px; }
.daterangepicker.rtl .daterangepicker_input i {
left: auto;
right: 8px; }
.daterangepicker .calendar-time {
text-align: center;
margin: 5px auto;
line-height: 30px;
position: relative;
padding-left: 28px; }
.daterangepicker .calendar-time select.disabled {
color: #ccc;
cursor: not-allowed; }
.ranges {
font-size: 11px;
float: none;
margin: 4px;
text-align: left; }
.ranges ul {
list-style: none;
margin: 0 auto;
padding: 0;
width: 100%; }
.ranges li {
font-size: 13px;
background-color: #f5f5f5;
border: 1px solid #f5f5f5;
border-radius: 4px;
color: #08c;
padding: 3px 12px;
margin-bottom: 8px;
cursor: pointer; }
.ranges li:hover {
background-color: #08c;
border: 1px solid #08c;
color: #fff; }
.ranges li.active {
background-color: #08c;
border: 1px solid #08c;
color: #fff; }
/* Larger Screen Styling */
@media (min-width: 564px) {
.daterangepicker {
width: auto; }
.daterangepicker .ranges ul {
width: 160px; }
.daterangepicker.single .ranges ul {
width: 100%; }
.daterangepicker.single .calendar.left {
clear: none; }
.daterangepicker.single.ltr .ranges, .daterangepicker.single.ltr .calendar {
float: left; }
.daterangepicker.single.rtl .ranges, .daterangepicker.single.rtl .calendar {
float: right; }
.daterangepicker.ltr {
direction: ltr;
text-align: left; }
.daterangepicker.ltr .calendar.left {
clear: left;
margin-right: 0; }
.daterangepicker.ltr .calendar.left .calendar-table {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.daterangepicker.ltr .calendar.right {
margin-left: 0; }
.daterangepicker.ltr .calendar.right .calendar-table {
border-left: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.daterangepicker.ltr .left .daterangepicker_input {
padding-right: 12px; }
.daterangepicker.ltr .calendar.left .calendar-table {
padding-right: 12px; }
.daterangepicker.ltr .ranges, .daterangepicker.ltr .calendar {
float: left; }
.daterangepicker.rtl {
direction: rtl;
text-align: right; }
.daterangepicker.rtl .calendar.left {
clear: right;
margin-left: 0; }
.daterangepicker.rtl .calendar.left .calendar-table {
border-left: none;
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.daterangepicker.rtl .calendar.right {
margin-right: 0; }
.daterangepicker.rtl .calendar.right .calendar-table {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.daterangepicker.rtl .left .daterangepicker_input {
padding-left: 12px; }
.daterangepicker.rtl .calendar.left .calendar-table {
padding-left: 12px; }
.daterangepicker.rtl .ranges, .daterangepicker.rtl .calendar {
text-align: right;
float: right; } }
@media (min-width: 730px) {
.daterangepicker .ranges {
width: auto; }
.daterangepicker.ltr .ranges {
float: left; }
.daterangepicker.rtl .ranges {
float: right; }
.daterangepicker .calendar.left {
clear: none !important; } }
table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0}
/*!
DataTables Bootstrap 3 integration
©2011-2015 SpryMedia Ltd - datatables.net/license
*/
(function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-6'l><'col-sm-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-5'i><'col-sm-7'p>>",renderer:"bootstrap"});b.extend(f.ext.classes,
{sWrapper:"dataTables_wrapper form-inline dt-bootstrap",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sProcessing:"dataTables_processing panel panel-default"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault();!b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};
l=0;for(h=f.length;l<h;l++)if(c=f[l],b.isArray(c))q(d,c);else{g=e="";switch(c){case "ellipsis":e="&#x2026;";g="disabled";break;case "first":e=k.sFirst;g=c+(0<j?"":" disabled");break;case "previous":e=k.sPrevious;g=c+(0<j?"":" disabled");break;case "next":e=k.sNext;g=c+(j<n-1?"":" disabled");break;case "last":e=k.sLast;g=c+(j<n-1?"":" disabled");break;default:e=c+1,g=j===c?"active":""}e&&(i=b("<li>",{"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("<a>",{href:"#",
"aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('<ul class="pagination"/>').children("ul"),s);i!==m&&b(h).find("[data-dt-idx="+i+"]").focus()};return f});
/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* Version: 1.3.8
*
*/
(function(e){e.fn.extend({slimScroll:function(f){var a=e.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},f);this.each(function(){function v(d){if(r){d=d||window.event;
var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);e(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&n(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function n(d,g,e){k=!1;var f=b.outerHeight()-c.outerHeight();g&&(g=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),g=Math.min(Math.max(g,0),f),g=0<d?Math.ceil(g):Math.floor(g),c.css({top:g+"px"}));l=parseInt(c.css("top"))/(b.outerHeight()-c.outerHeight());g=
l*(b[0].scrollHeight-b.outerHeight());e&&(g=d,d=g/b[0].scrollHeight*b.outerHeight(),d=Math.min(Math.max(d,0),f),c.css({top:d+"px"}));b.scrollTop(g);b.trigger("slimscrolling",~~g);w();p()}function x(){u=Math.max(b.outerHeight()/b[0].scrollHeight*b.outerHeight(),30);c.css({height:u+"px"});var a=u==b.outerHeight()?"none":"block";c.css({display:a})}function w(){x();clearTimeout(B);l==~~l?(k=a.allowPageScroll,C!=l&&b.trigger("slimscroll",0==~~l?"top":"bottom")):k=!1;C=l;u>=b.outerHeight()?k=!0:(c.stop(!0,
!0).fadeIn("fast"),a.railVisible&&m.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(B=setTimeout(function(){a.disableFadeOut&&r||y||z||(c.fadeOut("slow"),m.fadeOut("slow"))},1E3))}var r,y,z,B,A,u,l,C,k=!1,b=e(this);if(b.parent().hasClass(a.wrapperClass)){var q=b.scrollTop(),c=b.siblings("."+a.barClass),m=b.siblings("."+a.railClass);x();if(e.isPlainObject(f)){if("height"in f&&"auto"==f.height){b.parent().css("height","auto");b.css("height","auto");var h=b.parent().parent().height();b.parent().css("height",
h);b.css("height",h)}else"height"in f&&(h=f.height,b.parent().css("height",h),b.css("height",h));if("scrollTo"in f)q=parseInt(a.scrollTo);else if("scrollBy"in f)q+=parseInt(a.scrollBy);else if("destroy"in f){c.remove();m.remove();b.unwrap();return}n(q,!1,!0)}}else if(!(e.isPlainObject(f)&&"destroy"in f)){a.height="auto"==a.height?b.parent().height():a.height;q=e("<div></div>").addClass(a.wrapperClass).css({position:"relative",overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden",
width:a.width,height:a.height});var m=e("<div></div>").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=e("<div></div>").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible?"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius,
WebkitBorderRadius:a.borderRadius,zIndex:99}),h="right"==a.position?{right:a.distance}:{left:a.distance};m.css(h);c.css(h);b.wrap(q);b.parent().append(c);b.parent().append(m);a.railDraggable&&c.bind("mousedown",function(a){var b=e(document);z=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);n(0,c.position().top,!1)});b.bind("mouseup.slimscroll",function(a){z=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll",
function(a){a.stopPropagation();a.preventDefault();return!1});m.hover(function(){w()},function(){p()});c.hover(function(){y=!0},function(){y=!1});b.hover(function(){r=!0;w();p()},function(){r=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(A=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&&(n((A-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),A=b.originalEvent.touches[0].pageY)});
x();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),n(0,!0)):"top"!==a.start&&(n(e(a.start).position().top,null,!0),a.alwaysVisible||c.hide());window.addEventListener?(this.addEventListener("DOMMouseScroll",v,!1),this.addEventListener("mousewheel",v,!1)):document.attachEvent("onmousewheel",v)}});return this}});e.fn.extend({slimscroll:e.fn.slimScroll})})(jQuery);
\ No newline at end of file
/*! Select2 4.0.5 | https://github.com/select2/select2/blob/master/LICENSE.md */
(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(e){var t=e.input.length-e.maximum,n="请删除"+t+"个字符";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n="请再输入至少"+t+"个字符";return n},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(e){var t="最多只能选择"+e.maximum+"个项目";return t},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"}}}),{define:e.define,require:e.require}})();
\ No newline at end of file
/*! iCheck v1.0.1 by Damir Sultanov, http://git.io/arlzeA, MIT Licensed */
(function(h){function F(a,b,d){var c=a[0],e=/er/.test(d)?m:/bl/.test(d)?s:l,f=d==H?{checked:c[l],disabled:c[s],indeterminate:"true"==a.attr(m)||"false"==a.attr(w)}:c[e];if(/^(ch|di|in)/.test(d)&&!f)D(a,e);else if(/^(un|en|de)/.test(d)&&f)t(a,e);else if(d==H)for(e in f)f[e]?D(a,e,!0):t(a,e,!0);else if(!b||"toggle"==d){if(!b)a[p]("ifClicked");f?c[n]!==u&&t(a,e):D(a,e)}}function D(a,b,d){var c=a[0],e=a.parent(),f=b==l,A=b==m,B=b==s,K=A?w:f?E:"enabled",p=k(a,K+x(c[n])),N=k(a,b+x(c[n]));if(!0!==c[b]){if(!d&&
b==l&&c[n]==u&&c.name){var C=a.closest("form"),r='input[name="'+c.name+'"]',r=C.length?C.find(r):h(r);r.each(function(){this!==c&&h(this).data(q)&&t(h(this),b)})}A?(c[b]=!0,c[l]&&t(a,l,"force")):(d||(c[b]=!0),f&&c[m]&&t(a,m,!1));L(a,f,b,d)}c[s]&&k(a,y,!0)&&e.find("."+I).css(y,"default");e[v](N||k(a,b)||"");B?e.attr("aria-disabled","true"):e.attr("aria-checked",A?"mixed":"true");e[z](p||k(a,K)||"")}function t(a,b,d){var c=a[0],e=a.parent(),f=b==l,h=b==m,q=b==s,p=h?w:f?E:"enabled",t=k(a,p+x(c[n])),
u=k(a,b+x(c[n]));if(!1!==c[b]){if(h||!d||"force"==d)c[b]=!1;L(a,f,p,d)}!c[s]&&k(a,y,!0)&&e.find("."+I).css(y,"pointer");e[z](u||k(a,b)||"");q?e.attr("aria-disabled","false"):e.attr("aria-checked","false");e[v](t||k(a,p)||"")}function M(a,b){if(a.data(q)){a.parent().html(a.attr("style",a.data(q).s||""));if(b)a[p](b);a.off(".i").unwrap();h(G+'[for="'+a[0].id+'"]').add(a.closest(G)).off(".i")}}function k(a,b,d){if(a.data(q))return a.data(q).o[b+(d?"":"Class")]}function x(a){return a.charAt(0).toUpperCase()+
a.slice(1)}function L(a,b,d,c){if(!c){if(b)a[p]("ifToggled");a[p]("ifChanged")[p]("if"+x(d))}}var q="iCheck",I=q+"-helper",u="radio",l="checked",E="un"+l,s="disabled",w="determinate",m="in"+w,H="update",n="type",v="addClass",z="removeClass",p="trigger",G="label",y="cursor",J=/ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);h.fn[q]=function(a,b){var d='input[type="checkbox"], input[type="'+u+'"]',c=h(),e=function(a){a.each(function(){var a=h(this);c=a.is(d)?
c.add(a):c.add(a.find(d))})};if(/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a))return a=a.toLowerCase(),e(this),c.each(function(){var c=h(this);"destroy"==a?M(c,"ifDestroyed"):F(c,!0,a);h.isFunction(b)&&b()});if("object"!=typeof a&&a)return this;var f=h.extend({checkedClass:l,disabledClass:s,indeterminateClass:m,labelHover:!0,aria:!1},a),k=f.handle,B=f.hoverClass||"hover",x=f.focusClass||"focus",w=f.activeClass||"active",y=!!f.labelHover,C=f.labelHoverClass||
"hover",r=(""+f.increaseArea).replace("%","")|0;if("checkbox"==k||k==u)d='input[type="'+k+'"]';-50>r&&(r=-50);e(this);return c.each(function(){var a=h(this);M(a);var c=this,b=c.id,e=-r+"%",d=100+2*r+"%",d={position:"absolute",top:e,left:e,display:"block",width:d,height:d,margin:0,padding:0,background:"#fff",border:0,opacity:0},e=J?{position:"absolute",visibility:"hidden"}:r?d:{position:"absolute",opacity:0},k="checkbox"==c[n]?f.checkboxClass||"icheckbox":f.radioClass||"i"+u,m=h(G+'[for="'+b+'"]').add(a.closest(G)),
A=!!f.aria,E=q+"-"+Math.random().toString(36).replace("0.",""),g='<div class="'+k+'" '+(A?'role="'+c[n]+'" ':"");m.length&&A&&m.each(function(){g+='aria-labelledby="';this.id?g+=this.id:(this.id=E,g+=E);g+='"'});g=a.wrap(g+"/>")[p]("ifCreated").parent().append(f.insert);d=h('<ins class="'+I+'"/>').css(d).appendTo(g);a.data(q,{o:f,s:a.attr("style")}).css(e);f.inheritClass&&g[v](c.className||"");f.inheritID&&b&&g.attr("id",q+"-"+b);"static"==g.css("position")&&g.css("position","relative");F(a,!0,H);
if(m.length)m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i",function(b){var d=b[n],e=h(this);if(!c[s]){if("click"==d){if(h(b.target).is("a"))return;F(a,!1,!0)}else y&&(/ut|nd/.test(d)?(g[z](B),e[z](C)):(g[v](B),e[v](C)));if(J)b.stopPropagation();else return!1}});a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i",function(b){var d=b[n];b=b.keyCode;if("click"==d)return!1;if("keydown"==d&&32==b)return c[n]==u&&c[l]||(c[l]?t(a,l):D(a,l)),!1;if("keyup"==d&&c[n]==u)!c[l]&&D(a,l);else if(/us|ur/.test(d))g["blur"==
d?z:v](x)});d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i",function(b){var d=b[n],e=/wn|up/.test(d)?w:B;if(!c[s]){if("click"==d)F(a,!1,!0);else{if(/wn|er|in/.test(d))g[v](e);else g[z](e+" "+w);if(m.length&&y&&e==B)m[/ut|nd/.test(d)?z:v](C)}if(J)b.stopPropagation();else return!1}})})}})(window.jQuery||window.Zepto);
/* iCheck plugin Square skin, blue
----------------------------------- */
.icheckbox_square-blue,
.iradio_square-blue {
display: inline-block;
*display: inline;
vertical-align: middle;
margin: 0;
padding: 0;
width: 22px;
height: 22px;
background: url(blue.png) no-repeat;
border: none;
cursor: pointer;
}
.icheckbox_square-blue {
background-position: 0 0;
}
.icheckbox_square-blue.hover {
background-position: -24px 0;
}
.icheckbox_square-blue.checked {
background-position: -48px 0;
}
.icheckbox_square-blue.disabled {
background-position: -72px 0;
cursor: default;
}
.icheckbox_square-blue.checked.disabled {
background-position: -96px 0;
}
.iradio_square-blue {
background-position: -120px 0;
}
.iradio_square-blue.hover {
background-position: -144px 0;
}
.iradio_square-blue.checked {
background-position: -168px 0;
}
.iradio_square-blue.disabled {
background-position: -192px 0;
cursor: default;
}
.iradio_square-blue.checked.disabled {
background-position: -216px 0;
}
/* Retina support */
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
.icheckbox_square-blue,
.iradio_square-blue {
background-image: url(blue@2x.png);
-webkit-background-size: 240px 24px;
background-size: 240px 24px;
}
}
\ No newline at end of file
$(function(){
// logout
$("#logoutBtn").click(function(){
layer.confirm( "确认注销登录?" , {
icon: 3,
title: "系统提示" ,
btn: [ "确认", "取消" ]
}, function(index){
layer.close(index);
$.post(base_url + "/logout", function(data, status) {
if (data.code == "200") {
layer.msg( "注销成功" );
setTimeout(function(){
window.location.href = base_url + "/";
}, 500);
} else {
layer.open({
title: I18n.system_tips ,
btn: [ I18n.system_ok ],
content: (data.msg || "注销失败" ),
icon: '2'
});
}
});
});
});
// scrollup
$.scrollUp({
animation: 'fade', // fade/slide/none
scrollImg: true
});
// left menu status v: js + server + cookie
$('.sidebar-toggle').click(function(){
var registry_adminlte_settings = $.cookie('registry_adminlte_settings'); // on=open,off=close
if ('off' == registry_adminlte_settings) {
registry_adminlte_settings = 'on';
} else {
registry_adminlte_settings = 'off';
}
$.cookie('registry_adminlte_settings', registry_adminlte_settings, { expires: 7 }); //$.cookie('the_cookie', '', { expires: -1 });
});
});
/**
* Created by xuxueli on 17/4/24.
*/
$(function () {
});
$(function(){
// input iCheck
$('input').iCheck({
checkboxClass: 'icheckbox_square-blue',
radioClass: 'iradio_square-blue',
increaseArea: '20%' // optional
});
// login Form Valid
var loginFormValid = $("#loginForm").validate({
errorElement : 'span',
errorClass : 'help-block',
focusInvalid : true,
rules : {
userName : {
required : true ,
minlength: 5,
maxlength: 18
},
password : {
required : true ,
minlength: 5,
maxlength: 18
}
},
messages : {
userName : {
required :"请输入登陆账号." ,
minlength:"登陆账号不应低于5位"
},
password : {
required :"请输入登陆密码." ,
minlength:"登陆密码不应低于5位"
}
},
highlight : function(element) {
$(element).closest('.form-group').addClass('has-error');
},
success : function(label) {
label.closest('.form-group').removeClass('has-error');
label.remove();
},
errorPlacement : function(error, element) {
element.parent('div').append(error);
},
submitHandler : function(form) {
$.post(base_url + "/login", $("#loginForm").serialize(), function(data, status) {
if (data.code == "200") {
layer.msg( "登陆成功" );
setTimeout(function(){
window.location.href = base_url;
}, 500);
} else {
layer.open({
title: "系统提示",
btn: [ "确认" ],
content: (data.msg || "登陆失败" ),
icon: '2'
});
}
});
}
});
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/*!
* jQuery Cookie Plugin v1.4.1
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2013 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var pluses = /\+/g;
function encode(s) {
return config.raw ? s : encodeURIComponent(s);
}
function decode(s) {
return config.raw ? s : decodeURIComponent(s);
}
function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
}
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
}
function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
}
var config = $.cookie = function (key, value, options) {
// Write
if (value !== undefined && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options);
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setTime(+t + days * 864e+5);
}
return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// Read
var result = key ? undefined : {};
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
var cookies = document.cookie ? document.cookie.split('; ') : [];
for (var i = 0, l = cookies.length; i < l; i++) {
var parts = cookies[i].split('=');
var name = decode(parts.shift());
var cookie = parts.join('=');
if (key && key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
}
return result;
};
config.defaults = {};
$.removeCookie = function (key, options) {
if ($.cookie(key) === undefined) {
return false;
}
// Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
};
}));
/* Image style */
#scrollUp {
background-image: url('top.png');
bottom: 20px;
right: 20px;
width: 38px; /* Width of image */
height: 38px; /* Height of image */
}
/*!
* scrollup v2.4.1
* Url: http://markgoodyear.com/labs/scrollup/
* Copyright (c) Mark Goodyear — @markgdyr — http://markgoodyear.com
* License: MIT
*/
!function(l,o,e){"use strict";l.fn.scrollUp=function(o){l.data(e.body,"scrollUp")||(l.data(e.body,"scrollUp",!0),l.fn.scrollUp.init(o))},l.fn.scrollUp.init=function(r){var s,t,c,i,n,a,d,p=l.fn.scrollUp.settings=l.extend({},l.fn.scrollUp.defaults,r),f=!1;switch(d=p.scrollTrigger?l(p.scrollTrigger):l("<a/>",{id:p.scrollName,href:"#top"}),p.scrollTitle&&d.attr("title",p.scrollTitle),d.appendTo("body"),p.scrollImg||p.scrollTrigger||d.html(p.scrollText),d.css({display:"none",position:"fixed",zIndex:p.zIndex}),p.activeOverlay&&l("<div/>",{id:p.scrollName+"-active"}).css({position:"absolute",top:p.scrollDistance+"px",width:"100%",borderTop:"1px dotted"+p.activeOverlay,zIndex:p.zIndex}).appendTo("body"),p.animation){case"fade":s="fadeIn",t="fadeOut",c=p.animationSpeed;break;case"slide":s="slideDown",t="slideUp",c=p.animationSpeed;break;default:s="show",t="hide",c=0}i="top"===p.scrollFrom?p.scrollDistance:l(e).height()-l(o).height()-p.scrollDistance,n=l(o).scroll(function(){l(o).scrollTop()>i?f||(d[s](c),f=!0):f&&(d[t](c),f=!1)}),p.scrollTarget?"number"==typeof p.scrollTarget?a=p.scrollTarget:"string"==typeof p.scrollTarget&&(a=Math.floor(l(p.scrollTarget).offset().top)):a=0,d.click(function(o){o.preventDefault(),l("html, body").animate({scrollTop:a},p.scrollSpeed,p.easingType)})},l.fn.scrollUp.defaults={scrollName:"scrollUp",scrollDistance:300,scrollFrom:"top",scrollSpeed:300,easingType:"linear",animation:"fade",animationSpeed:200,scrollTrigger:!1,scrollTarget:!1,scrollText:"Scroll to top",scrollTitle:!1,scrollImg:!1,activeOverlay:!1,zIndex:2147483647},l.fn.scrollUp.destroy=function(r){l.removeData(e.body,"scrollUp"),l("#"+l.fn.scrollUp.settings.scrollName).remove(),l("#"+l.fn.scrollUp.settings.scrollName+"-active").remove(),l.fn.jquery.split(".")[1]>=7?l(o).off("scroll",r):l(o).unbind("scroll",r)},l.scrollUp=l.fn.scrollUp}(jQuery,window,document);
\ No newline at end of file
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment