{
public boolean isExpect() {
return expect;
}
+
}
/**
diff --git a/src/main/java/org/redkale/boot/LoggingBaseHandler.java b/src/main/java/org/redkale/boot/LoggingBaseHandler.java
new file mode 100644
index 000000000..0c87b04cc
--- /dev/null
+++ b/src/main/java/org/redkale/boot/LoggingBaseHandler.java
@@ -0,0 +1,20 @@
+/*
+ */
+package org.redkale.boot;
+
+import java.util.logging.Handler;
+
+/**
+ * Handler鍩虹被
+ *
+ * 璇︽儏瑙: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.7.0
+ */
+public abstract class LoggingBaseHandler extends Handler {
+
+ protected Application currentApplication() {
+ return Application.currentApplication; //涓嶈兘鐩存帴鏆撮湶澶栫晫璁块棶
+ }
+}
diff --git a/src/main/java/org/redkale/boot/LoggingFileHandler.java b/src/main/java/org/redkale/boot/LoggingFileHandler.java
index 32fc1c8f0..15a981d2d 100644
--- a/src/main/java/org/redkale/boot/LoggingFileHandler.java
+++ b/src/main/java/org/redkale/boot/LoggingFileHandler.java
@@ -10,13 +10,13 @@ import org.redkale.util.RedkaleClassLoader;
import java.io.*;
import java.nio.file.*;
import static java.nio.file.StandardCopyOption.*;
-import java.time.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.logging.*;
import java.util.logging.Formatter;
import java.util.regex.Pattern;
+import org.redkale.util.*;
/**
* 鑷畾涔夌殑鏃ュ織杈撳嚭绫
@@ -26,11 +26,13 @@ import java.util.regex.Pattern;
* @author zhangjx
*/
@SuppressWarnings("unchecked")
-public class LoggingFileHandler extends Handler {
+public class LoggingFileHandler extends LoggingBaseHandler {
//public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s%n%5$s%6$s%n";
public static final String FORMATTER_FORMAT = "%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%tL %4$s %2$s\r\n%5$s%6$s\r\n";
+ static boolean traceflag = false; //闃叉璁剧疆system.property鍓嶈皟鐢═races绫诲鑷磂nable鎻愬墠鍒濆鍖
+
/**
* SNCP鐨勬棩蹇楄緭鍑篐andler
*/
@@ -42,6 +44,46 @@ public class LoggingFileHandler extends Handler {
}
}
+ public static class LoggingConsoleHandler extends ConsoleHandler {
+
+ private Pattern denyreg;
+
+ public LoggingConsoleHandler() {
+ super();
+ configure();
+ }
+
+ private void configure() {
+ LogManager manager = LogManager.getLogManager();
+ String denyregstr = manager.getProperty("java.util.logging.ConsoleHandler.denyreg");
+ try {
+ if (denyregstr != null && !denyregstr.trim().isEmpty()) {
+ denyreg = Pattern.compile(denyregstr);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ @Override
+ public void publish(LogRecord log) {
+ if (denyreg != null && denyreg.matcher(log.getMessage()).find()) return;
+ if (traceflag && Traces.enable()) {
+ String traceid = Traces.currTraceid();
+ if (traceid == null || traceid.isEmpty()) {
+ traceid = "[TID:N/A] ";
+ } else {
+ traceid = "[TID:" + traceid + "] ";
+ }
+ if (log.getMessage() == null) {
+ log.setMessage(traceid);
+ } else {
+ log.setMessage(traceid + log.getMessage());
+ }
+ }
+ super.publish(log);
+ }
+ }
+
/**
* 榛樿鐨勬棩蹇楁椂闂存牸寮忓寲绫
* 涓嶴impleFormatter鐨勫尯鍒湪浜巐evel涓嶄娇鐢ㄦ湰鍦板寲
@@ -51,6 +93,9 @@ public class LoggingFileHandler extends Handler {
@Override
public String format(LogRecord log) {
+ if (log.getThrown() == null && log.getMessage() != null && log.getMessage().startsWith("------")) {
+ return formatMessage(log) + "\r\n";
+ }
String source;
if (log.getSourceClassName() != null) {
source = log.getSourceClassName();
@@ -104,9 +149,13 @@ public class LoggingFileHandler extends Handler {
protected final LinkedBlockingQueue logqueue = new LinkedBlockingQueue();
- private String pattern;
+ protected String pattern;
- private String unusual; //涓嶄负null琛ㄧず灏 WARNING銆丼EVERE 绾у埆鐨勬棩蹇楀啓鍏ュ崟鐙殑鏂囦欢涓
+ protected String patternDateFormat; //闇瑕佹椂闂存牸寮忓寲
+
+ protected String unusual; //涓嶄负null琛ㄧず灏 WARNING銆丼EVERE 绾у埆鐨勬棩蹇楀啓鍏ュ崟鐙殑鏂囦欢涓
+
+ protected String unusualDateFormat; //闇瑕佹椂闂存牸寮忓寲
private int limit; //鏂囦欢澶у皬闄愬埗
@@ -118,9 +167,9 @@ public class LoggingFileHandler extends Handler {
private long tomorrow;
- private boolean append;
+ protected boolean append;
- private Pattern denyreg;
+ protected Pattern denyreg;
private final AtomicLong loglength = new AtomicLong();
@@ -198,16 +247,14 @@ public class LoggingFileHandler extends Handler {
}
if (logstream == null) {
logindex.incrementAndGet();
- java.time.LocalDate date = LocalDate.now();
- logfile = new File(pattern.replace("%m", String.valueOf((date.getYear() * 100 + date.getMonthValue()))).replace("%d", String.valueOf((date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth()))));
+ logfile = new File(patternDateFormat == null ? pattern : Utility.formatTime(patternDateFormat, -1, System.currentTimeMillis()));
logfile.getParentFile().mkdirs();
loglength.set(logfile.length());
logstream = new FileOutputStream(logfile, append);
}
if (unusual != null && logunusualstream == null) {
logunusualindex.incrementAndGet();
- java.time.LocalDate date = LocalDate.now();
- logunusualfile = new File(unusual.replace("%m", String.valueOf((date.getYear() * 100 + date.getMonthValue()))).replace("%d", String.valueOf((date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth()))));
+ logunusualfile = new File(unusualDateFormat == null ? unusual : Utility.formatTime(unusualDateFormat, -1, System.currentTimeMillis()));
logunusualfile.getParentFile().mkdirs();
logunusuallength.set(logunusualfile.length());
logunusualstream = new FileOutputStream(logunusualfile, append);
@@ -241,7 +288,7 @@ public class LoggingFileHandler extends Handler {
String cname = LoggingFileHandler.class.getName();
this.pattern = manager.getProperty(cname + ".pattern");
if (this.pattern == null) {
- this.pattern = "logs-%m/" + getPrefix() + "log-%d.log";
+ this.pattern = "logs-%tm/" + getPrefix() + "log-%td.log";
} else {
int pos = this.pattern.lastIndexOf('/');
if (pos > 0) {
@@ -250,6 +297,10 @@ public class LoggingFileHandler extends Handler {
this.pattern = getPrefix() + this.pattern;
}
}
+ if (this.pattern != null && this.pattern.contains("%")) { //闇瑕佹椂闂存牸寮忓寲
+ this.patternDateFormat = this.pattern;
+ Utility.formatTime(this.patternDateFormat, -1, System.currentTimeMillis()); //娴嬭瘯鏃堕棿鏍煎紡鏄惁姝g‘
+ }
String unusualstr = manager.getProperty(cname + ".unusual");
if (unusualstr != null) {
int pos = unusualstr.lastIndexOf('/');
@@ -259,6 +310,10 @@ public class LoggingFileHandler extends Handler {
this.unusual = getPrefix() + unusualstr;
}
}
+ if (this.unusual != null && this.unusual.contains("%")) { //闇瑕佹椂闂存牸寮忓寲
+ this.unusualDateFormat = this.unusual;
+ Utility.formatTime(this.unusualDateFormat, -1, System.currentTimeMillis()); //娴嬭瘯鏃堕棿鏍煎紡鏄惁姝g‘
+ }
String limitstr = manager.getProperty(cname + ".limit");
try {
if (limitstr != null) {
@@ -333,6 +388,7 @@ public class LoggingFileHandler extends Handler {
@Override
public void publish(LogRecord log) {
+ if (!isLoggable(log)) return;
final String sourceClassName = log.getSourceClassName();
if (sourceClassName == null || true) {
StackTraceElement[] ses = new Throwable().getStackTrace();
@@ -346,6 +402,19 @@ public class LoggingFileHandler extends Handler {
log.setSourceClassName('[' + Thread.currentThread().getName() + "] " + sourceClassName);
}
if (denyreg != null && denyreg.matcher(log.getMessage()).find()) return;
+ if (traceflag && Traces.enable()) {
+ String traceid = Traces.currTraceid();
+ if (traceid == null || traceid.isEmpty()) {
+ traceid = "[TID:N/A] ";
+ } else {
+ traceid = "[TID:" + traceid + "] ";
+ }
+ if (log.getMessage() == null) {
+ log.setMessage(traceid);
+ } else {
+ log.setMessage(traceid + log.getMessage());
+ }
+ }
logqueue.offer(log);
}
diff --git a/src/main/java/org/redkale/boot/LoggingSearchHandler.java b/src/main/java/org/redkale/boot/LoggingSearchHandler.java
new file mode 100644
index 000000000..98c1329f6
--- /dev/null
+++ b/src/main/java/org/redkale/boot/LoggingSearchHandler.java
@@ -0,0 +1,303 @@
+/*
+ */
+package org.redkale.boot;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.*;
+import java.util.logging.Formatter;
+import java.util.regex.Pattern;
+import javax.persistence.*;
+import org.redkale.convert.*;
+import org.redkale.convert.json.JsonConvert;
+import org.redkale.source.*;
+import org.redkale.util.*;
+
+/**
+ * 鍩轰簬SearchSource鐨勬棩蹇楄緭鍑虹被
+ *
+ * 璇︽儏瑙: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.7.0
+ */
+public class LoggingSearchHandler extends LoggingBaseHandler {
+
+ protected static final String DEFAULT_TABLE_NAME = "log-record";
+
+ protected final LinkedBlockingQueue logqueue = new LinkedBlockingQueue();
+
+ protected final AtomicInteger retryCount = new AtomicInteger(3);
+
+ protected String tag = DEFAULT_TABLE_NAME; //鐢ㄤ簬琛ㄥ墠缂锛 榛樿鏄
+
+ protected String tagDateFormat; //闇瑕佹椂闂存牸寮忓寲
+
+ protected String pattern;
+
+ protected Pattern denyreg;
+
+ protected String sourceResourceName;
+
+ protected SearchSource source;
+
+ public LoggingSearchHandler() {
+ configure();
+ open();
+ }
+
+ private void open() {
+ final String name = "Redkale-" + getClass().getSimpleName() + "-Thread";
+ final int batchSize = 100; //鎵归噺鏈澶100鏉
+ final List logList = new ArrayList<>();
+ final SimpleFormatter formatter = new SimpleFormatter();
+ final PrintStream outStream = System.out;
+ new Thread() {
+ {
+ setName(name);
+ setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ try {
+ SearchLogRecord log = logqueue.take();
+ while (source == null && retryCount.get() > 0) initSource();
+ //----------------------鍐欐棩蹇-------------------------
+ if (source == null) { //source鍔犺浇澶辫触
+ outStream.print(formatter.format(log.rawLog));
+ } else {
+ logList.add(log);
+ int size = batchSize;
+ while (--size > 0) {
+ log = logqueue.poll();
+ if (log == null) break;
+ logList.add(log);
+ }
+ source.insert(logList);
+ }
+ } catch (Exception e) {
+ ErrorManager err = getErrorManager();
+ if (err != null) err.error(null, e, ErrorManager.WRITE_FAILURE);
+ } finally {
+ logList.clear();
+ }
+ }
+
+ }
+ }.start();
+ }
+
+ private synchronized void initSource() {
+ if (retryCount.get() < 1) return;
+ try {
+ Utility.sleep(3000); //濡傛灉SearchSource鑷韩鍦ㄦ墦鍗版棩蹇楋紝闇瑕佸仠椤夸竴鐐规椂闂磋SearchSource鍒濆鍖栧畬鎴
+ Application application = currentApplication();
+ this.source = (SearchSource) application.loadDataSource(sourceResourceName, false);
+ if (retryCount.get() == 1 && this.source == null) System.err.println("ERROR: not load logging.source(" + sourceResourceName + ")");
+ } catch (Exception t) {
+ ErrorManager err = getErrorManager();
+ if (err != null) err.error(null, t, ErrorManager.WRITE_FAILURE);
+ } finally {
+ retryCount.decrementAndGet();
+ }
+ }
+
+ private static boolean checkTagName(String name) { //鍙兘鏄瓧姣嶃佹暟瀛椼佺煭妯佺偣銆%銆$鍜屼笅鍒掔嚎
+ if (name.isEmpty()) return false;
+ for (char ch : name.toCharArray()) {
+ if (ch >= '0' && ch <= '9') continue;
+ if (ch >= 'a' && ch <= 'z') continue;
+ if (ch >= 'A' && ch <= 'Z') continue;
+ if (ch == '_' || ch == '-' || ch == '%' || ch == '$' || ch == '.') continue;
+ return false;
+ }
+ return true;
+ }
+
+ private void configure() {
+ LogManager manager = LogManager.getLogManager();
+ String cname = getClass().getName();
+ this.sourceResourceName = manager.getProperty(cname + ".source");
+ if (this.sourceResourceName == null || this.sourceResourceName.isEmpty()) {
+ throw new RuntimeException("not found logging.property " + cname + ".source");
+ }
+ String tagstr = manager.getProperty(cname + ".tag");
+ if (tagstr != null && !tagstr.isEmpty()) {
+ if (!checkTagName(tagstr.replaceAll("\\$\\{.+\\}", ""))) throw new RuntimeException("found illegal logging.property " + cname + ".tag = " + tagstr);
+ this.tag = tagstr;
+ if (tagstr.contains("%")) {
+ this.tagDateFormat = this.tag;
+ Utility.formatTime(this.tagDateFormat, -1, System.currentTimeMillis()); //娴嬭瘯鏃堕棿鏍煎紡鏄惁姝g‘
+ }
+ }
+
+ String levelstr = manager.getProperty(cname + ".level");
+ try {
+ if (levelstr != null) {
+ Level l = Level.parse(levelstr);
+ setLevel(l != null ? l : Level.ALL);
+ }
+ } catch (Exception e) {
+ }
+ String filterstr = manager.getProperty(cname + ".filter");
+ try {
+ if (filterstr != null) {
+ Class> clz = ClassLoader.getSystemClassLoader().loadClass(filterstr);
+ RedkaleClassLoader.putReflectionDeclaredConstructors(clz, clz.getName());
+ setFilter((Filter) clz.getDeclaredConstructor().newInstance());
+ }
+ } catch (Exception e) {
+ }
+ String formatterstr = manager.getProperty(cname + ".formatter");
+ try {
+ if (formatterstr != null) {
+ Class> clz = ClassLoader.getSystemClassLoader().loadClass(formatterstr);
+ RedkaleClassLoader.putReflectionDeclaredConstructors(clz, clz.getName());
+ setFormatter((Formatter) clz.getDeclaredConstructor().newInstance());
+ }
+ } catch (Exception e) {
+ }
+ if (getFormatter() == null) setFormatter(new SimpleFormatter());
+
+ String encodingstr = manager.getProperty(cname + ".encoding");
+ try {
+ if (encodingstr != null) setEncoding(encodingstr);
+ } catch (Exception e) {
+ }
+
+ String denyregstr = manager.getProperty(cname + ".denyreg");
+ try {
+ if (denyregstr != null && !denyregstr.trim().isEmpty()) {
+ denyreg = Pattern.compile(denyregstr);
+ }
+ } catch (Exception e) {
+ }
+ }
+
+ @Override
+ public void publish(LogRecord log) {
+ if (!isLoggable(log)) return;
+ final String sourceClassName = log.getSourceClassName();
+ if (sourceClassName == null || true) {
+ StackTraceElement[] ses = new Throwable().getStackTrace();
+ for (int i = 2; i < ses.length; i++) {
+ if (ses[i].getClassName().startsWith("java.util.logging")) continue;
+ log.setSourceClassName(ses[i].getClassName());
+ log.setSourceMethodName(ses[i].getMethodName());
+ break;
+ }
+ }
+ if (denyreg != null && denyreg.matcher(log.getMessage()).find()) return;
+ String rawTag = tagDateFormat == null ? tag : Utility.formatTime(tagDateFormat, -1, log.getInstant().toEpochMilli());
+ logqueue.offer(new SearchLogRecord(rawTag, log));
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() throws SecurityException {
+ }
+
+ @Entity
+ @Table(name = DEFAULT_TABLE_NAME)
+ @DistributeTable(strategy = SearchLogRecord.TableStrategy.class)
+ public static class SearchLogRecord {
+
+ @Id
+ @ConvertColumn(index = 1)
+ @SearchColumn(options = "false")
+ public String logid;
+
+ @ConvertColumn(index = 2)
+ @SearchColumn(options = "false")
+ public String level;
+
+ @ConvertColumn(index = 3)
+ @SearchColumn(date = true)
+ public long timestamp;
+
+ @ConvertColumn(index = 4)
+ @SearchColumn(options = "false")
+ public String traceid;
+
+ @ConvertColumn(index = 5)
+ public String threadName;
+
+ @ConvertColumn(index = 6)
+ @SearchColumn(text = true, options = "offsets")
+ public String loggerName;
+
+ @ConvertColumn(index = 7)
+ @SearchColumn(text = true, options = "offsets")
+ public String methodName;
+
+ @ConvertColumn(index = 8)
+ @SearchColumn(text = true, options = "offsets") //, analyzer = "ik_max_word"
+ public String message; //log.message +"\r\n"+ log.thrown
+
+ @Transient
+ @ConvertDisabled
+ LogRecord rawLog;
+
+ @Transient
+ @ConvertDisabled
+ String rawTag;
+
+ public SearchLogRecord() {
+ }
+
+ protected SearchLogRecord(String tag, LogRecord log) {
+ this.rawLog = log;
+ this.rawTag = tag;
+ this.threadName = Thread.currentThread().getName();
+ this.traceid = LoggingFileHandler.traceflag ? Traces.currTraceid() : null;
+ String msg = log.getMessage();
+ if (log.getThrown() != null) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println();
+ log.getThrown().printStackTrace(pw);
+ pw.close();
+ String throwable = sw.toString();
+ this.message = (msg != null && !msg.isEmpty()) ? (msg + "\r\n" + throwable) : throwable;
+ } else {
+ this.message = msg;
+ }
+ this.level = log.getLevel().toString();
+ this.loggerName = log.getLoggerName();
+ this.methodName = log.getSourceClassName() + " " + log.getSourceMethodName();
+ this.timestamp = log.getInstant().toEpochMilli();
+ this.logid = Utility.format36time(timestamp) + "_" + Utility.uuid();
+ }
+
+ @Override
+ public String toString() {
+ return JsonConvert.root().convertTo(this);
+ }
+
+ public static class TableStrategy implements DistributeTableStrategy {
+
+ @Override
+ public String getTable(String table, SearchLogRecord bean) {
+ return bean.rawTag;
+ }
+
+ @Override
+ public String getTable(String table, Serializable primary) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getTable(String table, FilterNode node) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ }
+ }
+}
diff --git a/src/main/java/org/redkale/boot/NodeHttpServer.java b/src/main/java/org/redkale/boot/NodeHttpServer.java
index f7778bdae..0e2462a1d 100644
--- a/src/main/java/org/redkale/boot/NodeHttpServer.java
+++ b/src/main/java/org/redkale/boot/NodeHttpServer.java
@@ -90,7 +90,7 @@ public class NodeHttpServer extends NodeServer {
@Override
protected void loadFilter(ClassFilter extends Filter> filterFilter, ClassFilter otherFilter) throws Exception {
- if (httpServer != null) loadHttpFilter(this.serverConf.getAnyValue("filters"), filterFilter);
+ if (httpServer != null) loadHttpFilter(filterFilter);
}
@Override
@@ -102,19 +102,19 @@ public class NodeHttpServer extends NodeServer {
private void initWebSocketService() {
final NodeServer self = this;
final ResourceFactory regFactory = application.getResourceFactory();
- resourceFactory.register((ResourceFactory rf, final Object src, final String resourceName, Field field, Object attachment) -> { //涓昏鐢ㄤ簬鍗曠偣鐨勬湇鍔
+ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, Object attachment) -> { //涓昏鐢ㄤ簬鍗曠偣鐨勬湇鍔
try {
if (field.getAnnotation(Resource.class) == null) return;
- if (!(src instanceof WebSocketServlet)) return;
- ResourceFactory.ResourceLoader loader = null;
+ if (!(srcObj instanceof WebSocketServlet)) return;
+ ResourceTypeLoader loader = null;
ResourceFactory sncpResFactory = null;
for (NodeServer ns : application.servers) {
if (!ns.isSNCP()) continue;
sncpResFactory = ns.resourceFactory;
- loader = sncpResFactory.findLoader(WebSocketNode.class, field);
+ loader = sncpResFactory.findTypeLoader(WebSocketNode.class, field);
if (loader != null) break;
}
- if (loader != null) loader.load(sncpResFactory, src, resourceName, field, attachment);
+ if (loader != null) loader.load(sncpResFactory, srcResourceName, srcObj, resourceName, field, attachment);
synchronized (regFactory) {
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (sncpResFactory != null && resourceFactory.find(RESNAME_SNCP_ADDR, String.class) == null) {
@@ -127,15 +127,15 @@ public class NodeHttpServer extends NodeServer {
try {
Field c = WebSocketServlet.class.getDeclaredField("messageAgent");
c.setAccessible(true);
- messageAgent = (MessageAgent) c.get(src);
+ messageAgent = (MessageAgent) c.get(srcObj);
} catch (Exception ex) {
logger.log(Level.WARNING, "WebSocketServlet getMessageAgent error", ex);
}
nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, messageAgent, application.getResourceFactory(), application.getSncpTransportFactory(), (InetSocketAddress) null, (Set) null, (AnyValue) null);
regFactory.register(resourceName, WebSocketNode.class, nodeService);
}
- resourceFactory.inject(nodeService, self);
- field.set(src, nodeService);
+ resourceFactory.inject(resourceName, nodeService, self);
+ field.set(srcObj, nodeService);
logger.fine("[" + Thread.currentThread().getName() + "] Load Service " + nodeService);
}
} catch (Exception e) {
@@ -145,7 +145,7 @@ public class NodeHttpServer extends NodeServer {
}
@SuppressWarnings("unchecked")
- protected void loadHttpFilter(final AnyValue filtersConf, final ClassFilter extends Filter> classFilter) throws Exception {
+ protected void loadHttpFilter(final ClassFilter extends Filter> classFilter) throws Exception {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
final String localThreadName = "[" + Thread.currentThread().getName() + "] ";
List> list = new ArrayList(classFilter.getFilterEntrys());
diff --git a/src/main/java/org/redkale/boot/NodeServer.java b/src/main/java/org/redkale/boot/NodeServer.java
index 6646f4d25..ab3230cc3 100644
--- a/src/main/java/org/redkale/boot/NodeServer.java
+++ b/src/main/java/org/redkale/boot/NodeServer.java
@@ -14,7 +14,6 @@ import java.lang.reflect.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
-import java.util.AbstractMap.SimpleEntry;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.logging.*;
@@ -212,66 +211,13 @@ public abstract class NodeServer {
final ResourceFactory appResFactory = application.getResourceFactory();
final TransportFactory appSncpTranFactory = application.getSncpTransportFactory();
final AnyValue resources = application.config.getAnyValue("resources");
- final String confURI = appResFactory.find(RESNAME_APP_CONF, String.class);
- final Map> cacheResource = new HashMap<>();
- final Map> dataResources = new HashMap<>();
- if (resources != null) {
- for (AnyValue sourceConf : resources.getAnyValues("source")) {
- try {
- String classval = sourceConf.getValue("value");
- Class type = null;
- if (classval == null || classval.isEmpty()) {
- RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
- List providers = new ArrayList<>();
- Iterator it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
- while (it.hasNext()) {
- CacheSourceProvider s = it.next();
- if (s != null) RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
- if (s != null && s.acceptsConf(sourceConf)) {
- providers.add(s);
- }
- }
- Collections.sort(providers, (a, b) -> {
- Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
- Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
- return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
- });
- for (CacheSourceProvider provider : providers) {
- type = provider.sourceClass();
- if (type != null) break;
- }
- } else {
- type = serverClassLoader.loadClass(classval);
- }
- if (type == DataSource.class) {
- type = DataMemorySource.class;
- for (AnyValue itemConf : sourceConf.getAnyValues("property")) {
- if (itemConf.getValue("name", "").contains(DataSources.JDBC_URL)) {
- type = DataJdbcSource.class;
- break;
- }
- }
- }
- if (!Service.class.isAssignableFrom(type)) {
- logger.log(Level.SEVERE, "load application source resource, but not Service error: " + sourceConf);
- } else if (CacheSource.class.isAssignableFrom(type)) {
- cacheResource.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
- } else if (DataSource.class.isAssignableFrom(type)) {
- dataResources.put(sourceConf.getValue("name", ""), new SimpleEntry(type, sourceConf));
- } else {
- logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
- }
- } catch (Exception e) {
- logger.log(Level.SEVERE, "load application source resource error: " + sourceConf, e);
- }
- }
- }
+ final String confURI = appResFactory.find(RESNAME_APP_CONF_DIR, String.class);
//------------------------------------- 娉ㄥ唽 Resource --------------------------------------------------------
- resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
+ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try {
Resource res = field.getAnnotation(Resource.class);
if (res == null || !res.name().startsWith("properties.")) return;
- if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 DataSource
+ if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 DataSource
Class type = field.getType();
if (type != AnyValue.class && type != AnyValue[].class) return;
Object resource = null;
@@ -283,18 +229,18 @@ public abstract class NodeServer {
resource = properties.getAnyValues(res.name().substring("properties.".length()));
appResFactory.register(resourceName, AnyValue[].class, resource);
}
- field.set(src, resource);
+ field.set(srcObj, resource);
} catch (Exception e) {
logger.log(Level.SEVERE, "Resource inject error", e);
}
}, AnyValue.class, AnyValue[].class);
//------------------------------------- 娉ㄥ唽 Local AutoLoad(false) Service --------------------------------------------------------
- resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
+ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
Class resServiceType = Service.class;
try {
if (field.getAnnotation(Resource.class) == null) return;
- if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 AutoLoad Service
+ if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 AutoLoad Service
if (!Service.class.isAssignableFrom(field.getType())) return;
resServiceType = (Class) field.getType();
if (resServiceType.getAnnotation(Local.class) == null) return;
@@ -302,150 +248,56 @@ public abstract class NodeServer {
if (al == null || al.value()) return;
//ResourceFactory resfactory = (isSNCP() ? appResFactory : resourceFactory);
- SncpClient client = src instanceof Service ? Sncp.getSncpClient((Service) src) : null;
+ SncpClient client = srcObj instanceof Service ? Sncp.getSncpClient((Service) srcObj) : null;
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
final Set groups = new HashSet<>();
Service service = Modifier.isFinal(resServiceType.getModifiers()) ? (Service) resServiceType.getConstructor().newInstance() : Sncp.createLocalService(serverClassLoader, resourceName, resServiceType, null, appResFactory, appSncpTranFactory, sncpAddr, groups, null);
appResFactory.register(resourceName, resServiceType, service);
- field.set(src, service);
- rf.inject(service, self); // 缁欏叾鍙兘鍖呭惈@Resource鐨勫瓧娈佃祴鍊;
+ field.set(srcObj, service);
+ rf.inject(resourceName, service, self); // 缁欏叾鍙兘鍖呭惈@Resource鐨勫瓧娈佃祴鍊;
if (!application.isCompileMode()) service.init(null);
logger.info("[" + Thread.currentThread().getName() + "] Load Service(@Local @AutoLoad service = " + resServiceType.getSimpleName() + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
- logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + src + " error", e);
+ logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] Load @Local @AutoLoad(false) Service inject " + resServiceType + " to " + srcObj + " error", e);
}
}, Service.class);
//------------------------------------- 娉ㄥ唽 DataSource --------------------------------------------------------
- resourceFactory.register((ResourceFactory rf, final Object src, String resourceName, Field field, final Object attachment) -> {
+ resourceFactory.register((ResourceFactory rf, String srcResourceName, final Object srcObj, String resourceName, Field field, final Object attachment) -> {
try {
if (field.getAnnotation(Resource.class) == null) return;
- if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 DataSource
- SimpleEntry resEntry = dataResources.get(resourceName);
- AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
- DataSource source = null;
- if (sourceConf != null) {
- final Class sourceType = resEntry.getKey();
- if (sourceType == DataJdbcSource.class) {
- source = DataSources.createDataSource(resourceName, sourceConf);
- } else {
- boolean can = false;
- RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
- for (Constructor cr : sourceType.getConstructors()) {
- if (cr.getParameterCount() == 0) {
- can = true;
- break;
- }
- }
- if (DataSource.class.isAssignableFrom(sourceType) && can) { // 蹇呴』鏈夌┖鏋勯犲嚱鏁
- if (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) {
- source = (DataSource) sourceType.getConstructor().newInstance();
- RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
- } else {
- final Service srcService = (Service) src;
- SncpClient client = Sncp.getSncpClient(srcService);
- final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
- final Set groups = new HashSet<>();
- source = (DataSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
- }
- }
- }
- }
- if (source == null) {
- source = DataSources.createDataSource(confURI, resourceName); //浠巔ersistence.xml閰嶇疆涓垱寤
- }
-
- RedkaleClassLoader.putReflectionPublicConstructors(source.getClass(), source.getClass().getName());
- application.dataSources.add(source);
- ResourceType rt = source.getClass().getAnnotation(ResourceType.class);
- if (rt != null && rt.value() != DataSource.class) {
- appResFactory.register(resourceName, rt.value(), source);
- } else if (source instanceof SearchSource) {
- appResFactory.register(resourceName, SearchSource.class, source);
- }
- appResFactory.register(resourceName, DataSource.class, source);
-
- field.set(src, source);
- rf.inject(source, self); // 缁橝syncGroup鍜屽叾浠朄Resource鐨勫瓧娈佃祴鍊;
- //NodeServer.this.watchFactory.inject(src);
- if (!application.isCompileMode() && source instanceof Service) ((Service) source).init(sourceConf);
- logger.info("[" + Thread.currentThread().getName() + "] Load DataSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
+ if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //杩滅▼妯″紡涓嶅緱娉ㄥ叆 DataSource
+ DataSource source = application.loadDataSource(resourceName, false);
+ field.set(srcObj, source);
} catch (Exception e) {
- logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + src + " error", e);
+ logger.log(Level.SEVERE, "[" + Thread.currentThread().getName() + "] DataSource inject to " + srcObj + " error", e);
}
}, DataSource.class);
//------------------------------------- 娉ㄥ唽 CacheSource --------------------------------------------------------
- resourceFactory.register(new ResourceFactory.ResourceLoader() {
+ resourceFactory.register(new ResourceTypeLoader() {
@Override
- public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
+ public void load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null) return;
- if (!(src instanceof Service)) throw new RuntimeException("CacheSource must be inject in Service, cannot " + src);
- if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //杩滅▼妯″紡涓嶉渶瑕佹敞鍏 CacheSource
- final Service srcService = (Service) src;
+ if (!(srcObj instanceof Service)) throw new RuntimeException("CacheSource must be inject in Service, cannot " + srcObj);
+ if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //杩滅▼妯″紡涓嶉渶瑕佹敞鍏 CacheSource
+ final Service srcService = (Service) srcObj;
SncpClient client = Sncp.getSncpClient(srcService);
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
- SimpleEntry resEntry = cacheResource.get(resourceName);
- AnyValue sourceConf = resEntry == null ? null : resEntry.getValue();
- if (sourceConf == null) {
- SimpleEntry resEntry2 = dataResources.get(resourceName);
- sourceConf = resEntry2 == null ? null : resEntry2.getValue();
- }
- Class sourceType0 = CacheMemorySource.class;
- if (sourceConf != null) {
- String classval = sourceConf.getValue("value");
- if (classval == null || classval.isEmpty()) {
- RedkaleClassLoader.putServiceLoader(CacheSourceProvider.class);
- List providers = new ArrayList<>();
- Iterator it = ServiceLoader.load(CacheSourceProvider.class, serverClassLoader).iterator();
- while (it.hasNext()) {
- CacheSourceProvider s = it.next();
- if (s != null) RedkaleClassLoader.putReflectionPublicConstructors(s.getClass(), s.getClass().getName());
- if (s != null && s.acceptsConf(sourceConf)) {
- providers.add(s);
- }
- }
- Collections.sort(providers, (a, b) -> {
- Priority p1 = a == null ? null : a.getClass().getAnnotation(Priority.class);
- Priority p2 = b == null ? null : b.getClass().getAnnotation(Priority.class);
- return (p2 == null ? 0 : p2.value()) - (p1 == null ? 0 : p1.value());
- });
- for (CacheSourceProvider provider : providers) {
- sourceType0 = provider.sourceClass();
- if (sourceType0 != null) break;
- }
- } else {
- sourceType0 = serverClassLoader.loadClass(classval);
- }
- }
- final Class sourceType = sourceType0;
- Object source = null;
- if (CacheSource.class.isAssignableFrom(sourceType)) { // CacheSource
- RedkaleClassLoader.putReflectionPublicConstructors(sourceType, sourceType.getName());
- source = sourceType == CacheMemorySource.class ? new CacheMemorySource(resourceName)
- : (Modifier.isFinal(sourceType.getModifiers()) || sourceType.getAnnotation(Local.class) != null) ? sourceType.getConstructor().newInstance()
- : (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, client == null ? null : client.getMessageAgent(), appResFactory, appSncpTranFactory, sncpAddr, null, Sncp.getConf(srcService));
- Type genericType = field.getGenericType();
- application.cacheSources.add((CacheSource) source);
- appResFactory.register(resourceName, CacheSource.class, source);
- if (genericType != CacheSource.class) {
- appResFactory.register(resourceName, genericType, source);
- }
- }
- field.set(src, source);
- rf.inject(source, self); //
- if (!application.isCompileMode() && source instanceof Service) ((Service) source).init(sourceConf);
+ final boolean ws = (srcObj instanceof org.redkale.net.http.WebSocketNodeService) && sncpAddr != null;
+ CacheSource source = application.loadCacheSource(resourceName, ws);
+ field.set(srcObj, source);
- if ((src instanceof org.redkale.net.http.WebSocketNodeService) && sncpAddr != null) { //鍙湁WebSocketNodeService鐨勬湇鍔℃墠闇瑕佺粰SNCP鏈嶅姟娉ㄥ叆CacheMemorySource
+ if (ws) { //鍙湁WebSocketNodeService鐨勬湇鍔℃墠闇瑕佺粰SNCP鏈嶅姟娉ㄥ叆CacheMemorySource
NodeSncpServer sncpServer = application.findNodeSncpServer(sncpAddr);
if (source != null && source.getClass().getAnnotation(Local.class) == null) { //鏈湴妯″紡鐨凷ervice涓嶇敓鎴怱ncpServlet
sncpServer.getSncpServer().addSncpServlet((Service) source);
}
//logger.info("[" + Thread.currentThread().getName() + "] Load Service " + source);
}
- logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + source.getClass().getSimpleName() + ", resourceName = '" + resourceName + "')");
+ logger.info("[" + Thread.currentThread().getName() + "] Load CacheSource (type = " + (source == null ? null : source.getClass().getSimpleName()) + ", resourceName = '" + resourceName + "')");
} catch (Exception e) {
logger.log(Level.SEVERE, "DataSource inject error", e);
}
@@ -458,28 +310,28 @@ public abstract class NodeServer {
}, CacheSource.class);
//------------------------------------- 娉ㄥ唽 WebSocketNode --------------------------------------------------------
- resourceFactory.register(new ResourceFactory.ResourceLoader() {
+ resourceFactory.register(new ResourceTypeLoader() {
@Override
- public void load(ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) {
+ public void load(ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) {
try {
if (field.getAnnotation(Resource.class) == null) return;
- if ((src instanceof Service) && Sncp.isRemote((Service) src)) return; //杩滅▼妯″紡涓嶉渶瑕佹敞鍏 WebSocketNode
+ if ((srcObj instanceof Service) && Sncp.isRemote((Service) srcObj)) return; //杩滅▼妯″紡涓嶉渶瑕佹敞鍏 WebSocketNode
Service nodeService = (Service) rf.find(resourceName, WebSocketNode.class);
if (nodeService == null) {
final HashSet groups = new HashSet<>();
if (groups.isEmpty() && isSNCP() && NodeServer.this.sncpGroup != null) groups.add(NodeServer.this.sncpGroup);
- nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, Sncp.getMessageAgent((Service) src), application.getResourceFactory(), application.getSncpTransportFactory(), NodeServer.this.sncpAddress, groups, (AnyValue) null);
+ nodeService = Sncp.createLocalService(serverClassLoader, resourceName, org.redkale.net.http.WebSocketNodeService.class, Sncp.getMessageAgent((Service) srcObj), application.getResourceFactory(), application.getSncpTransportFactory(), NodeServer.this.sncpAddress, groups, (AnyValue) null);
(isSNCP() ? appResFactory : resourceFactory).register(resourceName, WebSocketNode.class, nodeService);
((org.redkale.net.http.WebSocketNodeService) nodeService).setName(resourceName);
}
- resourceFactory.inject(nodeService, self);
- MessageAgent messageAgent = Sncp.getMessageAgent((Service) src);
+ resourceFactory.inject(resourceName, nodeService, self);
+ MessageAgent messageAgent = Sncp.getMessageAgent((Service) srcObj);
if (messageAgent != null && Sncp.getMessageAgent(nodeService) == null) Sncp.setMessageAgent(nodeService, messageAgent);
- field.set(src, nodeService);
+ field.set(srcObj, nodeService);
if (Sncp.isRemote(nodeService)) {
remoteServices.add(nodeService);
} else {
- rf.inject(nodeService); //鍔ㄦ佸姞杞界殑Service涔熷瓨鍦ㄦ寜闇鍔犺浇鐨勬敞鍏ヨ祫婧
+ rf.inject(resourceName, nodeService); //鍔ㄦ佸姞杞界殑Service涔熷瓨鍦ㄦ寜闇鍔犺浇鐨勬敞鍏ヨ祫婧
localServices.add(nodeService);
interceptorServices.add(nodeService);
if (consumer != null) consumer.accept(null, nodeService);
@@ -529,7 +381,7 @@ public abstract class NodeServer {
|| (this.sncpGroup == null && entry.isEmptyGroups()) //绌虹殑SNCP閰嶇疆
|| serviceImplClass.getAnnotation(Local.class) != null;//鏈湴妯″紡
if (localed && (serviceImplClass.isInterface() || Modifier.isAbstract(serviceImplClass.getModifiers()))) continue; //鏈湴妯″紡涓嶈兘瀹炰緥鍖栨帴鍙e拰鎶借薄绫荤殑Service绫
- final ResourceFactory.ResourceLoader resourceLoader = (ResourceFactory rf, final Object src, final String resourceName, Field field, final Object attachment) -> {
+ final ResourceTypeLoader resourceLoader = (ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) -> {
try {
if (SncpClient.parseMethod(serviceImplClass).isEmpty() && serviceImplClass.getAnnotation(Priority.class) == null) { //class娌℃湁鍙敤鐨勬柟娉曚笖娌℃湁鏍囪鍚姩浼樺厛绾х殑锛 閫氬父涓築aseService
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) {
@@ -545,7 +397,7 @@ public abstract class NodeServer {
}
Service service;
- final boolean ws = src instanceof WebSocketServlet;
+ final boolean ws = srcObj instanceof WebSocketServlet;
if (ws || localed) { //鏈湴妯″紡
service = Sncp.createLocalService(serverClassLoader, resourceName, serviceImplClass, agent, appResourceFactory, appSncpTransFactory, NodeServer.this.sncpAddress, groups, entry.getProperty());
} else {
@@ -565,7 +417,7 @@ public abstract class NodeServer {
remoteServices.add(service);
if (agent != null) sncpRemoteAgents.put(agent.getName(), agent);
} else {
- if (field != null) rf.inject(service); //鍔ㄦ佸姞杞界殑Service涔熷瓨鍦ㄦ寜闇鍔犺浇鐨勬敞鍏ヨ祫婧
+ if (field != null) rf.inject(resourceName, service); //鍔ㄦ佸姞杞界殑Service涔熷瓨鍦ㄦ寜闇鍔犺浇鐨勬敞鍏ヨ祫婧
localServices.add(service);
interceptorServices.add(service);
if (consumer != null) consumer.accept(agent, service);
@@ -577,10 +429,12 @@ public abstract class NodeServer {
}
};
if (entry.isExpect()) {
- ResourceType rty = entry.getType().getAnnotation(ResourceType.class);
- resourceFactory.register(resourceLoader, rty == null ? entry.getType() : rty.value());
+ Class t = ResourceFactory.getResourceType(entry.getType());
+ if (resourceFactory.findResourceTypeLoader(t) == null) {
+ resourceFactory.register(resourceLoader, t);
+ }
} else {
- resourceLoader.load(resourceFactory, null, entry.getName(), null, false);
+ resourceLoader.load(resourceFactory, null, null, entry.getName(), null, false);
}
}
@@ -591,10 +445,10 @@ public abstract class NodeServer {
final StringBuilder sb = logger.isLoggable(Level.INFO) ? new StringBuilder() : null;
//---------------- inject ----------------
new ArrayList<>(localServices).forEach(y -> {
- resourceFactory.inject(y, NodeServer.this);
+ resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
});
new ArrayList<>(remoteServices).forEach(y -> {
- resourceFactory.inject(y, NodeServer.this);
+ resourceFactory.inject(Sncp.getResourceName(y), y, NodeServer.this);
calcMaxLength(y);
});
@@ -852,9 +706,9 @@ public abstract class NodeServer {
server.shutdown();
}
- public void command(String cmd) throws IOException {
+ public List