From b172b66263af93789ef86a5184a4f9b7887c0a72 Mon Sep 17 00:00:00 2001 From: Redkale <22250530@qq.com> Date: Thu, 5 Jul 2018 09:49:19 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E6=8E=89persistence.xml=E7=9A=84?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E6=96=87=E4=BB=B6=E5=8F=98=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E8=AF=A5=E6=9C=89watch=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=8F=90=E4=BE=9B=E5=8A=A8=E6=80=81=E4=BF=AE=E6=94=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=BA=90=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/redkale/boot/Application.java | 8 ++ .../boot/watch/AbstractWatchService.java | 3 + .../boot/watch/SourceWatchService.java | 63 +++++++++++++-- src/org/redkale/source/PoolJdbcSource.java | 80 +------------------ src/org/redkale/source/PoolTcpSource.java | 10 +-- 5 files changed, 78 insertions(+), 86 deletions(-) diff --git a/src/org/redkale/boot/Application.java b/src/org/redkale/boot/Application.java index a9933ff3b..cd538ab3f 100644 --- a/src/org/redkale/boot/Application.java +++ b/src/org/redkale/boot/Application.java @@ -362,6 +362,14 @@ public final class Application { return new ArrayList<>(servers); } + public List getDataSources() { + return new ArrayList<>(dataSources); + } + + public List getCacheSources() { + return new ArrayList<>(cacheSources); + } + public File getHome() { return home; } diff --git a/src/org/redkale/boot/watch/AbstractWatchService.java b/src/org/redkale/boot/watch/AbstractWatchService.java index 05ab2bd80..f4a993e4b 100644 --- a/src/org/redkale/boot/watch/AbstractWatchService.java +++ b/src/org/redkale/boot/watch/AbstractWatchService.java @@ -6,6 +6,7 @@ package org.redkale.boot.watch; import org.redkale.service.AbstractService; +import org.redkale.util.Comment; import org.redkale.watch.WatchService; /** @@ -14,4 +15,6 @@ import org.redkale.watch.WatchService; */ public abstract class AbstractWatchService extends AbstractService implements WatchService { + @Comment("缺少参数") + public static final int RET_WATCH_PARAMS_ILLEGAL = 1600_0001; } diff --git a/src/org/redkale/boot/watch/SourceWatchService.java b/src/org/redkale/boot/watch/SourceWatchService.java index bc3cba427..17904e696 100644 --- a/src/org/redkale/boot/watch/SourceWatchService.java +++ b/src/org/redkale/boot/watch/SourceWatchService.java @@ -5,10 +5,15 @@ */ package org.redkale.boot.watch; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Properties; import javax.annotation.Resource; import org.redkale.boot.Application; -import org.redkale.net.TransportFactory; -import org.redkale.net.http.RestService; +import org.redkale.net.http.*; +import org.redkale.service.*; +import org.redkale.source.*; +import org.redkale.util.*; /** * @@ -17,10 +22,58 @@ import org.redkale.net.http.RestService; @RestService(name = "source", catalog = "watch", repair = false) public class SourceWatchService extends AbstractWatchService { + @Comment("不存在的Source") + public static final int RET_SOURCE_NOT_EXISTS = 1605_0001; + + @Comment("Source不支持getReadPoolSource/getWritePoolSource方法") + public static final int RET_SOURCE_CHANGE_METHOD_NOT_EXISTS = 1605_0002; + + @Comment("PoolSource调用change方法失败") + public static final int RET_SOURCE_METHOD_INVOKE_NOT_EXISTS = 1605_0003; + @Resource private Application application; - @Resource - private TransportFactory transportFactory; - + @RestMapping(name = "change", auth = false, comment = "动态更改DataSource的配置") + public RetResult addNode(@RestParam(name = "name", comment = "DataSource的标识") final String name, + @RestParam(name = "properties", comment = "配置") final Properties properties) throws IOException { + if (name == null) return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param (name)"); + if (properties == null) return new RetResult(RET_WATCH_PARAMS_ILLEGAL, "not found param (properties)"); + DataSource source = null; + for (DataSource s : application.getDataSources()) { + String resName = ((Resourcable) s).resourceName(); + if (resName == null) continue; + if (!resName.equals(name)) continue; + source = s; + break; + } + if (source == null) return new RetResult(RET_SOURCE_NOT_EXISTS, "not found source (name = " + name + ")"); + Method readPoolMethod = null; + Method writePoolMethod = null; + Class stype = source.getClass(); + do { + for (Method m : stype.getDeclaredMethods()) { + if (!PoolSource.class.isAssignableFrom(m.getReturnType())) continue; + if (m.getParameterCount() != 0) continue; + if (m.getName().equals("getReadPoolSource")) { + readPoolMethod = m; + } else if (m.getName().equals("getWritePoolSource")) { + writePoolMethod = m; + } + } + } while ((stype = stype.getSuperclass()) != Object.class); + if (readPoolMethod == null) return new RetResult(RET_SOURCE_CHANGE_METHOD_NOT_EXISTS, "not found source method(getReadPoolSource)"); + if (writePoolMethod == null) return new RetResult(RET_SOURCE_CHANGE_METHOD_NOT_EXISTS, "not found source method(getWritePoolSource)"); + readPoolMethod.setAccessible(true); + writePoolMethod.setAccessible(true); + try { + PoolSource readPoolSource = (PoolSource) readPoolMethod.invoke(source); + readPoolSource.change(properties); + PoolSource writePoolSource = (PoolSource) writePoolMethod.invoke(source); + writePoolSource.change(properties); + return RetResult.success(); + } catch (Exception e) { + return new RetResult(RET_SOURCE_METHOD_INVOKE_NOT_EXISTS, "poolsource invoke method('change') error"); + } + } } diff --git a/src/org/redkale/source/PoolJdbcSource.java b/src/org/redkale/source/PoolJdbcSource.java index 62f5d5778..205dd810e 100644 --- a/src/org/redkale/source/PoolJdbcSource.java +++ b/src/org/redkale/source/PoolJdbcSource.java @@ -5,12 +5,8 @@ */ package org.redkale.source; -import java.io.*; -import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.net.URL; -import java.nio.file.*; -import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; import java.sql.*; import java.util.*; import java.util.concurrent.*; @@ -27,8 +23,6 @@ import static org.redkale.source.DataSources.*; */ public class PoolJdbcSource extends PoolSource { - private static final Map>>> maps = new HashMap<>(); - private final ConnectionPoolDataSource source; private final ArrayBlockingQueue queue; @@ -68,12 +62,6 @@ public class PoolJdbcSource extends PoolSource { logger.log(Level.WARNING, "connectionErronOccurred [" + event.getSQLException().getSQLState() + "]", event.getSQLException()); } }; - - try { - this.watch(); - } catch (Exception e) { - logger.log(Level.WARNING, DataSource.class.getSimpleName() + " watch " + persistxml + " error", e); - } } private static ConnectionPoolDataSource createDataSource(Properties property) { @@ -152,74 +140,14 @@ public class PoolJdbcSource extends PoolSource { return 0; } - private void watch() throws IOException { - if (persistxml == null || unitName == null) return; - final String file = persistxml.getFile(); - final File f = new File(file); - if (!f.isFile() || !f.canRead()) return; - synchronized (maps) { - AbstractMap.SimpleEntry>> entry = maps.get(file); - if (entry != null) { - entry.getValue().add(new WeakReference<>(this)); - return; - } - final WatchService watcher = f.toPath().getFileSystem().newWatchService(); - final List> list = new CopyOnWriteArrayList<>(); - Thread watchThread = new Thread() { - - @Override - public void run() { - try { - while (!this.isInterrupted()) { - final WatchKey key = watcher.take(); - long d; //防止文件正在更新过程中去读取 - for (;;) { - d = f.lastModified(); - Thread.sleep(2000L); - if (d == f.lastModified()) break; - } - final Map m = loadPersistenceXml(new FileInputStream(file)); - key.pollEvents().stream().forEach((event) -> { - if (event.kind() != ENTRY_MODIFY) return; - if (!((Path) event.context()).toFile().getName().equals(f.getName())) return; - for (WeakReference ref : list) { - PoolJdbcSource pool = ref.get(); - if (pool == null) continue; - try { - Properties property = m.get(unitName); - if (property == null) property = m.get(unitName + "." + pool.rwtype); - if (property != null) pool.change(property); - } catch (Exception ex) { - logger.log(Level.INFO, event.context() + " occur error", ex); - } - } - }); - key.reset(); - } - } catch (Exception e) { - logger.log(Level.WARNING, "DataSource watch " + file + " occur error", e); - } - } - }; - f.getParentFile().toPath().register(watcher, ENTRY_MODIFY); - watchThread.setName("DataSource-Watch-" + maps.size() + "-Thread"); - watchThread.setDaemon(true); - watchThread.start(); - logger.log(Level.INFO, watchThread.getName() + " start watching " + file); - //----------------------------------------------------------- - list.add(new WeakReference<>(this)); - maps.put(file, new AbstractMap.SimpleEntry<>(watcher, list)); - } - } - @Override public void change(Properties property) { Method seturlm; Class clazz = source.getClass(); - String newurl = property.getProperty(JDBC_URL); - String newuser = property.getProperty(JDBC_USER); - String newpassword = property.getProperty(JDBC_PWD); - if (this.url.equals(newurl) && this.username.equals(newuser) && this.password.equals(newpassword)) return; + String newurl = property.getProperty(JDBC_URL, this.url); + String newuser = property.getProperty(JDBC_USER, this.username); + String newpassword = property.getProperty(JDBC_PWD, this.password); + if (Objects.equals(this.url, newurl) && Objects.equals(this.username, newuser) && Objects.equals(this.password, newpassword)) return; try { try { seturlm = clazz.getMethod("setUrl", String.class); diff --git a/src/org/redkale/source/PoolTcpSource.java b/src/org/redkale/source/PoolTcpSource.java index 9c8c86d3f..e80d82e85 100644 --- a/src/org/redkale/source/PoolTcpSource.java +++ b/src/org/redkale/source/PoolTcpSource.java @@ -9,7 +9,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.*; import java.sql.*; -import java.util.Properties; +import java.util.*; import java.util.concurrent.*; import java.util.logging.*; import org.redkale.net.AsyncConnection; @@ -70,10 +70,10 @@ public abstract class PoolTcpSource extends PoolSource { @Override public void change(Properties prop) { - String newurl = prop.getProperty(JDBC_URL); - String newuser = prop.getProperty(JDBC_USER, ""); - String newpassword = prop.getProperty(JDBC_PWD, ""); - if (this.url.equals(newurl) && this.username.equals(newuser) && this.password.equals(newpassword)) return; + String newurl = prop.getProperty(JDBC_URL, this.url); + String newuser = prop.getProperty(JDBC_USER, this.username); + String newpassword = prop.getProperty(JDBC_PWD, this.password); + if (Objects.equals(this.url, newurl) && Objects.equals(this.username, newuser) && Objects.equals(this.password, newpassword)) return; this.url = newurl; this.username = newuser; this.password = newpassword;