Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4931c66868 | ||
|
|
fcff1c3a4b | ||
|
|
2005bf7e3b | ||
|
|
cb07a38f04 | ||
|
|
6085cd5eef | ||
|
|
086275c135 | ||
|
|
a449a96ef9 | ||
|
|
bc3209a09c | ||
|
|
63d1ef985d | ||
|
|
24505564c8 | ||
|
|
93a7bd63cf | ||
|
|
0b9b5baa49 | ||
|
|
5c4100e762 | ||
|
|
eb861014c4 | ||
|
|
e62f7ea63d | ||
|
|
d6df2055b2 | ||
|
|
570aac947a | ||
|
|
1fdc33b565 | ||
|
|
af8d0e978e | ||
|
|
c58022a81e | ||
|
|
f4cf828993 | ||
|
|
c4dc0de5fe |
@@ -22,3 +22,7 @@
|
|||||||
由于RedKale使用了JDK 8 内置的ASM包,所以需要在源码工程中的编译器选项中加入: <b>-XDignore.symbol.file=true</b>
|
由于RedKale使用了JDK 8 内置的ASM包,所以需要在源码工程中的编译器选项中加入: <b>-XDignore.symbol.file=true</b>
|
||||||
|
|
||||||
<h5>详情请访问: <a href='https://redkale.org' target='_blank'>https://redkale.org</a></h5>
|
<h5>详情请访问: <a href='https://redkale.org' target='_blank'>https://redkale.org</a></h5>
|
||||||
|
|
||||||
|
<h5>基本文档: <a href='https://redkale.org/articles.html' target='_blank'>https://redkale.org/articles.html</a></h5>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export LC_ALL="zh_CN.UTF-8"
|
|||||||
|
|
||||||
APP_HOME=`dirname "$0"`
|
APP_HOME=`dirname "$0"`
|
||||||
|
|
||||||
if [ ! -a "$APP_HOME"/conf/application.xml ]; then
|
if [ ! -f "$APP_HOME"/conf/application.xml ]; then
|
||||||
APP_HOME="$APP_HOME"/..
|
APP_HOME="$APP_HOME"/..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ export LC_ALL="zh_CN.UTF-8"
|
|||||||
|
|
||||||
APP_HOME=`dirname "$0"`
|
APP_HOME=`dirname "$0"`
|
||||||
|
|
||||||
if [ ! -a "$APP_HOME"/conf/application.xml ]; then
|
if [ ! -f "$APP_HOME"/conf/application.xml ]; then
|
||||||
APP_HOME="$APP_HOME"/..
|
APP_HOME="$APP_HOME"/..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export LC_ALL="zh_CN.UTF-8"
|
|||||||
|
|
||||||
APP_HOME=`dirname "$0"`
|
APP_HOME=`dirname "$0"`
|
||||||
|
|
||||||
if [ ! -a "$APP_HOME"/conf/application.xml ]; then
|
if [ ! -f "$APP_HOME"/conf/application.xml ]; then
|
||||||
APP_HOME="$APP_HOME"/..
|
APP_HOME="$APP_HOME"/..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
|
|
||||||
<server protocol="HTTP" host="0.0.0.0" port="6060" root="root">
|
<server protocol="HTTP" host="0.0.0.0" port="6060" root="root">
|
||||||
|
|
||||||
|
<request>
|
||||||
|
<remoteaddr value="request.headers.X-RemoteAddress"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<response>
|
||||||
|
<defcookie domain="" path=""/>
|
||||||
|
<addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" />
|
||||||
|
<setheader name="Access-Control-Allow-Credentials" value="true"/>
|
||||||
|
</response>
|
||||||
|
|
||||||
<services autoload="true"/>
|
<services autoload="true"/>
|
||||||
|
|
||||||
<filters autoload="true"/>
|
<filters autoload="true"/>
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
<persistence-unit name="user.read" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="user.read" transaction-type="RESOURCE_LOCAL">
|
||||||
<shared-cache-mode>ALL</shared-cache-mode>
|
<shared-cache-mode>ALL</shared-cache-mode>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/user?autoReconnect=true&characterEncoding=utf8"/>
|
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
|
||||||
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
|
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
|
||||||
<property name="javax.persistence.jdbc.user" value="root"/>
|
<property name="javax.persistence.jdbc.user" value="system"/>
|
||||||
<property name="javax.persistence.jdbc.password" value="1234"/>
|
<property name="javax.persistence.jdbc.password" value="1234"/>
|
||||||
</properties>
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
|
|||||||
@@ -211,11 +211,14 @@
|
|||||||
如果addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值
|
如果addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值
|
||||||
如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值
|
如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值
|
||||||
例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。
|
例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。
|
||||||
|
options 节点: 设置了该节点却auto=true,当request的method=OPTIONS自动设置addheader、setheader并返回200状态码
|
||||||
-->
|
-->
|
||||||
<response>
|
<response>
|
||||||
<defcookie domain="" path=""/>
|
<defcookie domain="" path=""/>
|
||||||
<addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" />
|
<addheader name="Access-Control-Allow-Origin" value="request.headers.Origin" />
|
||||||
|
<setheader name="Access-Control-Allow-Headers" value="request.headers.Access-Control-Request-Headers"/>
|
||||||
<setheader name="Access-Control-Allow-Credentials" value="true"/>
|
<setheader name="Access-Control-Allow-Credentials" value="true"/>
|
||||||
|
<options auto="true" />
|
||||||
</response>
|
</response>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
@@ -3,13 +3,15 @@
|
|||||||
<persistence>
|
<persistence>
|
||||||
<!-- 系统基本库 -->
|
<!-- 系统基本库 -->
|
||||||
<persistence-unit name="demouser">
|
<persistence-unit name="demouser">
|
||||||
<!-- 为NONE表示不启动缓存,@Cacheable 失效; 非NONE值(通常用ALL)表示开启缓存。 -->
|
|
||||||
<shared-cache-mode>NONE</shared-cache-mode>
|
|
||||||
<properties>
|
<properties>
|
||||||
<!--
|
<!--
|
||||||
DataSource的实现类,没有设置默认为org.redkale.source.DataJdbcSource的实现,使用常规基于JDBC的数据库驱动一般无需设置
|
DataSource的实现类,没有设置默认为org.redkale.source.DataJdbcSource的实现,使用常规基于JDBC的数据库驱动一般无需设置
|
||||||
-->
|
-->
|
||||||
<property name="javax.persistence.datasource" value="org.redkale.source.DataJdbcSource"/>
|
<property name="javax.persistence.datasource" value="org.redkale.source.DataJdbcSource"/>
|
||||||
|
<!--
|
||||||
|
是否开启缓存(标记为@Cacheable的Entity类),值目前只支持两种: ALL: 所有开启缓存。 NONE: 关闭所有缓存
|
||||||
|
-->
|
||||||
|
<property name="javax.persistence.cachemode" value="ALL"/>
|
||||||
|
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbuser?characterEncoding=utf8"/>
|
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbuser?characterEncoding=utf8"/>
|
||||||
<!--
|
<!--
|
||||||
@@ -42,7 +44,6 @@
|
|||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
<!-- IM消息库 -->
|
<!-- IM消息库 -->
|
||||||
<persistence-unit name="demoim">
|
<persistence-unit name="demoim">
|
||||||
<shared-cache-mode>NONE</shared-cache-mode>
|
|
||||||
<properties>
|
<properties>
|
||||||
<!-- jdbc:mysql://127.0.0.1:3306/dbim?autoReconnect=true&autoReconnectForPools=true&characterEncoding=utf8 -->
|
<!-- jdbc:mysql://127.0.0.1:3306/dbim?autoReconnect=true&autoReconnectForPools=true&characterEncoding=utf8 -->
|
||||||
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbim?characterEncoding=utf8"/>
|
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/dbim?characterEncoding=utf8"/>
|
||||||
|
|||||||
@@ -248,9 +248,9 @@ public final class Application {
|
|||||||
//--------------transportBufferPool-----------
|
//--------------transportBufferPool-----------
|
||||||
AtomicLong createBufferCounter = new AtomicLong();
|
AtomicLong createBufferCounter = new AtomicLong();
|
||||||
AtomicLong cycleBufferCounter = new AtomicLong();
|
AtomicLong cycleBufferCounter = new AtomicLong();
|
||||||
final int bufferCapacity = transportConf.getIntValue("bufferCapacity", 8 * 1024);
|
final int bufferCapacity = Math.max(parseLenth(transportConf.getValue("bufferCapacity"), 8 * 1024), 4 * 1024);
|
||||||
final int bufferPoolSize = transportConf.getIntValue("bufferPoolSize", groupsize * Runtime.getRuntime().availableProcessors() * 8);
|
final int bufferPoolSize = parseLenth(transportConf.getValue("bufferPoolSize"), groupsize * Runtime.getRuntime().availableProcessors() * 8);
|
||||||
final int threads = transportConf.getIntValue("threads", groupsize * Runtime.getRuntime().availableProcessors() * 8);
|
final int threads = parseLenth(transportConf.getValue("threads"), groupsize * Runtime.getRuntime().availableProcessors() * 8);
|
||||||
transportPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, bufferPoolSize,
|
transportPool = new ObjectPool<>(createBufferCounter, cycleBufferCounter, bufferPoolSize,
|
||||||
(Object... params) -> ByteBuffer.allocateDirect(bufferCapacity), null, (e) -> {
|
(Object... params) -> ByteBuffer.allocateDirect(bufferCapacity), null, (e) -> {
|
||||||
if (e == null || e.isReadOnly() || e.capacity() != bufferCapacity) return false;
|
if (e == null || e.isReadOnly() || e.capacity() != bufferCapacity) return false;
|
||||||
@@ -763,6 +763,15 @@ public final class Application {
|
|||||||
this.transportFactory.shutdownNow();
|
this.transportFactory.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int parseLenth(String value, int defValue) {
|
||||||
|
if (value == null) return defValue;
|
||||||
|
value = value.toUpperCase().replace("B", "");
|
||||||
|
if (value.endsWith("G")) return Integer.decode(value.replace("G", "")) * 1024 * 1024 * 1024;
|
||||||
|
if (value.endsWith("M")) return Integer.decode(value.replace("M", "")) * 1024 * 1024;
|
||||||
|
if (value.endsWith("K")) return Integer.decode(value.replace("K", "")) * 1024;
|
||||||
|
return Integer.decode(value);
|
||||||
|
}
|
||||||
|
|
||||||
private static AnyValue load(final InputStream in0) {
|
private static AnyValue load(final InputStream in0) {
|
||||||
final DefaultAnyValue any = new DefaultAnyValue();
|
final DefaultAnyValue any = new DefaultAnyValue();
|
||||||
try (final InputStream in = in0) {
|
try (final InputStream in = in0) {
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public final class ClassFilter<T> {
|
|||||||
*/
|
*/
|
||||||
public final Set<FilterEntry<T>> getFilterExpectEntrys() {
|
public final Set<FilterEntry<T>> getFilterExpectEntrys() {
|
||||||
HashSet<FilterEntry<T>> set = new HashSet<>();
|
HashSet<FilterEntry<T>> set = new HashSet<>();
|
||||||
set.addAll(entrys);
|
set.addAll(expectEntrys);
|
||||||
if (ors != null) ors.forEach(f -> set.addAll(f.getFilterExpectEntrys()));
|
if (ors != null) ors.forEach(f -> set.addAll(f.getFilterExpectEntrys()));
|
||||||
if (ands != null) ands.forEach(f -> set.addAll(f.getFilterExpectEntrys()));
|
if (ands != null) ands.forEach(f -> set.addAll(f.getFilterExpectEntrys()));
|
||||||
return set;
|
return set;
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public abstract class NodeServer {
|
|||||||
final TransportFactory appTranFactory = application.getTransportFactory();
|
final TransportFactory appTranFactory = application.getTransportFactory();
|
||||||
final AnyValue resources = application.config.getAnyValue("resources");
|
final AnyValue resources = application.config.getAnyValue("resources");
|
||||||
final Map<String, AnyValue> cacheResource = new HashMap<>();
|
final Map<String, AnyValue> cacheResource = new HashMap<>();
|
||||||
//final Map<String, AnyValue> dataResources = new HashMap<>();
|
final Map<String, AnyValue> dataResources = new HashMap<>();
|
||||||
if (resources != null) {
|
if (resources != null) {
|
||||||
for (AnyValue sourceConf : resources.getAnyValues("source")) {
|
for (AnyValue sourceConf : resources.getAnyValues("source")) {
|
||||||
try {
|
try {
|
||||||
@@ -183,9 +183,7 @@ public abstract class NodeServer {
|
|||||||
} else if (CacheSource.class.isAssignableFrom(type)) {
|
} else if (CacheSource.class.isAssignableFrom(type)) {
|
||||||
cacheResource.put(sourceConf.getValue("name", ""), sourceConf);
|
cacheResource.put(sourceConf.getValue("name", ""), sourceConf);
|
||||||
} else if (DataSource.class.isAssignableFrom(type)) {
|
} else if (DataSource.class.isAssignableFrom(type)) {
|
||||||
//dataResources.put(sourceConf.getValue("name", ""), sourceConf);
|
dataResources.put(sourceConf.getValue("name", ""), sourceConf);
|
||||||
//暂时不支持DataSource通过<resources>设置
|
|
||||||
logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
|
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
|
logger.log(Level.SEVERE, "load application source resource, but not CacheSource error: " + sourceConf);
|
||||||
}
|
}
|
||||||
@@ -258,12 +256,20 @@ public abstract class NodeServer {
|
|||||||
final Service srcService = (Service) src;
|
final Service srcService = (Service) src;
|
||||||
SncpClient client = Sncp.getSncpClient(srcService);
|
SncpClient client = Sncp.getSncpClient(srcService);
|
||||||
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
|
final InetSocketAddress sncpAddr = client == null ? null : client.getClientAddress();
|
||||||
final AnyValue sourceConf = cacheResource.get(resourceName);
|
|
||||||
final Class sourceType = sourceConf == null ? CacheMemorySource.class : serverClassLoader.loadClass(sourceConf.getValue("type"));
|
|
||||||
final Set<String> groups = new HashSet<>();
|
final Set<String> groups = new HashSet<>();
|
||||||
if (client != null && client.getSameGroup() != null) groups.add(client.getSameGroup());
|
if (client != null && client.getSameGroup() != null) groups.add(client.getSameGroup());
|
||||||
if (client != null && client.getDiffGroups() != null) groups.addAll(client.getDiffGroups());
|
if (client != null && client.getDiffGroups() != null) groups.addAll(client.getDiffGroups());
|
||||||
final CacheSource source = (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, appResFactory, appTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
|
|
||||||
|
AnyValue sourceConf = cacheResource.get(resourceName);
|
||||||
|
if (sourceConf == null) sourceConf = dataResources.get(resourceName);
|
||||||
|
final Class sourceType = sourceConf == null ? CacheMemorySource.class : serverClassLoader.loadClass(sourceConf.getValue("value"));
|
||||||
|
Object source;
|
||||||
|
if (DataSource.class.isAssignableFrom(sourceType)) { // DataSource
|
||||||
|
source = (DataSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, appResFactory, appTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
|
||||||
|
application.dataSources.add((DataSource) source);
|
||||||
|
appResFactory.register(resourceName, DataSource.class, source);
|
||||||
|
} else { // CacheSource
|
||||||
|
source = (CacheSource) Sncp.createLocalService(serverClassLoader, resourceName, sourceType, appResFactory, appTranFactory, sncpAddr, groups, Sncp.getConf(srcService));
|
||||||
Type genericType = field.getGenericType();
|
Type genericType = field.getGenericType();
|
||||||
ParameterizedType pt = (genericType instanceof ParameterizedType) ? (ParameterizedType) genericType : null;
|
ParameterizedType pt = (genericType instanceof ParameterizedType) ? (ParameterizedType) genericType : null;
|
||||||
Type valType = pt == null ? null : pt.getActualTypeArguments()[1];
|
Type valType = pt == null ? null : pt.getActualTypeArguments()[1];
|
||||||
@@ -272,9 +278,10 @@ public abstract class NodeServer {
|
|||||||
memorySource.setStoreType(pt == null ? Serializable.class : (Class) pt.getActualTypeArguments()[0], valType instanceof Class ? (Class) valType : Object.class);
|
memorySource.setStoreType(pt == null ? Serializable.class : (Class) pt.getActualTypeArguments()[0], valType instanceof Class ? (Class) valType : Object.class);
|
||||||
if (field.getAnnotation(Transient.class) != null) memorySource.setNeedStore(false); //必须在setStoreType之后
|
if (field.getAnnotation(Transient.class) != null) memorySource.setNeedStore(false); //必须在setStoreType之后
|
||||||
}
|
}
|
||||||
application.cacheSources.add(source);
|
application.cacheSources.add((CacheSource) source);
|
||||||
appResFactory.register(resourceName, genericType, source);
|
appResFactory.register(resourceName, genericType, source);
|
||||||
appResFactory.register(resourceName, CacheSource.class, source);
|
appResFactory.register(resourceName, CacheSource.class, source);
|
||||||
|
}
|
||||||
field.set(src, source);
|
field.set(src, source);
|
||||||
rf.inject(source, self); //
|
rf.inject(source, self); //
|
||||||
if (source instanceof Service) ((Service) source).init(sourceConf);
|
if (source instanceof Service) ((Service) source).init(sourceConf);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.io.IOException;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.CompletionHandler;
|
import java.nio.channels.CompletionHandler;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 协议响应对象
|
* 协议响应对象
|
||||||
@@ -113,8 +114,7 @@ public abstract class Response<C extends Context, R extends Request<C>> {
|
|||||||
try {
|
try {
|
||||||
recycleListener.accept(request, this);
|
recycleListener.accept(request, this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println(request);
|
context.logger.log(Level.WARNING, "Response.recycleListener error, request = " + request, e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
recycleListener = null;
|
recycleListener = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,11 +99,11 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.address = new InetSocketAddress(config.getValue("host", "0.0.0.0"), config.getIntValue("port", 80));
|
this.address = new InetSocketAddress(config.getValue("host", "0.0.0.0"), config.getIntValue("port", 80));
|
||||||
this.charset = Charset.forName(config.getValue("charset", "UTF-8"));
|
this.charset = Charset.forName(config.getValue("charset", "UTF-8"));
|
||||||
this.backlog = config.getIntValue("backlog", 8 * 1024);
|
|
||||||
this.readTimeoutSecond = config.getIntValue("readTimeoutSecond", 0);
|
this.readTimeoutSecond = config.getIntValue("readTimeoutSecond", 0);
|
||||||
this.writeTimeoutSecond = config.getIntValue("writeTimeoutSecond", 0);
|
this.writeTimeoutSecond = config.getIntValue("writeTimeoutSecond", 0);
|
||||||
this.maxbody = config.getIntValue("maxbody", 64 * 1024);
|
this.backlog = parseLenth(config.getValue("backlog"), 8 * 1024);
|
||||||
int bufCapacity = config.getIntValue("bufferCapacity", 8 * 1024);
|
this.maxbody = parseLenth(config.getValue("maxbody"), 64 * 1024);
|
||||||
|
int bufCapacity = parseLenth(config.getValue("bufferCapacity"), 8 * 1024);
|
||||||
this.bufferCapacity = bufCapacity < 256 ? 256 : bufCapacity;
|
this.bufferCapacity = bufCapacity < 256 ? 256 : bufCapacity;
|
||||||
this.threads = config.getIntValue("threads", Runtime.getRuntime().availableProcessors() * 16);
|
this.threads = config.getIntValue("threads", Runtime.getRuntime().availableProcessors() * 16);
|
||||||
this.bufferPoolSize = config.getIntValue("bufferPoolSize", Runtime.getRuntime().availableProcessors() * 512);
|
this.bufferPoolSize = config.getIntValue("bufferPoolSize", Runtime.getRuntime().availableProcessors() * 512);
|
||||||
@@ -120,6 +120,24 @@ public abstract class Server<K extends Serializable, C extends Context, R extend
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static int parseLenth(String value, int defValue) {
|
||||||
|
if (value == null) return defValue;
|
||||||
|
value = value.toUpperCase().replace("B", "");
|
||||||
|
if (value.endsWith("G")) return Integer.decode(value.replace("G", "")) * 1024 * 1024 * 1024;
|
||||||
|
if (value.endsWith("M")) return Integer.decode(value.replace("M", "")) * 1024 * 1024;
|
||||||
|
if (value.endsWith("K")) return Integer.decode(value.replace("K", "")) * 1024;
|
||||||
|
return Integer.decode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static long parseLenth(String value, long defValue) {
|
||||||
|
if (value == null) return defValue;
|
||||||
|
value = value.toUpperCase().replace("B", "");
|
||||||
|
if (value.endsWith("G")) return Long.decode(value.replace("G", "")) * 1024 * 1024 * 1024;
|
||||||
|
if (value.endsWith("M")) return Long.decode(value.replace("M", "")) * 1024 * 1024;
|
||||||
|
if (value.endsWith("K")) return Long.decode(value.replace("K", "")) * 1024;
|
||||||
|
return Long.decode(value);
|
||||||
|
}
|
||||||
|
|
||||||
public void destroy(final AnyValue config) throws Exception {
|
public void destroy(final AnyValue config) throws Exception {
|
||||||
this.prepare.destroy(context, config);
|
this.prepare.destroy(context, config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -235,6 +235,10 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
|
|||||||
try {
|
try {
|
||||||
final String uri = request.getRequestURI();
|
final String uri = request.getRequestURI();
|
||||||
HttpServlet servlet;
|
HttpServlet servlet;
|
||||||
|
if (response.isAutoOptions() && "OPTIONS".equals(request.getMethod())) {
|
||||||
|
response.finish(200, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (request.isWebSocket()) {
|
if (request.isWebSocket()) {
|
||||||
servlet = wsmappings.get(uri);
|
servlet = wsmappings.get(uri);
|
||||||
if (servlet == null && this.regWsArray != null) {
|
if (servlet == null && this.regWsArray != null) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
|
|
||||||
protected static final Charset UTF8 = Charset.forName("UTF-8");
|
protected static final Charset UTF8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
protected static final String SESSIONID_NAME = "JSESSIONID";
|
public static final String SESSIONID_NAME = "JSESSIONID";
|
||||||
|
|
||||||
@Comment("Method GET/POST/...")
|
@Comment("Method GET/POST/...")
|
||||||
private String method;
|
private String method;
|
||||||
@@ -888,6 +888,15 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* 获取请求Header总对象
|
||||||
|
*
|
||||||
|
* @return AnyValue
|
||||||
|
*/
|
||||||
|
public AnyValue getHeaders() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有的header名
|
* 获取所有的header名
|
||||||
*
|
*
|
||||||
@@ -1086,6 +1095,16 @@ public class HttpRequest extends Request<HttpContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* 获取请求参数总对象
|
||||||
|
*
|
||||||
|
* @return AnyValue
|
||||||
|
*/
|
||||||
|
public AnyValue getParameters() {
|
||||||
|
parseBody();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有参数名
|
* 获取所有参数名
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -125,17 +125,21 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
|
|
||||||
private final String[][] defaultSetHeaders;
|
private final String[][] defaultSetHeaders;
|
||||||
|
|
||||||
|
private final boolean autoOptions;
|
||||||
|
|
||||||
private final HttpCookie defcookie;
|
private final HttpCookie defcookie;
|
||||||
|
|
||||||
public static ObjectPool<Response> createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator<Response> creator) {
|
public static ObjectPool<Response> createPool(AtomicLong creatCounter, AtomicLong cycleCounter, int max, Creator<Response> creator) {
|
||||||
return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((HttpResponse) x).prepare(), (x) -> ((HttpResponse) x).recycle());
|
return new ObjectPool<>(creatCounter, cycleCounter, max, creator, (x) -> ((HttpResponse) x).prepare(), (x) -> ((HttpResponse) x).recycle());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponse(HttpContext context, HttpRequest request, String[][] defaultAddHeaders, String[][] defaultSetHeaders, HttpCookie defcookie) {
|
public HttpResponse(HttpContext context, HttpRequest request, String[][] defaultAddHeaders, String[][] defaultSetHeaders,
|
||||||
|
HttpCookie defcookie, boolean autoOptions) {
|
||||||
super(context, request);
|
super(context, request);
|
||||||
this.defaultAddHeaders = defaultAddHeaders;
|
this.defaultAddHeaders = defaultAddHeaders;
|
||||||
this.defaultSetHeaders = defaultSetHeaders;
|
this.defaultSetHeaders = defaultSetHeaders;
|
||||||
this.defcookie = defcookie;
|
this.defcookie = defcookie;
|
||||||
|
this.autoOptions = autoOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,6 +149,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean recycle() {
|
protected boolean recycle() {
|
||||||
|
boolean rs = super.recycle();
|
||||||
this.status = 200;
|
this.status = 200;
|
||||||
this.contentLength = -1;
|
this.contentLength = -1;
|
||||||
this.contentType = null;
|
this.contentType = null;
|
||||||
@@ -152,7 +157,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
this.headsended = false;
|
this.headsended = false;
|
||||||
this.header.clear();
|
this.header.clear();
|
||||||
this.bufferHandler = null;
|
this.bufferHandler = null;
|
||||||
return super.recycle();
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -185,6 +190,10 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
this.servlet = servlet;
|
this.servlet = servlet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isAutoOptions() {
|
||||||
|
return this.autoOptions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加Cookie值
|
* 增加Cookie值
|
||||||
*
|
*
|
||||||
@@ -439,6 +448,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
if (isClosed()) return;
|
if (isClosed()) return;
|
||||||
if (this.recycleListener != null) this.output = obj;
|
if (this.recycleListener != null) this.output = obj;
|
||||||
if (obj == null || obj.isEmpty()) {
|
if (obj == null || obj.isEmpty()) {
|
||||||
|
this.contentLength = 0;
|
||||||
final ByteBuffer headbuf = createHeader();
|
final ByteBuffer headbuf = createHeader();
|
||||||
headbuf.flip();
|
headbuf.flip();
|
||||||
super.finish(headbuf);
|
super.finish(headbuf);
|
||||||
@@ -733,12 +743,14 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
ByteBuffer hbuffer = createHeader();
|
ByteBuffer hbuffer = createHeader();
|
||||||
hbuffer.flip();
|
hbuffer.flip();
|
||||||
if (fileBody == null) {
|
if (fileBody == null) {
|
||||||
|
if (this.recycleListener != null) this.output = file;
|
||||||
finishFile(hbuffer, file, start, len);
|
finishFile(hbuffer, file, start, len);
|
||||||
} else {
|
} else {
|
||||||
if (start >= 0) {
|
if (start >= 0) {
|
||||||
fileBody.position((int) start);
|
fileBody.position((int) start);
|
||||||
if (len > 0) fileBody.limit((int) (fileBody.position() + len));
|
if (len > 0) fileBody.limit((int) (fileBody.position() + len));
|
||||||
}
|
}
|
||||||
|
if (this.recycleListener != null) this.output = fileBody;
|
||||||
super.finish(hbuffer, fileBody);
|
super.finish(hbuffer, fileBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,7 +766,7 @@ public class HttpResponse extends Response<HttpContext, HttpRequest> {
|
|||||||
|
|
||||||
buffer.put(("Content-Type: " + (this.contentType == null ? "text/plain; charset=utf-8" : this.contentType) + "\r\n").getBytes());
|
buffer.put(("Content-Type: " + (this.contentType == null ? "text/plain; charset=utf-8" : this.contentType) + "\r\n").getBytes());
|
||||||
|
|
||||||
if (this.contentLength > 0) {
|
if (this.contentLength >= 0) {
|
||||||
buffer.put(("Content-Length: " + this.contentLength + "\r\n").getBytes());
|
buffer.put(("Content-Length: " + this.contentLength + "\r\n").getBytes());
|
||||||
}
|
}
|
||||||
if (!this.request.isKeepAlive()) {
|
if (!this.request.isKeepAlive()) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import java.net.HttpCookie;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.redkale.net.*;
|
import org.redkale.net.*;
|
||||||
import org.redkale.net.sncp.Sncp;
|
import org.redkale.net.sncp.Sncp;
|
||||||
import org.redkale.service.Service;
|
import org.redkale.service.Service;
|
||||||
@@ -231,8 +232,7 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (NoSuchFieldException | SecurityException e) {
|
} catch (NoSuchFieldException | SecurityException e) {
|
||||||
System.err.println("serviceType = " + serviceType + ", servletClass = " + item.getClass());
|
logger.log(Level.SEVERE, "serviceType = " + serviceType + ", servletClass = " + item.getClass(), e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final boolean first = servlet == null;
|
final boolean first = servlet == null;
|
||||||
@@ -280,6 +280,8 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
|
|||||||
});
|
});
|
||||||
final List<String[]> defaultAddHeaders = new ArrayList<>();
|
final List<String[]> defaultAddHeaders = new ArrayList<>();
|
||||||
final List<String[]> defaultSetHeaders = new ArrayList<>();
|
final List<String[]> defaultSetHeaders = new ArrayList<>();
|
||||||
|
boolean autoOptions = false;
|
||||||
|
|
||||||
HttpCookie defaultCookie = null;
|
HttpCookie defaultCookie = null;
|
||||||
String remoteAddrHeader = null;
|
String remoteAddrHeader = null;
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
@@ -342,10 +344,15 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
|
|||||||
defaultCookie.setPath(path);
|
defaultCookie.setPath(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
AnyValue options = resps == null ? null : resps.getAnyValue("options");
|
||||||
|
autoOptions = options != null && options.getBoolValue("auto", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
final String[][] addHeaders = defaultAddHeaders.isEmpty() ? null : defaultAddHeaders.toArray(new String[defaultAddHeaders.size()][]);
|
final String[][] addHeaders = defaultAddHeaders.isEmpty() ? null : defaultAddHeaders.toArray(new String[defaultAddHeaders.size()][]);
|
||||||
final String[][] setHeaders = defaultSetHeaders.isEmpty() ? null : defaultSetHeaders.toArray(new String[defaultSetHeaders.size()][]);
|
final String[][] setHeaders = defaultSetHeaders.isEmpty() ? null : defaultSetHeaders.toArray(new String[defaultSetHeaders.size()][]);
|
||||||
|
final boolean options = autoOptions;
|
||||||
|
|
||||||
final HttpCookie defCookie = defaultCookie;
|
final HttpCookie defCookie = defaultCookie;
|
||||||
final String addrHeader = remoteAddrHeader;
|
final String addrHeader = remoteAddrHeader;
|
||||||
AtomicLong createResponseCounter = new AtomicLong();
|
AtomicLong createResponseCounter = new AtomicLong();
|
||||||
@@ -353,7 +360,7 @@ public class HttpServer extends Server<String, HttpContext, HttpRequest, HttpRes
|
|||||||
ObjectPool<Response> responsePool = HttpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
|
ObjectPool<Response> responsePool = HttpResponse.createPool(createResponseCounter, cycleResponseCounter, this.responsePoolSize, null);
|
||||||
HttpContext httpcontext = new HttpContext(this.serverStartTime, this.logger, executor, rcapacity, bufferPool, responsePool,
|
HttpContext httpcontext = new HttpContext(this.serverStartTime, this.logger, executor, rcapacity, bufferPool, responsePool,
|
||||||
this.maxbody, this.charset, this.address, this.prepare, this.readTimeoutSecond, this.writeTimeoutSecond);
|
this.maxbody, this.charset, this.address, this.prepare, this.readTimeoutSecond, this.writeTimeoutSecond);
|
||||||
responsePool.setCreator((Object... params) -> new HttpResponse(httpcontext, new HttpRequest(httpcontext, addrHeader), addHeaders, setHeaders, defCookie));
|
responsePool.setCreator((Object... params) -> new HttpResponse(httpcontext, new HttpRequest(httpcontext, addrHeader), addHeaders, setHeaders, defCookie, options));
|
||||||
return httpcontext;
|
return httpcontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ public final class Rest {
|
|||||||
childFactory.register(rc.type(), true, rc.ignoreColumns());
|
childFactory.register(rc.type(), true, rc.ignoreColumns());
|
||||||
childFactory.reloadCoder(rc.type());
|
childFactory.reloadCoder(rc.type());
|
||||||
types.add(rc.type());
|
types.add(rc.type());
|
||||||
|
childFactory.tiny(rc.tiny());
|
||||||
}
|
}
|
||||||
return childFactory.getConvert();
|
return childFactory.getConvert();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||||||
@Repeatable(RestConvert.RestConverts.class)
|
@Repeatable(RestConvert.RestConverts.class)
|
||||||
public @interface RestConvert {
|
public @interface RestConvert {
|
||||||
|
|
||||||
|
boolean tiny() default true;
|
||||||
|
|
||||||
Class type();
|
Class type();
|
||||||
|
|
||||||
String[] ignoreColumns() default {};
|
String[] ignoreColumns() default {};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.logging.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import org.redkale.convert.Convert;
|
import org.redkale.convert.Convert;
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
@@ -482,6 +483,25 @@ public abstract class WebSocket<G extends Serializable, T> {
|
|||||||
public void onClose(int code, String reason) {
|
public void onClose(int code, String reason) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发生异常时调用
|
||||||
|
*
|
||||||
|
* @param t 异常
|
||||||
|
* @param buffers ByteBuffer[]
|
||||||
|
*/
|
||||||
|
public void onOccurException(Throwable t, ByteBuffer[] buffers) {
|
||||||
|
this.getLogger().log(Level.SEVERE, "WebSocket receive or send Message error", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Logger
|
||||||
|
*
|
||||||
|
* @return Logger Logger
|
||||||
|
*/
|
||||||
|
public Logger getLogger() {
|
||||||
|
return this._engine.logger;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取最后一次发送消息的时间
|
* 获取最后一次发送消息的时间
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public abstract class WebSocketNode {
|
|||||||
/**
|
/**
|
||||||
* 判断指定用户是否WebSocket在线
|
* 判断指定用户是否WebSocket在线
|
||||||
*
|
*
|
||||||
* @param userid
|
* @param userid Serializable
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public final class WebSocketPacket {
|
|||||||
ByteBuffer[] duplicateSendBuffers() {
|
ByteBuffer[] duplicateSendBuffers() {
|
||||||
ByteBuffer[] rs = new ByteBuffer[this.sendBuffers.length];
|
ByteBuffer[] rs = new ByteBuffer[this.sendBuffers.length];
|
||||||
for (int i = 0; i < this.sendBuffers.length; i++) {
|
for (int i = 0; i < this.sendBuffers.length; i++) {
|
||||||
rs[i] = this.sendBuffers[i].duplicate();
|
rs[i] = this.sendBuffers[i].duplicate().asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import org.redkale.convert.Convert;
|
import org.redkale.convert.Convert;
|
||||||
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebSocket的消息接收发送器, 一个WebSocket对应一个WebSocketRunner
|
* WebSocket的消息接收发送器, 一个WebSocket对应一个WebSocketRunner
|
||||||
@@ -99,8 +100,17 @@ class WebSocketRunner implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
WebSocketPacket packet = new WebSocketPacket().decode(context.getLogger(), readBuffer, exBuffers);
|
WebSocketPacket packet;
|
||||||
|
try {
|
||||||
|
packet = new WebSocketPacket().decode(context.getLogger(), readBuffer, exBuffers);
|
||||||
|
} catch (Exception e) { //接收的消息体解析失败
|
||||||
|
webSocket.onOccurException(e, Utility.append(new ByteBuffer[]{readBuffer}, exBuffers == null ? new ByteBuffer[0] : exBuffers));
|
||||||
|
if (readBuffer != null) {
|
||||||
|
readBuffer.clear();
|
||||||
|
channel.read(readBuffer, null, this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (packet == null) {
|
if (packet == null) {
|
||||||
failed(null, attachment1);
|
failed(null, attachment1);
|
||||||
if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner abort on decode WebSocketPacket, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds");
|
if (debug) context.getLogger().log(Level.FINEST, "WebSocketRunner abort on decode WebSocketPacket, force to close channel, live " + (System.currentTimeMillis() - webSocket.getCreatetime()) / 1000 + " seconds");
|
||||||
@@ -121,7 +131,17 @@ class WebSocketRunner implements Runnable {
|
|||||||
context.getLogger().log(Level.SEVERE, "WebSocket onBinaryMessage error (" + packet + ")", e);
|
context.getLogger().log(Level.SEVERE, "WebSocket onBinaryMessage error (" + packet + ")", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object message = textConvert.convertFrom(webSocket._messageTextType, packet.receiveMasker, packet.receiveBuffers);
|
Object message;
|
||||||
|
try {
|
||||||
|
message = textConvert.convertFrom(webSocket._messageTextType, packet.receiveMasker, packet.receiveBuffers);
|
||||||
|
} catch (Exception e) { //接收的消息体解析失败
|
||||||
|
webSocket.onOccurException(e, packet.receiveBuffers);
|
||||||
|
if (readBuffer != null) {
|
||||||
|
readBuffer.clear();
|
||||||
|
channel.read(readBuffer, null, this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (readBuffer != null) {
|
if (readBuffer != null) {
|
||||||
readBuffer.clear();
|
readBuffer.clear();
|
||||||
channel.read(readBuffer, null, this);
|
channel.read(readBuffer, null, this);
|
||||||
@@ -150,7 +170,17 @@ class WebSocketRunner implements Runnable {
|
|||||||
context.getLogger().log(Level.SEVERE, "WebSocket onBinaryMessage error (" + packet + ")", e);
|
context.getLogger().log(Level.SEVERE, "WebSocket onBinaryMessage error (" + packet + ")", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object message = binaryConvert.convertFrom(webSocket._messageTextType, packet.receiveMasker, packet.receiveBuffers);
|
Object message;
|
||||||
|
try {
|
||||||
|
message = binaryConvert.convertFrom(webSocket._messageTextType, packet.receiveMasker, packet.receiveBuffers);
|
||||||
|
} catch (Exception e) { //接收的消息体解析失败
|
||||||
|
webSocket.onOccurException(e, packet.receiveBuffers);
|
||||||
|
if (readBuffer != null) {
|
||||||
|
readBuffer.clear();
|
||||||
|
channel.read(readBuffer, null, this);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (readBuffer != null) {
|
if (readBuffer != null) {
|
||||||
readBuffer.clear();
|
readBuffer.clear();
|
||||||
channel.read(readBuffer, null, this);
|
channel.read(readBuffer, null, this);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import java.util.function.*;
|
|||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.redkale.service.*;
|
import org.redkale.service.*;
|
||||||
|
import static org.redkale.source.DataSources.*;
|
||||||
import org.redkale.util.*;
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +30,7 @@ import org.redkale.util.*;
|
|||||||
@AutoLoad(false)
|
@AutoLoad(false)
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ResourceType(DataSource.class)
|
@ResourceType(DataSource.class)
|
||||||
public class DataJdbcSource extends AbstractService implements DataSource, Service, DataCacheListener, Function<Class, EntityInfo>, AutoCloseable, Resourcable {
|
public class DataJdbcSource extends AbstractService implements DataSource, DataCacheListener, Function<Class, EntityInfo>, AutoCloseable, Resourcable {
|
||||||
|
|
||||||
protected static final Flipper FLIPPER_ONE = new Flipper(1);
|
protected static final Flipper FLIPPER_ONE = new Flipper(1);
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ public class DataJdbcSource extends AbstractService implements DataSource, Servi
|
|||||||
this.conf = null;
|
this.conf = null;
|
||||||
this.readPool = new PoolJdbcSource(this, "read", readprop);
|
this.readPool = new PoolJdbcSource(this, "read", readprop);
|
||||||
this.writePool = new PoolJdbcSource(this, "write", writeprop);
|
this.writePool = new PoolJdbcSource(this, "write", writeprop);
|
||||||
this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty("shared-cache-mode"));
|
this.cacheForbidden = "NONE".equalsIgnoreCase(readprop.getProperty(JDBC_CACHE_MODE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ public final class DataSources {
|
|||||||
|
|
||||||
public static final String JDBC_DATASOURCE_CLASS = "javax.persistence.datasource";
|
public static final String JDBC_DATASOURCE_CLASS = "javax.persistence.datasource";
|
||||||
|
|
||||||
|
public static final String JDBC_CACHE_MODE = "javax.persistence.cachemode";
|
||||||
|
|
||||||
public static final String JDBC_CONNECTIONSMAX = "javax.persistence.connections.limit";
|
public static final String JDBC_CONNECTIONSMAX = "javax.persistence.connections.limit";
|
||||||
|
|
||||||
public static final String JDBC_CONTAIN_SQLTEMPLATE = "javax.persistence.contain.sqltemplate";
|
public static final String JDBC_CONTAIN_SQLTEMPLATE = "javax.persistence.contain.sqltemplate";
|
||||||
@@ -122,8 +124,8 @@ public final class DataSources {
|
|||||||
String value = reader.getAttributeValue(null, "value");
|
String value = reader.getAttributeValue(null, "value");
|
||||||
if (name == null) continue;
|
if (name == null) continue;
|
||||||
result.put(name, value);
|
result.put(name, value);
|
||||||
} else if (flag && "shared-cache-mode".equalsIgnoreCase(reader.getLocalName())) {
|
} else if (flag && "shared-cache-mode".equalsIgnoreCase(reader.getLocalName())) { //兼容shared-cache-mode属性
|
||||||
result.put(reader.getLocalName(), reader.getElementText());
|
result.put(JDBC_CACHE_MODE, reader.getElementText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public final class Redkale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getDotedVersion() {
|
public static String getDotedVersion() {
|
||||||
return "1.8.1";
|
return "1.8.2";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMajorVersion() {
|
public static int getMajorVersion() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
package org.redkale.util;
|
package org.redkale.util;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.*;
|
||||||
import java.util.stream.*;
|
import java.util.stream.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,6 +108,15 @@ public class Sheet<T> implements java.io.Serializable, Iterable<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <R> Sheet<R> map(Function<T, R> mapper) {
|
||||||
|
if (this.isEmpty()) return (Sheet) this;
|
||||||
|
final List<R> list = new ArrayList<>();
|
||||||
|
for (T item : this.rows) {
|
||||||
|
list.add(mapper.apply(item));
|
||||||
|
}
|
||||||
|
return new Sheet<>(getTotal(), list);
|
||||||
|
}
|
||||||
|
|
||||||
public void forEachParallel(final Consumer<? super T> consumer) {
|
public void forEachParallel(final Consumer<? super T> consumer) {
|
||||||
if (consumer != null && this.rows != null && !this.rows.isEmpty()) {
|
if (consumer != null && this.rows != null && !this.rows.isEmpty()) {
|
||||||
this.rows.parallelStream().forEach(consumer);
|
this.rows.parallelStream().forEach(consumer);
|
||||||
|
|||||||
Reference in New Issue
Block a user