服务端去除neutrino-core依赖

This commit is contained in:
aoshiguchen
2023-03-12 02:01:09 +08:00
parent 3e1bbfbd02
commit 56b216406e
77 changed files with 2976 additions and 836 deletions
@@ -23,7 +23,6 @@ package fun.asgc.neutrino.core.web.interceptor;
import fun.asgc.neutrino.core.web.context.HttpRequestWrapper;
import fun.asgc.neutrino.core.web.context.HttpResponseWrapper;
import io.netty.channel.ChannelHandlerContext;
/**
* 异常处理
+5
View File
@@ -14,6 +14,11 @@
<artifactId>neutrino-proxy-client</artifactId>
<dependencies>
<dependency>
<groupId>fun.asgc.neutrino</groupId>
<artifactId>neutrino-core</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>fun.asgc.neutrino</groupId>
<artifactId>neutrino-proxy-core</artifactId>
@@ -24,13 +24,13 @@ package fun.asgc.neutrino.proxy.client.config;
import fun.asgc.neutrino.core.annotation.Bean;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Order;
import fun.asgc.neutrino.core.base.DefaultDispatcher;
import fun.asgc.neutrino.core.base.Dispatcher;
import fun.asgc.neutrino.core.base.Ordered;
import fun.asgc.neutrino.core.util.BeanManager;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.DefaultDispatcher;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import io.netty.channel.ChannelHandlerContext;
/**
@@ -22,11 +22,11 @@
package fun.asgc.neutrino.proxy.client.core;
import fun.asgc.neutrino.core.base.Dispatcher;
import fun.asgc.neutrino.core.util.BeanManager;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
@@ -25,7 +25,6 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
@@ -34,6 +33,7 @@ import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ExceptionEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
@@ -24,12 +24,15 @@ package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.client.config.ProxyConfig;
import fun.asgc.neutrino.proxy.client.core.ProxyChannelBorrowListener;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
@@ -23,13 +23,13 @@
package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.client.util.ProxyUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
@@ -24,9 +24,9 @@ package fun.asgc.neutrino.proxy.client.handler;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
@@ -23,12 +23,12 @@
package fun.asgc.neutrino.proxy.client.handler;
import fun.asgc.neutrino.core.annotation.Component;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
+13 -3
View File
@@ -14,10 +14,20 @@
<dependencies>
<dependency>
<groupId>fun.asgc.neutrino</groupId>
<artifactId>neutrino-core</artifactId>
<version>${revision}</version>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<!--hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.15</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>fun.asgc.neutrino</groupId>-->
<!-- <artifactId>neutrino-core</artifactId>-->
<!-- <version>${revision}</version>-->
<!-- </dependency>-->
</dependencies>
</project>
@@ -22,7 +22,7 @@
package fun.asgc.neutrino.proxy.core;
import fun.asgc.neutrino.core.base.Handler;
import fun.asgc.neutrino.proxy.core.dispatcher.Handler;
import io.netty.channel.ChannelHandlerContext;
/**
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.core.base;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@FunctionalInterface
public interface CodeBlock {
/**
* 执行
*/
void execute() throws Exception;
}
@@ -0,0 +1,19 @@
package fun.asgc.neutrino.proxy.core.base;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class InternalException extends RuntimeException {
public InternalException(String message) {
super(message);
}
public InternalException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -0,0 +1,102 @@
package fun.asgc.neutrino.proxy.core.base;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public interface MetaDataConstant {
String DEFAULT_BANNER = "\n _____ _____ _____ _____ _____ _____ _____ _______ \n" +
" /\\ \\ /\\ \\ /\\ \\ /\\ \\ /\\ \\ /\\ \\ /\\ \\ /::\\ \\ \n" +
" /::\\____\\ /::\\ \\ /::\\____\\ /::\\ \\ /::\\ \\ /::\\ \\ /::\\____\\ /::::\\ \\ \n" +
" /::::| | /::::\\ \\ /:::/ / \\:::\\ \\ /::::\\ \\ \\:::\\ \\ /::::| | /::::::\\ \\ \n" +
" /:::::| | /::::::\\ \\ /:::/ / \\:::\\ \\ /::::::\\ \\ \\:::\\ \\ /:::::| | /::::::::\\ \\ \n" +
" /::::::| | /:::/\\:::\\ \\ /:::/ / \\:::\\ \\ /:::/\\:::\\ \\ \\:::\\ \\ /::::::| | /:::/~~\\:::\\ \\ \n" +
" /:::/|::| | /:::/__\\:::\\ \\ /:::/ / \\:::\\ \\ /:::/__\\:::\\ \\ \\:::\\ \\ /:::/|::| | /:::/ \\:::\\ \\ \n" +
" /:::/ |::| | /::::\\ \\:::\\ \\ /:::/ / /::::\\ \\ /::::\\ \\:::\\ \\ /::::\\ \\ /:::/ |::| | /:::/ / \\:::\\ \\ \n" +
" /:::/ |::| | _____ /::::::\\ \\:::\\ \\ /:::/ / _____ /::::::\\ \\ /::::::\\ \\:::\\ \\ ____ /::::::\\ \\ /:::/ |::| | _____ /:::/____/ \\:::\\____\\ \n" +
" /:::/ |::| |/\\ \\ /:::/\\:::\\ \\:::\\ \\ /:::/____/ /\\ \\ /:::/\\:::\\ \\ /:::/\\:::\\ \\:::\\____\\ /\\ \\ /:::/\\:::\\ \\ /:::/ |::| |/\\ \\ |:::| | |:::| |\n" +
"/:: / |::| /::\\____\\/:::/__\\:::\\ \\:::\\____\\|:::| / /::\\____\\ /:::/ \\:::\\____\\/:::/ \\:::\\ \\:::| |/::\\ \\/:::/ \\:::\\____\\/:: / |::| /::\\____\\|:::|____| |:::| |\n" +
"\\::/ /|::| /:::/ /\\:::\\ \\:::\\ \\::/ /|:::|____\\ /:::/ / /:::/ \\::/ /\\::/ |::::\\ /:::|____|\\:::\\ /:::/ \\::/ /\\::/ /|::| /:::/ / \\:::\\ \\ /:::/ / \n" +
" \\/____/ |::| /:::/ / \\:::\\ \\:::\\ \\/____/ \\:::\\ \\ /:::/ / /:::/ / \\/____/ \\/____|:::::\\/:::/ / \\:::\\/:::/ / \\/____/ \\/____/ |::| /:::/ / \\:::\\ \\ /:::/ / \n" +
" |::|/:::/ / \\:::\\ \\:::\\ \\ \\:::\\ \\ /:::/ / /:::/ / |:::::::::/ / \\::::::/ / |::|/:::/ / \\:::\\ /:::/ / \n" +
" |::::::/ / \\:::\\ \\:::\\____\\ \\:::\\ /:::/ / /:::/ / |::|\\::::/ / \\::::/____/ |::::::/ / \\:::\\__/:::/ / \n" +
" |:::::/ / \\:::\\ \\::/ / \\:::\\__/:::/ / \\::/ / |::| \\::/____/ \\:::\\ \\ |:::::/ / \\::::::::/ / \n" +
" |::::/ / \\:::\\ \\/____/ \\::::::::/ / \\/____/ |::| ~| \\:::\\ \\ |::::/ / \\::::::/ / \n" +
" /:::/ / \\:::\\ \\ \\::::::/ / |::| | \\:::\\ \\ /:::/ / \\::::/ / \n" +
" /:::/ / \\:::\\____\\ \\::::/ / \\::| | \\:::\\____\\ /:::/ / \\::/____/ \n" +
" \\::/ / \\::/ / \\::/____/ \\:| | \\::/ / \\::/ / ~~ \n" +
" \\/____/ \\/____/ ~~ \\|___| \\/____/ \\/____/ \n" +
" ";
/**
* classpath标识符
*/
String CLASSPATH_IDENTIFIER = "classpath";
/**
* classpath资源标识
*/
String CLASSPATH_RESOURCE_IDENTIFIER = CLASSPATH_IDENTIFIER + ":";
/**
* 默认的yml配置文件名
*/
String DEFAULT_YML_CONFIG_FILE_NAME = "application.yml";
/**
* 应用banner路径
*/
String APP_BANNER_FILE_PATH = CLASSPATH_RESOURCE_IDENTIFIER.concat("/banner.txt");
/**
* 默认的http页面路径
*/
String DEFAULT_HTTP_PAGE_PATH = CLASSPATH_RESOURCE_IDENTIFIER.concat("/webapp/");
/**
* 服务版本
*/
String SERVER_VS = "Neutrino-1.0";
/**
* app生命周期主题
*/
String TOPIC_APP_LIFE_CYCLE = "TP_APP_LIFE_CYCLE";
/**
* 环境变量key
*/
String ENVIRONMENT_VARIABLE_KEY = "NEUTRINO_PROXY";
interface Config {
String NEUTRINO_APPLICATION_NAME = "neutrino.application.name";
String NEUTRINO_HTTP_ENABLE = "neutrino.http.enable";
String NEUTRINO_HTTP_PORT = "neutrino.http.port";
String NEUTRINO_HTTP_CONTEXT_PATH = "neutrino.http.context-path";
String NEUTRINO_HTTP_MAX_CONTENT_LENGTH_DESC = "neutrino.http.max-content-length-desc";
String NEUTRINO_HTTP_STATIC_RESOURCE_LOCATIONS = "neutrino.http.static-resource.locations";
String NEUTRINO_PROXY_PROTOCOL_MAX_FRAME_LENGTH = "neutrino.proxy.protocol.max-frame-length";
String NEUTRINO_PROXY_PROTOCOL_LENGTH_FIELD_OFFSET = "neutrino.proxy.protocol.length-field-offset";
String NEUTRINO_PROXY_PROTOCOL_LENGTH_FIELD_LENGTH = "neutrino.proxy.protocol.length-field-length";
String NEUTRINO_PROXY_PROTOCOL_INITIAL_BYTES_TO_STRIP = "neutrino.proxy.protocol.initial-bytes-to-strip";
String NEUTRINO_PROXY_PROTOCOL_LENGTH_ADJUSTMENT = "neutrino.proxy.protocol.length-adjustment";
String NEUTRINO_PROXY_PROTOCOL_READ_IDLE_TIME = "neutrino.proxy.protocol.read-idle-time";
String NEUTRINO_PROXY_PROTOCOL_WRITE_IDLE_TIME = "neutrino.proxy.protocol.write-idle-time";
String NEUTRINO_PROXY_PROTOCOL_ALL_IDLE_TIME_SECONDS = "neutrino.proxy.protocol.all-idle-time-seconds";
String NEUTRINO_PROXY_SERVER_PORT = "neutrino.proxy.server.port";
String NEUTRINO_PROXY_SERVER_SSL_PORT = "neutrino.proxy.server.ssl-port";
String NEUTRINO_PROXY_SERVER_KEY_STORE_PASSWORD = "neutrino.proxy.server.key-store-password";
String NEUTRINO_PROXY_SERVER_KEY_MANAGER_PASSWORD = "neutrino.proxy.server.key-manager-password";
String NEUTRINO_PROXY_SERVER_JKS_PATH = "neutrino.proxy.server.jks-path";
String NEUTRINO_PROXY_CLIENT_KEY_STORE_PASSWORD = "neutrino.proxy.client.key-store-password";
String NEUTRINO_PROXY_CLIENT_JKS_PATH = "neutrino.proxy.client.jks-path";
String NEUTRINO_PROXY_CLIENT_SERVER_IP = "neutrino.proxy.client.server-ip";
String NEUTRINO_PROXY_CLIENT_SERVER_PORT = "neutrino.proxy.client.server-port";
String NEUTRINO_PROXY_CLIENT_SSL_ENABLE = "neutrino.proxy.client.ssl-enable";
String NEUTRINO_PROXY_CLIENT_OBTAIN_LICENSE_INTERVAL = "neutrino.proxy.client.obtain-license-interval";
String NEUTRINO_DATA_DB_TYPE = "neutrino.data.db.type";
String NEUTRINO_DATA_DB_URL = "neutrino.data.db.url";
String NEUTRINO_DATA_DB_DRIVER_CLASS = "neutrino.data.db.driver-class";
String NEUTRINO_DATA_DB_USERNAME = "neutrino.data.db.username";
String NEUTRINO_DATA_DB_PASSWORD = "neutrino.data.db.password";
}
}
@@ -0,0 +1,89 @@
package fun.asgc.neutrino.proxy.core.dispatcher;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Slf4j
public class DefaultDispatcher<Context, Data> implements Dispatcher<Context, Data> {
/**
* 调度器名称
*/
private String name;
/**
* 处理器映射
*/
private Map<String, Handler<Context,Data>> handlerMap;
/**
* 匹配器
*/
private Function<Data,String> matcher;
public DefaultDispatcher(String name, List<? extends Handler<Context,Data>> handlerList, Function<Data,String> matcher) {
Assert.notNull(name, "名称不能为空!");
Assert.notNull(matcher, "匹配器不能为空!");
if (CollectionUtil.isEmpty(handlerList)) {
log.error("{} 处理器列表为空.", name);
return;
}
this.name = name == null ? "" : name;
this.handlerMap = new HashMap<>();
this.matcher = matcher;
for (Handler handler : handlerList) {
Match match = handler.getClass().getAnnotation(Match.class);
if (null == match) {
log.warn("{} 类: {} 缺失Match注解", this.name, handler.getClass().getName());
continue;
}
if (StrUtil.isEmpty(match.type())) {
log.warn("{} 类: {} match注解缺失type参数!", this.name, handler.getClass().getName());
continue;
}
if (handlerMap.containsKey(match.type())) {
log.warn("{} 类: {} match注解type值{} 存在重复!", this.name, handler.getClass().getName(), match.type());
continue;
}
handlerMap.put(match.type(), handler);
}
log.info("{} 处理器初始化完成", this.name);
}
@Override
public void dispatch(Context context, Data data) {
if (CollectionUtil.isEmpty(handlerMap)) {
return;
}
String type = matcher.apply(data);
if (null == type) {
log.warn("{} 获取匹配类型失败 data:{}", this.name, JSONObject.toJSONString(data));
return;
}
Handler<Context,Data> handler = handlerMap.get(type);
if (null == handler) {
// log.debug("{} 找不到匹配的处理器 type:{}", this.name, type);
return;
}
String handlerName = handler.name();
if (StrUtil.isEmpty(handlerName)) {
handlerName = TypeUtil.getSimpleName(handler.getClass());
}
log.debug("{} 处理器[{}]执行.", this.name, handlerName);
handler.handle(context, data);
}
}
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.core.dispatcher;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public interface Dispatcher<Context, Data> {
/**
* 调度
* @param context
* @param data
*/
void dispatch(Context context, Data data);
}
@@ -19,42 +19,28 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.core.util;
import io.netty.channel.Channel;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
package fun.asgc.neutrino.proxy.core.dispatcher;
/**
*
* @author: aoshiguchen
* @date: 2022/9/3
* @date: 2022/6/16
*/
public class ChannelUtil {
public interface Handler<Context, Data> {
/**
* 获取ip地址
* @param channel
* 处理
* @param context
* @param data
*/
void handle(Context context, Data data);
/**
* 名称
* @return
*/
public static String getIP(Channel channel) {
if (null == channel) {
return "";
}
String ip = ((InetSocketAddress)channel.remoteAddress()).getAddress().getHostAddress();
if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) {
//根据网卡取本机配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ip = inet.getHostAddress();
}
return ip;
}
default String name() {
return "";
};
}
@@ -0,0 +1,37 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.core.dispatcher;
import java.lang.annotation.*;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Match {
String type();
}
@@ -0,0 +1,56 @@
package fun.asgc.neutrino.proxy.core.type;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象的匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public abstract class AbstractMatcherGroup implements TypeMatcherGroup {
/**
* 最小距离
*/
protected int distanceMin;
/**
* 最大距离
*/
protected int distanceMax;
/**
* 匹配器列表
*/
private List<TypeMatcher> matchers;
public AbstractMatcherGroup(int distanceMin, int distanceMax) {
this.distanceMin = distanceMin;
this.distanceMax = distanceMax;
this.matchers = new ArrayList<>();
this.init();
}
protected abstract void init();
@Override
public List<TypeMatcher> matchers() {
return matchers;
}
public synchronized void add(TypeMatcher matcher) {
if (null != matcher) {
this.matchers.add(matcher);
}
}
@Override
public int getDistanceMin() {
return distanceMin;
}
@Override
public int getDistanceMax() {
return distanceMax;
}
}
@@ -0,0 +1,112 @@
package fun.asgc.neutrino.proxy.core.type;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
/**
* 默认的类型匹配器组
* @author: aoshiguchen
* @date: 2022/7/1
*/
public class DefaultTypeMatcherGroup extends AbstractMatcherGroup {
public DefaultTypeMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
protected void init() {
// 空匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (null == clazz) {
matchInfo.setTypeDistance(TypeMatchLevel.NULL.getDistanceMin());
matchInfo.setTypeConverter((value, type) -> TypeUtil.getDefaultValue(type));
}
return matchInfo;
}
});
// 完美匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (clazz == targetClass) {
matchInfo.setTypeDistance(TypeMatchLevel.PERFECT.getDistanceMin());
matchInfo.setTypeConverter((value, type) -> value);
}
return matchInfo;
}
});
// 装箱匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isStrictBasicType(clazz) && TypeUtil.getWrapType(clazz) == targetClass) {
matchInfo.setTypeDistance(TypeMatchLevel.PACKING.getDistanceMin());
matchInfo.setTypeConverter((value, type) -> value);
}
return matchInfo;
}
});
// 拆箱匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isStrictBasicType(targetClass) && TypeUtil.getWrapType(targetClass) == clazz) {
matchInfo.setTypeDistance(TypeMatchLevel.UNPACKING.getDistanceMin());
matchInfo.setTypeConverter((value, type) -> value);
}
return matchInfo;
}
});
// 类型提升匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
int index1 = TypeUtil.basicTypeList.indexOf(clazz);
int index2 = TypeUtil.basicTypeList.indexOf(targetClass);
if (index2 > index1 && index1 >= 0) {
matchInfo.setTypeDistance(TypeMatchLevel.ASCENSION.getDistanceMin() + (index2 - index1));
matchInfo.setTypeConverter((value, type) -> {
if (value == type || TypeUtil.getWrapType(value.getClass()) == type) {
return value;
}
if (TypeUtil.isInteger(clazz) && TypeUtil.isLong(targetClass)) {
return Long.valueOf(String.valueOf(value));
}
if (TypeUtil.isBoolean(value.getClass())) {
return ((boolean)value) ? 1 : 0;
}
if (TypeUtil.isBoolean(type)) {
return TypeUtil.isChar(value.getClass()) ? ((char)value == 0 ? false : true) :
(((Number)value).intValue() == 0 ? false : true);
}
if (TypeUtil.isChar(type)) {
return (char)(int)value;
}
return value;
});
}
return matchInfo;
}
});
// 超类匹配
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (targetClass.isAssignableFrom(clazz)) {
int level = TypeUtil.getInheritLevel(targetClass, clazz);
matchInfo.setTypeDistance(TypeMatchLevel.SUPER.getDistanceMin() + level);
matchInfo.setTypeConverter((value, type) -> value);
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,17 @@
package fun.asgc.neutrino.proxy.core.type;
/**
* 类型转换器
* @author: aoshiguchen
* @date: 2022/6/17
*/
@FunctionalInterface
public interface TypeConverter {
/**
* 类型转换
* @param value
* @param targetType
* @return
*/
Object convert(Object value, Class<?> targetType);
}
@@ -0,0 +1,55 @@
package fun.asgc.neutrino.proxy.core.type;
import lombok.Data;
import lombok.experimental.Accessors;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Accessors(chain = true)
@Data
public class TypeMatchInfo {
/**
* 目标类型类型
*/
private Class<?> targetType;
/**
* 值类型
*/
private Class<?> valueType;
/**
* 类型距离
*/
private int typeDistance;
/**
* 类型匹配器
*/
private TypeMatcher typeMatcher;
/**
* 类型转换器
*/
private TypeConverter typeConverter;
public TypeMatchInfo(Class<?> valueType, Class<?> targetType, TypeMatcher typeMatcher) {
this.valueType = valueType;
this.targetType = targetType;
this.typeMatcher = typeMatcher;
this.typeDistance = TypeMatchLevel.NOT.getDistanceMin();
}
public boolean isNotMatch() {
return !isMatched();
}
public boolean isMatched() {
TypeMatchLevel matchLevel = TypeMatchLevel.byTypeDistance(this.typeDistance);
return matchLevel != null && matchLevel != TypeMatchLevel.NOT && typeConverter != null;
}
}
@@ -0,0 +1,68 @@
package fun.asgc.neutrino.proxy.core.type;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 类型匹配等级
* @author: aoshiguchen
* @date: 2022/6/17
*/
@Getter
@AllArgsConstructor
public enum TypeMatchLevel {
// 当且仅当匹配类为空(即匹配对象为null没有类型)时
NULL(0, 0, 0, "空匹配"),
// 当且仅当匹配类与目标类完全相等
PERFECT(1, 1, 1, "完美匹配"),
// 当且仅当匹配类为严格基本数据类型,且目标类为对应的包装类型
PACKING(2, 100, 100, "装箱匹配"),
// 当且仅当目标类为严格基本数据类型,且匹配类为对应的包装类型
UNPACKING(3, 200,200,"拆箱匹配"),
// 当且仅当匹配类和目标类均为一般基本数据类型(非严格),且目标类型的范围更加宽泛时
ASCENSION(4, 1000, 2000, "类型提升匹配"),
// 超类匹配,当且仅当目标类是匹配类的超类时
SUPER(5, 1000000, 2000000, "超类匹配"),
// 内置的扩展匹配
EXTENSION(6, 10000000, 50000000, "扩展匹配"),
// 自定义匹配
CUSTOM(7, 100000000, 500000000, "自定义匹配"),
// 不匹配
NOT(8, Integer.MAX_VALUE, Integer.MAX_VALUE, "不匹配");
private static Map<Integer,TypeMatchLevel> levelMap = Stream.of(TypeMatchLevel.values()).collect(Collectors.toMap(TypeMatchLevel::getLevel, Function.identity()));
/**
* 匹配级别
*/
private int level;
/**
* 类型距离最小值
*/
private int distanceMin;
/**
* 类型距离最大值
*/
private int distanceMax;
/**
* 描述
*/
private String desc;
public static TypeMatchLevel byLevel(int level) {
return levelMap.get(level);
}
public static TypeMatchLevel byTypeDistance(int typeDistance) {
for (TypeMatchLevel item : values()) {
if (typeDistance >= item.getDistanceMin() && typeDistance <= item.getDistanceMax()) {
return item;
}
}
return null;
}
}
@@ -0,0 +1,21 @@
package fun.asgc.neutrino.proxy.core.type;
/**
* 值类型匹配器
*
* @author: aoshiguchen
* @date: 2022/6/17
*/
@FunctionalInterface
public interface TypeMatcher {
/**
* 匹配
* @param clazz
* @param targetClass
* @return
*/
TypeMatchInfo match(Class<?> clazz, Class<?> targetClass);
}
@@ -0,0 +1,28 @@
package fun.asgc.neutrino.proxy.core.type;
import java.util.List;
/**
* 匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public interface TypeMatcherGroup {
/**
* 匹配器列表
* @return
*/
List<TypeMatcher> matchers();
/**
* 获取最小距离
* @return
*/
int getDistanceMin();
/**
* 获取最大距离
* @return
*/
int getDistanceMax();
}
@@ -0,0 +1,218 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.core.type;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.core.type.extension.*;
import fun.asgc.neutrino.proxy.core.util.Assert;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* @author: aoshiguchen
* @date: 2022/6/17
*/
public class TypeMatchers {
/**
* 默认的基本匹配器列表
*/
private static List<TypeMatcher> defaultTypeMatcherList = new ArrayList<>();
/**
* 默认内置扩展的匹配器列表
*/
private static List<TypeMatcher> extensionMatcherList = new ArrayList<>();
/**
* 内置扩展匹配器组列表
*/
private static List<TypeMatcherGroup> extensionMatcherGroupList = new ArrayList<>();
/**
* 用户自定义的匹配器列表
*/
private List<TypeMatcher> customTypeMatcherList = new ArrayList<>();
/**
* 是否启用内置扩展匹配器
*/
private volatile boolean enableExtensionMatcher = true;
static {
init();
}
/**
* 注册内置扩展匹配器组
* @param typeMatcherGroup
*/
private static synchronized void registerExtensionTypeMatcher(TypeMatcherGroup typeMatcherGroup) {
if (null == typeMatcherGroup || CollectionUtil.isEmpty(typeMatcherGroup.matchers())) {
return;
}
// 内置扩展匹配器距离区间检测
if (typeMatcherGroup.getDistanceMin() < TypeMatchLevel.EXTENSION.getDistanceMin() ||
typeMatcherGroup.getDistanceMax() > TypeMatchLevel.EXTENSION.getDistanceMax() ||
typeMatcherGroup.getDistanceMax() < typeMatcherGroup.getDistanceMin()) {
throw new RuntimeException(String.format("内置扩展匹配器:[%s] 距离区间定义有误!", typeMatcherGroup.getClass().getSimpleName()));
}
for (TypeMatcherGroup group : extensionMatcherGroupList) {
// 距离区间不能重叠
if (!(typeMatcherGroup.getDistanceMin() > group.getDistanceMax() || typeMatcherGroup.getDistanceMax() < group.getDistanceMin())) {
throw new RuntimeException(String.format("内置扩展匹配器:[%s]与[%s] 距离区间定义有重叠!", typeMatcherGroup.getClass().getSimpleName(), group.getClass().getSimpleName()));
}
}
extensionMatcherGroupList.add(typeMatcherGroup);
}
/**
* 注册默认的类型匹配器组
* @param typeMatcherGroup
*/
private static synchronized void registerDefaultTypeMatcher(TypeMatcherGroup typeMatcherGroup) {
if (null == typeMatcherGroup || CollectionUtil.isEmpty(typeMatcherGroup.matchers())) {
return;
}
// 自定义匹配器距离区间检测
if (typeMatcherGroup.getDistanceMin() < TypeMatchLevel.NULL.getDistanceMin() ||
typeMatcherGroup.getDistanceMax() > TypeMatchLevel.SUPER.getDistanceMax() ||
typeMatcherGroup.getDistanceMax() < typeMatcherGroup.getDistanceMin()) {
throw new RuntimeException(String.format("默认匹配器组器:[%s] 距离区间定义有误!", typeMatcherGroup.getClass().getSimpleName()));
}
defaultTypeMatcherList.addAll(typeMatcherGroup.matchers());
}
/**
* 注册自定义类型匹配器具
* @param typeMatcher
*/
public synchronized void registerCustomTypeMatcher(TypeMatcher typeMatcher) {
Assert.notNull(typeMatcher, "匹配器不能为空!");
customTypeMatcherList.add(typeMatcher);
}
/**
* 注册自定义匹配器组
* @param typeMatcherGroup
*/
public synchronized void registerCustomTypeMatcher(TypeMatcherGroup typeMatcherGroup) {
if (null == typeMatcherGroup || CollectionUtil.isEmpty(typeMatcherGroup.matchers())) {
return;
}
// 自定义匹配器距离区间检测
if (typeMatcherGroup.getDistanceMin() < TypeMatchLevel.CUSTOM.getDistanceMin() ||
typeMatcherGroup.getDistanceMax() > TypeMatchLevel.CUSTOM.getDistanceMax() ||
typeMatcherGroup.getDistanceMax() < typeMatcherGroup.getDistanceMin()) {
throw new RuntimeException(String.format("自定义扩展匹配器:[%s] 距离区间定义有误!", typeMatcherGroup.getClass().getSimpleName()));
}
customTypeMatcherList.addAll(typeMatcherGroup.matchers());
}
/**
* 匹配
* @param clazz
* @param targetClass
* @return
*/
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
// 先匹配自定义的
for (TypeMatcher matcher : customTypeMatcherList) {
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
if (typeMatchInfo.isMatched()) {
return typeMatchInfo;
}
}
// 再匹配内置默认的
for (TypeMatcher matcher : defaultTypeMatcherList) {
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
if (typeMatchInfo.isMatched()) {
return typeMatchInfo;
}
}
if (enableExtensionMatcher) {
// 再匹配内置扩展的
for (TypeMatcher matcher : extensionMatcherList) {
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
if (typeMatchInfo.isMatched()) {
return typeMatchInfo;
}
}
}
return null;
}
public boolean isEnableExtensionMatcher() {
return enableExtensionMatcher;
}
public void setEnableExtensionMatcher(boolean enableExtensionMatcher) {
this.enableExtensionMatcher = enableExtensionMatcher;
}
/**
* 类型转换
* @param value
* @param targetType
* @return
*/
public Object conversion(Object value, Class<?> targetType) {
Assert.notNull(targetType, "目标类型不能为空!");
TypeMatchInfo typeMatchInfo = match(value == null ? null : value.getClass(), targetType);
if (null == typeMatchInfo || typeMatchInfo.isNotMatch()) {
return null;
}
return typeMatchInfo.getTypeConverter().convert(value, targetType);
}
/**
* 初始化
*/
private static void init() {
// 注册默认的类型匹配器组
registerDefaultTypeMatcher(new DefaultTypeMatcherGroup(TypeMatchLevel.NULL.getDistanceMin(), TypeMatchLevel.SUPER.getDistanceMax()));
// 注册内置扩展匹配
int extensionMatcherGroupSize = 100000;
int extensionMatcherGroupDistance = TypeMatchLevel.EXTENSION.getDistanceMin();
registerExtensionTypeMatcher(new StringMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 0,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 1 - 1));
registerExtensionTypeMatcher(new BooleanMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 1,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 2 - 1));
registerExtensionTypeMatcher(new NumberMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 2,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 3 - 1));
registerExtensionTypeMatcher(new DateMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 3,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 4 - 1));
registerExtensionTypeMatcher(new ListMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 4,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 5 - 1));
registerExtensionTypeMatcher(new SetMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 5,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 6 - 1));
registerExtensionTypeMatcher(new MapMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 6,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 7 - 1));
registerExtensionTypeMatcher(new ArrayMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 7,
extensionMatcherGroupDistance + extensionMatcherGroupSize * 8 - 1));
// 按照距离区间排序
extensionMatcherList = extensionMatcherGroupList.stream().sorted(Comparator.comparing(TypeMatcherGroup::getDistanceMin))
.map(TypeMatcherGroup::matchers).flatMap(List::stream).collect(Collectors.toList());
}
}
@@ -0,0 +1,50 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import java.util.List;
import java.util.Set;
/**
* 数组匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class ArrayMatcherGroup extends AbstractMatcherGroup {
public ArrayMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
// List -> Object[]
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (List.class.isAssignableFrom(clazz) && targetClass.isArray()) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter((value, targetType) -> ((List)value).toArray());
}
return matchInfo;
}
});
// Set -> Object[]
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (Set.class.isAssignableFrom(clazz) && targetClass.isArray()) {
matchInfo.setTypeDistance(getDistanceMin() + 1);
matchInfo.setTypeConverter((value, targetType) -> ((Set)value).toArray());
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,34 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
/**
* 布尔值匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class BooleanMatcherGroup extends AbstractMatcherGroup {
public BooleanMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isBoolean(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).toLowerCase().equals("true")));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,62 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
/**
* 日期匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class DateMatcherGroup extends AbstractMatcherGroup {
public DateMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
// Long -> Date
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isLong(clazz) && TypeUtil.isDate(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter(((value, targetType) -> {
if (targetClass == Date.class) {
return new Date((long)value);
} else {
return new java.sql.Date((long)value);
}
}));
}
return matchInfo;
}
});
// LocalDateTime -> Date
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (LocalDateTime.class.isAssignableFrom(clazz) && TypeUtil.isDate(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 1);
matchInfo.setTypeConverter(((value, targetType) -> {
ZoneId zone = ZoneId.systemDefault();
Instant instant = ((LocalDateTime)value).atZone(zone).toInstant();
return Date.from(instant);
}));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,37 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* list匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class ListMatcherGroup extends AbstractMatcherGroup {
public ListMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (List.class == targetClass && clazz.isArray()) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toList())));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,21 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
/**
* Map匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class MapMatcherGroup extends AbstractMatcherGroup {
public MapMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
}
}
@@ -0,0 +1,161 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
/**
* 字符串匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class NumberMatcherGroup extends AbstractMatcherGroup {
public NumberMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
// String -> Byte
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isByte(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Byte.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// String -> Short
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isShort(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 1);
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Short.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// String -> Integer
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isInteger(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 2);
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Integer.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// String -> Long
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isLong(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 3);
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Long.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// String -> Float
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isFloat(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 4);
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Float.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// String -> Double
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isString(clazz) && TypeUtil.isDouble(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin() + 5);
matchInfo.setTypeConverter((value, targetType) -> {
try {
return Double.valueOf((String)value);
} catch (Exception e) {
// ignore
}
return 0;
});
}
return matchInfo;
}
});
// date -> Long
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isLong(targetClass) && TypeUtil.isDate(clazz)) {
matchInfo.setTypeDistance(getDistanceMin() + 6);
matchInfo.setTypeConverter(((value, targetType) -> ((java.util.Date)value).getTime()));
}
return matchInfo;
}
});
// Long - > int
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isInteger(targetClass) && TypeUtil.isLong(clazz)) {
matchInfo.setTypeDistance(getDistanceMin() + 7);
matchInfo.setTypeConverter(((value, targetType) -> ((Long)value).intValue()));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,49 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* set匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class SetMatcherGroup extends AbstractMatcherGroup {
public SetMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (Set.class == targetClass && clazz.isArray()) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toSet())));
}
return matchInfo;
}
});
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (Set.class == targetClass && Collection.class.isAssignableFrom(clazz)) {
matchInfo.setTypeDistance(getDistanceMin() + 1);
matchInfo.setTypeConverter(((value, targetType) -> ((Collection)value).stream().collect(Collectors.toSet())));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,47 @@
package fun.asgc.neutrino.proxy.core.type.extension;
import fun.asgc.neutrino.proxy.core.type.AbstractMatcherGroup;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatcher;
import fun.asgc.neutrino.proxy.core.util.TypeUtil;
/**
* 字符串匹配器组
* @author: aoshiguchen
* @date: 2022/6/29
*/
public class StringMatcherGroup extends AbstractMatcherGroup {
public StringMatcherGroup(int distanceMin, int distanceMax) {
super(distanceMin, distanceMax);
}
@Override
public void init() {
// 基本类型 -> String
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isNormalBasicType(clazz) && TypeUtil.isString(targetClass)) {
matchInfo.setTypeDistance(getDistanceMin());
matchInfo.setTypeConverter(((value, targetType) -> String.valueOf(value)));
}
return matchInfo;
}
});
// String -> char
add(new TypeMatcher() {
@Override
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
if (TypeUtil.isChar(targetClass) && TypeUtil.isString(clazz)) {
matchInfo.setTypeDistance(getDistanceMin() + 1);
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).charAt(0)));
}
return matchInfo;
}
});
}
}
@@ -0,0 +1,220 @@
package fun.asgc.neutrino.proxy.core.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public abstract class Assert {
/**
*
* @param expression
* @param message
*/
public static void state(boolean expression, String message) {
if (!expression) {
throw new IllegalStateException(message);
}
}
/**
*
* @param expression
* @param messageSupplier
*/
public static void state(boolean expression, Supplier<String> messageSupplier) {
if (!expression) {
throw new IllegalStateException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param expression
* @param message
*/
public static void isTrue(boolean expression, String message) {
if (!expression) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param expression
* @param messageSupplier
*/
public static void isTrue(boolean expression, Supplier<String> messageSupplier) {
if (!expression) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param object
* @param message
*/
public static void isNull(Object object, String message) {
if (object != null) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param object
* @param messageSupplier
*/
public static void isNull(Object object, Supplier<String> messageSupplier) {
if (object != null) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param object
* @param message
*/
public static void notNull(Object object, String message) {
if (object == null) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param object
* @param messageSupplier
*/
public static void notNull(Object object, Supplier<String> messageSupplier) {
if (object == null) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param array
* @param message
*/
public static void notEmpty(Object[] array, String message) {
if (ObjectUtils.isEmpty(array)) {
throw new IllegalArgumentException(message);
}
}
public static void notEmpty(String s, String message) {
if (StrUtil.isEmpty(s)) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param array
* @param messageSupplier
*/
public static void notEmpty(Object[] array, Supplier<String> messageSupplier) {
if (ObjectUtils.isEmpty(array)) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param array
* @param message
*/
public static void noNullElements(Object[] array, String message) {
if (array != null) {
for (Object element : array) {
if (element == null) {
throw new IllegalArgumentException(message);
}
}
}
}
/**
*
* @param array
* @param messageSupplier
*/
public static void noNullElements(Object[] array, Supplier<String> messageSupplier) {
if (array != null) {
for (Object element : array) {
if (element == null) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
}
}
/**
*
* @param collection
* @param message
*/
public static void notEmpty(Collection<?> collection, String message) {
if (CollectionUtil.isEmpty(collection)) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param collection
* @param messageSupplier
*/
public static void notEmpty(Collection<?> collection, Supplier<String> messageSupplier) {
if (CollectionUtil.isEmpty(collection)) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
/**
*
* @param map
* @param message
*/
public static void notEmpty(Map<?, ?> map, String message) {
if (CollectionUtil.isEmpty(map)) {
throw new IllegalArgumentException(message);
}
}
/**
*
* @param map
* @param messageSupplier
*/
public static void notEmpty(Map<?, ?> map, Supplier<String> messageSupplier) {
if (CollectionUtil.isEmpty(map)) {
throw new IllegalArgumentException(nullSafeGet(messageSupplier));
}
}
private static boolean endsWithSeparator(String msg) {
return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith("."));
}
private static String messageWithTypeName(String msg, Object typeName) {
return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
}
private static String nullSafeGet(Supplier<String> messageSupplier) {
return (messageSupplier != null ? messageSupplier.get() : null);
}
}
@@ -0,0 +1,357 @@
package fun.asgc.neutrino.proxy.core.util;
import org.apache.commons.lang3.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Consumer;
/**
*
* @author: aoshiguchen
* @date: 2022/6/28
*/
public class DateUtil {
public static final long SECOND_LONG = 1000L;
public static final long MINUTE_LONG = 60 * SECOND_LONG;
public static final long HOUR_LONG = 60 * MINUTE_LONG;
private static final Map<String, SimpleDateFormat> sdfCache = new HashMap<>();
private static SimpleDateFormat getSimpleDateFormat(String format) {
try {
return LockUtil.doubleCheckProcess(
() -> !sdfCache.containsKey(format),
format,
() -> sdfCache.put(format, new SimpleDateFormat(format)),
() -> sdfCache.get(format)
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解析日期
*
* @param date 日期类
* @param pattern 日期格式
* @return 返回日期
*/
public static Date parseStr(String date, String pattern) {
if (date == null || pattern == null) {
return null;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
Date parse = null;
try {
parse = simpleDateFormat.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return parse;
}
/**
* @param date 时间。若为空,则返回空串
* @param pattern 时间格式化
* @return 格式化后的时间字符串.
*/
public static String format(Date date, String pattern) {
if (date == null) {
return "";
}
return new SimpleDateFormat(pattern).format(date);
}
/**
* @param date 日期
* @param pattern 格式
* @return 日期类型
*/
public static Date parse(String date, String pattern) {
try {
return new SimpleDateFormat(pattern).parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* 是否在指定时间段之间
*
* @param judgeTime 比较时间
* @param beginTime 开始时间
* @param endTime 结束时间
* @param flag 0-[beginTime<=judgeTime<=endTime]
* 1-[beginTime<judgeTime<=endTime]
* 2-[beginTime<=judgeTime<endTime]
* 3-[beginTime<judgeTime<endTime]
* @return 判断结果
*/
public static boolean isBetweenTimes(Date judgeTime, Date beginTime, Date endTime, int flag) {
switch (flag) {
case 0:
return (beginTime.getTime() <= judgeTime.getTime() && judgeTime.getTime() <= endTime.getTime());
case 1:
return (beginTime.getTime() < judgeTime.getTime() && judgeTime.getTime() <= endTime.getTime());
case 2:
return (beginTime.getTime() <= judgeTime.getTime() && judgeTime.getTime() < endTime.getTime());
case 3:
return (beginTime.getTime() < judgeTime.getTime() && judgeTime.getTime() < endTime.getTime());
default:
return false;
}
}
/**
* 取得日期所在月的month个月同一天<br />
*
* @param date 日期
* @param month 月
* @return 日期
*/
public static Date getMonthDay(Date date, int month) {
Calendar cal = Calendar.getInstance();
if (date != null) {
cal.setTime(date);
}
cal.add(Calendar.MONTH, month);
return cal.getTime();
}
/**
* 获取该日期当月第一天
*
* @param date 日期
* @return 结果日期
*/
public static Date getMonthBegin(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(getDayBegin(date));
calendar.set(Calendar.DAY_OF_MONTH, 1);
return calendar.getTime();
}
/**
* 获取该日期当月最后一天
*
* @param date 日期
* @return 结果日期
*/
public static Date getMonthEnd(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(getDayBegin(date));
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.MILLISECOND, -1);
return calendar.getTime();
}
/**
* 计算当期时间相差的日期
*
* @param date 设置时间
* @param field 日历字段.<br/>eg:Calendar.MONTH,Calendar.DAY_OF_MONTH,<br/>Calendar.HOUR_OF_DAY等.
* @param amount 相差的数值
* @return 计算后的日志
*/
public static Date addDate(Date date, int field, int amount) {
Calendar c = Calendar.getInstance();
if (date != null) {
c.setTime(date);
}
c.add(field, amount);
return c.getTime();
}
/**
* 计算当期时间相差的日期
*
* @param field 日历字段.<br/>eg:Calendar.MONTH,Calendar.DAY_OF_MONTH,<br/>Calendar.HOUR_OF_DAY等.
* @param amount 相差的数值
* @return 计算后的日志
*/
public static Date addDate(int field, int amount) {
return addDate(null, field, amount);
}
/**
* 设置Calendar的小时、分钟、秒、毫秒
*
* @param calendar 日历
* @param hour 小时
* @param minute 分钟
* @param second 秒
* @param milliSecond 毫秒
* @return 结果日期
*/
public static void setCalender(Calendar calendar, int hour, int minute, int second, int milliSecond) {
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.MILLISECOND, milliSecond);
}
/**
* 获取某个时间段内的每天时间日期
*
* @param beginDate 开始日期
* @param endDate 结束日期
* @return 返回结果
*/
public static List<String> getBetweenTimes(String beginDate, String endDate) {
if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) {
return Collections.emptyList();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dBegin = null;
Date dEnd = null;
try {
dBegin = sdf.parse(beginDate);
dEnd = sdf.parse(endDate);
} catch (ParseException e) {
e.printStackTrace();
}
if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) {
return Collections.emptyList();
}
return findDates(dBegin, dEnd);
}
/**
* @param dBegin 开始时间
* @param dEnd 结束时间
* @return 结果集
*/
public static List<String> findDates(Date dBegin, Date dEnd) {
List<String> lDate = new ArrayList<>();
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
lDate.add(sd.format(dBegin));
Calendar calBegin = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calBegin.setTime(dBegin);
Calendar calEnd = Calendar.getInstance();
// 使用给定的 Date 设置此 Calendar 的时间
calEnd.setTime(dEnd);
// 测试此日期是否在指定日期之后
while (dEnd.after(calBegin.getTime())) {
// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
calBegin.add(Calendar.DAY_OF_MONTH, 1);
lDate.add(sd.format(calBegin.getTime()));
}
return lDate;
}
/**
* 取得日期所在年的下一年同一天<br />
* 注:若参数date为空,则取得第当前年所对应的下一年
*
* @param date
* @return
*/
public static Date getNextYearDay(Date date) {
Calendar cal = Calendar.getInstance();
if (date != null) {
cal.setTime(date);
}
cal.add(Calendar.YEAR, 1);
return cal.getTime();
}
/**
* 获取指定天开始时间
*
* @param date 日期
* @return 获得该日期的开始
*/
public static Date getDayBegin(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
setCalender(calendar, 0, 0, 0, 0);
return calendar.getTime();
}
/**
* 获取指定小时开始时间
* @param date 日期
* @return 指定小时开始时间
*/
public static Date getHourBegin(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
setCalender(calendar, calendar.get(Calendar.HOUR), 0, 0, 0);
return calendar.getTime();
}
/**
* 获取指定小时结束时间
* @param date 日期
* @return 指定小时结束时间
*/
public static Date getHourEnd(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
setCalender(calendar, calendar.get(Calendar.HOUR), 59, 59, 999);
return calendar.getTime();
}
/**
* 获取当天开始时间
*
* @return 获得该日期的开始
*/
public static Date getDayBegin() {
return getDayBegin(new Date());
}
/**
* 获取指定天结束时间
*
* @param date 日期
* @return 获得该日期的结束
*/
public static Date getDayEnd(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
setCalender(calendar, 23, 59, 59, 999);
return calendar.getTime();
}
/**
* 获取指定天结束时间
*
* @param date 日期
* @return 获得该日期的结束
*/
public static Date getDayEnd2(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
setCalender(calendar, 23, 59, 59, 000);
return calendar.getTime();
}
/**
* 日期遍历接口
* @param startDate 开始日期 yyyy-MM-dd
* @param endDate 结束日期 yyyy-MM-dd
* @param consumer 执行器回调
*/
public static void dayForEach(String startDate, String endDate, Consumer<String> consumer) {
if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate) || null == consumer) {
return;
}
Date current = parse(startDate, "yyyy-MM-dd");
Date end = parse(endDate, "yyyy-MM-dd");
while (!current.after(end)) {
consumer.accept(format(current, "yyyy-MM-dd"));
current = addDate(current, Calendar.DATE, 1);
}
}
}
@@ -0,0 +1,206 @@
package fun.asgc.neutrino.proxy.core.util;
import fun.asgc.neutrino.proxy.core.base.InternalException;
import fun.asgc.neutrino.proxy.core.base.MetaDataConstant;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class FileUtil {
/**
* 根据文件路径获取输入流
* @param path
* @return
*/
public static InputStream getInputStream(String path) throws FileNotFoundException {
if (StringUtils.isEmpty(path)) {
throw new NullPointerException("path 不能为空!");
}
if (path.startsWith(MetaDataConstant.CLASSPATH_RESOURCE_IDENTIFIER)) {
String subPath = path.substring(MetaDataConstant.CLASSPATH_RESOURCE_IDENTIFIER.length());
return FileUtil.class.getResourceAsStream(subPath);
}
return new FileInputStream(path);
}
/**
* 根据文件路径获取输出流
* @param path
* @return
*/
public static OutputStream getOutputStream(String path) throws FileNotFoundException {
if (StringUtils.isEmpty(path)) {
throw new NullPointerException("path 不能为空!");
}
if (path.startsWith(MetaDataConstant.CLASSPATH_RESOURCE_IDENTIFIER)) {
throw new InternalException("不支持路径以'" + MetaDataConstant.CLASSPATH_IDENTIFIER + "'开头");
}
return new FileOutputStream(path);
}
/**
* 读取文件内容
* @param path
* @return
* @throws IOException
*/
public static String readContentAsString(String path) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(getInputStream(path)))){
return br.lines().collect(Collectors.joining("\n"));
} catch (Exception e) {
return null;
}
}
/**
* 读取文件内容
* @param in
* @return
* @throws IOException
*/
public static String readContentAsString(InputStream in) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))){
return br.lines().collect(Collectors.joining("\n"));
} catch (Exception e) {
return null;
}
}
/**
* 读取文件内容
* @param path
* @return
* @throws IOException
*/
public static List<String> readContentAsStringList(String path) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(getInputStream(path)))){
return br.lines().collect(Collectors.toList());
} catch (Exception e) {
return null;
}
}
/**
* 读取字节内容
* @param path
* @return
*/
public static byte[] readBytes(String path) {
try (InputStream in = getInputStream(path)){
return readBytes(in);
} catch (Exception e) {
return null;
}
}
public static byte[] readBytes(File file) {
try (InputStream in = new FileInputStream(file)){
return readBytes(in);
} catch (Exception e) {
return null;
}
}
public static byte[] readBytes(InputStream in) throws IOException {
byte[] bytes = new byte[1024];
int length = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((length = in.read(bytes)) != -1) {
baos.write(bytes, 0, length);
}
return baos.toByteArray();
}
public static void write(String path, String content) {
// try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(path), StandardCharsets.UTF_8)){
// writer.write(content);
// } catch (Exception e) {
// e.printStackTrace();
// }
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(getOutputStream(path)))){
bw.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
public static File getDirectory(String path) {
if (path.endsWith("/./")) {
path = path.substring(0, path.length() - 2);
}
File file = new File(path);
if (file.isDirectory() || path.endsWith("/")) {
return file;
}
return file.getParentFile();
}
public static void makeDirs(String path) {
try {
File file = getDirectory(path);
if (null != file && !file.exists()) {
file.mkdirs();
}
} catch (Exception e) {
// ignore
}
}
public static File save(String path, String fileName, String content) {
if (!path.endsWith("/")) {
path += "/";
}
makeDirs(path);
write(path + fileName, content);
return new File(path + "/" + fileName);
}
public static void unzipJar(String destinationDir, String jarPath) throws IOException {
File file = new File(jarPath);
JarFile jar = new JarFile(file);
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements();) {
JarEntry entry = (JarEntry) enums.nextElement();
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (fileName.endsWith("/")) {
f.mkdirs();
}
}
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements();) {
JarEntry entry = (JarEntry) enums.nextElement();
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (!fileName.endsWith("/")) {
InputStream is = jar.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(f);
while (is.available() > 0) {
fos.write(is.read());
}
fos.close();
is.close();
}
}
}
public static String getFileSuffix(String path) {
if (StringUtils.isBlank(path)) {
return "";
}
int index = path.lastIndexOf(".");
if (index >= 0) {
return path.substring(index);
}
return "";
}
}
@@ -0,0 +1,69 @@
package fun.asgc.neutrino.proxy.core.util;
import fun.asgc.neutrino.proxy.core.base.CodeBlock;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class LockUtil {
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
*/
public static void doubleCheckProcess(BooleanSupplier isLock, Object lock, CodeBlock lockProcess) throws Exception {
if (isLock.getAsBoolean()) {
synchronized (lock) {
if (isLock.getAsBoolean()) {
lockProcess.execute();
}
}
}
}
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
*/
public static void doubleCheckProcessForNoException(BooleanSupplier isLock, Object lock, CodeBlock lockProcess) {
try {
doubleCheckProcess(isLock, lock, lockProcess);
} catch (Exception e) {
// ignore
e.printStackTrace();
}
}
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
* @param nonLockProcess
*/
public static <T> T doubleCheckProcess(BooleanSupplier isLock, Object lock, CodeBlock lockProcess, Supplier<T> nonLockProcess) throws Exception {
doubleCheckProcess(isLock, lock, lockProcess);
return nonLockProcess.get();
}
/**
* 双重校验处理
* @param isLock
* @param lock
* @param lockProcess
* @param nonLockProcess
*/
public static <T> T doubleCheckProcessForNoException(BooleanSupplier isLock, Object lock, CodeBlock lockProcess, Supplier<T> nonLockProcess) {
doubleCheckProcessForNoException(isLock, lock, lockProcess);
return nonLockProcess.get();
}
}
@@ -0,0 +1,580 @@
package fun.asgc.neutrino.proxy.core.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Pair;
import com.google.common.collect.Lists;
import fun.asgc.neutrino.proxy.core.type.TypeMatchInfo;
import fun.asgc.neutrino.proxy.core.type.TypeMatchers;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class TypeUtil {
/**
* 严格意义上的基本数据类型
*/
private static final Set<Class<?>> strictBasicType = new HashSet<Class<?>>() {
{
this.add(byte.class);
this.add(short.class);
this.add(int.class);
this.add(long.class);
this.add(float.class);
this.add(double.class);
this.add(char.class);
this.add(boolean.class);
}
};
/**
* 一般意义上的基本数据类型
*/
private static final Set<Class<?>> normalBasicType = new HashSet<Class<?>>() {
{
this.addAll(strictBasicType);
this.add(Byte.class);
this.add(Short.class);
this.add(Integer.class);
this.add(Long.class);
this.add(Float.class);
this.add(Double.class);
this.add(Character.class);
this.add(Boolean.class);
this.add(String.class);
}
};
/**
* 基本类型的映射
*/
private static final Map<Class<?>, Class<?>> basicTypeMap = new HashMap<Class<?>, Class<?>>() {
{
this.put(byte.class, byte.class);
this.put(short.class, short.class);
this.put(int.class, int.class);
this.put(long.class, long.class);
this.put(float.class, float.class);
this.put(double.class, double.class);
this.put(char.class, char.class);
this.put(boolean.class, boolean.class);
this.put(Byte.class, byte.class);
this.put(Short.class, short.class);
this.put(Integer.class, int.class);
this.put(Long.class, long.class);
this.put(Float.class, float.class);
this.put(Double.class, double.class);
this.put(Character.class, char.class);
this.put(Boolean.class, boolean.class);
}
};
/**
* 包装类型的映射
*/
private static final Map<Class<?>, Class<?>> wrapTypeMap = new HashMap<Class<?>, Class<?>>() {
{
this.put(byte.class, Byte.class);
this.put(short.class, Short.class);
this.put(int.class, Integer.class);
this.put(long.class, Long.class);
this.put(float.class, Float.class);
this.put(double.class, Double.class);
this.put(char.class, Character.class);
this.put(boolean.class, Boolean.class);
this.put(Byte.class, Byte.class);
this.put(Short.class, Short.class);
this.put(Integer.class, Integer.class);
this.put(Long.class, Long.class);
this.put(Float.class, Float.class);
this.put(Double.class, Double.class);
this.put(Character.class, Character.class);
this.put(Boolean.class, Boolean.class);
this.put(String.class, String.class);
}
};
/**
* 基本类型列表(用于计算类型提升距离)
*/
public static final List<Class<?>> basicTypeList = Lists.newArrayList(
boolean.class, Boolean.class, byte.class, Byte.class, short.class, Short.class, char.class, Character.class,
int.class, Integer.class, long.class, Long.class, float.class, Float.class, double.class, Double.class
);
/**
* 默认值
*/
private static final Map<Class<?>, Object> defaultValueMap = new HashMap<Class<?>, Object>() {
{
this.put(byte.class, 0);
this.put(short.class, 0);
this.put(int.class, 0);
this.put(long.class, 0);
this.put(float.class, 0);
this.put(double.class, 0);
this.put(char.class, 0);
this.put(boolean.class, false);
}
};
/**
* 默认的类型匹配器
*/
private static final TypeMatchers defaultTypeMatchers = new TypeMatchers();
/**
* 获取字段类型
* @param field
* @return
*/
public static Class<?> getFieldType(Field field) {
return field.getType();
}
/**
* 字段类型匹配
* @param field
* @param clazz
* @return
*/
public static boolean fieldTypeMatch(Field field, Class<?> clazz) {
return getFieldType(field) == clazz;
}
/**
* 是否是严格基本类型
* @param clazz
* @return
*/
public static boolean isStrictBasicType(Class<?> clazz) {
return strictBasicType.contains(clazz);
}
/**
* 是否是严格基本类型
* @param field
* @return
*/
public static boolean isStrictBasicType(Field field) {
return isStrictBasicType(getFieldType(field));
}
/**
* 是否是一般基本类型
* @param clazz
* @return
*/
public static boolean isNormalBasicType(Class<?> clazz) {
return normalBasicType.contains(clazz);
}
/**
* 是否是数字
* @param clazz
* @return
*/
public static boolean isNumber(Class<?> clazz) {
return Number.class.isAssignableFrom(clazz);
}
/**
* 是否是一般基本类型
* @param field
* @return
*/
public static boolean isNormalBasicType(Field field) {
return isNormalBasicType(getFieldType(field));
}
/**
* 是否是包装类型
* @param clazz
* @return
*/
public static boolean isWrapType(Class<?> clazz) {
return !isStrictBasicType(clazz);
}
/**
* 是否是包装类型
* @param field
* @return
*/
public static boolean isWrapType(Field field) {
return !isStrictBasicType(field);
}
/**
* 是否是byte类型
* @param field
* @return
*/
public static boolean isByte(Field field) {
return isByte(getFieldType(field));
}
/**
* 是否是byte类型
* @param clazz
* @return
*/
public static boolean isByte(Class clazz) {
return clazz == byte.class || clazz == Byte.class;
}
/**
* 是否是short类型
* @param field
* @return
*/
public static boolean isShort(Field field) {
return isShort(getFieldType(field));
}
/**
* 是否是short类型
* @param clazz
* @return
*/
public static boolean isShort(Class clazz) {
return clazz == short.class || clazz == Short.class;
}
/**
* 是否是integer类型
* @param field
* @return
*/
public static boolean isInteger(Field field) {
return isInteger(getFieldType(field));
}
/**
* 是否是integer类型
* @param clazz
* @return
*/
public static boolean isInteger(Class clazz) {
return clazz == int.class || clazz == Integer.class;
}
/**
* 是否是long类型
* @param field
* @return
*/
public static boolean isLong(Field field) {
return isLong(getFieldType(field));
}
/**
* 是否是long类型
* @param clazz
* @return
*/
public static boolean isLong(Class<?> clazz) {
return clazz == long.class || clazz == Long.class;
}
/**
* 是否是float类型
* @param field
* @return
*/
public static boolean isFloat(Field field) {
return isFloat(getFieldType(field));
}
/**
* 是否是float类型
* @param clazz
* @return
*/
public static boolean isFloat(Class<?> clazz) {
return clazz == float.class || clazz == Float.class;
}
/**
* 是否是double类型
* @param field
* @return
*/
public static boolean isDouble(Field field) {
return isDouble(getFieldType(field));
}
/**
* 是否是double类型
* @param clazz
* @return
*/
public static boolean isDouble(Class<?> clazz) {
return clazz == double.class || clazz == Double.class;
}
/**
* 是否是char类型
* @param field
* @return
*/
public static boolean isChar(Field field) {
Class<?> clazz = getFieldType(field);
return clazz == char.class || clazz == Character.class;
}
/**
* 是否是boolean类型
* @param field
* @return
*/
public static boolean isBoolean(Field field) {
Class<?> clazz = getFieldType(field);
return clazz == boolean.class || clazz == Boolean.class;
}
/**
* 是否是String类型
* @param field
* @return
*/
public static boolean isString(Field field) {
return isString(getFieldType(field));
}
/**
* 是否是String类型
* @param clazz
* @return
*/
public static boolean isString(Class clazz) {
return clazz == String.class;
}
/**
* 是否是日期类型
* @param field
* @return
*/
public static boolean isDate(Field field) {
return isDate(getFieldType(field));
}
/**
* 是否是日期类型
* @param clazz
* @return
*/
public static boolean isDate(Class<?> clazz) {
return clazz == Date.class || clazz == java.sql.Date.class;
}
/**
* 是否是布尔值
* @param clazz
* @return
*/
public static boolean isBoolean(Class<?> clazz) {
return clazz == boolean.class || clazz == Boolean.class;
}
/**
* 是否是字符
* @param clazz
* @return
*/
public static boolean isChar(Class<?> clazz) {
return clazz == char.class || clazz == Character.class;
}
/**
* 是否是map类型
* @param clazz
* @return
*/
public static boolean isMap(Class<?> clazz) {
return Map.class.isAssignableFrom(clazz);
}
/**
* 获取包装类型
* @param clazz
* @return
*/
public static Class<?> getWrapType(Class<?> clazz) {
if (isStrictBasicType(clazz)) {
return wrapTypeMap.get(clazz);
}
return clazz;
}
/**
* 获取包装类型
* @param field
* @return
*/
public static Class<?> getWrapType(Field field) {
return getWrapType(getFieldType(field));
}
/**
* 是否是超类
* @param superClass
* @param childClass
* @return
*/
public static boolean isSupper(Class<?> superClass, Class<?> childClass) {
return superClass.isAssignableFrom(childClass);
}
/**
* 获取简单类名
* @param clazz
* @return
*/
public static String getSimpleName(Class<?> clazz) {
return clazz.getSimpleName();
}
/**
* 获取包名
* @param clazz
* @return
*/
public static String getPackageName(Class<?> clazz) {
return clazz.getPackage().getName();
}
/**
* 获取默认变量名
* @param clazz
* @return
*/
public static String getDefaultVariableName(Class<?> clazz) {
String name = getSimpleName(clazz);
return name.substring(0, 1).toLowerCase() + name.substring(1);
}
/**
* 获取默认值
* @param clazz
* @return
*/
public static Object getDefaultValue(Class<?> clazz) {
return defaultValueMap.get(clazz);
}
/**
* 是否是集合类型
* @param clazz
* @return
*/
public static boolean isCollection(Class<?> clazz) {
return Collection.class.isAssignableFrom(clazz);
}
/**
* 是否可列举
* @param clazz
* @return
*/
public static boolean isListable(Class<?> clazz) {
return clazz.isArray() || isCollection(clazz);
}
/**
* 是否是list
* @param clazz
* @return
*/
public static boolean isList(Class<?> clazz) {
return List.class.isAssignableFrom(clazz);
}
/**
* list转成其他形式
* @param list
* @param targetType
* @return
*/
public static Object listTo(List list, Class<?> targetType) {
if (null == list) {
return null;
}
if (isList(targetType)) {
return list;
}
// 数组
if (targetType.isArray()) {
return list.toArray();
}
// set
if (Set.class.isAssignableFrom(targetType)) {
return list.stream().collect(Collectors.toSet());
}
return null;
}
/**
* 获取继承层级
* 此处假定继承层级最多为100层,避免计算太过耗时
* @param superClass
* @param childClass
* @return
*/
public static int getInheritLevel(Class<?> superClass, Class<?> childClass) {
if (!isSupper(superClass, childClass)) {
return -1;
}
List<Pair<Class<?>, Integer>> list = new LinkedList<>();
list.add(Pair.of(childClass, 0));
while (CollectionUtil.isNotEmpty(list) && list.get(0).getKey() != superClass && list.get(0).getValue() < 100) {
Pair<Class<?>, Integer> current = list.remove(0);
Class<?> clazz = current.getKey();
int level = current.getValue();
if (null != clazz.getSuperclass()) {
list.add(Pair.of(clazz.getSuperclass(), level + 1));
}
if (null != clazz.getInterfaces() && clazz.getInterfaces().length > 0) {
for (Class<?> inter : clazz.getInterfaces()) {
list.add(Pair.of(inter, level + 1));
}
}
}
if (list.isEmpty()) {
return 100;
}
return Math.min(list.get(0).getValue(), 100);
}
/**
* 计算一个类型的值是否可以赋值给指定类型的匹配信息
* @param fieldType
* @param valueType
* @return
*/
public static TypeMatchInfo typeMatch(Class<?> fieldType, Class<?> valueType) {
Assert.notNull(fieldType, "字段类型不能为空!");
Assert.notNull(valueType, "值类型不能为空!");
return new TypeMatchInfo(fieldType, valueType, null);
}
/**
* 类型转换
* @param value
* @param targetType
* @return
*/
public static <T> T conversion(Object value, Class<T> targetType) {
return (T)defaultTypeMatchers.conversion(value, targetType);
}
}
-6
View File
@@ -56,12 +56,6 @@
<scope>system</scope>
<systemPath>${project.basedir}/../_solon_plugin/job-solon-plugin/pom.xml</systemPath>
</dependency>
<!--hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.8.15</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.hutool</groupId>-->
<!-- <artifactId>hutool-db</artifactId>-->
@@ -21,12 +21,12 @@
*/
package fun.asgc.neutrino.proxy.server.base.db;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.jfinal.plugin.activerecord.Db;
import fun.asgc.neutrino.core.util.Assert;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import fun.asgc.neutrino.proxy.core.util.Assert;
import fun.asgc.neutrino.proxy.core.util.FileUtil;
import fun.asgc.neutrino.proxy.server.constant.DbTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
@@ -81,7 +81,7 @@ public class DBInitialize implements EventListener<AppLoadEndEvent> {
}
String sql = "";
for (String line : lines) {
if (StringUtil.isEmpty(line) || StringUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
if (StrUtil.isEmpty(line) || StrUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
continue;
}
sql += "\r\n" + line.trim();
@@ -114,7 +114,7 @@ public class DBInitialize implements EventListener<AppLoadEndEvent> {
}
String sql = "";
for (String line : lines) {
if (StringUtil.isEmpty(line) || StringUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
if (StrUtil.isEmpty(line) || StrUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
continue;
}
sql += "\r\n" + line.trim();
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.base.proxy;
import fun.asgc.neutrino.core.base.DefaultDispatcher;
import fun.asgc.neutrino.core.base.Dispatcher;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.DefaultDispatcher;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.nio.NioEventLoopGroup;
import org.noear.solon.annotation.Bean;
@@ -1,6 +1,6 @@
package fun.asgc.neutrino.proxy.server.base.rest.interceptor;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.server.base.rest.*;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
import fun.asgc.neutrino.proxy.server.constant.ExceptionConstant;
@@ -39,7 +39,7 @@ public class BaseAuthInterceptor implements RouterInterceptor {
Authorization authorization = targetMethod.getAnnotation(Authorization.class);
if (null == authorization || authorization.login()) {
String authorize = ctx.header("Authorize");
if (StringUtil.isEmpty(authorize)) {
if (StrUtil.isEmpty(authorize)) {
throw ServiceException.create(ExceptionConstant.USER_NOT_LOGIN);
}
UserDO userDO = Solon.context().getBean(UserService.class).findByToken(authorize);
@@ -1,80 +1,77 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.base.rest.interceptor;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.web.context.HttpRequestWrapper;
import fun.asgc.neutrino.core.web.context.HttpResponseWrapper;
import fun.asgc.neutrino.core.web.interceptor.HandlerInterceptor;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.util.Date;
/**
* 访问日志拦截器
* @author: aoshiguchen
* @date: 2022/8/14
*/
@Slf4j
public class VisitLogInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod) throws Exception {
if (null != SystemContextHolder.getContext()) {
SystemContextHolder.getContext().setReceiveTime(new Date());
}
return true;
}
@Override
public void postHandle(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod, Object result) throws Exception {
if (null == SystemContextHolder.getContext() || null == SystemContextHolder.getContext().getReceiveTime()) {
return;
}
Date receiveTime = SystemContextHolder.getContext().getReceiveTime();
Date now = new Date();
long elapsedTime = now.getTime() - receiveTime.getTime();
log.info("\n-----------------------------------------------------------------接口请求日志:\n{} url:{} 执行耗时:{}\nURL参数:{}\n请求体参数:{}\n响应结果:{}\n客户端IP:{}\n",
requestParser.getMethod().name(), requestParser.getUrl(), getElapsedTimeStr(elapsedTime),
requestParser.getQueryString(),
requestParser.getContentAsString(),
JSONObject.toJSONString(result),
SystemContextHolder.getIp()
);
}
/**
* 获取耗时描述
* @param elapsedTime
* @return
*/
private static String getElapsedTimeStr(long elapsedTime) {
if (elapsedTime < 1000) {
return String.format("%s毫秒", elapsedTime);
} else if (elapsedTime < 60000) {
return String.format("%.2f秒", (elapsedTime * 1.0) / 1000);
}
return String.format("%.2f分钟", (elapsedTime * 1.0) / 1000 / 60);
}
}
///**
// * Copyright (c) 2022 aoshiguchen
// *
// * Permission is hereby granted, free of charge, to any person obtaining a copy
// * of this software and associated documentation files (the "Software"), to deal
// * in the Software without restriction, including without limitation the rights
// * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// * copies of the Software, and to permit persons to whom the Software is
// * furnished to do so, subject to the following conditions:
// *
// * The above copyright notice and this permission notice shall be included in all
// * copies or substantial portions of the Software.
// *
// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// * SOFTWARE.
// */
//package fun.asgc.neutrino.proxy.server.base.rest.interceptor;
//
//import com.alibaba.fastjson.JSONObject;
//import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
//import lombok.extern.slf4j.Slf4j;
//
//import java.lang.reflect.Method;
//import java.util.Date;
//
///**
// * 访问日志拦截器
// * @author: aoshiguchen
// * @date: 2022/8/14
// */
//@Slf4j
//public class VisitLogInterceptor implements HandlerInterceptor {
//
// @Override
// public boolean preHandle(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod) throws Exception {
// if (null != SystemContextHolder.getContext()) {
// SystemContextHolder.getContext().setReceiveTime(new Date());
// }
// return true;
// }
//
// @Override
// public void postHandle(HttpRequestWrapper requestParser, HttpResponseWrapper responseWrapper, String route, Method targetMethod, Object result) throws Exception {
// if (null == SystemContextHolder.getContext() || null == SystemContextHolder.getContext().getReceiveTime()) {
// return;
// }
// Date receiveTime = SystemContextHolder.getContext().getReceiveTime();
// Date now = new Date();
// long elapsedTime = now.getTime() - receiveTime.getTime();
// log.info("\n-----------------------------------------------------------------接口请求日志:\n{} url:{} 执行耗时:{}\nURL参数:{}\n请求体参数:{}\n响应结果:{}\n客户端IP:{}\n",
// requestParser.getMethod().name(), requestParser.getUrl(), getElapsedTimeStr(elapsedTime),
// requestParser.getQueryString(),
// requestParser.getContentAsString(),
// JSONObject.toJSONString(result),
// SystemContextHolder.getIp()
// );
// }
//
// /**
// * 获取耗时描述
// * @param elapsedTime
// * @return
// */
// private static String getElapsedTimeStr(long elapsedTime) {
// if (elapsedTime < 1000) {
// return String.format("%s毫秒", elapsedTime);
// } else if (elapsedTime < 60000) {
// return String.format("%.2f秒", (elapsedTime * 1.0) / 1000);
// }
// return String.format("%.2f分钟", (elapsedTime * 1.0) / 1000 / 60);
// }
//}
@@ -1,27 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.controller;
import fun.asgc.neutrino.core.annotation.NonIntercept;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.controller.req.*;
@@ -35,7 +13,6 @@ import org.noear.solon.annotation.*;
* @author: aoshiguchen
* @date: 2022/8/8
*/
@NonIntercept
@Mapping("/port-mapping")
@Controller
public class PortMappingController {
@@ -1,28 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.controller;
import fun.asgc.neutrino.core.db.page.PageInfo;
import fun.asgc.neutrino.core.db.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.controller.req.LicenseFlowReportReq;
import fun.asgc.neutrino.proxy.server.controller.req.UserFlowReportReq;
import fun.asgc.neutrino.proxy.server.controller.res.LicenseFlowReportRes;
@@ -1,27 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.controller.res;
import fun.asgc.neutrino.core.db.annotation.Id;
import fun.asgc.neutrino.proxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -36,7 +14,6 @@ import java.util.Date;
@Accessors(chain = true)
@Data
public class LicenseListRes {
@Id
private Integer id;
/**
* 名称
@@ -1,27 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.controller.res;
import fun.asgc.neutrino.core.db.annotation.Id;
import fun.asgc.neutrino.proxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -36,7 +14,6 @@ import java.util.Date;
@Accessors(chain = true)
@Data
public class PortMappingDetailRes {
@Id
private Integer id;
/**
* licenseId
@@ -1,27 +1,5 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.controller.res;
import fun.asgc.neutrino.core.db.annotation.Id;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -1,30 +1,9 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.dal;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
import org.apache.ibatis.annotations.Mapper;
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import fun.asgc.neutrino.core.db.annotation.Insert;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
@@ -1,29 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.job;
import com.alibaba.fastjson.JSONObject;
import fun.asgc.neutrino.core.annotation.Autowired;
import fun.asgc.neutrino.core.util.DateUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.dal.*;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
@@ -32,6 +10,7 @@ import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -71,17 +50,17 @@ public class DataCleanJob implements IJobHandler {
* 流量统计天报表记录保留天数
*/
private static final Integer FLOW_DAY_REPORT_KEEP_DAYS = 400;
@Autowired
@Inject
private JobLogMapper jobLogMapper;
@Autowired
@Inject
private UserLoginRecordMapper userLoginRecordMapper;
@Autowired
@Inject
private ClientConnectRecordMapper clientConnectRecordMapper;
@Autowired
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Autowired
@Inject
private FlowReportHourMapper flowReportHourMapper;
@Autowired
@Inject
private FlowReportDayMapper flowReportDayMapper;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -1,24 +1,3 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.job;
import fun.asgc.solon.extend.job.IJobHandler;
@@ -21,8 +21,8 @@
*/
package fun.asgc.neutrino.proxy.server.job;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.DateUtil;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.dal.FlowReportDayMapper;
import fun.asgc.neutrino.proxy.server.dal.FlowReportHourMapper;
import fun.asgc.neutrino.proxy.server.dal.FlowReportMinuteMapper;
@@ -1,28 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.job;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.DateUtil;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.dal.FlowReportHourMapper;
import fun.asgc.neutrino.proxy.server.dal.FlowReportMinuteMapper;
import fun.asgc.neutrino.proxy.server.dal.LicenseMapper;
@@ -1,28 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.job;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.DateUtil;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.dal.FlowReportMinuteMapper;
import fun.asgc.neutrino.proxy.server.dal.LicenseMapper;
import fun.asgc.neutrino.proxy.server.dal.entity.FlowReportMinuteDO;
@@ -1,28 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.job;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.core.util.DateUtil;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.dal.*;
import fun.asgc.neutrino.proxy.server.dal.entity.FlowReportDayDO;
import fun.asgc.neutrino.proxy.server.dal.entity.FlowReportMonthDO;
@@ -1,30 +1,8 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.core;
import fun.asgc.neutrino.core.util.FileUtil;
import fun.asgc.neutrino.proxy.core.ProxyMessageDecoder;
import fun.asgc.neutrino.proxy.core.ProxyMessageEncoder;
import fun.asgc.neutrino.proxy.core.util.FileUtil;
import fun.asgc.neutrino.proxy.server.base.proxy.ProxyConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandler;
@@ -22,10 +22,9 @@
package fun.asgc.neutrino.proxy.server.proxy.core;
import fun.asgc.neutrino.core.base.Dispatcher;
import fun.asgc.neutrino.core.util.ChannelUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.dispatcher.Dispatcher;
import fun.asgc.neutrino.proxy.server.constant.ClientConnectTypeEnum;
import fun.asgc.neutrino.proxy.server.constant.SuccessCodeEnum;
import fun.asgc.neutrino.proxy.server.dal.entity.ClientConnectRecordDO;
@@ -39,6 +38,7 @@ import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Solon;
import java.net.InetSocketAddress;
import java.util.Date;
/**
@@ -89,7 +89,7 @@ public class ServerChannelHandler extends SimpleChannelInboundHandler<ProxyMessa
if (null != cmdChannelAttachInfo) {
Solon.context().getBean(ProxyMutualService.class).offline(cmdChannelAttachInfo);
Solon.context().getBean(ClientConnectRecordService.class).add(new ClientConnectRecordDO()
.setIp(ChannelUtil.getIP(ctx.channel()))
.setIp(((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress())
.setLicenseId(cmdChannelAttachInfo.getLicenseId())
.setType(ClientConnectTypeEnum.DISCONNECT.getType())
.setMsg("")
@@ -1,28 +1,6 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.core;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.server.proxy.domain.VisitorChannelAttachInfo;
@@ -88,7 +66,7 @@ public class VisitorChannelHandler extends SimpleChannelInboundHandler<ByteBuf>
} else {
String visitorId = newVisitorId();
String lanInfo = ProxyUtil.getClientLanInfoByServerPort(sa.getPort());
if (StringUtil.isEmpty(lanInfo)) {
if (StrUtil.isEmpty(lanInfo)) {
ctx.channel().close();
} else {
// 用户连接到代理服务器时,设置用户连接不可读,等待代理后端服务器连接成功后再改变为可读状态
@@ -1,27 +1,6 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.domain;
import fun.asgc.neutrino.core.util.CollectionUtil;
import cn.hutool.core.collection.CollectionUtil;
import fun.asgc.neutrino.proxy.server.dal.entity.PortMappingDO;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -22,10 +22,9 @@
package fun.asgc.neutrino.proxy.server.proxy.handler;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.util.ChannelUtil;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import fun.asgc.neutrino.proxy.server.base.proxy.ProxyConfig;
import fun.asgc.neutrino.proxy.server.constant.ClientConnectTypeEnum;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
@@ -43,6 +42,7 @@ import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.net.InetSocketAddress;
import java.util.Date;
/**
@@ -75,11 +75,11 @@ public class ProxyMessageAuthHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
String ip = ChannelUtil.getIP(ctx.channel());
String ip = ((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();
Date now = new Date();
String licenseKey = proxyMessage.getInfo();
if (StringUtil.isEmpty(licenseKey)) {
if (StrUtil.isEmpty(licenseKey)) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "license不能为空!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
@@ -1,30 +1,8 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.handler;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.core.*;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
import fun.asgc.neutrino.proxy.server.dal.entity.LicenseDO;
import fun.asgc.neutrino.proxy.server.dal.entity.UserDO;
@@ -53,7 +31,7 @@ public class ProxyMessageConnectHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
String info = proxyMessage.getInfo();
if (StringUtil.isEmpty(info)) {
if (StrUtil.isEmpty(info)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "info不能为空!"));
ctx.channel().close();
return;
@@ -1,32 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.handler;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import fun.asgc.neutrino.proxy.server.util.ProxyUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
@@ -1,32 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.handler;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import org.noear.solon.annotation.Component;
@@ -1,32 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.proxy.handler;
import fun.asgc.neutrino.core.annotation.Match;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.core.ProxyDataTypeEnum;
import fun.asgc.neutrino.proxy.core.ProxyMessage;
import fun.asgc.neutrino.proxy.core.ProxyMessageHandler;
import fun.asgc.neutrino.proxy.core.dispatcher.Match;
import fun.asgc.neutrino.proxy.server.proxy.domain.VisitorChannelAttachInfo;
import fun.asgc.neutrino.proxy.server.service.FlowReportService;
import fun.asgc.neutrino.proxy.server.util.ProxyUtil;
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
@@ -21,7 +21,7 @@
*/
package fun.asgc.neutrino.proxy.server.service;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.proxy.core.util.LockUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
@@ -1,32 +1,11 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Sets;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
@@ -1,32 +1,11 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Sets;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.rest.SystemContextHolder;
@@ -1,28 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import fun.asgc.neutrino.core.db.page.PageInfo;
import fun.asgc.neutrino.core.db.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.controller.req.LicenseFlowReportReq;
import fun.asgc.neutrino.proxy.server.controller.req.UserFlowReportReq;
import fun.asgc.neutrino.proxy.server.controller.res.LicenseFlowReportRes;
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.controller.req.UserLoginRecordListReq;
@@ -1,31 +1,10 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import fun.asgc.neutrino.core.util.DateUtil;
import fun.asgc.neutrino.proxy.core.util.DateUtil;
import fun.asgc.neutrino.proxy.server.base.page.PageInfo;
import fun.asgc.neutrino.proxy.server.base.page.PageQuery;
import fun.asgc.neutrino.proxy.server.base.rest.ServiceException;
@@ -1,29 +1,8 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.core.Constants;
import fun.asgc.neutrino.proxy.server.constant.EnableStatusEnum;
import fun.asgc.neutrino.proxy.server.dal.LicenseMapper;
@@ -1,27 +1,6 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.util;
import fun.asgc.neutrino.core.util.StringUtil;
import cn.hutool.core.util.StrUtil;
import fun.asgc.neutrino.proxy.server.constant.ExceptionConstant;
import fun.asgc.neutrino.proxy.server.base.rest.ServiceException;
@@ -43,7 +22,7 @@ public class ParamCheckUtil {
}
public static void checkNotEmpty(String str, String name) {
if (StringUtil.isEmpty(str)) {
if (StrUtil.isEmpty(str)) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_EMPTY, name);
}
}
@@ -80,7 +59,7 @@ public class ParamCheckUtil {
}
public static void checkNotEmpty(String str, ExceptionConstant constant, Object... params) {
if (StringUtil.isEmpty(str)) {
if (StrUtil.isEmpty(str)) {
throw ServiceException.create(constant, params);
}
}
@@ -1,29 +1,7 @@
/**
* Copyright (c) 2022 aoshiguchen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fun.asgc.neutrino.proxy.server.util;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Sets;
import fun.asgc.neutrino.core.util.ChannelUtil;
import fun.asgc.neutrino.core.util.CollectionUtil;
import fun.asgc.neutrino.proxy.core.ChannelAttribute;
import fun.asgc.neutrino.proxy.server.proxy.domain.CmdChannelAttachInfo;
import fun.asgc.neutrino.proxy.server.proxy.domain.ProxyMapping;
@@ -134,7 +112,7 @@ public class ProxyUtil {
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
if (null == cmdChannelAttachInfo) {
cmdChannelAttachInfo = new CmdChannelAttachInfo()
.setIp(ChannelUtil.getIP(cmdChannel))
.setIp(((InetSocketAddress)cmdChannel.remoteAddress()).getAddress().getHostAddress())
.setLicenseId(licenseId)
.setVisitorChannelMap(new HashMap<>(16))
.setServerPorts(Sets.newHashSet());
@@ -213,7 +191,7 @@ public class ProxyUtil {
.setLanInfo(lanInfo)
.setServerPort(serverPort)
.setLicenseId(cmdChannelAttachInfo.getLicenseId())
.setIp(ChannelUtil.getIP(visitorChannel))
.setIp(((InetSocketAddress)visitorChannel.remoteAddress()).getAddress().getHostAddress())
);
userChannelMapLock.writeLock().lock();
try {