基础包名改为org.dromara.neutrinoproxy

This commit is contained in:
aoshiguchen
2023-04-01 20:41:56 +08:00
parent bb4ca4daf5
commit cbbaca8590
253 changed files with 805 additions and 795 deletions
@@ -0,0 +1,23 @@
package org.dromara.neutrinoproxy.server;
import fun.asgc.solon.extend.job.annotation.EnableJob;
import org.noear.solon.Solon;
import org.noear.solon.annotation.SolonMain;
import org.noear.solon.web.cors.CrossFilter;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@EnableJob
@SolonMain
public class ProxyServer {
public static void main(String[] args) {
Solon.start(ProxyServer.class, args, app -> {
// 跨域支持。加-1 优先级更高
app.filter(-1, new CrossFilter().allowedOrigins("*"));
});
}
}
@@ -0,0 +1,127 @@
/**
* 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 org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.core.util.Assert;
import org.dromara.neutrinoproxy.core.util.FileUtil;
import org.dromara.neutrinoproxy.server.constant.DbTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.event.EventListener;
import java.util.List;
/**
* 初始化数据库
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Slf4j
@Component
public class DBInitialize implements EventListener<AppLoadEndEvent> {
private static List<String> initDataTableNameList = Lists.newArrayList("user", "license", "port_group", "port_pool", "port_mapping", "job_info");
@Inject
private DbConfig dbConfig;
private DbTypeEnum dbTypeEnum;
@Init
public void init() throws Throwable {
Assert.notNull(dbConfig.getType(), "neutrino.data.db.type不能为空!");
dbTypeEnum = DbTypeEnum.of(dbConfig.getType());
Assert.notNull(dbTypeEnum, "neutrino.data.db.type取值异常!");
log.info("{}数据库初始化...", dbConfig.getType());
initDBStructure();
initDBData();
}
@Override
public void onEvent(AppLoadEndEvent appLoadEndEvent) throws Throwable {
// TODO 该事件有50%的概率不触发
System.out.println("11");
}
/**
* 初始化数据库结构
*/
private void initDBStructure() throws Exception {
List<String> lines = FileUtil.readContentAsStringList(String.format("classpath:/sql/%s/init-structure.sql", dbConfig.getType()));
if (CollectionUtil.isEmpty(lines)) {
return;
}
String sql = "";
for (String line : lines) {
if (StrUtil.isEmpty(line) || StrUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
continue;
}
sql += "\r\n" + line.trim();
if (sql.endsWith(";")) {
log.debug("初始化数据库表 sql:{}", sql);
Db.update(sql);
sql = "";
}
}
}
/**
* 初始化数据
*
* @throws Exception
*/
private void initDBData() throws Exception {
if (CollectionUtil.isEmpty(initDataTableNameList)) {
return;
}
for (String tableName : initDataTableNameList) {
// 表里没有数据的时候,才进行初始化操作
int count = Db.queryInt(String.format("select count(1) from `%s`", tableName));
if (count > 0) {
continue;
}
List<String> lines = FileUtil.readContentAsStringList(String.format("classpath:/sql/%s/%s.data.sql", dbConfig.getType(), tableName));
if (CollectionUtil.isEmpty(lines)) {
return;
}
String sql = "";
for (String line : lines) {
if (StrUtil.isEmpty(line) || StrUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) {
continue;
}
sql += "\r\n" + line.trim();
if (sql.endsWith(";")) {
log.debug("初始化数据[table={}] sql:{}", tableName, sql);
Db.update(sql);
sql = "";
}
}
}
}
}
@@ -0,0 +1,64 @@
/**
* 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 org.dromara.neutrinoproxy.server.base.db;
import org.dromara.neutrinoproxy.server.constant.DbTypeEnum;
import lombok.Data;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
/**
* sqlite数据库配置
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Data
@Component
public class DbConfig {
/**
* 数据库类型
* {@link DbTypeEnum}
*/
@Inject("${neutrino.data.db.type}")
private String type;
/**
* 连接url
*/
@Inject("${neutrino.data.db.url}")
private String url;
/**
* 驱动类
*/
@Inject("${neutrino.data.db.driver-class}")
private String driverClass;
/**
* 用户名
*/
@Inject("${neutrino.data.db.username}")
private String username;
/**
* 密码
*/
@Inject("${neutrino.data.db.password}")
private String password;
}
@@ -0,0 +1,70 @@
package org.dromara.neutrinoproxy.server.base.db;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.zaxxer.hikari.HikariDataSource;
import org.dromara.neutrinoproxy.server.constant.DbTypeEnum;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.sqlite.SQLiteConfig;
import org.sqlite.SQLiteDataSource;
import javax.sql.DataSource;
/**
* @author: aoshiguchen
* @date: 2023/3/10
*/
@Configuration
public class DbConfiguration {
@Bean(value = "db", typed = true)
public DataSource dataSource(@Inject DbConfig dbConfig) {
DbTypeEnum dbTypeEnum = DbTypeEnum.of(dbConfig.getType());
if (DbTypeEnum.SQLITE == dbTypeEnum) {
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl(dbConfig.getUrl());
dataSource.setJournalMode(SQLiteConfig.JournalMode.WAL.getValue());
return dataSource;
} else if (DbTypeEnum.MYSQL == dbTypeEnum) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName(dbConfig.getDriverClass());
dataSource.setJdbcUrl(dbConfig.getUrl());
dataSource.setMinimumIdle(5);
dataSource.setMaximumPoolSize(20);
dataSource.setMaxLifetime(60000);
// dataSource.setInitialSize(5);
// dataSource.setMinIdle(5);
// dataSource.setMaxActive(20);
// dataSource.setMaxWait(60000);
// dataSource.setPoolPreparedStatements(true);
dataSource.setUsername(dbConfig.getUsername());
dataSource.setPassword(dbConfig.getPassword());
return dataSource;
}
return null;
}
@Bean
public void db1_ext(@Db("db") GlobalConfig globalConfig) {
MetaObjectHandler metaObjectHandler = new MetaObjectHandlerImpl();
globalConfig.setMetaObjectHandler(metaObjectHandler);
}
@Bean
public void db1_ext2(@Db("db") MybatisConfiguration config){
config.getTypeHandlerRegistry().register("fun.asgc.neutrino.proxy.server.dal");
config.setDefaultEnumTypeHandler(null);
}
@Bean
public MybatisSqlSessionFactoryBuilder factoryBuilderNew(){
return new MybatisSqlSessionFactoryBuilderImpl();
}
}
@@ -0,0 +1,20 @@
package org.dromara.neutrinoproxy.server.base.db;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
/**
* @author: aoshiguchen
* @date: 2023/3/10
*/
public class MetaObjectHandlerImpl implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
}
@Override
public void updateFill(MetaObject metaObject) {
}
}
@@ -0,0 +1,11 @@
package org.dromara.neutrinoproxy.server.base.db;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
/**
* @author: aoshiguchen
* @date: 2023/3/10
*/
public class MybatisSqlSessionFactoryBuilderImpl extends MybatisSqlSessionFactoryBuilder {
}
@@ -0,0 +1,111 @@
package org.dromara.neutrinoproxy.server.base.page;
import lombok.Data;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 8545996863226528797L;
private List<T> records;
private Long total;
private Integer size;
private Integer current;
public PageInfo() {
this.records = Collections.emptyList();
this.total = 0L;
this.size = 10;
this.current = 1;
}
public PageInfo(Integer current, Integer size) {
this(current, size, 0L);
}
public PageInfo(Integer current, Integer size, Long total) {
this.records = Collections.emptyList();
this.total = 0L;
this.size = 10;
this.current = 1;
if ((long)current > 1L) {
this.current = current;
}
this.size = size;
this.total = total;
}
public Long getPages() {
if ((long)this.getSize() == 0L) {
return 0L;
} else {
Long pages = this.getTotal() / (long)this.getSize();
if (this.getTotal() % (long)this.getSize() != 0L) {
pages = pages + 1L;
}
return pages;
}
}
public Long getTotal() {
return this.total;
}
public Integer getSize() {
return this.size;
}
public boolean hasPrevious() {
return (long)this.current > 1L;
}
public boolean hasNext() {
return (long)this.current < this.getPages();
}
public List<T> getRecords() {
return this.records;
}
public PageInfo<T> setRecords(List<T> records) {
this.records = records;
return this;
}
public PageInfo<T> setTotal(Long total) {
this.total = total;
return this;
}
public PageInfo<T> setSize(Integer size) {
this.size = size;
return this;
}
public Integer getCurrent() {
return this.current;
}
public PageInfo<T> setCurrent(Integer current) {
this.current = current;
return this;
}
public static <T> PageInfo<T> of(List<T> records, Long total, Integer current, Integer size) {
PageInfo<T> pageInfo = new PageInfo();
pageInfo.setRecords(records);
pageInfo.setTotal(total);
pageInfo.setCurrent(current);
pageInfo.setSize(size);
return pageInfo;
}
}
@@ -0,0 +1,22 @@
package org.dromara.neutrinoproxy.server.base.page;
import lombok.Data;
import java.io.Serializable;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class PageQuery implements Serializable {
/**
* 当前页
*/
private int current = 1;
/**
* 分页大小
*/
private int size = 10;
}
@@ -0,0 +1,49 @@
package org.dromara.neutrinoproxy.server.base.proxy;
import lombok.Data;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
/**
* 服务端代理配置
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Data
@Component
public class ProxyConfig {
/**
* 传输协议相关配置
*/
@Inject("${neutrino.proxy.protocol}")
private Protocol protocol;
/**
* 服务端配置
*/
@Inject("${neutrino.proxy.server}")
private Server server;
@Data
public static class Protocol {
private Integer maxFrameLength;
private Integer lengthFieldOffset;
private Integer lengthFieldLength;
private Integer initialBytesToStrip;
private Integer lengthAdjustment;
private Integer readIdleTime;
private Integer writeIdleTime;
private Integer allIdleTimeSeconds;
}
@Data
public static class Server {
private Integer port;
private Integer sslPort;
private String keyStorePassword;
private String keyManagerPassword;
private String jksPath;
private Integer bossThreadCount;
private Integer workThreadCount;
}
}
@@ -0,0 +1,46 @@
package org.dromara.neutrinoproxy.server.base.proxy;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.DefaultDispatcher;
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.nio.NioEventLoopGroup;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.bean.LifecycleBean;
import java.util.List;
/**
* 代理配置
* @author: aoshiguchen
* @date: 2022/10/8
*/
@Configuration
public class ProxyConfiguration implements LifecycleBean {
@Override
public void start() throws Throwable {
List<ProxyMessageHandler> list = Solon.context().getBeansOfType(ProxyMessageHandler.class);
Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher = new DefaultDispatcher<>("消息调度器", list,
proxyMessage -> ProxyDataTypeEnum.of((int)proxyMessage.getType()) == null ?
null : ProxyDataTypeEnum.of((int)proxyMessage.getType()).getName());
Solon.context().wrapAndPut(Dispatcher.class, dispatcher);
}
@Bean("serverBossGroup")
public NioEventLoopGroup serverBossGroup(@Inject ProxyConfig proxyConfig) {
return new NioEventLoopGroup(proxyConfig.getServer().getBossThreadCount());
}
@Bean("serverWorkerGroup")
public NioEventLoopGroup serverWorkerGroup(@Inject ProxyConfig proxyConfig) {
return new NioEventLoopGroup(proxyConfig.getServer().getWorkThreadCount());
}
}
@@ -0,0 +1,40 @@
/**
* 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 org.dromara.neutrinoproxy.server.base.rest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 鉴权注解
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Authorization {
boolean login() default true;
boolean onlyAdmin() default false;
}
@@ -0,0 +1,39 @@
/**
* 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 org.dromara.neutrinoproxy.server.base.rest;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 响应体
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Accessors(chain = true)
@Data
public class ResponseBody<T> {
private Integer code;
private String msg;
private T data;
private String stack;
}
@@ -0,0 +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 org.dromara.neutrinoproxy.server.base.rest;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
/**
* 服务异常
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Getter
public class ServiceException extends RuntimeException {
/**
* 错误码
*/
private int code;
/**
* 异常消息
*/
private String msg;
public ServiceException(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static ServiceException create(ExceptionConstant constant) {
return new ServiceException(constant.getCode(), constant.getMsg());
}
public static ServiceException create(ExceptionConstant constant, Object... params) {
return new ServiceException(constant.getCode(), format(constant.getMsg(), params));
}
/**
* 字符串格式化
* @param template
* @param params
* @return
*/
public static String format(String template, Object[] params) {
if (StringUtils.isEmpty(template) || null == params || params.length == 0) {
return template;
}
String result = template;
for (Object param : params) {
int index = result.indexOf("{}");
if (index == -1) {
return result;
}
result = result.substring(0, index) + param + result.substring(index + 2);
}
return result;
}
}
@@ -0,0 +1,56 @@
/**
* 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 org.dromara.neutrinoproxy.server.base.rest;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import lombok.Data;
import lombok.experimental.Accessors;
import org.noear.solon.core.handle.Action;
import java.util.Date;
/**
* 系统上下文
* @author: aoshiguchen
* @date: 2022/8/2
*/
@Accessors(chain = true)
@Data
public class SystemContext {
/**
* 当前用户
*/
private UserDO user;
/**
* 鉴权token
*/
private String token;
/**
* 客户端ip
*/
private String ip;
/**
* 接收请求时间
*/
private Date receiveTime;
private Action action;
}
@@ -0,0 +1,71 @@
/**
* 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 org.dromara.neutrinoproxy.server.base.rest;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
/**
* 系统上下文持有者
* @author: aoshiguchen
* @date: 2022/8/2
*/
public class SystemContextHolder {
private static final ThreadLocal<SystemContext> systemContextHolder = new ThreadLocal<>();
public static void remove() {
systemContextHolder.remove();
}
public static void set(SystemContext systemContext) {
systemContextHolder.set(systemContext);
}
public static UserDO getUser() {
SystemContext context = getContext();
return (null == context) ? null : context.getUser();
}
public static Integer getUserId() {
UserDO userDO = getUser();
return (null == userDO) ? null : userDO.getId();
}
public static String getToken() {
return systemContextHolder.get().getToken();
}
public static String getIp() {
return systemContextHolder.get().getIp();
}
public static SystemContext getContext() {
return systemContextHolder.get();
}
public static boolean isAdmin() {
UserDO userDO = getUser();
if (null != userDO && userDO.getLoginName().equals("admin")) {
return true;
}
return false;
}
}
@@ -0,0 +1,96 @@
package org.dromara.neutrinoproxy.server.base.rest.interceptor;
import cn.hutool.core.util.StrUtil;
import org.dromara.neutrinoproxy.server.base.rest.*;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.dromara.neutrinoproxy.server.base.rest.*;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import java.lang.reflect.Method;
/**
* @author: aoshiguchen
* @date: 2023/3/9
*/
@Slf4j
@Component
public class BaseAuthInterceptor implements RouterInterceptor {
@Override
public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
if (!(mainHandler instanceof Action)) {
chain.doIntercept(ctx, mainHandler);
return;
}
Action action = (Action) mainHandler;
Method targetMethod = action.method().getMethod();
SystemContext systemContext = new SystemContext();
SystemContextHolder.set(systemContext);
systemContext.setIp(ctx.realIp());
Authorization authorization = targetMethod.getAnnotation(Authorization.class);
if (null == authorization || authorization.login()) {
String authorize = ctx.header("Authorize");
if (StrUtil.isEmpty(authorize)) {
throw ServiceException.create(ExceptionConstant.USER_NOT_LOGIN);
}
UserDO userDO = Solon.context().getBean(UserService.class).findByToken(authorize);
if (null == userDO) {
throw ServiceException.create(ExceptionConstant.USER_NOT_LOGIN);
}
if (EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) {
throw ServiceException.create(ExceptionConstant.USER_DISABLE);
}
if (null != authorization && authorization.onlyAdmin() && !userDO.getLoginName().equals("admin")) {
throw ServiceException.create(ExceptionConstant.NO_PERMISSION_VISIT);
}
systemContext.setToken(authorize);
systemContext.setUser(userDO);
// token续期
Solon.context().getBean(UserService.class).updateTokenExpirationTime(authorize);
}
chain.doIntercept(ctx, mainHandler);
}
@Override
public Object postResult(Context ctx, Object result) throws Throwable {
SystemContextHolder.remove();
if (result instanceof ResponseBody) {
return result;
}
if (result instanceof Throwable) {
log.error("全局异常", (Throwable) result);
if (result instanceof ServiceException) {
ServiceException exception = (ServiceException) result;
return new ResponseBody<>()
.setCode(exception.getCode())
.setMsg(exception.getMsg());
}
return new ResponseBody<>()
.setCode(ExceptionConstant.SYSTEM_ERROR.getCode())
.setMsg(ExceptionConstant.SYSTEM_ERROR.getMsg())
.setStack(ExceptionUtils.getStackTrace((Throwable) result));
}
return new ResponseBody<>()
.setCode(0)
.setData(result);
}
}
@@ -0,0 +1,42 @@
package org.dromara.neutrinoproxy.server.base.rest.interceptor;
import org.dromara.neutrinoproxy.server.base.rest.ResponseBody;
import org.dromara.neutrinoproxy.server.base.rest.ServiceException;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
/**
* @author: aoshiguchen
* @date: 2023/3/9
*/
@Slf4j
@Component
public class GlobalExceptionFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
try {
chain.doFilter(ctx);
} catch (Throwable e) {
log.error("全局异常", e);
if (e instanceof ServiceException) {
ServiceException serviceException = (ServiceException) e;
ctx.render(new ResponseBody<>()
.setCode(serviceException.getCode())
.setMsg(serviceException.getMsg()));
return;
}
ctx.render(new ResponseBody<>()
.setCode(ExceptionConstant.SYSTEM_ERROR.getCode())
.setMsg(ExceptionConstant.SYSTEM_ERROR.getMsg())
.setStack(ExceptionUtils.getStackTrace(e)));
}
}
}
@@ -0,0 +1,57 @@
package org.dromara.neutrinoproxy.server.base.rest.interceptor;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
import org.noear.solon.core.route.RouterInterceptor;
import org.noear.solon.core.route.RouterInterceptorChain;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2023/3/12
*/
@Slf4j
@Component(index = 1)
public class VisitLogInterceptor implements RouterInterceptor {
@Override
public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
if (!(mainHandler instanceof Action)) {
chain.doIntercept(ctx, mainHandler);
return;
}
Date startTime = new Date();
try {
chain.doIntercept(ctx, mainHandler);
} finally {
Date now = new Date();
long elapsedTime = now.getTime() - startTime.getTime();
log.info("\n-----------------------------------------------------------------接口请求日志:\n{} url:{} 执行耗时:{}\n请求体参数:{}\n响应结果:{}\n客户端IP:{}\n",
ctx.method(), ctx.path(), getElapsedTimeStr(elapsedTime),
JSONObject.toJSONString(ctx.paramMap()),
JSONObject.toJSONString(JSONObject.toJSONString(ctx.result)),
ctx.realIp()
);
}
}
/**
* 获取耗时描述
* @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);
}
}
@@ -0,0 +1,42 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 启用状态枚举
* @author: zCans
* @date: 2022/9/25
*/
@Getter
@AllArgsConstructor
public enum AlarmStatusEnum {
NOT(0, "-"),
WAIT(1, "待发送"),
SUCCESS(2, "发送成功"),
ERROR(3, "发送失败");
private Integer status;
private String desc;
}
@@ -0,0 +1,39 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: aoshiguchen
* @date: 2022/11/23
*/
@Getter
@AllArgsConstructor
public enum ClientConnectTypeEnum {
CONNECT(1, "连接"),
DISCONNECT(2, "断开连接");
private Integer type;
private String desc;
}
@@ -0,0 +1,39 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 连接类型枚举
* @author: aoshiguchen
* @date: 2022/8/31
*/
@Getter
@AllArgsConstructor
public enum ConnectTypeEnum {
CONNECT(1, "连接"),
DISCONNECT(2, "端开连接");
private Integer type;
private String desc;
}
@@ -0,0 +1,16 @@
package org.dromara.neutrinoproxy.server.constant;
/**
* @author: aoshiguchen
* @date: 2023/3/18
*/
public interface Constants {
/**
* 默认的端口分组ID
*/
int DEFAULT_PORT_GROUP_ID = 1;
/**
* 首页流量监控展示天数
*/
int HOME_FLOW_DAYS = 15;
}
@@ -0,0 +1,50 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
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/11/25
*/
@Getter
@AllArgsConstructor
public enum DbTypeEnum {
SQLITE("sqlite"),
MYSQL("mysql");
private String type;
private static final Map<String, DbTypeEnum> cache = Stream.of(DbTypeEnum.values()).collect(Collectors.toMap(DbTypeEnum::getType, Function.identity()));
public static DbTypeEnum of(String type) {
return cache.get(type);
}
}
@@ -0,0 +1,49 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
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/8/5
*/
@Getter
@AllArgsConstructor
public enum EnableStatusEnum {
ENABLE(1, "启用"),
DISABLE(2, "禁用");
private static Map<Integer, EnableStatusEnum> CACHE = Stream.of(EnableStatusEnum.values()).collect(Collectors.toMap(EnableStatusEnum::getStatus, Function.identity()));
private Integer status;
private String desc;
public static EnableStatusEnum of(Integer status) {
return CACHE.get(status);
}
}
@@ -0,0 +1,69 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 异常常量枚举
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Getter
@AllArgsConstructor
public enum ExceptionConstant {
SUCCESS(0, "成功"),
USER_NOT_LOGIN(1, "用户未登录"),
PARAMS_INVALID(2, "参数不正确"),
USER_NAME_OR_PASSWORD_ERROR(3, "用户名或密码错误"),
USER_DISABLE(4, "当前用户已被禁止登录"),
NO_PERMISSION_VISIT(5, "当前用户无权访问该资源"),
PARAMS_NOT_NULL(10, "参数[{}]不能为空"),
PARAMS_NOT_EMPTY(11, "参数[{}]不能为空"),
// 用户管理(11000)
// license管理(12000)
LICENSE_NAME_CANNOT_REPEAT(12000, "license名称不能重复"),
LICENSE_NOT_EXIST(12001, "license数据不存在"),
ORIGIN_PASSWORD_CHECK_FAIL(12002, "原密码验证失败"),
LOGIN_PASSWORD_LENGTH_CHECK_FAIL(12003, "登录密码不能小于6位数"),
LOGIN_PASSWORD_NO_CHANGE_MODIFY_FAIL(12004, "密码没有变化,修改失败"),
// 端口池管理(13000)
PORT_CANNOT_REPEAT(13000,"端口不能重复"),
PORT_NOT_EXIST(13001, "该端口在端口池中不存在"),
PORT_RANGE_FAIL(13002, "端口值范围为MIN-MAX"),
// 端口映射管理(14000)
PORT_MAPPING_NOT_EXIST(14000, "端口映射记录不存在"),
PORT_CANNOT_REPEAT_MAPPING(14001, "服务端口[{}]不能重复映射"),
// 调度管理(15000)
JOB_INFO_NOT_EXIST(15000, "调度管理记录不存在"),
SYSTEM_ERROR(500, "系统异常"),
PORT_GROUP_NAME_ALREADY_EXIST(16000,"端口分组名称[{}]已经存在"),
PORT_GROUP_NAME_DOES_NOT_EXIST(16001,"端口分组不存在"),
DEFAULT_GROUP_FORBID_DELETE(16002,"默认分组禁止删除")
;
private int code;
private String msg;
}
@@ -0,0 +1,40 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 在线状态枚举
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Getter
@AllArgsConstructor
public enum OnlineStatusEnum {
ONLINE(1, "在线"),
OFFLINE(2, "离线");
private Integer status;
private String desc;
}
@@ -0,0 +1,21 @@
package org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 端口池分组枚举类型
* @author Yohanes
* @date 2023/03/17
*/
@Getter
@AllArgsConstructor
public enum PoolGroupEnum {
GLOBAL(0, "全局"),
USER(1, "用户"),
LICENSE(2, "License");
private Integer status;
private String desc;
}
@@ -0,0 +1,39 @@
/**
* 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 org.dromara.neutrinoproxy.server.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: aoshiguchen
* @date: 2022/11/23
*/
@Getter
@AllArgsConstructor
public enum SuccessCodeEnum {
SUCCESS(1, "成功"),
FAIL(2, "失败");
private Integer code;
private String desc;
}
@@ -0,0 +1,53 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.log.ClientConnectRecordListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.ClientConnectRecordListRes;
import org.dromara.neutrinoproxy.server.service.ClientConnectRecordService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
/**
* @author: aoshiguchen
* @date: 2022/11/26
*/
@Slf4j
@Mapping("/client-connect-record")
@Controller
public class ClientConnectRecordController {
@Inject
private ClientConnectRecordService clientConnectRecordService;
@Get
@Mapping("/page")
public PageInfo<ClientConnectRecordListRes> page(PageQuery pageQuery, ClientConnectRecordListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return clientConnectRecordService.page(pageQuery, req);
}
}
@@ -0,0 +1,64 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.controller.req.system.LoginReq;
import org.dromara.neutrinoproxy.server.controller.res.system.LoginRes;
import org.dromara.neutrinoproxy.server.service.UserService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Controller
public class IndexController {
@Inject
private UserService userService;
@Authorization(login = false)
@Get
@Mapping("/")
public void home(Context ctx) {
ctx.forward("/index.html");
}
@Authorization(login = false)
@Post
@Mapping("/login")
public LoginRes login(LoginReq req) {
ParamCheckUtil.checkNotEmpty(req.getLoginName(), "loginName");
ParamCheckUtil.checkNotEmpty(req.getLoginPassword(), "loginPassword");
return userService.login(req);
}
@Post
@Mapping("/logout")
public void logout() {
userService.logout();
}
}
@@ -0,0 +1,96 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoExecuteReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoListReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoUpdateReq;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoExecuteRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoListRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoUpdateEnableStatusRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoUpdateRes;
import org.dromara.neutrinoproxy.server.dal.entity.JobInfoDO;
import org.dromara.neutrinoproxy.server.service.JobInfoService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.*;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/9/5
*/
@Slf4j
@Mapping("/job-info")
@Controller
public class JobInfoController {
@Inject
private JobInfoService jobInfoService;
@Get
@Mapping("/page")
public PageInfo<JobInfoListRes> page(PageQuery pageQuery, JobInfoListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return jobInfoService.page(pageQuery, req);
}
@Get
@Mapping("/findList")
public List<JobInfoDO> findList() {
return jobInfoService.findList();
}
@Post
@Mapping("/update/enable-status")
@Authorization(onlyAdmin = true)
public JobInfoUpdateEnableStatusRes updateEnableStatus(JobInfoUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return jobInfoService.updateEnableStatus(req);
}
@Post
@Mapping("/execute")
@Authorization(onlyAdmin = true)
public JobInfoExecuteRes execute(JobInfoExecuteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
return jobInfoService.execute(req);
}
@Post
@Mapping("/update")
public JobInfoUpdateRes update(JobInfoUpdateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
return jobInfoService.update(req);
}
}
@@ -0,0 +1,55 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.log.JobLogListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.JobLogListRes;
import org.dromara.neutrinoproxy.server.service.JobLogService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
/**
*
* @author: zCans
* @date: 2022/9/25
*/
@Slf4j
@Mapping("/job-log")
@Controller
public class JobLogController {
@Inject
private JobLogService jobLogService;
@Get
@Mapping("/page")
public PageInfo<JobLogListRes> page(PageQuery pageQuery, JobLogListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return jobLogService.page(pageQuery, req);
}
}
@@ -0,0 +1,128 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.controller.req.proxy.*;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.controller.req.proxy.*;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.service.LicenseService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.noear.solon.annotation.*;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Mapping("/license")
@Controller
public class LicenseController {
@Inject
private LicenseService licenseService;
@Get
@Mapping("/page")
public PageInfo<LicenseListRes> page(PageQuery pageQuery, LicenseListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return licenseService.page(pageQuery, req);
}
@Mapping("/list")
public List<LicenseListRes> list(LicenseListReq req) {
return licenseService.list(req);
}
@Mapping("/auth-list")
public List<LicenseListRes> queryCurUserLicense(LicenseListReq req) {
return licenseService.queryCurUserLicense(req);
}
@Post
@Mapping("/create")
@Authorization(onlyAdmin = true)
public LicenseCreateRes create(LicenseCreateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotEmpty(req.getName(), "name");
ParamCheckUtil.checkNotNull(req.getUserId(), "userId");
return licenseService.create(req);
}
@Post
@Mapping("/update")
@Authorization(onlyAdmin = true)
public LicenseUpdateRes update(LicenseUpdateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotEmpty(req.getName(), "name");
return licenseService.update(req);
}
@Post
@Mapping("/detail")
public LicenseDetailRes detail(LicenseDetailReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
return licenseService.detail(req.getId());
}
@Post
@Mapping("/update/enable-status")
@Authorization(onlyAdmin = true)
public LicenseUpdateEnableStatusRes updateEnableStatus(LicenseUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return licenseService.updateEnableStatus(req);
}
@Post
@Mapping("/delete")
@Authorization(onlyAdmin = true)
public void delete(LicenseDeleteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
licenseService.delete(req.getId());
}
@Post
@Mapping("/reset")
@Authorization(onlyAdmin = true)
public void reset(LicenseResetReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
licenseService.reset(req.getId());
}
}
@@ -0,0 +1,76 @@
package org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupCreateReq;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupDeleteReq;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupListReq;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupCreateRes;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupListRes;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupUpdateEnableStatusRes;
import org.dromara.neutrinoproxy.server.service.PortGroupService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.noear.solon.annotation.*;
import java.util.List;
/**
* 端口分组控制层
*/
@Mapping("/port-group")
@Controller
public class PortGroupController {
@Inject
private PortGroupService portGroupService;
@Post
@Mapping("/create")
public PortGroupCreateRes create(PortGroupCreateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotEmpty(req.getName(), "name");
ParamCheckUtil.checkNotNull(req.getPossessorType(), "possessorType");
ParamCheckUtil.checkNotNull(req.getPossessorId(), "possessorId");
return portGroupService.create(req);
}
@Get
@Mapping("/page")
public PageInfo<PortGroupListRes> page(PageQuery pageQuery, PortGroupListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return portGroupService.page(pageQuery, req);
}
@Get
@Mapping("/list")
public List<PortGroupListRes> list(PortGroupListReq req) {
return portGroupService.list(req);
}
@Post
@Mapping("/update/enable-status")
public PortGroupUpdateEnableStatusRes updateEnableStatus(PortGroupUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return portGroupService.updateEnableStatus(req);
}
@Post
@Mapping("/delete")
@Authorization(onlyAdmin = true)
public void delete(PortGroupDeleteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
portGroupService.delete(req.getId());
}
}
@@ -0,0 +1,83 @@
package org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.proxy.*;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.controller.req.proxy.*;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.service.PortMappingService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.apache.commons.lang3.StringUtils;
import org.noear.solon.annotation.*;
/**
* 端口映射
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Mapping("/port-mapping")
@Controller
public class PortMappingController {
@Inject
private PortMappingService portMappingService;
@Get
@Mapping("/page")
public PageInfo<PortMappingListRes> page(PageQuery pageQuery, PortMappingListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return portMappingService.page(pageQuery, req);
}
@Post
@Mapping("/create")
public PortMappingCreateRes create(PortMappingCreateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getLicenseId(), "licenseId");
ParamCheckUtil.checkNotNull(req.getServerPort(), "serverPort");
ParamCheckUtil.checkNotNull(req.getClientPort(), "clientPort");
if (StringUtils.isBlank(req.getClientIp())) {
// 没传客户端ip,默认为127.0.0.1
req.setClientIp("127.0.0.1");
}
return portMappingService.create(req);
}
@Post
@Mapping("/update")
public PortMappingUpdateRes update(PortMappingUpdateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
return portMappingService.update(req);
}
@Get
@Mapping("/detail")
public PortMappingDetailRes detail(PortMappingDetailReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
return portMappingService.detail(req.getId());
}
@Post
@Mapping("/update/enable-status")
public PortMappingUpdateEnableStatusRes updateEnableStatus(PortMappingUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return portMappingService.updateEnableStatus(req);
}
@Post
@Mapping("/delete")
public void delete(PortMappingDeleteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
portMappingService.delete(req.getId());
}
}
@@ -0,0 +1,126 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.service.PortPoolService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.noear.solon.annotation.*;
import java.util.List;
/**
* 端口池
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Mapping("/port-pool")
@Controller
public class PortPoolController {
@Inject
private PortPoolService portPoolService;
@Get
@Mapping("/page")
public PageInfo<PortPoolListRes> page(PageQuery pageQuery, PortPoolListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return portPoolService.page(pageQuery, req);
}
@Post
@Mapping("/update")
public PortPoolUpdateRes update(PortPoolUpdateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getGroupId(), "groupId");
return portPoolService.update(req);
}
@Get
@Mapping("/list")
public List<PortPoolListRes> list(PortPoolListReq req) {
return portPoolService.list(req);
}
@Post
@Mapping("/create")
@Authorization(onlyAdmin = true)
public PortPoolCreateRes create(PortPoolCreateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotEmpty(req.getPort(), "port");
ParamCheckUtil.checkNotNull(req.getGroupId(), "groupId");
return portPoolService.create(req);
}
@Post
@Mapping("/update/enable-status")
@Authorization(onlyAdmin = true)
public PortPoolUpdateEnableStatusRes updateEnableStatus(PortPoolUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return portPoolService.updateEnableStatus(req);
}
@Post
@Mapping("/delete")
@Authorization(onlyAdmin = true)
public void delete(PortPoolDeleteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
portPoolService.delete(req.getId());
}
@Get
@Mapping("/get-available-port-list")
public List<PortPoolListRes> getAvailablePortList(AvailablePortListReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getLicenseId(), "licenseId");
return portPoolService.getAvailablePortList(req);
}
@Get
@Mapping("/get-by-group")
public List<PortPoolListRes> portListByGroupId(String groupId) {
return portPoolService.portListByGroupId(groupId);
}
@Put
@Mapping("/update-group")
public PortPoolUpdateGroupRes updateGroup(PortPoolUpdateGroupReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getGroupId(), "groupId");
ParamCheckUtil.checkNotEmpty(req.getPortIdList(), "portIdList");
return portPoolService.updateGroup(req);
}
}
@@ -0,0 +1,95 @@
package org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.report.LicenseFlowMonthReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.LicenseFlowReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.UserFlowMonthReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.UserFlowReportReq;
import org.dromara.neutrinoproxy.server.controller.res.report.*;
import org.dromara.neutrinoproxy.server.controller.res.report.*;
import org.dromara.neutrinoproxy.server.service.ReportService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
/**
* 报表管理
* @author: aoshiguchen
* @date: 2022/9/12
*/
@Mapping("/report")
@Controller
public class ReportController {
@Inject
private ReportService reportService;
/**
* 首页数据一览
* @return
*/
@Get
@Mapping("/home/data-view")
public HomeDataView homeDataView() {
return reportService.homeDataView();
}
/**
* 用户流量报表分页
* @param pageQuery
* @param req
* @return
*/
@Get
@Mapping("/user/flow-report/page")
public PageInfo<UserFlowReportRes> userFlowReportPage(PageQuery pageQuery, UserFlowReportReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return reportService.userFlowReportPage(pageQuery, req);
}
/**
* license流量报表分页
* @param pageQuery
* @param req
* @return
*/
@Get
@Mapping("/license/flow-report/page")
public PageInfo<LicenseFlowReportRes> licenseFlowReportPage(PageQuery pageQuery, LicenseFlowReportReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return reportService.licenseFlowReportPage(pageQuery, req);
}
/**
* 用户流量报表月度明细
* @param pageQuery
* @param req
* @return
*/
@Get
@Mapping("/user/flow-month-report/page")
public PageInfo<UserFlowMonthReportRes> userFlowMonthReportPage(PageQuery pageQuery, UserFlowMonthReportReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return reportService.userFlowMonthReportPage(pageQuery, req);
}
/**
* license流量报表月度明细
* @param pageQuery
* @param req
* @return
*/
@Get
@Mapping("/license/flow-month-report/page")
public PageInfo<LicenseFlowMonthReportRes> licenseFlowMonthReportPage(PageQuery pageQuery, LicenseFlowMonthReportReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return reportService.licenseFlowMonthReportPage(pageQuery, req);
}
}
@@ -0,0 +1,147 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.Authorization;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.service.UserService;
import org.dromara.neutrinoproxy.server.util.Md5Util;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.noear.solon.annotation.*;
import java.util.List;
/**
* 用户管理
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Mapping("/user")
@Controller
public class UserController {
@Inject
private UserService userService;
@Inject
private UserMapper userMapper;
@Get
@Mapping("/page")
public PageInfo<UserListRes> page(PageQuery pageQuery, UserListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return userService.page(pageQuery, req);
}
@Get
@Mapping("/list")
public List<UserListRes> list(UserListReq req) {
return userService.list(req);
}
@Get
@Mapping("/info")
public UserInfoRes info(UserInfoReq req) {
return userService.info(req);
}
@Post
@Mapping("/update/enable-status")
@Authorization(onlyAdmin = true)
public UserUpdateEnableStatusRes updateEnableStatus(UserUpdateEnableStatusReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotNull(req.getEnable(), "enable");
return userService.updateEnableStatus(req);
}
@Post
@Mapping("/create")
@Authorization(onlyAdmin = true)
public UserCreateRes create(UserCreateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotEmpty(req.getName(), "name");
ParamCheckUtil.checkNotEmpty(req.getLoginName(), "loginName");
return userService.create(req);
}
@Post
@Mapping("/update")
@Authorization(onlyAdmin = true)
public UserUpdateRes update(UserUpdateReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotEmpty(req.getName(), "name");
ParamCheckUtil.checkNotEmpty(req.getLoginName(), "loginName");
return userService.update(req);
}
@Post
@Mapping("/update/password")
@Authorization(onlyAdmin = true)
public UserUpdatePasswordRes updatePassword(UserUpdatePasswordReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
ParamCheckUtil.checkNotEmpty(req.getLoginPassword(), "loginPassword");
ParamCheckUtil.checkExpression(req.getLoginPassword().length() >= 6, ExceptionConstant.LOGIN_PASSWORD_LENGTH_CHECK_FAIL);
return userService.updatePassword(req);
}
@Post
@Mapping("/current-user/update/password")
public UserUpdatePasswordRes currentUserUpdatePassword(UserUpdatePasswordReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotEmpty(req.getOldLoginPassword(), "oldLoginPassword");
ParamCheckUtil.checkNotEmpty(req.getLoginPassword(), "loginPassword");
req.setId(SystemContextHolder.getUserId());
ParamCheckUtil.checkExpression(req.getLoginPassword().length() >= 6, ExceptionConstant.LOGIN_PASSWORD_LENGTH_CHECK_FAIL);
// 验证原密码
Integer userId = req.getId();
UserDO userDO = userMapper.findById(userId);
ParamCheckUtil.checkExpression(Md5Util.encode(req.getOldLoginPassword()).equals(userDO.getLoginPassword()), ExceptionConstant.ORIGIN_PASSWORD_CHECK_FAIL);
return userService.updatePassword(req);
}
@Post
@Mapping("/delete")
@Authorization(onlyAdmin = true)
public void delete(UserDeleteReq req) {
ParamCheckUtil.checkNotNull(req, "req");
ParamCheckUtil.checkNotNull(req.getId(), "id");
userService.delete(req.getId());
}
}
@@ -0,0 +1,52 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.log.UserLoginRecordListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.UserLoginRecordListRes;
import org.dromara.neutrinoproxy.server.service.UserLoginRecordService;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
/**
* @author: aoshiguchen
* @date: 2022/10/20
*/
@Mapping("/user-login-record")
@Controller
public class UserLoginRecordController {
@Inject
private UserLoginRecordService userLoginRecordService;
@Get
@Mapping("/page")
public PageInfo<UserLoginRecordListRes> page(PageQuery pageQuery, UserLoginRecordListReq req) {
ParamCheckUtil.checkNotNull(pageQuery, "pageQuery");
return userLoginRecordService.page(pageQuery, req);
}
}
@@ -0,0 +1,36 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.log;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2022/11/26
*/
@Data
public class ClientConnectRecordListReq {
/**
* licenseId
*/
private Integer licenseId;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.log;
import lombok.Data;
/**
* 端口映射列表请求
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobLogListReq {
public Integer jobId;
}
@@ -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 org.dromara.neutrinoproxy.server.controller.req.log;
import lombok.Data;
/**
* 用户登录日志列表请求
* @author: aoshiguchen
* @date: 2022/10/20
*/
@Data
public class UserLoginRecordListReq {
/**
* 用户ID
*/
private Integer userId;
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* license创建请求
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class LicenseCreateReq {
/**
* 名称
*/
private String name;
/**
* 用户ID
*/
private Integer userId;
}
@@ -0,0 +1,13 @@
package org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* license删除请求
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class LicenseDeleteReq {
private Integer id;
}
@@ -0,0 +1,12 @@
package org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class LicenseDetailReq {
private Integer id;
}
@@ -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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class LicenseListReq {
private Integer userId;
private Integer isOnline;
private Integer enable;
}
@@ -0,0 +1,12 @@
package org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class LicenseResetReq {
private Integer id;
}
@@ -0,0 +1,43 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
/**
* 更新启用状态请求
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class LicenseUpdateEnableStatusReq {
/**
* id
*/
private Integer id;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class LicenseUpdateReq {
/**
* id
*/
private Integer id;
/**
* license名称
*/
private String name;
}
@@ -0,0 +1,49 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* 端口映射创建请求
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingCreateReq {
/**
* licenseId
*/
private Integer licenseId;
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端ip
*/
private String clientIp;
/**
* 客户端端口
*/
private Integer clientPort;
}
@@ -0,0 +1,12 @@
package org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class PortMappingDeleteReq {
private Integer id;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* 端口映射详情请求
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingDetailReq {
private Integer id;
}
@@ -0,0 +1,58 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
/**
* 端口映射列表请求
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingListReq {
/**
* 用户ID
*/
private Integer userId;
/**
* licenseId
*/
private Integer licenseId;
/**
* 服务端口号
*/
private Integer serverPort;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
}
@@ -0,0 +1,43 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* 端口映射更新启用状态请求
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingUpdateEnableStatusReq {
/**
* id
*/
private Integer id;
/**
* 启用状态
*/
private Integer enable;
}
@@ -0,0 +1,53 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.proxy;
import lombok.Data;
/**
* 端口映射更新请求
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingUpdateReq {
/**
* id
*/
private Integer id;
/**
* licenseId
*/
private Integer licenseId;
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端ip
*/
private String clientIp;
/**
* 客户端端口
*/
private Integer clientPort;
}
@@ -0,0 +1,13 @@
package org.dromara.neutrinoproxy.server.controller.req.report;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Data
public class LicenseFlowMonthReportReq {
private Integer userId;
private Integer licenseId;
}
@@ -0,0 +1,13 @@
package org.dromara.neutrinoproxy.server.controller.req.report;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Data
public class LicenseFlowReportReq {
private Integer userId;
private Integer licenseId;
}
@@ -0,0 +1,15 @@
package org.dromara.neutrinoproxy.server.controller.req.report;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Data
public class UserFlowMonthReportReq {
/**
* 用户ID
*/
private Integer userId;
}
@@ -0,0 +1,15 @@
package org.dromara.neutrinoproxy.server.controller.req.report;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Data
public class UserFlowReportReq {
/**
* 用户ID
*/
private Integer userId;
}
@@ -0,0 +1,15 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 获取可用端口请求
*/
@Data
public class AvailablePortListReq {
/**
* licenseId
*/
private Integer licenseId;
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 调度管理执行请求
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoExecuteReq {
/**
* id
*/
private Integer id;
/**
* 任务参数
*/
private String param;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口映射列表请求
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoListReq {
}
@@ -0,0 +1,43 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 调度管理更新启用状态请求
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoUpdateEnableStatusReq {
/**
* id
*/
private Integer id;
/**
* 启用状态
*/
private Integer enable;
}
@@ -0,0 +1,74 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import java.util.Date;
/**
* 调度管理更新请求
* @author: zCans
* @date: 2022/9/17
*/
@Data
public class JobInfoUpdateReq {
private Integer id;
/**
* 描述
*/
private String desc;
/**
* 处理器
*/
private String handler;
/**
* cron
*/
private String cron;
/**
* 任务参数
*/
private String param;
/**
* 任务报警邮箱
*/
private String alarmEmail;
/**
* 任务报警钉钉
*/
private String alarmDing;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 登录请求参数
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Data
public class LoginReq {
/**
* 登录名
*/
private String loginName;
/**
* 登录密码
*/
private String loginPassword;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 退出登录请求参数
* @author: aoshiguchen
* @date: 2022/8/1
*/
@Data
public class LogoutReq {
}
@@ -0,0 +1,27 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口分组创建请求
*
*
*/
@Data
public class PortGroupCreateReq {
/**
* 分组名称
*/
private String name ;
/**
* 所有者类型 (0、全局共享 1、用户所有 2License所有)
*/
private Integer possessorType ;
/**
* 所有者id(当type为0时 固定为-1、当type为1时为用户id 、当type为2时为licenseid)
*/
private Integer possessorId ;
}
@@ -0,0 +1,11 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 删除端口分组请求
*/
@Data
public class PortGroupDeleteReq {
private Integer id;
}
@@ -0,0 +1,27 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口分组查询请求
*
*
*/
@Data
public class PortGroupListReq {
/**
* 分组名称
*/
private String name ;
/**
* 所有者类型 (0、全局共享 1、用户所有 2License所有)
*/
private Integer possessorType ;
/**
* 所有者id(当type为0时 固定为-1、当type为1时为用户id 、当type为2时为licenseid)
*/
private Integer possessorId ;
}
@@ -0,0 +1,13 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 修改端口分组请求
*/
@Data
public class PortGroupUpdateEnableStatusReq {
private Integer id;
private Integer enable;
}
@@ -0,0 +1,36 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口池创建请求
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolCreateReq {
private String port;
private Integer groupId;
}
@@ -0,0 +1,12 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class PortPoolDeleteReq {
private Integer id;
}
@@ -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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口池列表请求
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolListReq {
/**
* 分组ID
*/
private Integer groupId;
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 端口池更新启用状态请求
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolUpdateEnableStatusReq {
/**
* id
*/
private Integer id;
/**
* 启用状态
*/
private Integer enable;
}
@@ -0,0 +1,17 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
import java.util.List;
/**
* 批量修改端口分组请求
*/
@Data
public class PortPoolUpdateGroupReq {
private String groupId;
private List<Integer> portIdList;
}
@@ -0,0 +1,14 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/25
*/
@Data
public class PortPoolUpdateReq {
private Integer id;
private Integer groupId;
}
@@ -0,0 +1,35 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
@Data
public class UserCreateReq {
private String name;
private String loginName;
}
@@ -0,0 +1,12 @@
package org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/11
*/
@Data
public class UserDeleteReq {
private Integer id;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
* 用户信息请求
* @author: aoshiguchen
* @date: 2022/8/27
*/
@Data
public class UserInfoReq {
private Integer id;
}
@@ -0,0 +1,31 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
/**
* 用户列表请求
* @author: aoshiguchen
* @date: 2022/8/14
*/
public class UserListReq {
}
@@ -0,0 +1,41 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
@Data
public class UserUpdateEnableStatusReq {
/**
* id
*/
private Integer id;
/**
* 启用状态
*/
private Integer enable;
}
@@ -0,0 +1,36 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
@Data
public class UserUpdatePasswordReq {
private Integer id;
private String oldLoginPassword;
private String loginPassword;
}
@@ -0,0 +1,36 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.req.system;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
@Data
public class UserUpdateReq {
private Integer id;
private String name;
private String loginName;
}
@@ -0,0 +1,52 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.log;
import lombok.Data;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/11/26
*/
@Data
public class ClientConnectRecordListRes {
private Integer id;
private String ip;
private Integer licenseId;
private Integer type;
private Integer userId;
private String userName;
private String licenseName;
private String msg;
/**
* 1、成功
* 2、失败
*/
private Integer code;
private String err;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,66 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.log;
import lombok.Data;
import org.dromara.neutrinoproxy.server.constant.AlarmStatusEnum;
import java.util.Date;
/**
* 调度日志列表响应
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobLogListRes {
private Integer id;
/**
* job_id
*/
private Integer jobId;
/**
* 处理器
*/
private String handler;
/**
* 任务参数
*/
private String param;
/**
* code
*/
private Integer code;
/**
* msg
*/
private String msg;
/**
* 报警状态
* {@link AlarmStatusEnum}
*/
private Integer alarmStatus;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,56 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.log;
import lombok.Data;
import java.util.Date;
/**
* 用户登录日志列表响应
* @author: aoshiguchen
* @date: 2022/10/20
*/
@Data
public class UserLoginRecordListRes {
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名
*/
private String userName;
/**
* ip
*/
private String ip;
/**
* 类型
*/
private Integer type;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,33 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Data
public class LicenseCreateRes {
}
@@ -0,0 +1,74 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Accessors(chain = true)
@Data
public class LicenseDetailRes {
private Integer id;
/**
* 名称
*/
private String name;
/**
* licenseKey
*/
private String key;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名
*/
private String userName;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,53 @@
package org.dromara.neutrinoproxy.server.controller.res.proxy;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Accessors(chain = true)
@Data
public class LicenseListRes {
private Integer id;
/**
* 名称
*/
private String name;
/**
* licenseKey
*/
private String key;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名
*/
private String userName;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,30 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
/**
* 更新启用状态响应
* @author: wen.y
* @date: 2022/8/6
*/
public class LicenseUpdateEnableStatusRes {
}
@@ -0,0 +1,31 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
public class LicenseUpdateRes {
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import lombok.Data;
/**
* 端口映射创建响应
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingCreateRes {
}
@@ -0,0 +1,65 @@
package org.dromara.neutrinoproxy.server.controller.res.proxy;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 端口映射详情响应
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Accessors(chain = true)
@Data
public class PortMappingDetailRes {
private Integer id;
/**
* licenseId
*/
private Integer licenseId;
/**
* license名称
*/
private String licenseName;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端ip
*/
private String clientIp;
/**
* 客户端端口
*/
private Integer clientPort;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,88 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import java.util.Date;
/**
* 端口映射列表响应
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingListRes {
private Integer id;
/**
* licenseId
*/
private Integer licenseId;
/**
* license名称
*/
private String licenseName;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户姓名
*/
private String userName;
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端ip
*/
private String clientIp;
/**
* 客户端端口
*/
private Integer clientPort;
/**
* 客户端端口
*/
private Integer port;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import lombok.Data;
/**
* 端口映射更新启用状态响应
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingUpdateEnableStatusRes {
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.proxy;
import lombok.Data;
/**
* 端口映射更新响应
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Data
public class PortMappingUpdateRes {
}
@@ -0,0 +1,208 @@
package org.dromara.neutrinoproxy.server.controller.res.report;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
/**
* @author: aoshiguchen
* @date: 2023/3/26
*/
@Accessors(chain = true)
@Data
public class HomeDataView {
/**
* licenses数据
*/
private License license;
/**
* 端口映射
*/
private PortMapping portMapping;
/**
* 今日流量
*/
private TodayFlow todayFlow;
/**
* 总流量
*/
private TotalFlow totalFlow;
/**
* 最近7日流量
*/
private Last7dFlow last7dFlow;
@Accessors(chain = true)
@Data
public static class License {
/**
* 总数
*/
private Integer totalCount;
/**
* 在线数
*/
private Integer onlineCount;
/**
* 离线数
*/
private Integer offlineCount;
}
@Accessors(chain = true)
@Data
public static class PortMapping {
/**
* 总数
*/
private Integer totalCount;
/**
* 在线数
*/
private Integer onlineCount;
/**
* 离线数
*/
private Integer offlineCount;
}
@Accessors(chain = true)
@Data
public static class TodayFlow {
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
}
@Accessors(chain = true)
@Data
public static class TotalFlow {
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
}
@Accessors(chain = true)
@Data
public static class Last7dFlow {
/**
* 最近7日流量数据
*/
private List<SingleDayFlow> dataList;
/**
* x轴日期
*/
private List<String> xDate;
/**
* 图例(上行流量、下行流量、总流量)
*/
private List<String> legendData;
/**
* 折线列表
*/
private List<Series> seriesList;
}
@Accessors(chain = true)
@Data
public static class SingleDayFlow {
/**
* 日期字符串
*/
private String dateStr;
/**
* 日期
*/
private Date date;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
}
@Accessors(chain = true)
@Data
public static class Series {
/**
* 此处目前固定为:line
*/
private String seriesType;
/**
* 名称:上行流量、下行流量、总流量
*/
private String seriesName;
/**
* y值序列
*/
private List<Long> seriesData;
}
}
@@ -0,0 +1,59 @@
package org.dromara.neutrinoproxy.server.controller.res.report;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Accessors(chain = true)
@Data
public class LicenseFlowMonthReportRes {
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* licenseId
*/
private Integer licenseId;
/**
* license名称
*/
private String licenseName;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
/**
* 日期
*/
private Date date;
}
@@ -0,0 +1,55 @@
package org.dromara.neutrinoproxy.server.controller.res.report;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Accessors(chain = true)
@Data
public class LicenseFlowReportRes {
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* licenseId
*/
private Integer licenseId;
/**
* license名称
*/
private String licenseName;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
}
@@ -0,0 +1,51 @@
package org.dromara.neutrinoproxy.server.controller.res.report;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Accessors(chain = true)
@Data
public class UserFlowMonthReportRes {
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
/**
* 日期
*/
private Date date;
}
@@ -0,0 +1,47 @@
package org.dromara.neutrinoproxy.server.controller.res.report;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/12/21
*/
@Accessors(chain = true)
@Data
public class UserFlowReportRes {
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
/**
* 总流量字节数
*/
private Long totalFlowBytes;
/**
* 上行流量描述
*/
private String upFlowDesc;
/**
* 下行流量描述
*/
private String downFlowDesc;
/**
* 总流量描述
*/
private String totalFlowDesc;
}
@@ -0,0 +1,7 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
@Data
public class AvailablePortListRes {
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* 调度管理执行响应
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoExecuteRes {
}
@@ -0,0 +1,74 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import java.util.Date;
/**
* 调度管理列表响应
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoListRes {
private Integer id;
/**
* 描述
*/
private String desc;
/**
* 处理器
*/
private String handler;
/**
* cron
*/
private String cron;
/**
* 任务参数
*/
private String param;
/**
* 任务报警邮箱
*/
private String alarmEmail;
/**
* 任务报警钉钉
*/
private String alarmDing;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* 调度管理列表响应
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoUpdateEnableStatusRes {
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* 调度管理更新响应
* @author: zCans
* @date: 2022/9/12
*/
@Data
public class JobInfoUpdateRes {
}
@@ -0,0 +1,47 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 登录响应参数
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Accessors(chain = true)
@Data
public class LoginRes {
/**
* token
*/
private String token;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户名
*/
private String userName;
}
@@ -0,0 +1,36 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 退出登录响应参数
* @author: aoshiguchen
* @date: 2022/8/2
*/
@Accessors(chain = true)
@Data
public class LogoutRes {
}
@@ -0,0 +1,4 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
public class PortGroupCreateRes {
}
@@ -0,0 +1,50 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date;
public class PortGroupListRes {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 分组名称
*/
private String name;
/**
* 所有者类型 (0、全局共享 1、用户所有 2License所有)
*/
private Integer possessorType;
/**
* 所有者id(当type为0时 固定为-1、当type为1时为用户id 、当type为2时为licenseid)
*/
private Integer possessorId;
/**
* 是否启用(1、启用 2、禁用)
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 来源
*/
private String possessor;
}
@@ -0,0 +1,7 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
@Data
public class PortGroupUpdateEnableStatusRes {
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* 端口池创建响应
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolCreateRes {
}
@@ -0,0 +1,66 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import java.util.Date;
/**
* 端口池列表响应
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolListRes {
private Integer id;
/**
* 端口
*/
private Integer port;
/**
* 是否禁用
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 分组类型
*/
private Integer possessorType;
/**
* 分组
*/
private String groupName;
/**
* 分组ID
*/
private Integer groupId;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* 端口池更新启用状态响应
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Data
public class PortPoolUpdateEnableStatusRes {
}
@@ -0,0 +1,4 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
public class PortPoolUpdateGroupRes {
}
@@ -0,0 +1,11 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/25
*/
@Data
public class PortPoolUpdateRes {
}
@@ -0,0 +1,31 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
public class UserCreateRes {
}
@@ -0,0 +1,33 @@
package org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 用户信息响应
* @author: wen.y
* @date: 2022/8/27
*/
@Accessors(chain = true)
@Data
public class UserInfoRes {
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 登录名
*/
private String loginName;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
import java.util.Date;
/**
* 用户列表响应
* @author: aoshiguchen
* @date: 2022/8/14
*/
@Data
public class UserListRes {
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 登录名
*/
private String loginName;
/**
* 登录密码
*/
private String loginPassword;
/**
* 是否禁用
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,34 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
import lombok.Data;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
@Data
public class UserUpdateEnableStatusRes {
}
@@ -0,0 +1,30 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
public class UserUpdatePasswordRes {
}
@@ -0,0 +1,31 @@
/**
* 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 org.dromara.neutrinoproxy.server.controller.res.system;
/**
*
* @author: aoshiguchen
* @date: 2022/8/28
*/
public class UserUpdateRes {
}
@@ -0,0 +1,21 @@
package org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.ClientConnectRecordDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/11/23
*/
@Mapper
public interface ClientConnectRecordMapper extends BaseMapper<ClientConnectRecordDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<ClientConnectRecordDO>()
.lt(ClientConnectRecordDO::getCreateTime, date)
);
}
}
@@ -0,0 +1,52 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportDayDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
@Mapper
public interface FlowReportDayMapper extends BaseMapper<FlowReportDayDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<FlowReportDayDO>()
.lt(FlowReportDayDO::getDate, date)
);
}
default void deleteByDateStr(String dateStr) {
this.delete(new LambdaQueryWrapper<FlowReportDayDO>()
.eq(FlowReportDayDO::getDateStr, dateStr)
);
}
default List<FlowReportDayDO> findListByDateRange(Date startDate, Date endDate) {
return this.selectList(new LambdaQueryWrapper<FlowReportDayDO>()
.ge(FlowReportDayDO::getDate, startDate)
.le(FlowReportDayDO::getDate, endDate)
);
}
}
@@ -0,0 +1,53 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportHourDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
@Mapper
public interface FlowReportHourMapper extends BaseMapper<FlowReportHourDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<FlowReportHourDO>()
.lt(FlowReportHourDO::getDate, date)
);
}
default void deleteByDateStr(String dateStr) {
this.delete(new LambdaQueryWrapper<FlowReportHourDO>()
.eq(FlowReportHourDO::getDateStr, dateStr)
);
}
default List<FlowReportHourDO> findListByDateRange(Date startDate, Date endDate) {
return this.selectList(new LambdaQueryWrapper<FlowReportHourDO>()
.ge(FlowReportHourDO::getDateStr, startDate)
.le(FlowReportHourDO::getDateStr, endDate)
);
}
}
@@ -0,0 +1,55 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportMinuteDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Mapper
public interface FlowReportMinuteMapper extends BaseMapper<FlowReportMinuteDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<FlowReportMinuteDO>()
.lt(FlowReportMinuteDO::getDate, date)
);
}
default List<FlowReportMinuteDO> findList(Set<Integer> licenseIds, String date) {
return this.selectList(new LambdaQueryWrapper<FlowReportMinuteDO>()
.in(FlowReportMinuteDO::getLicenseId, licenseIds)
.eq(FlowReportMinuteDO::getDate, date)
);
}
default List<FlowReportMinuteDO> findListByDateRange(Date startDate, Date endDate) {
return this.selectList(new LambdaQueryWrapper<FlowReportMinuteDO>()
.ge(FlowReportMinuteDO::getDate, startDate)
.le(FlowReportMinuteDO::getDate, endDate)
);
}
}
@@ -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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportMonthDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface FlowReportMonthMapper extends BaseMapper<FlowReportMonthDO> {
default void deleteByDateStr(String dateStr) {
this.delete(new LambdaQueryWrapper<FlowReportMonthDO>()
.eq(FlowReportMonthDO::getDateStr, dateStr)
);
}
}
@@ -0,0 +1,51 @@
/**
* 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 org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.dal.entity.JobInfoDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
@Mapper
public interface JobInfoMapper extends BaseMapper<JobInfoDO> {
default JobInfoDO findById(Integer id) {
return this.selectById(id);
}
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<JobInfoDO>()
.eq(JobInfoDO::getId, id)
.set(JobInfoDO::getEnable, enable)
.set(JobInfoDO::getUpdateTime, updateTime)
);
}
default List<JobInfoDO> findList() {
return this.selectList(new LambdaQueryWrapper<>());
}
}
@@ -0,0 +1,45 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.JobLogDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/9/5
*/
@Mapper
public interface JobLogMapper extends BaseMapper<JobLogDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<JobLogDO>()
.lt(JobLogDO::getCreateTime, date)
);
}
}
@@ -0,0 +1,126 @@
/**
* Copyright (c) 2022 aoshiguchen
* <p>
* 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:
* <p>
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* <p>
* 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 org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Mapper
public interface LicenseMapper extends BaseMapper<LicenseDO> {
default List<LicenseDO> listAll() {
return this.selectList(new LambdaQueryWrapper<>());
}
default List<LicenseDO> listByUserId(Integer userId) {
return this.selectList(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getUserId, userId)
);
}
default LicenseDO queryById(Integer licenseId) {
return this.selectOne(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getId, licenseId));
}
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.eq(LicenseDO::getId, id)
.set(LicenseDO::getEnable, enable)
.set(LicenseDO::getUpdateTime, updateTime)
);
}
default void updateOnlineStatus(Integer id, Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.eq(LicenseDO::getId, id)
.set(LicenseDO::getIsOnline, isOnline)
.set(LicenseDO::getUpdateTime, updateTime)
);
}
default void updateOnlineStatus(Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.set(LicenseDO::getIsOnline, updateTime)
.set(LicenseDO::getUpdateTime, updateTime)
);
}
default void reset(Integer id, String key, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.eq(LicenseDO::getId, id)
.set(LicenseDO::getKey, key)
.set(LicenseDO::getUpdateTime, updateTime)
);
}
default LicenseDO findById(Integer id) {
return this.selectById(id);
}
default void update(Integer id, String name, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<LicenseDO>()
.eq(LicenseDO::getId, id)
.set(LicenseDO::getName, name)
.set(LicenseDO::getUpdateTime, updateTime)
);
}
default List<LicenseDO> findByIds(Set<Integer> ids) {
return selectBatchIds(ids);
}
default LicenseDO checkRepeat(Integer userId, String name) {
return this.selectOne(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getUserId, userId)
.eq(LicenseDO::getName, name)
.last("limit 1")
);
}
default LicenseDO checkRepeat(Integer userId, String name, Set<Integer> excludeIds) {
return this.selectOne(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getUserId, userId)
.eq(LicenseDO::getName, name)
.notIn(LicenseDO::getId, excludeIds)
.last("limit 1")
);
}
default LicenseDO findByKey(String licenseKey) {
return selectOne(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getKey, licenseKey)
);
}
}
@@ -0,0 +1,27 @@
package org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupListReq;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupListRes;
import org.dromara.neutrinoproxy.server.dal.entity.PortGroupDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
@Mapper
public interface PortGroupMapper extends BaseMapper<PortGroupDO> {
List<PortGroupListRes> selectPortGroupListResList(PortGroupListReq res);
default void updateEnableStatus(Integer id, Integer enable, Date now){
this.update(null, Wrappers.lambdaUpdate(PortGroupDO.class)
.eq(PortGroupDO::getId,id)
.set(PortGroupDO::getEnable,enable)
.set(PortGroupDO::getUpdateTime,now)
);
}
}
@@ -0,0 +1,89 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.controller.req.proxy.PortMappingListReq;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Mapper
public interface PortMappingMapper extends BaseMapper<PortMappingDO> {
default PortMappingDO findById(Integer id) {
return this.selectById(id);
}
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
.eq(PortMappingDO::getId, id)
.set(PortMappingDO::getEnable, enable)
.set(PortMappingDO::getUpdateTime, updateTime)
);
}
default PortMappingDO findByPort(Integer port, Set<Integer> excludeIds) {
return this.selectOne(new LambdaQueryWrapper<PortMappingDO>()
.eq(PortMappingDO::getServerPort, port)
.notIn(!CollectionUtil.isEmpty(excludeIds), PortMappingDO::getId, excludeIds)
.last("limit 1")
);
}
default List<PortMappingDO> findEnableListByLicenseId(Integer licenseId) {
return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
.eq(PortMappingDO::getLicenseId, licenseId)
.eq(PortMappingDO::getEnable, EnableStatusEnum.ENABLE.getStatus())
);
}
default List<PortMappingDO> findListByServerPort(Integer serverPort) {
return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
.eq(PortMappingDO::getServerPort, serverPort)
);
}
default List<PortMappingDO> findListByLicenseId(Integer licenseId) {
return this.selectList(new LambdaQueryWrapper<PortMappingDO>()
.eq(PortMappingDO::getLicenseId, licenseId)
);
}
default void updateOnlineStatus(Integer licenseId,Integer serverPort, Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
.eq(PortMappingDO::getLicenseId, licenseId)
.eq(PortMappingDO::getServerPort, serverPort)
.set(PortMappingDO::getIsOnline, isOnline)
.set(PortMappingDO::getUpdateTime, updateTime)
);
}
default void updateOnlineStatus(Integer licenseId, Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
.eq(PortMappingDO::getLicenseId, licenseId)
.set(PortMappingDO::getIsOnline, isOnline)
.set(PortMappingDO::getUpdateTime, updateTime)
);
}
default void updateOnlineStatus(Integer isOnline, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<PortMappingDO>()
.set(PortMappingDO::getIsOnline, isOnline)
.set(PortMappingDO::getUpdateTime, updateTime)
);
}
List<PortMappingDO> selectPortMappingByCondition(@Param("req") PortMappingListReq req);
}
@@ -0,0 +1,71 @@
/**
* 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 org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.controller.req.system.PortPoolListReq;
import org.dromara.neutrinoproxy.server.controller.res.system.PortPoolListRes;
import org.dromara.neutrinoproxy.server.dal.entity.PortPoolDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Mapper
public interface PortPoolMapper extends BaseMapper<PortPoolDO> {
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<PortPoolDO>()
.eq(PortPoolDO::getId, id)
.set(PortPoolDO::getEnable, enable)
.set(PortPoolDO::getUpdateTime, updateTime)
);
}
default PortPoolDO findByPort(Integer port) {
return this.selectOne(new LambdaQueryWrapper<PortPoolDO>()
.eq(PortPoolDO::getPort, port)
);
}
default PortPoolDO findById(Integer id) {
return this.selectById(id);
}
default List<PortPoolDO> getByGroupId(String groupId){
return this.selectList(
new LambdaQueryWrapper<PortPoolDO>()
.eq(PortPoolDO::getGroupId, groupId)
);
}
List<PortPoolListRes> selectResList(@Param("req") PortPoolListReq req);
List<PortPoolListRes> getAvailablePortList(@Param("licenseId") Integer licenseId,@Param("userId") Integer userId);
}
@@ -0,0 +1,73 @@
package org.dromara.neutrinoproxy.server.dal;
import org.dromara.neutrinoproxy.server.controller.res.report.*;
import org.dromara.neutrinoproxy.server.controller.res.report.LicenseFlowMonthReportRes;
import org.dromara.neutrinoproxy.server.controller.res.report.LicenseFlowReportRes;
import org.dromara.neutrinoproxy.server.controller.res.report.UserFlowMonthReportRes;
import org.dromara.neutrinoproxy.server.controller.res.report.UserFlowReportRes;
import org.dromara.neutrinoproxy.server.service.bo.FlowBO;
import org.dromara.neutrinoproxy.server.service.bo.SingleDayFlowBO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
* @author: aoshiguchen
* @date: 2023/3/19
*/
@Mapper
public interface ReportMapper {
/**
* 基于用户维度的流量报表
* @param userId
* @return
*/
List<UserFlowReportRes> userFlowReportList(@Param("userId") Integer userId, @Param("curMonthBeginDate") Date curMonthBeginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* 基于License维度的流量报表
* @param userId
* @return
*/
List<LicenseFlowReportRes> licenseFLowReportList(@Param("userId") Integer userId, @Param("curMonthBeginDate") Date curMonthBeginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* 用户流量月度明细
* @param userId
* @return
*/
List<UserFlowMonthReportRes> userFlowMonthReportList(@Param("userId") Integer userId, @Param("curMonthBeginDate") Date curMonthBeginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* License流量月度明细
* @param userId
* @return
*/
List<LicenseFlowMonthReportRes> licenseFLowMonthReportList(@Param("userId") Integer userId, @Param("licenseId") Integer licenseId, @Param("curMonthBeginDate") Date curMonthBeginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* 首页 - 今日流量
* @param curDayBeginDate
* @param curDate
* @return
*/
FlowBO homeTodayFlow(@Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* 首页 - 总流量
* @param curMonthBeginDate
* @param curDayBeginDate
* @param curDate
* @return
*/
FlowBO homeTotalFlow(@Param("curMonthBeginDate") Date curMonthBeginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
/**
* 首页最近7日流量
* @param beginDate
* @param curDayBeginDate
* @param curDate
* @return
*/
List<SingleDayFlowBO> homeLast7dFlowList(@Param("beginDate") Date beginDate, @Param("curDayBeginDate") Date curDayBeginDate, @Param("curDate") Date curDate);
}
@@ -0,0 +1,43 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.UserLoginRecordDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/2
*/
@Mapper
public interface UserLoginRecordMapper extends BaseMapper<UserLoginRecordDO> {
default void clean(Date date) {
this.delete(new LambdaQueryWrapper<UserLoginRecordDO>()
.lt(UserLoginRecordDO::getCreateTime, date)
);
}
}
@@ -0,0 +1,65 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
@Mapper
public interface UserMapper extends BaseMapper<UserDO> {
/**
* 根据登录名查询用户记录
* @param loginName
* @return
*/
default UserDO findByLoginName(String loginName) {
return selectOne(new LambdaQueryWrapper<UserDO>()
.eq(UserDO::getLoginName, loginName)
.last("limit 1")
);
}
/**
* 根据id查询单条记录
* @param id
* @return
*/
default UserDO findById(Integer id) {
return selectById(id);
}
default List<UserDO> findByIds(Set<Integer> ids) {
return selectBatchIds(ids);
}
default void updateEnableStatus(Integer id, Integer enable, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<UserDO>()
.eq(UserDO::getId, id)
.set(UserDO::getEnable, enable)
.set(UserDO::getUpdateTime, updateTime)
);
}
default void updateLoginPassword(Integer id, String loginPassword, Date updateTime) {
this.update(null, new LambdaUpdateWrapper<UserDO>()
.eq(UserDO::getId, id)
.set(UserDO::getLoginPassword, loginPassword)
.set(UserDO::getUpdateTime, updateTime)
);
}
@Insert("insert into user(`name`,`login_name`,`login_password`,`enable`,`create_time`,`update_time`) values(:name,:loginName,:loginPassword,:enable,:createTime,:updateTime)")
void add(UserDO user);
}
@@ -0,0 +1,80 @@
/**
* 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 org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.dal.entity.UserTokenDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
@Mapper
public interface UserTokenMapper extends BaseMapper<UserTokenDO> {
/**
* 根据token查询单条记录
* 支持注解 + xml配置2种方式
* @param token
* @param time
* @return
*/
default UserTokenDO findByAvailableToken(String token, Date date) {
return selectOne(new LambdaQueryWrapper<UserTokenDO>()
.eq(UserTokenDO::getToken, token)
.gt(UserTokenDO::getExpirationTime, date)
);
}
/**
* 根据token删除记录
* @param token
*/
default void deleteByToken(String token) {
this.delete(new LambdaQueryWrapper<UserTokenDO>()
.eq(UserTokenDO::getToken, token)
);
}
default void updateTokenExpirationTime(String token, Date expirationTime) {
this.update(null, new LambdaUpdateWrapper<UserTokenDO>()
.eq(UserTokenDO::getToken, token)
.set(UserTokenDO::getExpirationTime, expirationTime)
);
}
/**
* 根据userId删除token
* @param userId
*/
default void deleteByUserId(Integer userId) {
this.delete(new LambdaQueryWrapper<UserTokenDO>()
.eq(UserTokenDO::getUserId, userId)
);
}
}
@@ -0,0 +1,37 @@
package org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/11/23
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("client_connect_record")
public class ClientConnectRecordDO {
@TableId(type = IdType.AUTO)
private Integer id;
private String ip;
private Integer licenseId;
private Integer type;
private String msg;
/**
* 1、成功
* 2、失败
*/
private Integer code;
private String err;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,73 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/10/24
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("flow_report_day")
public class FlowReportDayDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* licenseId
*/
private Integer licenseId;
/**
* 写入字节数
*/
private Long writeBytes;
/**
* 读取字节数
*/
private Long readBytes;
/**
* 报表统计时间
*/
private Date date;
/**
* 报表统计时间
* yyyy-MM-dd
*/
private String dateStr;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,73 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/10/24
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("flow_report_hour")
public class FlowReportHourDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* licenseId
*/
private Integer licenseId;
/**
* 写入字节数
*/
private Long writeBytes;
/**
* 读取字节数
*/
private Long readBytes;
/**
* 报表统计时间
*/
private Date date;
/**
* 报表统计时间
* yyyy-MM-dd HH
*/
private String dateStr;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,73 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/10/24
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("flow_report_minute")
public class FlowReportMinuteDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* licenseId
*/
private Integer licenseId;
/**
* 写入字节数
*/
private Integer writeBytes;
/**
* 读取字节数
*/
private Integer readBytes;
/**
* 报表统计时间
*/
private Date date;
/**
* 报表统计时间
* yyyy-MM-dd HH:mm
*/
private String dateStr;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,73 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author: aoshiguchen
* @date: 2022/10/24
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("flow_report_month")
public class FlowReportMonthDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* licenseId
*/
private Integer licenseId;
/**
* 写入字节数
*/
private Long writeBytes;
/**
* 读取字节数
*/
private Long readBytes;
/**
* 报表统计时间
*/
private Date date;
/**
* 报表统计时间
* yyyy-MM
*/
private String dateStr;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,67 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/9/4
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("job_info")
public class JobInfoDO {
@TableId(type = IdType.AUTO)
private Integer id;
private String cron;
@TableField("`desc`")
private String desc;
private String alarmEmail;
private String alarmDing;
private String handler;
private String param;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,55 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: wen.y
* @date: 2022/9/4
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("job_log")
public class JobLogDO {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer jobId;
private String handler;
private String param;
private Integer code;
private String msg;
private Integer alarmStatus;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,79 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 许可证
* @author: aoshiguchen
* @date: 2022/8/6
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("license")
public class LicenseDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 名称
*/
private String name;
/**
* licenseKey
*/
@TableField("`key`")
private String key;
/**
* 用户ID
*/
private Integer userId;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,57 @@
package org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 端口组
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("port_group")
public class PortGroupDO {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 分组名称
*/
private String name;
/**
* 所有者类型 (0、全局共享 1、用户所有 2License所有)
*/
private Integer possessorType;
/**
* 所有者id(当type为0时 固定为-1、当type为1时为用户id 、当type为2时为licenseid)
*/
private Integer possessorId;
/**
* 是否启用(1、启用 2、禁用)
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,81 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 端口映射
* @author: aoshiguchen
* @date: 2022/8/8
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("port_mapping")
public class PortMappingDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* licenseId
*/
private Integer licenseId;
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端ip
*/
private String clientIp;
/**
* 客户端端口
*/
private Integer clientPort;
/**
* 是否在线
* {@link OnlineStatusEnum}
*/
private Integer isOnline;
/**
* 启用状态
* {@link EnableStatusEnum}
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,67 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 端口池
* @author: aoshiguchen
* @date: 2022/8/7
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("port_pool")
public class PortPoolDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 分组id
*/
private Integer groupId;
/**
* 端口
*/
private Integer port;
/**
* 是否禁用
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,67 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
@ToString
@Data
@TableName("user")
public class UserDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 登录名
*/
private String loginName;
/**
* 登录密码
*/
private String loginPassword;
/**
* 是否禁用
*/
private Integer enable;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,65 @@
/**
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
* <p>
* All right reserved.
* <p>
* This software is the confidential and proprietary
* information of Zeyi Company of China.
* ("Confidential Information"). You shall not disclose
* such Confidential Information and shall use it only
* in accordance with the terms of the contract agreement
* you entered into with Zeyi inc.
*/
package org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/2
*/
@ToString
@Data
@Accessors(chain = true)
@TableName("user_login_record")
public class UserLoginRecordDO {
/**
* 类型 - 登录
*/
public static final Integer TYPE_LOGIN = 1;
/**
* 类型 - 登出
*/
public static final Integer TYPE_LOGOUT = 2;
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 用户ID
*/
private Integer userId;
/**
* token
*/
private String token;
/**
* ip
*/
private String ip;
/**
* 类型
*/
private Integer type;
/**
* 创建时间
*/
private Date createTime;
}
@@ -0,0 +1,67 @@
/**
* 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 org.dromara.neutrinoproxy.server.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
@ToString
@Accessors(chain = true)
@Data
@TableName("user_token")
public class UserTokenDO {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* token
*/
private String token;
/**
* 用户ID
*/
private Integer userId;
/**
* 过期时间
*/
private Date expirationTime;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
}
@@ -0,0 +1,135 @@
package org.dromara.neutrinoproxy.server.job;
import com.alibaba.fastjson.JSONObject;
import org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.dal.*;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
import lombok.Data;
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;
import java.util.Date;
/**
* 日志清理Job
* @author: aoshiguchen
* @date: 2022/9/17
*/
@Slf4j
@Component
@JobHandler(name = "DataCleanJob", cron = "0 0 1 * * ?")
public class DataCleanJob implements IJobHandler {
/**
* Job日志保存天数
*/
private static final Integer JOB_LOG_KEEP_DAYS = 7;
/**
* 用户登录日志保留天数
*/
private static final Integer USER_LOGIN_RECORD_KEEP_DAYS = 30;
/**
* 客户端连接记录保留天数
*/
private static final Integer CLIENT_CONNECT_RECORD_KEEP_DAYS = 30;
/**
* 流量统计分钟报表记录保留天数
*/
private static final Integer FLOW_MINUTE_REPORT_KEEP_DAYS = 2;
/**
* 流量统计小时报表记录保留天数
*/
private static final Integer FLOW_HOUR_REPORT_KEEP_DAYS = 90;
/**
* 流量统计天报表记录保留天数
*/
private static final Integer FLOW_DAY_REPORT_KEEP_DAYS = 400;
@Inject
private JobLogMapper jobLogMapper;
@Inject
private UserLoginRecordMapper userLoginRecordMapper;
@Inject
private ClientConnectRecordMapper clientConnectRecordMapper;
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Inject
private FlowReportHourMapper flowReportHourMapper;
@Inject
private FlowReportDayMapper flowReportDayMapper;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void execute(String s) throws Exception {
JobParams jobParams = getParams(s);
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getJobLogKeepDays());
log.info("清理调度管理日志 date:{}", sdf.format(date));
jobLogMapper.clean(date);
}
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getUserLoginRecordKeepDays());
log.info("清理用户登录日志 date:{}", sdf.format(date));
userLoginRecordMapper.clean(date);
}
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getClientConnectRecordKeepDays());
log.info("清理客户端连接日志 date:{}", sdf.format(date));
clientConnectRecordMapper.clean(date);
}
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowMinuteReportKeepDays());
log.info("清理流通统计分钟报表日志 date:{}", sdf.format(date));
flowReportMinuteMapper.clean(date);
}
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowHourReportKeepDays());
log.info("清理流通统计小时报表日志 date:{}", sdf.format(date));
flowReportHourMapper.clean(date);
}
{
Date date = DateUtil.addDate(new Date(), Calendar.DATE, -1 * jobParams.getFlowDayReportKeepDays());
log.info("清理流通统计日报表日志 date:{}", sdf.format(date));
flowReportDayMapper.clean(date);
}
}
public static JobParams getParams(String s) {
try {
if (StringUtils.isNotBlank(s)) {
return JSONObject.parseObject(s, JobParams.class);
}
} catch (Exception e) {
// ignore
}
return new JobParams()
.setJobLogKeepDays(JOB_LOG_KEEP_DAYS)
.setUserLoginRecordKeepDays(USER_LOGIN_RECORD_KEEP_DAYS)
.setClientConnectRecordKeepDays(CLIENT_CONNECT_RECORD_KEEP_DAYS)
.setFlowMinuteReportKeepDays(FLOW_MINUTE_REPORT_KEEP_DAYS)
.setFlowHourReportKeepDays(FLOW_HOUR_REPORT_KEEP_DAYS)
.setFlowDayReportKeepDays(FLOW_DAY_REPORT_KEEP_DAYS);
}
@Accessors(chain = true)
@Data
public static class JobParams {
private Integer jobLogKeepDays;
private Integer userLoginRecordKeepDays;
private Integer clientConnectRecordKeepDays;
private Integer flowMinuteReportKeepDays;
private Integer flowHourReportKeepDays;
private Integer flowDayReportKeepDays;
}
}
@@ -0,0 +1,22 @@
package org.dromara.neutrinoproxy.server.job;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
/**
*
* @author: aoshiguchen
* @date: 2022/9/4
*/
@Slf4j
@Component
@JobHandler(name = "DemoJob", cron = "0/10 * * * * ?", param = "{\"a\":1}")
public class DemoJob implements IJobHandler {
@Override
public void execute(String param) throws Exception {
System.out.println("DemoJob execute param:" + param);
}
}
@@ -0,0 +1,115 @@
/**
* 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 org.dromara.neutrinoproxy.server.job;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.dal.FlowReportDayMapper;
import org.dromara.neutrinoproxy.server.dal.FlowReportHourMapper;
import org.dromara.neutrinoproxy.server.dal.FlowReportMinuteMapper;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportDayDO;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportHourDO;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
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.util.*;
/**
* @author: aoshiguchen
* @date: 2022/10/28
*/
@Slf4j
@Component
@JobHandler(name = "FlowReportForDayJob", cron = "0 0 1 * * ?", param = "")
public class FlowReportForDayJob implements IJobHandler {
@Inject
private FlowReportService flowReportService;
@Inject
private LicenseMapper licenseMapper;
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Inject
private FlowReportHourMapper flowReportHourMapper;
@Inject
private FlowReportDayMapper flowReportDayMapper;
@Override
public void execute(String param) throws Exception {
Date now = new Date();
String dateStr = getDateStr(now, param); // DateUtil.format(DateUtil.addDate(now, Calendar.DATE, -1), "yyyy-MM-dd");
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd");
Date startHourDate = DateUtil.getDayBegin(date);
Date endHourDate = DateUtil.getDayEnd(date);
// 删除原来的记录
flowReportDayMapper.deleteByDateStr(dateStr);
// 查询前一天的小时级别统计数据
List<FlowReportHourDO> flowReportHourDOList = flowReportHourMapper.findListByDateRange(startHourDate, endHourDate);
if (CollectionUtil.isEmpty(flowReportHourDOList)) {
return;
}
// 汇总前一个天的天级别统计数据
Map<Integer, FlowReportDayDO> map = new HashMap<>();
for (FlowReportHourDO item : flowReportHourDOList) {
FlowReportDayDO report = map.get(item.getLicenseId());
if (null == report) {
report = new FlowReportDayDO();
map.put(item.getLicenseId(), report);
}
Long writeBytes = report.getWriteBytes() == null ? 0 : report.getWriteBytes();
Long readBytes = report.getReadBytes() == null ? 0 : report.getReadBytes();
report.setUserId(item.getUserId());
report.setLicenseId(item.getLicenseId());
report.setWriteBytes(writeBytes + item.getWriteBytes());
report.setReadBytes(readBytes + item.getReadBytes());
report.setDate(date);
report.setDateStr(dateStr);
report.setCreateTime(now);
}
for (FlowReportDayDO item : map.values()) {
flowReportDayMapper.insert(item);
}
}
private String getDateStr(Date now, String params) {
if (StringUtils.isNotBlank(params)) {
try {
// 参数格式错误则取当前时间
DateUtil.parse(params, "yyyy-MM-dd");
return params;
} catch (Exception e) {
// ignore
}
}
return DateUtil.format(DateUtil.addDate(now, Calendar.DATE, -1), "yyyy-MM-dd");
}
}
@@ -0,0 +1,92 @@
package org.dromara.neutrinoproxy.server.job;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.dal.FlowReportHourMapper;
import org.dromara.neutrinoproxy.server.dal.FlowReportMinuteMapper;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportHourDO;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportMinuteDO;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
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.util.*;
/**
* @author: aoshiguchen
* @date: 2022/10/28
*/
@Slf4j
@Component
@JobHandler(name = "FlowReportForHourJob", cron = "0 0 */1 * * ?", param = "")
public class FlowReportForHourJob implements IJobHandler {
@Inject
private FlowReportService flowReportService;
@Inject
private LicenseMapper licenseMapper;
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Inject
private FlowReportHourMapper flowReportHourMapper;
@Override
public void execute(String param) throws Exception {
Date now = new Date();
String dateStr = getDateStr(now, param); // DateUtil.format(DateUtil.addDate(now, Calendar.HOUR, -1), "yyyy-MM-dd HH");
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd HH");
Date startHourDate = DateUtil.getHourBegin(date);
Date endHourDate = DateUtil.getHourEnd(date);
// 删除原来的记录
flowReportHourMapper.deleteByDateStr(dateStr);
// 查询前一个小时的分钟级别统计数据
List<FlowReportMinuteDO> flowReportMinuteDOList = flowReportMinuteMapper.findListByDateRange(startHourDate, endHourDate);
if (CollectionUtil.isEmpty(flowReportMinuteDOList)) {
return;
}
// 汇总前一个小时的小时级别统计数据
Map<Integer, FlowReportHourDO> map = new HashMap<>();
for (FlowReportMinuteDO item : flowReportMinuteDOList) {
FlowReportHourDO report = map.get(item.getLicenseId());
if (null == report) {
report = new FlowReportHourDO();
map.put(item.getLicenseId(), report);
}
Long writeBytes = report.getWriteBytes() == null ? 0 : report.getWriteBytes();
Long readBytes = report.getReadBytes() == null ? 0 : report.getReadBytes();
report.setUserId(item.getUserId());
report.setLicenseId(item.getLicenseId());
report.setWriteBytes(writeBytes + item.getWriteBytes());
report.setReadBytes(readBytes + item.getReadBytes());
report.setDate(date);
report.setDateStr(dateStr);
report.setCreateTime(now);
}
for (FlowReportHourDO item : map.values()) {
flowReportHourMapper.insert(item);
}
}
private String getDateStr(Date now, String params) {
if (StringUtils.isNotBlank(params)) {
try {
// 参数格式错误则取当前时间
DateUtil.parse(params, "yyyy-MM-dd HH");
return params;
} catch (Exception e) {
// ignore
}
}
return DateUtil.format(DateUtil.addDate(now, Calendar.HOUR, -1), "yyyy-MM-dd HH");
}
}
@@ -0,0 +1,69 @@
package org.dromara.neutrinoproxy.server.job;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.dal.FlowReportMinuteMapper;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportMinuteDO;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 流量统计报表 - 分钟级别
* @author: aoshiguchen
* @date: 2022/10/24
*/
@Slf4j
@Component
@JobHandler(name = "FlowReportForMinuteJob", cron = "0 */1 * * * ?", param = "")
public class FlowReportForMinuteJob implements IJobHandler {
@Inject
private FlowReportService flowReportService;
@Inject
private LicenseMapper licenseMapper;
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Override
public void execute(String param) throws Exception {
List<LicenseDO> list = licenseMapper.listAll();
if (CollectionUtil.isEmpty(list)) {
return;
}
Set<Integer> licenseIds = list.stream().map(LicenseDO::getId).collect(Collectors.toSet());
Date now = new Date();
String dateStr = DateUtil.format(DateUtil.addDate(now, Calendar.MINUTE, -1), "yyyy-MM-dd HH:mm");
Date date = DateUtil.parse(dateStr, "yyyy-MM-dd HH:mm");
List<FlowReportMinuteDO> oldList = flowReportMinuteMapper.findList(licenseIds, dateStr);
Map<Integer, FlowReportMinuteDO> oldMap = CollectionUtil.isEmpty(oldList) ? new HashMap<>() :
oldList.stream().collect(Collectors.toMap(FlowReportMinuteDO::getLicenseId, Function.identity(), (a,b) -> a));
for (LicenseDO item : list) {
// 避免job重复执行导致数据重复
if (oldMap.containsKey(item.getId())) {
continue;
}
Integer writeBytes = flowReportService.getAndResetWriteByte(item.getId());
Integer readBytes = flowReportService.getAndResetReadByte(item.getId());
FlowReportMinuteDO flowReportMinuteDO = new FlowReportMinuteDO();
flowReportMinuteDO.setUserId(item.getUserId());
flowReportMinuteDO.setLicenseId(item.getId());
flowReportMinuteDO.setWriteBytes(writeBytes);
flowReportMinuteDO.setReadBytes(readBytes);
flowReportMinuteDO.setDate(date);
flowReportMinuteDO.setDateStr(dateStr);
flowReportMinuteDO.setCreateTime(now);
flowReportMinuteMapper.insert(flowReportMinuteDO);
}
}
}
@@ -0,0 +1,93 @@
package org.dromara.neutrinoproxy.server.job;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.dal.*;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportDayDO;
import org.dromara.neutrinoproxy.server.dal.entity.FlowReportMonthDO;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import fun.asgc.solon.extend.job.IJobHandler;
import fun.asgc.solon.extend.job.annotation.JobHandler;
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.util.*;
/**
* @author: aoshiguchen
* @date: 2022/10/28
*/
@Slf4j
@Component
@JobHandler(name = "FlowReportForMonthJob", cron = "0 10 0 1 * ?", param = "")
public class FlowReportForMonthJob implements IJobHandler {
@Inject
private FlowReportService flowReportService;
@Inject
private LicenseMapper licenseMapper;
@Inject
private FlowReportMinuteMapper flowReportMinuteMapper;
@Inject
private FlowReportHourMapper flowReportHourMapper;
@Inject
private FlowReportDayMapper flowReportDayMapper;
@Inject
private FlowReportMonthMapper flowReportMonthMapper;
@Override
public void execute(String param) throws Exception {
Date now = new Date();
String dateStr = getDateStr(now, param); // DateUtil.format(DateUtil.addDate(now, Calendar.MONTH, -1), "yyyy-MM");
Date date = DateUtil.parse(dateStr, "yyyy-MM");
Date startDayDate = DateUtil.getMonthBegin(date);
Date endEndDate = DateUtil.getMonthEnd(date);
// 删除原来的记录
flowReportMonthMapper.deleteByDateStr(dateStr);
// 查询上个月的天级别统计数据
List<FlowReportDayDO> flowReportDayList = flowReportDayMapper.findListByDateRange(startDayDate, endEndDate);
if (CollectionUtil.isEmpty(flowReportDayList)) {
return;
}
// 汇总前一个天的天级别统计数据
Map<Integer, FlowReportMonthDO> map = new HashMap<>();
for (FlowReportDayDO item : flowReportDayList) {
FlowReportMonthDO report = map.get(item.getLicenseId());
if (null == report) {
report = new FlowReportMonthDO();
map.put(item.getLicenseId(), report);
}
Long writeBytes = report.getWriteBytes() == null ? 0 : report.getWriteBytes();
Long readBytes = report.getReadBytes() == null ? 0 : report.getReadBytes();
report.setUserId(item.getUserId());
report.setLicenseId(item.getLicenseId());
report.setWriteBytes(writeBytes + item.getWriteBytes());
report.setReadBytes(readBytes + item.getReadBytes());
report.setDate(date);
report.setDateStr(dateStr);
report.setCreateTime(now);
}
for (FlowReportMonthDO item : map.values()) {
flowReportMonthMapper.insert(item);
}
}
private String getDateStr(Date now, String params) {
if (StringUtils.isNotBlank(params)) {
try {
// 参数格式错误则取当前时间
DateUtil.parse(params, "yyyy-MM");
return params;
} catch (Exception e) {
// ignore
}
}
return DateUtil.format(DateUtil.addDate(now, Calendar.MONTH, -1), "yyyy-MM");
}
}
@@ -0,0 +1,73 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.core;
import org.dromara.neutrinoproxy.server.proxy.domain.MetricsCollector;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import java.net.InetSocketAddress;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class BytesMetricsHandler extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
InetSocketAddress sa = (InetSocketAddress) ctx.channel().localAddress();
MetricsCollector metricsCollector = MetricsCollector.getCollector(sa.getPort());
metricsCollector.incrementReadBytes(((ByteBuf) msg).readableBytes());
metricsCollector.incrementReadMsgs(1);
// System.out.println("字节数:" + metricsCollector.getMetrics().getReadBytes());
ctx.fireChannelRead(msg);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
InetSocketAddress sa = (InetSocketAddress) ctx.channel().localAddress();
MetricsCollector metricsCollector = MetricsCollector.getCollector(sa.getPort());
metricsCollector.incrementWriteBytes(((ByteBuf) msg).readableBytes());
metricsCollector.incrementWroteMsgs(1);
super.write(ctx, msg, promise);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
InetSocketAddress sa = (InetSocketAddress) ctx.channel().localAddress();
MetricsCollector.getCollector(sa.getPort()).getChannels().incrementAndGet();
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
InetSocketAddress sa = (InetSocketAddress) ctx.channel().localAddress();
MetricsCollector.getCollector(sa.getPort()).getChannels().decrementAndGet();
super.channelInactive(ctx);
}
}
@@ -0,0 +1,131 @@
package org.dromara.neutrinoproxy.server.proxy.core;
import org.dromara.neutrinoproxy.core.ProxyMessageDecoder;
import org.dromara.neutrinoproxy.core.ProxyMessageEncoder;
import org.dromara.neutrinoproxy.core.util.FileUtil;
import org.dromara.neutrinoproxy.server.base.proxy.ProxyConfig;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.AppLoadEndEvent;
import org.noear.solon.core.event.EventListener;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import java.io.InputStream;
import java.security.KeyStore;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Slf4j
@Component
public class ProxyServerRunner implements EventListener<AppLoadEndEvent> {
@Inject
private ProxyConfig proxyConfig;
@Inject("serverBossGroup")
private NioEventLoopGroup serverBossGroup;
@Inject("serverWorkerGroup")
private NioEventLoopGroup serverWorkerGroup;
@Inject("${neutrino.proxy.server.port}")
private Integer port;
@Inject("${neutrino.proxy.server.ssl-port}")
private Integer sslPort;
@Inject("${neutrino.proxy.server.jks-path}")
private String jksPath;
@Inject("${neutrino.proxy.server.key-store-password}")
private String keyStorePassword;
@Inject("${neutrino.proxy.server.key-manager-password}")
private String keyManagerPassword;
@Override
public void onEvent(AppLoadEndEvent appLoadEndEvent) throws Throwable {
startProxyServer();
startProxyServerForSSL();
}
/**
* 启动代理服务
*/
private void startProxyServer() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(serverBossGroup, serverWorkerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
proxyServerCommonInitHandler(ch);
}
});
try {
bootstrap.bind(port).sync();
log.info("代理服务启动,端口:{}", port);
} catch (Exception e) {
log.error("代理服务异常", e);
}
}
private void startProxyServerForSSL() {
if (null == sslPort) {
return;
}
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(serverBossGroup, serverWorkerGroup)
.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(createSslHandler());
proxyServerCommonInitHandler(ch);
}
});
try {
bootstrap.bind(sslPort).sync();
log.info("代理服务启动,SSL端口: {}", sslPort);
} catch (Exception e) {
log.error("代理服务异常", e);
}
}
private ChannelHandler createSslHandler() {
try {
InputStream jksInputStream = FileUtil.getInputStream(jksPath);
SSLContext serverContext = SSLContext.getInstance("TLS");
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(jksInputStream, keyStorePassword.toCharArray());
final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyManagerPassword.toCharArray());
TrustManager[] trustManagers = null;
serverContext.init(kmf.getKeyManagers(), trustManagers, null);
SSLEngine sslEngine = serverContext.createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(false);
return new SslHandler(sslEngine);
} catch (Exception e) {
log.error("创建SSL处理器失败", e);
e.printStackTrace();
}
return null;
}
private void proxyServerCommonInitHandler(SocketChannel ch) {
ch.pipeline().addLast(new ProxyMessageDecoder(proxyConfig.getProtocol().getMaxFrameLength(),
proxyConfig.getProtocol().getLengthFieldOffset(), proxyConfig.getProtocol().getLengthFieldLength(),
proxyConfig.getProtocol().getLengthAdjustment(), proxyConfig.getProtocol().getInitialBytesToStrip()));
ch.pipeline().addLast(new ProxyMessageEncoder());
ch.pipeline().addLast(new IdleStateHandler(proxyConfig.getProtocol().getReadIdleTime(), proxyConfig.getProtocol().getWriteIdleTime(), proxyConfig.getProtocol().getAllIdleTimeSeconds()));
ch.pipeline().addLast(new ServerChannelHandler());
}
}
@@ -0,0 +1,129 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.core;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.dispatcher.Dispatcher;
import org.dromara.neutrinoproxy.server.constant.ClientConnectTypeEnum;
import org.dromara.neutrinoproxy.server.constant.SuccessCodeEnum;
import org.dromara.neutrinoproxy.server.dal.entity.ClientConnectRecordDO;
import org.dromara.neutrinoproxy.server.proxy.domain.CmdChannelAttachInfo;
import org.dromara.neutrinoproxy.server.service.ClientConnectRecordService;
import org.dromara.neutrinoproxy.server.service.ProxyMutualService;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Solon;
import java.net.InetSocketAddress;
import java.util.Date;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Slf4j
public class ServerChannelHandler extends SimpleChannelInboundHandler<ProxyMessage> {
private static volatile Dispatcher<ChannelHandlerContext, ProxyMessage> dispatcher;
public ServerChannelHandler() {
dispatcher = Solon.context().getBean(Dispatcher.class);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ProxyMessage proxyMessage) throws Exception {
dispatcher.dispatch(ctx, proxyMessage);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
Channel userChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (userChannel != null) {
userChannel.config().setOption(ChannelOption.AUTO_READ, ctx.channel().isWritable());
}
super.channelWritabilityChanged(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
Channel userChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (userChannel != null && userChannel.isActive()) {
Integer licenseId = ctx.channel().attr(Constants.LICENSE_ID).get();
String visitorId = ctx.channel().attr(Constants.VISITOR_ID).get();
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(licenseId);
if (cmdChannel != null) {
ProxyUtil.removeVisitorChannelFromCmdChannel(cmdChannel, visitorId);
}
// 数据发送完成后再关闭连接,解决http1.0数据传输问题
userChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
userChannel.close();
} else {
CmdChannelAttachInfo cmdChannelAttachInfo = ProxyUtil.getAttachInfo(ctx.channel());
if (null != cmdChannelAttachInfo) {
Solon.context().getBean(ProxyMutualService.class).offline(cmdChannelAttachInfo);
Solon.context().getBean(ClientConnectRecordService.class).add(new ClientConnectRecordDO()
.setIp(((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress())
.setLicenseId(cmdChannelAttachInfo.getLicenseId())
.setType(ClientConnectTypeEnum.DISCONNECT.getType())
.setMsg("")
.setCode(SuccessCodeEnum.SUCCESS.getCode())
.setCreateTime(new Date())
);
}
ProxyUtil.removeCmdChannel(ctx.channel());
}
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if(evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent)evt;
switch (event.state()) {
case READER_IDLE:
// 读超时,断开连接
log.info("读超时");
ctx.channel().close();
break;
case WRITER_IDLE:
log.info("写超时");
break;
case ALL_IDLE:
break;
}
}
}
}
@@ -0,0 +1,145 @@
package org.dromara.neutrinoproxy.server.proxy.core;
import cn.hutool.core.util.StrUtil;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import org.noear.solon.Solon;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class VisitorChannelHandler extends SimpleChannelInboundHandler<ByteBuf> {
private static AtomicLong visitorIdProducer = new AtomicLong(0);
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// 当出现异常就关闭连接
ctx.close();
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
// 通知代理客户端
Channel visitorChannel = ctx.channel();
Channel proxyChannel = visitorChannel.attr(Constants.NEXT_CHANNEL).get();
if (proxyChannel == null) {
// 该端口还没有代理客户端
ctx.channel().close();
} else {
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
String visitorId = ProxyUtil.getVisitorIdByChannel(visitorChannel);
proxyChannel.writeAndFlush(ProxyMessage.buildTransferMessage(visitorId, bytes));
// 增加流量计数
VisitorChannelAttachInfo visitorChannelAttachInfo = ProxyUtil.getAttachInfo(visitorChannel);
Solon.context().getBean(FlowReportService.class).addWriteByte(visitorChannelAttachInfo.getLicenseId(), bytes.length);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Channel visitorChannel = ctx.channel();
InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress();
Channel cmdChannel = ProxyUtil.getCmdChannelByServerPort(sa.getPort());
if (cmdChannel == null) {
// 该端口还没有代理客户端
ctx.channel().close();
} else {
String visitorId = newVisitorId();
String lanInfo = ProxyUtil.getClientLanInfoByServerPort(sa.getPort());
if (StrUtil.isEmpty(lanInfo)) {
ctx.channel().close();
} else {
// 用户连接到代理服务器时,设置用户连接不可读,等待代理后端服务器连接成功后再改变为可读状态
visitorChannel.config().setOption(ChannelOption.AUTO_READ, false);
ProxyUtil.addVisitorChannelToCmdChannel(cmdChannel, visitorId, visitorChannel, sa.getPort());
cmdChannel.writeAndFlush(ProxyMessage.buildConnectMessage(visitorId).setData(lanInfo.getBytes()));
}
}
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// 通知代理客户端
Channel userChannel = ctx.channel();
InetSocketAddress sa = (InetSocketAddress) userChannel.localAddress();
Channel cmdChannel = ProxyUtil.getCmdChannelByServerPort(sa.getPort());
if (cmdChannel == null) {
// 该端口还没有代理客户端
ctx.channel().close();
} else {
// 用户连接断开,从控制连接中移除
String userId = ProxyUtil.getVisitorIdByChannel(userChannel);
ProxyUtil.removeVisitorChannelFromCmdChannel(cmdChannel, userId);
Channel proxyChannel = userChannel.attr(Constants.NEXT_CHANNEL).get();
if (proxyChannel != null && proxyChannel.isActive()) {
proxyChannel.attr(Constants.NEXT_CHANNEL).remove();
proxyChannel.attr(Constants.LICENSE_ID).remove();
proxyChannel.attr(Constants.VISITOR_ID).remove();
proxyChannel.config().setOption(ChannelOption.AUTO_READ, true);
// 通知客户端,用户连接已经断开
proxyChannel.writeAndFlush(ProxyMessage.buildDisconnectMessage(userId));
}
}
super.channelInactive(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
// 通知代理客户端
Channel visitorChannel = ctx.channel();
InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress();
Channel cmdChannel = ProxyUtil.getCmdChannelByServerPort(sa.getPort());
if (cmdChannel == null) {
// 该端口还没有代理客户端
ctx.channel().close();
} else {
Channel proxyChannel = visitorChannel.attr(Constants.NEXT_CHANNEL).get();
if (proxyChannel != null) {
proxyChannel.config().setOption(ChannelOption.AUTO_READ, visitorChannel.isWritable());
}
}
super.channelWritabilityChanged(ctx);
}
/**
* 为访问者连接产生ID
*
* @return
*/
private static String newVisitorId() {
return String.valueOf(visitorIdProducer.incrementAndGet());
}
}
@@ -0,0 +1,55 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.domain;
import io.netty.channel.Channel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Map;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/8/30
*/
@Accessors(chain = true)
@Data
public class CmdChannelAttachInfo {
/**
* 用户通道映射
*/
private Map<String, Channel> visitorChannelMap;
/**
* 服务端端口集合
*/
private Set<Integer> serverPorts;
/**
* licenseId
*/
private Integer licenseId;
/**
* ip
*/
private String ip;
}
@@ -0,0 +1,44 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.domain;
import lombok.Data;
import java.io.Serializable;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Data
public class Metrics implements Serializable {
private static final long serialVersionUID = 1L;
private int port;
private long readBytes;
private long wroteBytes;
private long readMsgs;
private long wroteMsgs;
private int channels;
private long timestamp;
}
@@ -0,0 +1,148 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.domain;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
public class MetricsCollector {
private static Map<Integer, MetricsCollector> metricsCollectors = new ConcurrentHashMap<Integer, MetricsCollector>();
private Integer port;
private AtomicLong readBytes = new AtomicLong();
private AtomicLong writeBytes = new AtomicLong();
private AtomicLong readMsgs = new AtomicLong();
private AtomicLong wroteMsgs = new AtomicLong();
private AtomicInteger channels = new AtomicInteger();
private MetricsCollector() {
}
public static MetricsCollector getCollector(Integer port) {
MetricsCollector collector = metricsCollectors.get(port);
if (collector == null) {
synchronized (metricsCollectors) {
collector = metricsCollectors.get(port);
if (collector == null) {
collector = new MetricsCollector();
collector.setPort(port);
metricsCollectors.put(port, collector);
}
}
}
return collector;
}
public static List<Metrics> getAndResetAllMetrics() {
List<Metrics> allMetrics = new ArrayList<Metrics>();
Iterator<Entry<Integer, MetricsCollector>> ite = metricsCollectors.entrySet().iterator();
while (ite.hasNext()) {
allMetrics.add(ite.next().getValue().getAndResetMetrics());
}
return allMetrics;
}
public static List<Metrics> getAllMetrics() {
List<Metrics> allMetrics = new ArrayList<Metrics>();
Iterator<Entry<Integer, MetricsCollector>> ite = metricsCollectors.entrySet().iterator();
while (ite.hasNext()) {
allMetrics.add(ite.next().getValue().getMetrics());
}
return allMetrics;
}
public Metrics getAndResetMetrics() {
Metrics metrics = new Metrics();
metrics.setChannels(channels.get());
metrics.setPort(port);
metrics.setReadBytes(readBytes.getAndSet(0));
metrics.setWroteBytes(writeBytes.getAndSet(0));
metrics.setTimestamp(System.currentTimeMillis());
metrics.setReadMsgs(readMsgs.getAndSet(0));
metrics.setWroteMsgs(wroteMsgs.getAndSet(0));
return metrics;
}
public Metrics getMetrics() {
Metrics metrics = new Metrics();
metrics.setChannels(channels.get());
metrics.setPort(port);
metrics.setReadBytes(readBytes.get());
metrics.setWroteBytes(writeBytes.get());
metrics.setTimestamp(System.currentTimeMillis());
metrics.setReadMsgs(readMsgs.get());
metrics.setWroteMsgs(wroteMsgs.get());
return metrics;
}
public void incrementReadBytes(long bytes) {
readBytes.addAndGet(bytes);
}
public void incrementWriteBytes(long bytes) {
writeBytes.addAndGet(bytes);
}
public void incrementReadMsgs(long msgs) {
readMsgs.addAndGet(msgs);
}
public void incrementWroteMsgs(long msgs) {
wroteMsgs.addAndGet(msgs);
}
public AtomicInteger getChannels() {
return channels;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
}
@@ -0,0 +1,45 @@
package org.dromara.neutrinoproxy.server.proxy.domain;
import cn.hutool.core.collection.CollectionUtil;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/8/30
*/
@Accessors(chain = true)
@Data
public class ProxyMapping {
/**
* 服务端端口
*/
private Integer serverPort;
/**
* 客户端信息 IP:port
*/
private String lanInfo;
public static List<ProxyMapping> buildList(List<PortMappingDO> portMappingList) {
List<ProxyMapping> list = new ArrayList<>();
if (CollectionUtil.isEmpty(portMappingList)) {
return list;
}
for (PortMappingDO portMapping : portMappingList) {
list.add(build(portMapping));
}
return list;
}
public static ProxyMapping build(PortMappingDO portMappingDO) {
return new ProxyMapping()
.setServerPort(portMappingDO.getServerPort())
.setLanInfo(String.format("%s:%s", portMappingDO.getClientIp(), portMappingDO.getClientPort()));
}
}
@@ -0,0 +1,46 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.domain;
import lombok.Data;
import lombok.experimental.Accessors;
/**
*
* @author: aoshiguchen
* @date: 2022/8/30
*/
@Accessors(chain = true)
@Data
public class VisitorChannelAttachInfo {
private String visitorId;
private String lanInfo;
private Integer serverPort;
/**
* licenseId
*/
private Integer licenseId;
/**
* ip地址
*/
private String ip;
}
@@ -0,0 +1,167 @@
/**
* 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 org.dromara.neutrinoproxy.server.proxy.handler;
import cn.hutool.core.util.StrUtil;
import org.dromara.neutrinoproxy.core.*;
import org.dromara.neutrinoproxy.core.*;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.dromara.neutrinoproxy.server.base.proxy.ProxyConfig;
import org.dromara.neutrinoproxy.server.constant.ClientConnectTypeEnum;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import org.dromara.neutrinoproxy.server.constant.SuccessCodeEnum;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.entity.ClientConnectRecordDO;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.service.*;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
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;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Slf4j
@Match(type = Constants.ProxyDataTypeName.AUTH)
@Component
public class ProxyMessageAuthHandler implements ProxyMessageHandler {
@Inject
private ProxyConfig proxyConfig;
@Inject
private LicenseService licenseService;
@Inject
private UserService userService;
@Inject
private PortMappingService portMappingService;
@Inject
private ProxyMutualService proxyMutualService;
@Inject
private FlowReportService flowReportService;
@Inject
private ClientConnectRecordService clientConnectRecordService;
@Inject
private LicenseMapper licenseMapper;
@Inject
private VisitorChannelService visitorChannelService;
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
String ip = ((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();
Date now = new Date();
String licenseKey = proxyMessage.getInfo();
if (StrUtil.isEmpty(licenseKey)) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "license不能为空!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.FAIL.getCode())
.setErr("license不能为空!")
.setCreateTime(now)
);
return;
}
LicenseDO licenseDO = licenseService.findByKey(licenseKey);
if (null == licenseDO) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "license不存在!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.FAIL.getCode())
.setErr("license不存在!")
.setCreateTime(now)
);
return;
}
if (EnableStatusEnum.DISABLE.getStatus().equals(licenseDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "当前license已被禁用!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setLicenseId(licenseDO.getId())
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.FAIL.getCode())
.setErr("当前license已被禁用!")
.setCreateTime(now));
return;
}
UserDO userDO = userService.findById(licenseDO.getUserId());
if (null == userDO || EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "当前license无效!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setLicenseId(licenseDO.getId())
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.FAIL.getCode())
.setErr("当前license无效!")
.setCreateTime(now));
return;
}
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(licenseDO.getId());
if (null != cmdChannel) {
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.AUTH_FAILED.getCode(), "当前license已被另一节点使用!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setLicenseId(licenseDO.getId())
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.FAIL.getCode())
.setErr("当前license已被另一节点使用!")
.setCreateTime(now));
return;
}
// 发送认证成功消息
ctx.channel().writeAndFlush(ProxyMessage.buildAuthResultMessage(ExceptionEnum.SUCCESS.getCode(), "认证成功!", licenseKey));
clientConnectRecordService.add(new ClientConnectRecordDO()
.setIp(ip)
.setLicenseId(licenseDO.getId())
.setType(ClientConnectTypeEnum.CONNECT.getType())
.setMsg(licenseKey)
.setCode(SuccessCodeEnum.SUCCESS.getCode())
.setCreateTime(now));
// 更新license在线状态
licenseMapper.updateOnlineStatus(licenseDO.getId(), OnlineStatusEnum.ONLINE.getStatus(), now);
// 初始化VisitorChannel
visitorChannelService.initVisitorChannel(licenseDO.getId(), ctx.channel());
}
@Override
public String name() {
return ProxyDataTypeEnum.AUTH.getDesc();
}
}
@@ -0,0 +1,91 @@
package org.dromara.neutrinoproxy.server.proxy.handler;
import cn.hutool.core.util.StrUtil;
import org.dromara.neutrinoproxy.core.*;
import org.dromara.neutrinoproxy.core.*;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.service.LicenseService;
import org.dromara.neutrinoproxy.server.service.UserService;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Match(type = Constants.ProxyDataTypeName.CONNECT)
@Component
public class ProxyMessageConnectHandler implements ProxyMessageHandler {
@Inject
private LicenseService licenseService;
@Inject
private UserService userService;
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
String info = proxyMessage.getInfo();
if (StrUtil.isEmpty(info)) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "info不能为空!"));
ctx.channel().close();
return;
}
String[] tokens = info.split("@");
if (tokens.length != 2) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "info格式有误!"));
ctx.channel().close();
return;
}
String visitorId = tokens[0];
String licenseKey = tokens[1];
LicenseDO licenseDO = licenseService.findByKey(licenseKey);
if (null == licenseDO) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "license不存在!"));
ctx.channel().close();
return;
}
if (EnableStatusEnum.DISABLE.getStatus().equals(licenseDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "当前license已被禁用!"));
ctx.channel().close();
return;
}
UserDO userDO = userService.findById(licenseDO.getUserId());
if (null == userDO || EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "当前license无效!"));
ctx.channel().close();
return;
}
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(licenseDO.getId());
if (null == cmdChannel) {
ctx.channel().writeAndFlush(ProxyMessage.buildErrMessage(ExceptionEnum.CONNECT_FAILED, "服务端异常,指令通道不存在!"));
ctx.channel().close();
return;
}
Channel visitorChannel = ProxyUtil.getVisitorChannel(cmdChannel, visitorId);
if (visitorChannel != null) {
ctx.channel().attr(Constants.VISITOR_ID).set(visitorId);
ctx.channel().attr(Constants.LICENSE_ID).set(licenseDO.getId());
ctx.channel().attr(Constants.NEXT_CHANNEL).set(visitorChannel);
visitorChannel.attr(Constants.NEXT_CHANNEL).set(ctx.channel());
// 代理客户端与后端服务器连接成功,修改用户连接为可读状态
visitorChannel.config().setOption(ChannelOption.AUTO_READ, true);
}
}
@Override
public String name() {
return ProxyDataTypeEnum.CONNECT.getDesc();
}
}
@@ -0,0 +1,45 @@
package org.dromara.neutrinoproxy.server.proxy.handler;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import org.noear.solon.annotation.Component;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Match(type = Constants.ProxyDataTypeName.DISCONNECT)
@Component
public class ProxyMessageDisconnectHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
Integer licenseId = ctx.channel().attr(Constants.LICENSE_ID).get();
// licenseId为空,说明访问者通道已经关闭,无需处理
if (null == licenseId) {
return;
}
// 代理连接没有连上服务器由控制连接发送用户端断开连接消息
String visitorId = proxyMessage.getInfo();
Channel userChannel = ProxyUtil.removeVisitorChannelFromCmdChannel(ctx.channel(), visitorId);
if (null != userChannel) {
// 数据发送完成后再关闭连接,解决http1.0数据传输问题
userChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public String name() {
return ProxyDataTypeEnum.DISCONNECT.getDesc();
}
}
@@ -0,0 +1,30 @@
package org.dromara.neutrinoproxy.server.proxy.handler;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import io.netty.channel.ChannelHandlerContext;
import org.noear.solon.annotation.Component;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Match(type = Constants.ProxyDataTypeName.HEARTBEAT)
@Component
public class ProxyMessageHeartbeatHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
ctx.channel().writeAndFlush(ProxyMessage.buildHeartbeatMessage());
}
@Override
public String name() {
return ProxyDataTypeEnum.HEARTBEAT.getDesc();
}
}
@@ -0,0 +1,45 @@
package org.dromara.neutrinoproxy.server.proxy.handler;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.core.ProxyDataTypeEnum;
import org.dromara.neutrinoproxy.core.ProxyMessage;
import org.dromara.neutrinoproxy.core.ProxyMessageHandler;
import org.dromara.neutrinoproxy.core.dispatcher.Match;
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
import org.dromara.neutrinoproxy.server.service.FlowReportService;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
/**
*
* @author: aoshiguchen
* @date: 2022/6/16
*/
@Match(type = Constants.ProxyDataTypeName.TRANSFER)
@Component
public class ProxyMessageTransferHandler implements ProxyMessageHandler {
@Override
public void handle(ChannelHandlerContext ctx, ProxyMessage proxyMessage) {
Channel visitorChannel = ctx.channel().attr(Constants.NEXT_CHANNEL).get();
if (null != visitorChannel) {
ByteBuf buf = ctx.alloc().buffer(proxyMessage.getData().length);
buf.writeBytes(proxyMessage.getData());
visitorChannel.writeAndFlush(buf);
// 增加流量计数
VisitorChannelAttachInfo visitorChannelAttachInfo = ProxyUtil.getAttachInfo(visitorChannel);
Solon.context().getBean(FlowReportService.class).addReadByte(visitorChannelAttachInfo.getLicenseId(), proxyMessage.getData().length);
}
}
@Override
public String name() {
return ProxyDataTypeEnum.TRANSFER.getDesc();
}
}
@@ -0,0 +1,90 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.controller.req.log.ClientConnectRecordListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.ClientConnectRecordListRes;
import org.dromara.neutrinoproxy.server.dal.ClientConnectRecordMapper;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.ClientConnectRecordDO;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author: aoshiguchen
* @date: 2022/11/23
*/
@Slf4j
@Component
public class ClientConnectRecordService {
@Inject
private MapperFacade mapperFacade;
@Db
private ClientConnectRecordMapper clientConnectRecordMapper;
@Db
private LicenseMapper licenseMapper;
@Db
private UserMapper userMapper;
public void add(ClientConnectRecordDO clientConnectRecordDO) {
clientConnectRecordMapper.insert(clientConnectRecordDO);
}
public PageInfo<ClientConnectRecordListRes> page(PageQuery pageQuery, ClientConnectRecordListReq req) {
Page<ClientConnectRecordListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<ClientConnectRecordDO> list = clientConnectRecordMapper.selectList(new LambdaQueryWrapper<ClientConnectRecordDO>()
.eq(null != req.getLicenseId(), ClientConnectRecordDO::getLicenseId, req.getLicenseId())
.orderByDesc(ClientConnectRecordDO::getId)
);
List<ClientConnectRecordListRes> respList = mapperFacade.mapAsList(list, ClientConnectRecordListRes.class);
if (CollectionUtils.isEmpty(list)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
Set<Integer> licenseIds = respList.stream().map(ClientConnectRecordListRes::getLicenseId).collect(Collectors.toSet());
List<LicenseDO> licenseList = licenseMapper.findByIds(licenseIds);
if (CollectionUtil.isEmpty(licenseList)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
Set<Integer> userIds = licenseList.stream().map(LicenseDO::getUserId).collect(Collectors.toSet());
List<UserDO> userList = userMapper.findByIds(userIds);
Map<Integer, LicenseDO> licenseMap = licenseList.stream().collect(Collectors.toMap(LicenseDO::getId, Function.identity()));
Map<Integer, UserDO> userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity()));
boolean isAdmin = SystemContextHolder.isAdmin();
respList.forEach(item -> {
LicenseDO license = licenseMap.get(item.getLicenseId());
if (null == license) {
return;
}
item.setLicenseName(license.getName());
item.setUserId(license.getUserId());
UserDO user = userMap.get(license.getUserId());
if (null == user) {
return;
}
item.setUserName(user.getName());
if (!isAdmin) {
// msg可能带有license等敏感信息,若登录者为游客,则不展示
item.setMsg("******");
}
});
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
}
@@ -0,0 +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 org.dromara.neutrinoproxy.server.service;
import org.dromara.neutrinoproxy.core.util.LockUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 流量报表服务
* @author: aoshiguchen
* @date: 2022/10/26
*/
@Slf4j
@Component
public class FlowReportService {
private Map<Integer/*licenseId*/, AtomicInteger/*writeByte*/> writeByteMap = new HashMap<>();
private Map<Integer/*licenseId*/, AtomicInteger/*readByte*/> readByteMap = new HashMap<>();
private AtomicInteger getWriteByte(Integer licenseId) {
return LockUtil.doubleCheckProcessForNoException(() -> !writeByteMap.containsKey(licenseId),
licenseId,
() -> {
writeByteMap.put(licenseId, new AtomicInteger());
},
() -> writeByteMap.get(licenseId));
}
private AtomicInteger getReadByte(Integer licenseId) {
return LockUtil.doubleCheckProcessForNoException(() -> !readByteMap.containsKey(licenseId),
licenseId,
() -> {
readByteMap.put(licenseId, new AtomicInteger());
},
() -> readByteMap.get(licenseId));
}
public void addWriteByte(Integer licenseId, Integer writeByte) {
getWriteByte(licenseId).addAndGet(writeByte);
}
public void addReadByte(Integer licenseId, Integer readByte) {
getReadByte(licenseId).addAndGet(readByte);
}
public Integer getAndResetWriteByte(Integer licenseId) {
return getWriteByte(licenseId).getAndSet(0);
}
public Integer getAndResetReadByte(Integer licenseId) {
return getReadByte(licenseId).getAndSet(0);
}
}
@@ -0,0 +1,123 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoExecuteReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoListReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.req.system.JobInfoUpdateReq;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoExecuteRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoListRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoUpdateEnableStatusRes;
import org.dromara.neutrinoproxy.server.controller.res.system.JobInfoUpdateRes;
import org.dromara.neutrinoproxy.server.dal.JobInfoMapper;
import org.dromara.neutrinoproxy.server.dal.entity.JobInfoDO;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import fun.asgc.solon.extend.job.IJobSource;
import fun.asgc.solon.extend.job.JobInfo;
import fun.asgc.solon.extend.job.impl.JobExecutor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.Date;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/9/5
*/
@Slf4j
@Component
public class JobInfoService implements IJobSource {
@Inject
private MapperFacade mapperFacade;
@Db
private JobInfoMapper jobInfoMapper;
public PageInfo<JobInfoListRes> page(PageQuery pageQuery, JobInfoListReq req) {
Page<JobInfoListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<JobInfoDO> list = jobInfoMapper.selectList(new LambdaQueryWrapper<JobInfoDO>()
.orderByAsc(JobInfoDO::getId)
);
List<JobInfoListRes> respList = mapperFacade.mapAsList(list, JobInfoListRes.class);
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public List<JobInfoDO> findList() {
List<JobInfoDO> jobInfoDOList = jobInfoMapper.findList();
return jobInfoDOList;
}
public JobInfoUpdateEnableStatusRes updateEnableStatus(JobInfoUpdateEnableStatusReq req) {
JobInfoDO jobInfoDO = jobInfoMapper.findById(req.getId());
ParamCheckUtil.checkNotNull(jobInfoDO, ExceptionConstant.JOB_INFO_NOT_EXIST);
jobInfoMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
if (EnableStatusEnum.ENABLE.getStatus().equals(req.getEnable())) {
Solon.context().getBean(JobExecutor.class).add(new JobInfo()
.setId(String.valueOf(jobInfoDO.getId()))
.setName(jobInfoDO.getHandler())
.setDesc(jobInfoDO.getDesc())
.setCron(jobInfoDO.getCron())
.setParam(jobInfoDO.getParam())
.setEnable(true)
);
} else {
Solon.context().getBean(JobExecutor.class).remove(String.valueOf(req.getId()));
}
return new JobInfoUpdateEnableStatusRes();
}
public JobInfoExecuteRes execute(JobInfoExecuteReq req) {
Solon.context().getBean(JobExecutor.class).trigger(String.valueOf(req.getId()), req.getParam());
return new JobInfoExecuteRes();
}
@Override
public List<JobInfo> sourceList() {
List<JobInfo> jobInfoList = Lists.newArrayList();
List<JobInfoDO> jobInfoDOList = jobInfoMapper.findList();
if (CollectionUtil.isEmpty(jobInfoDOList)) {
return jobInfoList;
}
for (JobInfoDO item : jobInfoDOList) {
jobInfoList.add(new JobInfo()
.setId(String.valueOf(item.getId()))
.setName(item.getHandler())
.setDesc(item.getDesc())
.setCron(item.getCron())
.setParam(item.getParam())
.setEnable(EnableStatusEnum.ENABLE.getStatus().equals(item.getEnable()))
);
}
return jobInfoList;
}
public JobInfoUpdateRes update(JobInfoUpdateReq req) {
JobInfoDO jobInfoDO = jobInfoMapper.findById(req.getId());
ParamCheckUtil.checkNotNull( jobInfoDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST);
JobInfoDO jobInfo = new JobInfoDO();
jobInfo.setId(req.getId());
jobInfo.setCron(req.getCron());
jobInfo.setDesc(req.getDesc());
jobInfo.setAlarmEmail(req.getAlarmEmail());
jobInfo.setAlarmDing(req.getAlarmDing());
jobInfo.setParam(req.getParam());
jobInfo.setUpdateTime(new Date());
jobInfoMapper.updateById(jobInfo);
return new JobInfoUpdateRes();
}
}
@@ -0,0 +1,91 @@
/**
* 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 org.dromara.neutrinoproxy.server.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.log.JobLogListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.JobLogListRes;
import org.dromara.neutrinoproxy.server.dal.JobLogMapper;
import org.dromara.neutrinoproxy.server.dal.entity.JobLogDO;
import fun.asgc.solon.extend.job.IJobCallback;
import fun.asgc.solon.extend.job.JobInfo;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.Date;
import java.util.List;
/**
*
* @author: aoshiguchen
* @date: 2022/9/4
*/
@Slf4j
@Component
public class JobLogService implements IJobCallback {
@Inject
private MapperFacade mapperFacade;
@Db
private JobLogMapper jobLogMapper;
@Override
public void executeLog(JobInfo jobInfo, String param, Throwable throwable) {
Integer code = 0;
String msg = "";
if (null == throwable) {
msg = "执行成功";
log.info("job[id={},name={}]执行完毕", jobInfo.getId(), jobInfo.getName());
} else {
log.error("job[id={},name={}]执行异常", jobInfo.getId(), jobInfo.getName(), throwable);
msg = "执行异常:\r\n" + ExceptionUtils.getStackTrace(throwable);
code = -1;
}
jobLogMapper.insert(new JobLogDO()
.setJobId(Integer.valueOf(jobInfo.getId()))
.setHandler(jobInfo.getName())
.setParam(param)
.setCode(code)
.setMsg(msg)
.setAlarmStatus(0)
.setCreateTime(new Date())
);
}
public PageInfo<JobLogListRes> page(PageQuery pageQuery, JobLogListReq req) {
Page<JobLogListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<JobLogDO> list = jobLogMapper.selectList(new LambdaQueryWrapper<JobLogDO>()
.eq(null != req.getJobId(), JobLogDO::getJobId, req.getJobId())
.orderByDesc(JobLogDO::getId)
);
List<JobLogListRes> respList = mapperFacade.mapAsList(list, JobLogListRes.class);
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
}
@@ -0,0 +1,247 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import org.dromara.neutrinoproxy.server.controller.req.proxy.LicenseCreateReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.LicenseListReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.LicenseUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.LicenseUpdateReq;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.jetbrains.annotations.Nullable;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.Lifecycle;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* license服务
* @author: aoshiguchen
* @date: 2022/8/6
*/
@Component
public class LicenseService implements Lifecycle {
@Inject
private MapperFacade mapperFacade;
@Db
private LicenseMapper licenseMapper;
@Db
private UserMapper userMapper;
@Inject
private VisitorChannelService visitorChannelService;
public PageInfo<LicenseListRes> page(PageQuery pageQuery, LicenseListReq req) {
Page<LicenseListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<LicenseDO> list = licenseMapper.selectList(new LambdaQueryWrapper<LicenseDO>()
.eq(req.getUserId() != null, LicenseDO::getUserId, req.getUserId())
.eq(req.getIsOnline() != null, LicenseDO::getIsOnline, req.getIsOnline())
.eq(req.getEnable() != null, LicenseDO::getEnable, req.getEnable())
.orderByAsc(Arrays.asList(LicenseDO::getUserId, LicenseDO::getId))
);
List<LicenseListRes> respList = mapperFacade.mapAsList(list, LicenseListRes.class);
if (CollectionUtils.isEmpty(list)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
if (!CollectionUtil.isEmpty(respList)) {
Set<Integer> userIds = respList.stream().map(LicenseListRes::getUserId).collect(Collectors.toSet());
List<UserDO> userList = userMapper.findByIds(userIds);
Map<Integer, UserDO> userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity()));
for (LicenseListRes item : respList) {
UserDO userDO = userMap.get(item.getUserId());
if (null != userDO) {
item.setUserName(userDO.getName());
}
item.setKey(desensitization(item.getUserId(), item.getKey()));
}
}
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public List<LicenseListRes> list(LicenseListReq req) {
List<LicenseDO> list = licenseMapper.selectList(new LambdaQueryWrapper<LicenseDO>()
.eq(null != req.getEnable(), LicenseDO::getEnable, req.getEnable())
);
List<LicenseListRes> licenseList = assembleConvertLicenses(list);
return licenseList;
}
@Nullable
private List<LicenseListRes> assembleConvertLicenses(List<LicenseDO> list) {
List<LicenseListRes> licenseList = mapperFacade.mapAsList(list, LicenseListRes.class);
if (!CollectionUtil.isEmpty(licenseList)) {
Set<Integer> userIds = licenseList.stream().map(LicenseListRes::getUserId).collect(Collectors.toSet());
List<UserDO> userList = userMapper.findByIds(userIds);
Map<Integer, UserDO> userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity()));
for (LicenseListRes item : licenseList) {
UserDO userDO = userMap.get(item.getUserId());
if (null != userDO) {
item.setUserName(userDO.getName());
}
item.setKey(desensitization(item.getUserId(), item.getKey()));
}
}
return licenseList;
}
/**
* 创建license
* @param req
* @return
*/
public LicenseCreateRes create(LicenseCreateReq req) {
LicenseDO licenseDO = licenseMapper.checkRepeat(req.getUserId(), req.getName());
ParamCheckUtil.checkExpression(null == licenseDO, ExceptionConstant.LICENSE_NAME_CANNOT_REPEAT);
String key = UUID.randomUUID().toString().replaceAll("-", "");
Date now = new Date();
licenseMapper.insert(new LicenseDO()
.setName(req.getName())
.setKey(key)
.setUserId(req.getUserId())
.setIsOnline(OnlineStatusEnum.OFFLINE.getStatus())
.setEnable(EnableStatusEnum.ENABLE.getStatus())
.setCreateTime(now)
.setUpdateTime(now)
);
return new LicenseCreateRes();
}
public LicenseUpdateRes update(LicenseUpdateReq req) {
LicenseDO oldLicenseDO = licenseMapper.findById(req.getId());
ParamCheckUtil.checkNotNull(oldLicenseDO, ExceptionConstant.LICENSE_NOT_EXIST);
LicenseDO licenseCheck = licenseMapper.checkRepeat(oldLicenseDO.getUserId(), req.getName(), Sets.newHashSet(oldLicenseDO.getId()));
ParamCheckUtil.checkMustNull(licenseCheck, ExceptionConstant.LICENSE_NAME_CANNOT_REPEAT);
licenseMapper.update(req.getId(), req.getName(), new Date());
return new LicenseUpdateRes();
}
public LicenseDetailRes detail(Integer id) {
LicenseDO licenseDO = licenseMapper.findById(id);
if (null == licenseDO) {
return null;
}
UserDO userDO = userMapper.findById(licenseDO.getUserId());
String userName = "";
if (null != userDO) {
userName = userDO.getName();
}
return new LicenseDetailRes()
.setId(licenseDO.getId())
.setName(licenseDO.getName())
.setKey(desensitization(licenseDO.getUserId(), licenseDO.getKey()))
.setUserId(licenseDO.getUserId())
.setUserName(userName)
.setIsOnline(licenseDO.getIsOnline())
.setEnable(licenseDO.getEnable())
.setCreateTime(licenseDO.getCreateTime())
.setUpdateTime(licenseDO.getUpdateTime())
;
}
/**
* 更新license启用状态
* @param req
* @return
*/
public LicenseUpdateEnableStatusRes updateEnableStatus(LicenseUpdateEnableStatusReq req) {
licenseMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByLicenseId(req.getId(), req.getEnable());
return new LicenseUpdateEnableStatusRes();
}
/**
* 删除license
* @param id
*/
public void delete(Integer id) {
licenseMapper.deleteById(id);
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByLicenseId(id, EnableStatusEnum.DISABLE.getStatus());
}
/**
* 重置license
* @param id
*/
public void reset(Integer id) {
String key = UUID.randomUUID().toString().replaceAll("-", "");
Date now = new Date();
licenseMapper.reset(id, key, now);
}
public LicenseDO findByKey(String license) {
return licenseMapper.findByKey(license);
}
/**
* 脱敏处理
* 非当前登录人的license,一律脱敏
* @param userId
* @param licenseKey
* @return
*/
private String desensitization(Integer userId, String licenseKey) {
Integer currentUserId = SystemContextHolder.getUser().getId();
if (currentUserId.equals(userId)) {
return licenseKey;
}
return licenseKey.substring(0, 10) + "****" + licenseKey.substring(licenseKey.length() - 10);
}
/**
* 服务端项目停止、启动时,更新在线状态为离线
*/
@Override
public void start() throws Throwable {
licenseMapper.updateOnlineStatus(OnlineStatusEnum.OFFLINE.getStatus(), new Date());
}
/**
* 服务端项目停止、启动时,更新在线状态为离线
*/
@Override
public void stop() throws Throwable {
licenseMapper.updateOnlineStatus(OnlineStatusEnum.OFFLINE.getStatus(), new Date());
}
/**
* 查询当前角色下的license,若为管理员 则返回全部license
*/
public List<LicenseListRes> queryCurUserLicense(LicenseListReq req) {
if(SystemContextHolder.isAdmin()){
return this.list(req);
}
List<LicenseDO> list = licenseMapper.selectList(new LambdaQueryWrapper<LicenseDO>()
.eq(LicenseDO::getEnable, EnableStatusEnum.ENABLE.getStatus())
.eq(LicenseDO::getUserId,SystemContextHolder.getUserId())
);
List<LicenseListRes> licenseList = assembleConvertLicenses(list);
return licenseList;
}
}
@@ -0,0 +1,105 @@
package org.dromara.neutrinoproxy.server.service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.ServiceException;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.constant.Constants;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupCreateReq;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupListReq;
import org.dromara.neutrinoproxy.server.controller.req.system.PortGroupUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupCreateRes;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupListRes;
import org.dromara.neutrinoproxy.server.controller.res.system.PortGroupUpdateEnableStatusRes;
import org.dromara.neutrinoproxy.server.dal.PortGroupMapper;
import org.dromara.neutrinoproxy.server.dal.PortPoolMapper;
import org.dromara.neutrinoproxy.server.dal.entity.PortGroupDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortPoolDO;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* 端口分组服务
*/
@Component
public class PortGroupService {
@Inject
private MapperFacade mapperFacade;
@Db
private PortGroupMapper portGroupMapper;
@Db
private PortPoolMapper portPoolMapper;
public PortGroupCreateRes create(PortGroupCreateReq req) {
PortGroupDO portGroupDO = portGroupMapper.selectOne(Wrappers.lambdaQuery(PortGroupDO.class)
.eq(PortGroupDO::getName, req.getName()));
if (Objects.nonNull(portGroupDO)) {
throw ServiceException.create(ExceptionConstant.PORT_GROUP_NAME_ALREADY_EXIST, req.getName());
}
Date now = new Date();
portGroupDO = new PortGroupDO();
portGroupDO.setName(req.getName());
portGroupDO.setPossessorType(req.getPossessorType());
portGroupDO.setPossessorId(req.getPossessorId());
portGroupDO.setEnable(EnableStatusEnum.ENABLE.getStatus());
portGroupDO.setCreateTime(now);
portGroupDO.setUpdateTime(now);
portGroupMapper.insert(portGroupDO);
return new PortGroupCreateRes();
}
public PageInfo<PortGroupListRes> page(PageQuery pageQuery, PortGroupListReq req) {
Page<PortGroupListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<PortGroupListRes> list = portGroupMapper.selectPortGroupListResList(req);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public List<PortGroupListRes> list(PortGroupListReq req) {
List<PortGroupListRes> list = portGroupMapper.selectPortGroupListResList(req);
return list;
}
public PortGroupUpdateEnableStatusRes updateEnableStatus(PortGroupUpdateEnableStatusReq req) {
PortGroupDO portGroupDO = portGroupMapper.selectById(req.getId());
ParamCheckUtil.checkNotNull(portGroupDO, ExceptionConstant.PORT_GROUP_NAME_DOES_NOT_EXIST);
if (!SystemContextHolder.isAdmin()) {
ParamCheckUtil.checkExpression(false, ExceptionConstant.NO_PERMISSION_VISIT);
}
portGroupMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
return new PortGroupUpdateEnableStatusRes();
}
public void delete(Integer id) {
if (id == Constants.DEFAULT_PORT_GROUP_ID) {
throw ServiceException.create(ExceptionConstant.DEFAULT_GROUP_FORBID_DELETE);
}
PortGroupDO portGroupDO = portGroupMapper.selectById(id);
//检验分组是否存在
ParamCheckUtil.checkNotNull(portGroupDO, ExceptionConstant.PORT_GROUP_NAME_DOES_NOT_EXIST);
//删除
portGroupMapper.deleteById(id);
//修改绑定此分组的端口到默认分组
portPoolMapper.update(null, Wrappers.lambdaUpdate(PortPoolDO.class)
.eq(PortPoolDO::getGroupId, portGroupDO.getId())
.set(PortPoolDO::getGroupId, Constants.DEFAULT_PORT_GROUP_ID)
.set(PortPoolDO::getUpdateTime, new Date())
);
}
}
@@ -0,0 +1,251 @@
package org.dromara.neutrinoproxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Sets;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import org.dromara.neutrinoproxy.server.controller.req.proxy.PortMappingCreateReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.PortMappingListReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.PortMappingUpdateEnableStatusReq;
import org.dromara.neutrinoproxy.server.controller.req.proxy.PortMappingUpdateReq;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.PortMappingMapper;
import org.dromara.neutrinoproxy.server.dal.PortPoolMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortPoolDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.dromara.neutrinoproxy.server.controller.res.proxy.*;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.Lifecycle;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
* @author: aoshiguchen
* @date: 2022/8/8
*/
@Component
public class PortMappingService implements Lifecycle {
@Inject
private MapperFacade mapperFacade;
@Db
private PortMappingMapper portMappingMapper;
@Db
private LicenseMapper licenseMapper;
@Db
private UserMapper userMapper;
@Db
private PortPoolMapper portPoolMapper;
@Inject
private VisitorChannelService visitorChannelService;
@Inject
private PortPoolService portPoolService;
public PageInfo<PortMappingListRes> page(PageQuery pageQuery, PortMappingListReq req) {
Page<PortMappingListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<PortMappingDO> list = portMappingMapper.selectPortMappingByCondition(req);
List<PortMappingListRes> respList = mapperFacade.mapAsList(list, PortMappingListRes.class);
if (CollectionUtils.isEmpty(list)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
Set<Integer> licenseIds = respList.stream().map(PortMappingListRes::getLicenseId).collect(Collectors.toSet());
List<LicenseDO> licenseList = licenseMapper.findByIds(licenseIds);
if (CollectionUtil.isEmpty(licenseList)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
Set<Integer> userIds = licenseList.stream().map(LicenseDO::getUserId).collect(Collectors.toSet());
List<UserDO> userList = userMapper.findByIds(userIds);
Map<Integer, LicenseDO> licenseMap = licenseList.stream().collect(Collectors.toMap(LicenseDO::getId, Function.identity()));
Map<Integer, UserDO> userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity()));
respList.forEach(item -> {
LicenseDO license = licenseMap.get(item.getLicenseId());
if (null == license) {
return;
}
item.setLicenseName(license.getName());
item.setUserId(license.getUserId());
UserDO user = userMap.get(license.getUserId());
if (null == user) {
return;
}
item.setUserName(user.getName());
});
//sorted [userId asc] [licenseId asc] [createTime asc]
respList = respList.stream().sorted(Comparator.comparing(PortMappingListRes::getUserId)
.thenComparing(PortMappingListRes::getLicenseId)
.thenComparing(PortMappingListRes::getCreateTime))
.collect(Collectors.toList());
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public PortMappingCreateRes create(PortMappingCreateReq req) {
LicenseDO licenseDO = licenseMapper.findById(req.getLicenseId());
ParamCheckUtil.checkNotNull(licenseDO, ExceptionConstant.LICENSE_NOT_EXIST);
if (!SystemContextHolder.isAdmin()) {
// 临时处理,如果当前用户不是管理员,则操作userId不能为1
ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT);
}
PortPoolDO portPoolDO = portPoolMapper.findByPort(req.getServerPort());
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
ParamCheckUtil.checkExpression(null == portMappingMapper.findByPort(req.getServerPort(), null), ExceptionConstant.PORT_CANNOT_REPEAT_MAPPING, req.getServerPort());
Date now = new Date();
PortMappingDO portMappingDO = new PortMappingDO();
portMappingDO.setLicenseId(req.getLicenseId());
portMappingDO.setServerPort(req.getServerPort());
portMappingDO.setClientIp(req.getClientIp());
portMappingDO.setClientPort(req.getClientPort());
portMappingDO.setIsOnline(OnlineStatusEnum.OFFLINE.getStatus());
portMappingDO.setEnable(EnableStatusEnum.ENABLE.getStatus());
portMappingDO.setCreateTime(now);
portMappingDO.setUpdateTime(now);
portMappingMapper.insert(portMappingDO);
// 更新VisitorChannel
visitorChannelService.addVisitorChannelByPortMapping(portMappingDO);
return new PortMappingCreateRes();
}
public PortMappingUpdateRes update(PortMappingUpdateReq req) {
LicenseDO licenseDO = licenseMapper.findById(req.getLicenseId());
ParamCheckUtil.checkNotNull(licenseDO, ExceptionConstant.LICENSE_NOT_EXIST);
if (!SystemContextHolder.isAdmin()) {
// 临时处理,如果当前用户不是管理员,则操作userId不能为1
ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT);
}
PortPoolDO portPoolDO = portPoolMapper.findByPort(req.getServerPort());
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
ParamCheckUtil.checkExpression(null == portMappingMapper.findByPort(req.getServerPort(), Sets.newHashSet(req.getId())), ExceptionConstant.PORT_CANNOT_REPEAT_MAPPING, req.getServerPort());
// 查询原端口映射
PortMappingDO oldPortMappingDO = portMappingMapper.findById(req.getId());
ParamCheckUtil.checkNotNull(oldPortMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST);
PortMappingDO portMappingDO = new PortMappingDO();
portMappingDO.setId(req.getId());
portMappingDO.setLicenseId(req.getLicenseId());
portMappingDO.setServerPort(req.getServerPort());
portMappingDO.setClientIp(req.getClientIp());
portMappingDO.setClientPort(req.getClientPort());
portMappingDO.setUpdateTime(new Date());
portMappingDO.setEnable(EnableStatusEnum.ENABLE.getStatus());
portMappingMapper.updateById(portMappingDO);
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByPortMapping(oldPortMappingDO, portMappingDO);
return new PortMappingUpdateRes();
}
public PortMappingDetailRes detail(Integer id) {
PortMappingDO portMappingDO = portMappingMapper.findById(id);
if (null == portMappingDO) {
return null;
}
PortMappingDetailRes res = new PortMappingDetailRes()
.setId(portMappingDO.getId())
.setLicenseId(portMappingDO.getLicenseId())
.setServerPort(portMappingDO.getServerPort())
.setClientIp(portMappingDO.getClientIp())
.setClientPort(portMappingDO.getClientPort())
.setIsOnline(portMappingDO.getIsOnline())
.setEnable(portMappingDO.getEnable())
.setCreateTime(portMappingDO.getCreateTime())
.setUpdateTime(portMappingDO.getUpdateTime());
LicenseDO license = licenseMapper.findById(portMappingDO.getLicenseId());
if (null != license) {
res.setLicenseName(license.getName());
res.setUserId(license.getUserId());
UserDO user = userMapper.findById(license.getUserId());
if (null != user) {
res.setUserName(user.getName());
}
}
return res;
}
public PortMappingUpdateEnableStatusRes updateEnableStatus(PortMappingUpdateEnableStatusReq req) {
PortMappingDO portMappingDO = portMappingMapper.findById(req.getId());
ParamCheckUtil.checkNotNull(portMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST);
LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId());
ParamCheckUtil.checkNotNull(licenseDO, ExceptionConstant.LICENSE_NOT_EXIST);
if (!SystemContextHolder.isAdmin()) {
ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT);
}
portMappingMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
// 更新VisitorChannel
portMappingDO.setEnable(req.getEnable());
if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(req.getEnable())) {
visitorChannelService.addVisitorChannelByPortMapping(portMappingDO);
} else {
visitorChannelService.removeVisitorChannelByPortMapping(portMappingDO);
}
return new PortMappingUpdateEnableStatusRes();
}
public void delete(Integer id) {
PortMappingDO portMappingDO = portMappingMapper.findById(id);
ParamCheckUtil.checkNotNull(portMappingDO, ExceptionConstant.PORT_MAPPING_NOT_EXIST);
LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId());
if (null != licenseDO && !SystemContextHolder.isAdmin()) {
// 临时处理,如果当前用户不是管理员,则操作userId不能为1
ParamCheckUtil.checkExpression(!licenseDO.getUserId().equals(1), ExceptionConstant.NO_PERMISSION_VISIT);
}
portMappingMapper.deleteById(id);
// 更新VisitorChannel
visitorChannelService.removeVisitorChannelByPortMapping(portMappingDO);
}
/**
* 根据license查询可用的端口映射列表
* @param licenseId
* @return
*/
public List<PortMappingDO> findEnableListByLicenseId(Integer licenseId) {
return portMappingMapper.findEnableListByLicenseId(licenseId);
}
/**
* 服务端项目停止、启动时,更新在线状态为离线
*/
@Override
public void start() throws Throwable {
portMappingMapper.updateOnlineStatus(OnlineStatusEnum.OFFLINE.getStatus(), new Date());
}
/**
* 服务端项目停止、启动时,更新在线状态为离线
*/
@Override
public void stop() throws Throwable {
portMappingMapper.updateOnlineStatus(OnlineStatusEnum.OFFLINE.getStatus(), new Date());
}
}
@@ -0,0 +1,182 @@
package org.dromara.neutrinoproxy.server.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.ServiceException;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.PortGroupMapper;
import org.dromara.neutrinoproxy.server.dal.PortMappingMapper;
import org.dromara.neutrinoproxy.server.dal.PortPoolMapper;
import org.dromara.neutrinoproxy.server.dal.entity.*;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortPoolDO;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.solon.annotation.Db;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.dal.entity.PortGroupDO;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static org.dromara.neutrinoproxy.server.constant.ExceptionConstant.*;
/**
*
* @author: aoshiguchen
* @date: 2022/8/7
*/
@Slf4j
@Component
public class PortPoolService {
@Inject
private MapperFacade mapperFacade;
@Db
private PortPoolMapper portPoolMapper;
@Inject
private VisitorChannelService visitorChannelService;
@Db
private PortGroupMapper portGroupMapper;
@Db
private PortMappingMapper portMappingMapper;
@Db
private LicenseMapper licenseMapper;
public PageInfo<PortPoolListRes> page(PageQuery pageQuery, PortPoolListReq req) {
Page<PortPoolListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<PortPoolListRes> list = portPoolMapper.selectResList(req);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public List<PortPoolListRes> list(PortPoolListReq req) {
List<PortPoolDO> list = portPoolMapper.selectList(new LambdaQueryWrapper<PortPoolDO>()
.eq(PortPoolDO::getEnable, EnableStatusEnum.ENABLE.getStatus())
);
return mapperFacade.mapAsList(this.filterUsedPorts(list), PortPoolListRes.class);
}
private List<PortPoolDO> filterUsedPorts(List<PortPoolDO> list) {
//Gets the used ports
List<PortMappingDO> usePorts = portMappingMapper.selectList(new LambdaQueryWrapper<PortMappingDO>().orderByAsc(PortMappingDO::getId));
List<Integer> serverPorts = usePorts.stream().map(item -> item.getServerPort()).collect(Collectors.toList());
return list.stream().filter(item -> !serverPorts.contains(item.getPort())).collect(Collectors.toList());
}
public PortPoolUpdateRes update(PortPoolUpdateReq req) {
portPoolMapper.update(null, new LambdaUpdateWrapper<PortPoolDO>()
.eq(PortPoolDO::getId, req.getId())
.set(PortPoolDO::getGroupId, req.getGroupId())
.set(PortPoolDO::getUpdateTime, new Date())
);
return new PortPoolUpdateRes();
}
public PortPoolCreateRes create(PortPoolCreateReq req) {
Consumer<Integer> consumer = port -> {
PortPoolDO oldPortPoolDO = portPoolMapper.findByPort(port);
ParamCheckUtil.checkMustNull(oldPortPoolDO, PORT_CANNOT_REPEAT);
PortGroupDO portGroupDO = portGroupMapper.selectById(req.getGroupId());
ParamCheckUtil.checkNotNull(portGroupDO, PORT_GROUP_NAME_DOES_NOT_EXIST);
Date now = new Date();
portPoolMapper.insert(new PortPoolDO()
.setPort(port)
.setGroupId(req.getGroupId())
.setEnable(EnableStatusEnum.ENABLE.getStatus())
.setCreateTime(now)
.setUpdateTime(now)
);
// 更新visitorChannel
visitorChannelService.updateVisitorChannelByPortPool(port, EnableStatusEnum.ENABLE.getStatus());
};
String[] portArr = StringUtils.split(req.getPort(), "-");
if(portArr.length == 1){
Integer port = Integer.valueOf(portArr[0]);
consumer.accept(port);
}else if(portArr.length == 2){
int min = Integer.parseInt(portArr[0]),max = Integer.parseInt(portArr[1]);
for (int i = min; i <= max; i++) {
try {
consumer.accept(i);
} catch (Exception e) {
log.warn("bulk add port err:{}",e.getMessage());
}
}
}else{
throw ServiceException.create(PORT_RANGE_FAIL);
}
return new PortPoolCreateRes();
}
public PortPoolUpdateEnableStatusRes updateEnableStatus(PortPoolUpdateEnableStatusReq req) {
PortPoolDO portPoolDO = portPoolMapper.findById(req.getId());
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
portPoolMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
// 更新visitorChannel
visitorChannelService.updateVisitorChannelByPortPool(portPoolDO.getPort(), req.getEnable());
return new PortPoolUpdateEnableStatusRes();
}
public void delete(Integer id) {
PortPoolDO portPoolDO = portPoolMapper.findById(id);
ParamCheckUtil.checkNotNull(portPoolDO, ExceptionConstant.PORT_NOT_EXIST);
portPoolMapper.deleteById(id);
// 更新visitorChannel
visitorChannelService.updateVisitorChannelByPortPool(portPoolDO.getPort(), EnableStatusEnum.DISABLE.getStatus());
}
public List<PortPoolListRes> portListByGroupId(String groupId) {
List<PortPoolDO> portPoolDOList = portPoolMapper.getByGroupId(groupId);
List<PortPoolListRes> portPoolListReList = mapperFacade.mapAsList(portPoolDOList, PortPoolListRes.class);
return portPoolListReList;
}
public PortPoolUpdateGroupRes updateGroup(PortPoolUpdateGroupReq req) {
PortGroupDO portGroupDO = portGroupMapper.selectById(req.getGroupId());
if (Objects.isNull(portGroupDO)) {
throw ServiceException.create(ExceptionConstant.PARAMS_INVALID);
}
portPoolMapper.update(null, Wrappers.lambdaUpdate(PortPoolDO.class)
.in(PortPoolDO::getId, req.getPortIdList())
.set(PortPoolDO::getGroupId, req.getGroupId())
.set(PortPoolDO::getUpdateTime, new Date())
);
return new PortPoolUpdateGroupRes();
}
/**
* 管理员: 全局端口 + 当前选择的用户独占端口 + 当前选择license独占端口
* 游客:全局端口 + 当前选择用户独占端口 + 当前选择license独占端口
* 非管理员身份时:下拉选择license,只能选当前用户下的LICENSE
*/
public List<PortPoolListRes> getAvailablePortList(AvailablePortListReq req) {
LicenseDO licenseDO = licenseMapper.queryById(req.getLicenseId());
return portPoolMapper.getAvailablePortList(req.getLicenseId(), licenseDO.getUserId());
}
}
@@ -0,0 +1,70 @@
/**
* 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 org.dromara.neutrinoproxy.server.service;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.PortMappingMapper;
import org.dromara.neutrinoproxy.server.proxy.domain.CmdChannelAttachInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import java.util.Date;
/**
* 代理交互服务
* @author: aoshiguchen
* @date: 2022/9/3
*/
@Slf4j
@Component
public class ProxyMutualService {
@Db
private PortMappingMapper portMappingMapper;
@Db
private LicenseMapper licenseMapper;
/**
* 绑定服务端端口处理
* @param attachInfo
* @param serverPort
*/
public void bindServerPort(CmdChannelAttachInfo attachInfo, Integer serverPort) {
Date now = new Date();
portMappingMapper.updateOnlineStatus(attachInfo.getLicenseId(), serverPort, OnlineStatusEnum.ONLINE.getStatus(), now);
licenseMapper.updateOnlineStatus(attachInfo.getLicenseId(), OnlineStatusEnum.ONLINE.getStatus(), now);
log.info("绑定服务端端口 licenseId:{},ip:{},serverPort:{}", attachInfo.getLicenseId(), attachInfo.getIp(), serverPort);
}
/**
* 客户端下线
* @param attachInfo
*/
public void offline(CmdChannelAttachInfo attachInfo) {
Date now = new Date();
portMappingMapper.updateOnlineStatus(attachInfo.getLicenseId(), OnlineStatusEnum.OFFLINE.getStatus(), now);
licenseMapper.updateOnlineStatus(attachInfo.getLicenseId(), OnlineStatusEnum.OFFLINE.getStatus(), now);
log.info("客户端下线 licenseId:{},ip:{}", attachInfo.getLicenseId(), attachInfo.getIp());
}
}
@@ -0,0 +1,353 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.base.db.DbConfig;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.constant.Constants;
import org.dromara.neutrinoproxy.server.constant.OnlineStatusEnum;
import org.dromara.neutrinoproxy.server.controller.req.report.LicenseFlowMonthReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.LicenseFlowReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.UserFlowMonthReportReq;
import org.dromara.neutrinoproxy.server.controller.req.report.UserFlowReportReq;
import org.dromara.neutrinoproxy.server.controller.res.report.*;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.PortMappingMapper;
import org.dromara.neutrinoproxy.server.dal.ReportMapper;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.dromara.neutrinoproxy.server.service.bo.FlowBO;
import org.dromara.neutrinoproxy.server.service.bo.SingleDayFlowBO;
import org.dromara.neutrinoproxy.server.util.FormatUtil;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author: aoshiguchen
* @date: 2022/12/23
*/
@Slf4j
@Component
public class ReportService {
@Inject
private MapperFacade mapperFacade;
@Db
private ReportMapper reportMapper;
@Db
private LicenseMapper licenseMapper;
@Db
private PortMappingMapper portMappingMapper;
@Inject
private DbConfig dbConfig;
/**
* 首页图表
* @return
*/
public HomeDataView homeDataView() {
HomeDataView homeDataView = new HomeDataView();
homeDataView.setLicense(new HomeDataView.License().setTotalCount(0).setOnlineCount(0));
homeDataView.setPortMapping(new HomeDataView.PortMapping().setTotalCount(0).setOnlineCount(0));
homeDataView.setTodayFlow(new HomeDataView.TodayFlow().setUpFlowBytes(0L).setDownFlowBytes(0L));
homeDataView.setTotalFlow(new HomeDataView.TotalFlow().setUpFlowBytes(0L).setDownFlowBytes(0L));
// 查询license列表
List<LicenseDO> licenseDOList = licenseMapper.listAll();
if (CollectionUtil.isNotEmpty(licenseDOList)) {
homeDataView.getLicense().setTotalCount(licenseDOList.size());
homeDataView.getLicense().setOnlineCount((int)licenseDOList.stream().filter(e -> OnlineStatusEnum.ONLINE.getStatus().equals(e.getIsOnline())).count());
}
// 查询端口映射列表
List<PortMappingDO> portMappingDOList = portMappingMapper.selectList(new LambdaQueryWrapper<>());
if (CollectionUtil.isNotEmpty(portMappingDOList)) {
homeDataView.getPortMapping().setTotalCount(portMappingDOList.size());
homeDataView.getPortMapping().setOnlineCount((int)portMappingDOList.stream().filter(e -> OnlineStatusEnum.ONLINE.getStatus().equals(e.getIsOnline())).count());
}
// 今日流量
Date now = new Date();
FlowBO todayFlow = reportMapper.homeTodayFlow(DateUtil.getDayBegin(now), now);
homeDataView.setTodayFlow(mapperFacade.map(todayFlow, HomeDataView.TodayFlow.class));
// 总流量
FlowBO totalFlow = reportMapper.homeTotalFlow(DateUtil.getMonthBegin(now), DateUtil.getDayBegin(now), now);
homeDataView.setTotalFlow(mapperFacade.map(totalFlow, HomeDataView.TotalFlow.class));
// 最近n日流量
Integer days = Constants.HOME_FLOW_DAYS;
List<SingleDayFlowBO> last7dFlowList = reportMapper.homeLast7dFlowList(DateUtil.getDayBegin(DateUtil.addDate(now, Calendar.DATE, -(days - 1))), DateUtil.getDayBegin(now), now);
homeDataView.setLast7dFlow(new HomeDataView.Last7dFlow());
homeDataView.getLast7dFlow().setDataList(mapperFacade.mapAsList(last7dFlowList, HomeDataView.SingleDayFlow.class));
// 数据处理
fillHomeDataView(homeDataView, now);
return homeDataView;
}
/**
* 用户流量报表分页
* @param pageQuery
* @param req
* @return
*/
public PageInfo<UserFlowReportRes> userFlowReportPage(PageQuery pageQuery, UserFlowReportReq req) {
Page<UserFlowReportRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
Date now = new Date();
List<UserFlowReportRes> list = reportMapper.userFlowReportList(req.getUserId(), DateUtil.getMonthBegin(now), DateUtil.getDayBegin(now), now);
fillUserFlowReport(list);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
/**
* license流量报表分页
* @param pageQuery
* @param req
* @return
*/
public PageInfo<LicenseFlowReportRes> licenseFlowReportPage(PageQuery pageQuery, LicenseFlowReportReq req) {
Page<LicenseFlowReportRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
Date now = new Date();
List<LicenseFlowReportRes> list = reportMapper.licenseFLowReportList(req.getUserId(), DateUtil.getMonthBegin(now), DateUtil.getDayBegin(now), now);
fillLicenseFlowReport(list);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
/**
* 用户流量月度明细
* @param pageQuery
* @param req
* @return
*/
public PageInfo<UserFlowMonthReportRes> userFlowMonthReportPage(PageQuery pageQuery, UserFlowMonthReportReq req) {
Page<UserFlowMonthReportRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
Date now = new Date();
List<UserFlowMonthReportRes> list = reportMapper.userFlowMonthReportList(req.getUserId(), DateUtil.getMonthBegin(now), DateUtil.getDayBegin(now), now);
fillUserFlowMonthReport(list);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
/**
* license流量月度明细
* @param pageQuery
* @param req
* @return
*/
public PageInfo<LicenseFlowMonthReportRes> licenseFlowMonthReportPage(PageQuery pageQuery, LicenseFlowMonthReportReq req) {
Page<LicenseFlowMonthReportRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
Date now = new Date();
List<LicenseFlowMonthReportRes> list = reportMapper.licenseFLowMonthReportList(req.getUserId(), req.getLicenseId(), DateUtil.getMonthBegin(now), DateUtil.getDayBegin(now), now);
fillLicenseFlowMonthReport(list);
return PageInfo.of(list, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
private void fillUserFlowReport(List<UserFlowReportRes> list) {
if (CollectionUtil.isEmpty(list)) {
return;
}
for (UserFlowReportRes item : list) {
long upFlowBytes = (null == item.getUpFlowBytes()) ? 0 : item.getUpFlowBytes();
long downFlowBytes = (null == item.getDownFlowBytes()) ? 0 : item.getDownFlowBytes();
long totalFlowBytes = upFlowBytes + downFlowBytes;
item.setUpFlowBytes(upFlowBytes);
item.setDownFlowBytes(downFlowBytes);
item.setTotalFlowBytes(totalFlowBytes);
item.setUpFlowDesc(FormatUtil.getSizeDescByByteCount(upFlowBytes));
item.setDownFlowDesc(FormatUtil.getSizeDescByByteCount(downFlowBytes));
item.setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(totalFlowBytes));
}
}
private void fillLicenseFlowReport(List<LicenseFlowReportRes> list) {
if (CollectionUtil.isEmpty(list)) {
return;
}
for (LicenseFlowReportRes item : list) {
long upFlowBytes = (null == item.getUpFlowBytes()) ? 0 : item.getUpFlowBytes();
long downFlowBytes = (null == item.getDownFlowBytes()) ? 0 : item.getDownFlowBytes();
long totalFlowBytes = upFlowBytes + downFlowBytes;
item.setUpFlowBytes(upFlowBytes);
item.setDownFlowBytes(downFlowBytes);
item.setTotalFlowBytes(totalFlowBytes);
item.setUpFlowDesc(FormatUtil.getSizeDescByByteCount(upFlowBytes));
item.setDownFlowDesc(FormatUtil.getSizeDescByByteCount(downFlowBytes));
item.setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(totalFlowBytes));
}
}
private void fillUserFlowMonthReport(List<UserFlowMonthReportRes> list) {
if (CollectionUtil.isEmpty(list)) {
return;
}
for (UserFlowMonthReportRes item : list) {
long upFlowBytes = (null == item.getUpFlowBytes()) ? 0 : item.getUpFlowBytes();
long downFlowBytes = (null == item.getDownFlowBytes()) ? 0 : item.getDownFlowBytes();
long totalFlowBytes = upFlowBytes + downFlowBytes;
item.setUpFlowBytes(upFlowBytes);
item.setDownFlowBytes(downFlowBytes);
item.setTotalFlowBytes(totalFlowBytes);
item.setUpFlowDesc(FormatUtil.getSizeDescByByteCount(upFlowBytes));
item.setDownFlowDesc(FormatUtil.getSizeDescByByteCount(downFlowBytes));
item.setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(totalFlowBytes));
}
}
private void fillLicenseFlowMonthReport(List<LicenseFlowMonthReportRes> list) {
if (CollectionUtil.isEmpty(list)) {
return;
}
for (LicenseFlowMonthReportRes item : list) {
long upFlowBytes = (null == item.getUpFlowBytes()) ? 0 : item.getUpFlowBytes();
long downFlowBytes = (null == item.getDownFlowBytes()) ? 0 : item.getDownFlowBytes();
long totalFlowBytes = upFlowBytes + downFlowBytes;
item.setUpFlowBytes(upFlowBytes);
item.setDownFlowBytes(downFlowBytes);
item.setTotalFlowBytes(totalFlowBytes);
item.setUpFlowDesc(FormatUtil.getSizeDescByByteCount(upFlowBytes));
item.setDownFlowDesc(FormatUtil.getSizeDescByByteCount(downFlowBytes));
item.setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(totalFlowBytes));
}
}
private void fillHomeDataView(HomeDataView homeDataView, Date now) {
if (null == homeDataView) {
return;
}
// License
if (null == homeDataView.getLicense()) {
homeDataView.setLicense(new HomeDataView.License());
}
if (null == homeDataView.getLicense().getTotalCount()) {
homeDataView.getLicense().setTotalCount(0);
}
if (null == homeDataView.getLicense().getOnlineCount()) {
homeDataView.getLicense().setOnlineCount(0);
}
homeDataView.getLicense().setOfflineCount(homeDataView.getLicense().getTotalCount() - homeDataView.getLicense().getOnlineCount());
// PortMapping
if (null == homeDataView.getPortMapping()) {
homeDataView.setPortMapping(new HomeDataView.PortMapping());
}
if (null == homeDataView.getPortMapping().getTotalCount()) {
homeDataView.getPortMapping().setTotalCount(0);
}
if (null == homeDataView.getPortMapping().getOnlineCount()) {
homeDataView.getPortMapping().setOnlineCount(0);
}
homeDataView.getPortMapping().setOfflineCount(homeDataView.getPortMapping().getTotalCount() - homeDataView.getPortMapping().getOnlineCount());
// TodayFlow
if (null == homeDataView.getTodayFlow()) {
homeDataView.setTodayFlow(new HomeDataView.TodayFlow());
}
if (null == homeDataView.getTodayFlow().getUpFlowBytes()) {
homeDataView.getTodayFlow().setUpFlowBytes(0L);
}
if (null == homeDataView.getTodayFlow().getDownFlowBytes()) {
homeDataView.getTodayFlow().setDownFlowBytes(0L);
}
homeDataView.getTodayFlow().setTotalFlowBytes(homeDataView.getTodayFlow().getUpFlowBytes() + homeDataView.getTodayFlow().getDownFlowBytes());
homeDataView.getTodayFlow().setUpFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTodayFlow().getUpFlowBytes()));
homeDataView.getTodayFlow().setDownFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTodayFlow().getDownFlowBytes()));
homeDataView.getTodayFlow().setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTodayFlow().getTotalFlowBytes()));
// TotalFlow
if (null == homeDataView.getTotalFlow()) {
homeDataView.setTotalFlow(new HomeDataView.TotalFlow());
}
if (null == homeDataView.getTotalFlow().getUpFlowBytes()) {
homeDataView.getTotalFlow().setUpFlowBytes(0L);
}
if (null == homeDataView.getTotalFlow().getDownFlowBytes()) {
homeDataView.getTotalFlow().setDownFlowBytes(0L);
}
homeDataView.getTotalFlow().setTotalFlowBytes(homeDataView.getTotalFlow().getUpFlowBytes() + homeDataView.getTotalFlow().getDownFlowBytes());
homeDataView.getTotalFlow().setUpFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTotalFlow().getUpFlowBytes()));
homeDataView.getTotalFlow().setDownFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTotalFlow().getDownFlowBytes()));
homeDataView.getTotalFlow().setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(homeDataView.getTotalFlow().getTotalFlowBytes()));
// 最近N日流量
Integer days = Constants.HOME_FLOW_DAYS;
HomeDataView.Last7dFlow last7dFlow = homeDataView.getLast7dFlow();
if (null == last7dFlow) {
last7dFlow = new HomeDataView.Last7dFlow();
homeDataView.setLast7dFlow(last7dFlow);
}
if (null == last7dFlow.getDataList()) {
last7dFlow.setDataList(Collections.emptyList());
}
// 数据列表
Set<String> existDateStrList = new HashSet<>();
if (CollectionUtil.isNotEmpty(last7dFlow.getDataList())) {
for (HomeDataView.SingleDayFlow singleDayFlow : last7dFlow.getDataList()) {
if (null == singleDayFlow.getUpFlowBytes()) {
singleDayFlow.setUpFlowBytes(0L);
}
if (null == singleDayFlow.getDownFlowBytes()) {
singleDayFlow.setDownFlowBytes(0L);
}
singleDayFlow.setTotalFlowBytes(singleDayFlow.getUpFlowBytes() + singleDayFlow.getDownFlowBytes());
singleDayFlow.setUpFlowDesc(FormatUtil.getSizeDescByByteCount(singleDayFlow.getUpFlowBytes()));
singleDayFlow.setDownFlowDesc(FormatUtil.getSizeDescByByteCount(singleDayFlow.getDownFlowBytes()));
singleDayFlow.setTotalFlowDesc(FormatUtil.getSizeDescByByteCount(singleDayFlow.getTotalFlowBytes()));
singleDayFlow.setDateStr(DateUtil.format(singleDayFlow.getDate(), "yyyy-MM-dd"));
existDateStrList.add(singleDayFlow.getDateStr());
}
}
// 获取最近7天的日期字符串列表。防止因统计数据缺失,造成图表展示错误的问题,缺失的日期数据,自动填充0
List<String> dateList = DateUtil.getBetweenTimes(DateUtil.format(DateUtil.addDate(now, Calendar.DATE, -(days - 1)), "yyyy-MM-dd"), DateUtil.format(now, "yyyy-MM-dd"));
for (String dateStr : dateList) {
if (existDateStrList.contains(dateStr)) {
continue;
}
last7dFlow.getDataList().add(new HomeDataView.SingleDayFlow()
.setDate(DateUtil.parse(dateStr, "yyyy-MM-dd"))
.setDateStr(dateStr)
.setUpFlowBytes(0L)
.setUpFlowDesc("0B")
.setDownFlowBytes(0L)
.setDownFlowDesc("0B")
.setTotalFlowBytes(0L)
.setTotalFlowDesc("0B")
);
}
// 按日期升序
Collections.sort(last7dFlow.getDataList(), Comparator.comparing(HomeDataView.SingleDayFlow::getDate));
// x轴日期
last7dFlow.setXDate(last7dFlow.getDataList().stream().map(HomeDataView.SingleDayFlow::getDateStr).collect(Collectors.toList()));
// 图例
last7dFlow.setLegendData(Lists.newArrayList("上行流量", "下行流量", "总流量"));
// 折线图
List<HomeDataView.Series> seriesList = Lists.newArrayList();
last7dFlow.setSeriesList(seriesList);
// 上行流量折线
seriesList.add(new HomeDataView.Series()
.setSeriesType("line")
.setSeriesName(last7dFlow.getLegendData().get(0))
.setSeriesData(last7dFlow.getDataList().stream().map(HomeDataView.SingleDayFlow::getUpFlowBytes).collect(Collectors.toList()))
);
// 下行流量折线
seriesList.add(new HomeDataView.Series()
.setSeriesType("line")
.setSeriesName(last7dFlow.getLegendData().get(1))
.setSeriesData(last7dFlow.getDataList().stream().map(HomeDataView.SingleDayFlow::getDownFlowBytes).collect(Collectors.toList()))
);
// 总流量折线
seriesList.add(new HomeDataView.Series()
.setSeriesType("line")
.setSeriesName(last7dFlow.getLegendData().get(2))
.setSeriesData(last7dFlow.getDataList().stream().map(HomeDataView.SingleDayFlow::getTotalFlowBytes).collect(Collectors.toList()))
);
}
}
@@ -0,0 +1,65 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.controller.req.log.UserLoginRecordListReq;
import org.dromara.neutrinoproxy.server.controller.res.log.UserLoginRecordListRes;
import org.dromara.neutrinoproxy.server.dal.UserLoginRecordMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserLoginRecordDO;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 用户登录日志
* @author: aoshiguchen
* @date: 2022/10/20
*/
@Component
public class UserLoginRecordService {
@Inject
private MapperFacade mapperFacade;
@Db
private UserLoginRecordMapper userLoginRecordMapper;
@Db
private UserMapper userMapper;
public PageInfo<UserLoginRecordListRes> page(PageQuery pageQuery, UserLoginRecordListReq req) {
Page<UserLoginRecordListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<UserLoginRecordDO> list = userLoginRecordMapper.selectList(new LambdaQueryWrapper<UserLoginRecordDO>()
.eq(null != req.getUserId(), UserLoginRecordDO::getUserId, req.getUserId())
.orderByDesc(UserLoginRecordDO::getCreateTime)
);
List<UserLoginRecordListRes> respList = mapperFacade.mapAsList(list, UserLoginRecordListRes.class);
if (CollectionUtils.isEmpty(list)) {
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
if (!CollectionUtil.isEmpty(respList)) {
Set<Integer> userIds = respList.stream().map(UserLoginRecordListRes::getUserId).collect(Collectors.toSet());
List<UserDO> userList = userMapper.findByIds(userIds);
Map<Integer, UserDO> userMap = userList.stream().collect(Collectors.toMap(UserDO::getId, Function.identity()));
for (UserLoginRecordListRes item : respList) {
UserDO userDO = userMap.get(item.getUserId());
if (null != userDO) {
item.setUserName(userDO.getName());
}
}
}
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
}
@@ -0,0 +1,205 @@
package org.dromara.neutrinoproxy.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 org.dromara.neutrinoproxy.core.util.DateUtil;
import org.dromara.neutrinoproxy.server.base.page.PageInfo;
import org.dromara.neutrinoproxy.server.base.page.PageQuery;
import org.dromara.neutrinoproxy.server.base.rest.ServiceException;
import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.controller.req.system.*;
import org.dromara.neutrinoproxy.server.controller.res.system.*;
import org.dromara.neutrinoproxy.server.dal.UserLoginRecordMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.UserTokenMapper;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserLoginRecordDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserTokenDO;
import org.dromara.neutrinoproxy.server.util.Md5Util;
import org.dromara.neutrinoproxy.server.util.ParamCheckUtil;
import ma.glasnost.orika.MapperFacade;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
*
* @author: aoshiguchen
* @date: 2022/7/31
*/
@Component
public class UserService {
private static final String DEFAULT_PASSWORD = "123456";
@Inject
private MapperFacade mapperFacade;
@Db
private UserMapper userMapper;
@Db
private UserTokenMapper userTokenMapper;
@Db
private UserLoginRecordMapper userLoginRecordMapper;
@Inject
private VisitorChannelService visitorChannelService;
public LoginRes login(LoginReq req) {
UserDO userDO = userMapper.findByLoginName(req.getLoginName());
if (null == userDO || !Md5Util.encode(req.getLoginPassword()).equals(userDO.getLoginPassword())) {
throw ServiceException.create(ExceptionConstant.USER_NAME_OR_PASSWORD_ERROR);
}
if (EnableStatusEnum.DISABLE.getStatus().equals(userDO.getEnable())) {
throw ServiceException.create(ExceptionConstant.USER_DISABLE);
}
String token = UUID.randomUUID().toString().replaceAll("-", "");
Date now = new Date();
Date expirationTime = DateUtil.addDate(now, Calendar.HOUR, 1);
// 缓存token
userTokenMapper.insert(new UserTokenDO()
.setToken(token)
.setUserId(userDO.getId())
.setExpirationTime(expirationTime)
.setCreateTime(now)
.setUpdateTime(now)
);
// 新增用户登录日志
userLoginRecordMapper.insert(new UserLoginRecordDO()
.setUserId(userDO.getId())
.setIp(SystemContextHolder.getIp())
.setToken(token)
.setType(UserLoginRecordDO.TYPE_LOGIN)
.setCreateTime(now)
);
return new LoginRes()
.setToken(token)
.setUserId(userDO.getId())
.setUserName(userDO.getName());
}
public void logout() {
userTokenMapper.deleteByToken(SystemContextHolder.getToken());
// 新增用户登录日志
userLoginRecordMapper.insert(new UserLoginRecordDO()
.setUserId(SystemContextHolder.getUser().getId())
.setIp(SystemContextHolder.getIp())
.setToken(SystemContextHolder.getToken())
.setType(UserLoginRecordDO.TYPE_LOGOUT)
.setCreateTime(new Date())
);
}
public UserDO findByToken(String token) {
Date now = new Date();
UserTokenDO userTokenDO = userTokenMapper.findByAvailableToken(token, now);
if (null == userTokenDO) {
return null;
}
return userMapper.findById(userTokenDO.getUserId());
}
public UserDO findById(Integer id) {
return userMapper.findById(id);
}
public void updateTokenExpirationTime(String token) {
Date now = new Date();
Date expirationTime = DateUtil.addDate(now, Calendar.HOUR, 1);
userTokenMapper.updateTokenExpirationTime(token, expirationTime);
}
public PageInfo<UserListRes> page(PageQuery pageQuery, UserListReq req) {
Page<UserListRes> result = PageHelper.startPage(pageQuery.getCurrent(), pageQuery.getSize());
List<UserDO> list = userMapper.selectList(new LambdaQueryWrapper<UserDO>()
.orderByAsc(UserDO::getId)
);
List<UserListRes> respList = mapperFacade.mapAsList(list, UserListRes.class);
return PageInfo.of(respList, result.getTotal(), pageQuery.getCurrent(), pageQuery.getSize());
}
public List<UserListRes> list(UserListReq req) {
List<UserDO> userDOList = userMapper.selectList(new LambdaQueryWrapper<UserDO>()
.eq(UserDO::getEnable, EnableStatusEnum.ENABLE.getStatus())
.orderByAsc(UserDO::getId)
);
return mapperFacade.mapAsList(userDOList, UserListRes.class);
}
public UserInfoRes info(UserInfoReq req) {
Integer userId = req.getId();
if (null == userId) {
userId = SystemContextHolder.getUser().getId();
}
UserDO userDO = userMapper.findById(userId);
if (null == userDO) {
return null;
}
return new UserInfoRes()
.setId(userDO.getId())
.setName(userDO.getName())
.setLoginName(userDO.getLoginName())
.setCreateTime(userDO.getCreateTime())
.setUpdateTime(userDO.getUpdateTime());
}
public UserUpdateEnableStatusRes updateEnableStatus(UserUpdateEnableStatusReq req) {
userMapper.updateEnableStatus(req.getId(), req.getEnable(), new Date());
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByUserId(req.getId(), req.getEnable());
return new UserUpdateEnableStatusRes();
}
public UserCreateRes create(UserCreateReq req) {
Date now = new Date();
UserDO userDO = new UserDO();
userDO.setName(req.getName());
userDO.setLoginName(req.getLoginName());
userDO.setLoginPassword(Md5Util.encode(DEFAULT_PASSWORD));
userDO.setEnable(EnableStatusEnum.ENABLE.getStatus());
userDO.setCreateTime(now);
userDO.setUpdateTime(now);
userMapper.insert(userDO);
return new UserCreateRes();
}
public UserUpdateRes update(UserUpdateReq req) {
userMapper.update(null, new LambdaUpdateWrapper<UserDO>()
.eq(UserDO::getId, req.getId())
.set(UserDO::getName, req.getName())
.set(UserDO::getLoginName, req.getLoginName())
.set(UserDO::getUpdateTime, new Date())
);
return new UserUpdateRes();
}
public UserUpdatePasswordRes updatePassword(UserUpdatePasswordReq req) {
UserDO userDO = userMapper.findById(req.getId());
// 更新密码
String loginPassword = Md5Util.encode(req.getLoginPassword());
ParamCheckUtil.checkExpression(!userDO.getLoginPassword().equals(loginPassword), ExceptionConstant.LOGIN_PASSWORD_NO_CHANGE_MODIFY_FAIL);
userMapper.updateLoginPassword(req.getId(), loginPassword, new Date());
// 删除该用户所有token
userTokenMapper.deleteByUserId(req.getId());
return new UserUpdatePasswordRes();
}
public void delete(Integer id) {
userMapper.deleteById(id);
// 更新VisitorChannel
visitorChannelService.updateVisitorChannelByUserId(id, EnableStatusEnum.DISABLE.getStatus());
}
}
@@ -0,0 +1,244 @@
package org.dromara.neutrinoproxy.server.service;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.dromara.neutrinoproxy.core.Constants;
import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum;
import org.dromara.neutrinoproxy.server.dal.LicenseMapper;
import org.dromara.neutrinoproxy.server.dal.PortMappingMapper;
import org.dromara.neutrinoproxy.server.dal.PortPoolMapper;
import org.dromara.neutrinoproxy.server.dal.UserMapper;
import org.dromara.neutrinoproxy.server.dal.entity.LicenseDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortMappingDO;
import org.dromara.neutrinoproxy.server.dal.entity.PortPoolDO;
import org.dromara.neutrinoproxy.server.dal.entity.UserDO;
import org.dromara.neutrinoproxy.server.proxy.core.BytesMetricsHandler;
import org.dromara.neutrinoproxy.server.proxy.core.VisitorChannelHandler;
import org.dromara.neutrinoproxy.server.proxy.domain.CmdChannelAttachInfo;
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
import org.dromara.neutrinoproxy.server.util.ProxyUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.solon.annotation.Db;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import java.net.BindException;
import java.util.List;
import java.util.stream.Collectors;
/**
* 访问者通道服务
* @author: aoshiguchen
* @date: 2023/2/5
*/
@Slf4j
@Component
public class VisitorChannelService {
@Inject("serverBossGroup")
private NioEventLoopGroup serverBossGroup;
@Inject("serverWorkerGroup")
private NioEventLoopGroup serverWorkerGroup;
@Inject
private ProxyMutualService proxyMutualService;
@Db
private UserMapper userMapper;
@Db
private LicenseMapper licenseMapper;
@Db
private PortMappingMapper portMappingMapper;
@Db
private PortPoolMapper portPoolMapper;
/**
* 初始化
* @param licenseId
*/
public void initVisitorChannel(Integer licenseId, Channel cmdChannel) {
List<PortMappingDO> portMappingList = portMappingMapper.findEnableListByLicenseId(licenseId);
// 没有端口映射仍然保持连接
ProxyUtil.initProxyInfo(licenseId, ProxyMapping.buildList(portMappingList));
ProxyUtil.addCmdChannel(licenseId, cmdChannel, portMappingList.stream().map(PortMappingDO::getServerPort).collect(Collectors.toSet()));
startUserPortServer(ProxyUtil.getAttachInfo(cmdChannel), portMappingList);
}
/**
* 更新
* 触发时机:删除端口池、禁用端口池、启用端口池
* @param serverPort
* @param enable
*/
public void updateVisitorChannelByPortPool(Integer serverPort, Integer enable) {
if (null == serverPort) {
return;
}
List<PortMappingDO> portMappingDOList = portMappingMapper.findListByServerPort(serverPort);
if (CollectionUtil.isEmpty(portMappingDOList)) {
return;
}
EnableStatusEnum enableStatusEnum = EnableStatusEnum.of(enable);
for (PortMappingDO portMappingDO : portMappingDOList) {
if (EnableStatusEnum.DISABLE == enableStatusEnum) {
removeVisitorChannelByPortMapping(portMappingDO);
} else if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(portMappingDO.getEnable())) {
addVisitorChannelByPortMapping(portMappingDO);
}
}
}
/**
* 更新
* 触发时机:删除用户、禁用用户、启用用户 (新增、修改用户不涉及VisitorChannel的变更)
* @param userId
*/
public void updateVisitorChannelByUserId(Integer userId, Integer enable) {
if (null == userId) {
return;
}
List<LicenseDO> licenseDOList = licenseMapper.listByUserId(userId);
if (CollectionUtil.isEmpty(licenseDOList)) {
return;
}
for (LicenseDO licenseDO : licenseDOList) {
updateVisitorChannelByLicenseId(licenseDO.getId(), enable);
}
}
/**
* 更新
* 触发时机:删除license、禁用license、启用license (新增、修改license不涉及VisitorChannel的变更)
* 重置licenseKey,不会立即影响已经连接成功的license,如果想要立即影响,请先进行禁用
* @param licenseId
*/
public void updateVisitorChannelByLicenseId(Integer licenseId, Integer enable) {
if (null == licenseId) {
return;
}
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(licenseId);
if (null == cmdChannel) {
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
return;
}
EnableStatusEnum enableStatusEnum = EnableStatusEnum.of(enable);
List<PortMappingDO> portMappingDOList = portMappingMapper.findListByLicenseId(licenseId);
if (!CollectionUtil.isEmpty(portMappingDOList)) {
for (PortMappingDO portMappingDO : portMappingDOList) {
if (EnableStatusEnum.DISABLE == enableStatusEnum) {
removeVisitorChannelByPortMapping(portMappingDO);
} else if (EnableStatusEnum.ENABLE == EnableStatusEnum.of(portMappingDO.getEnable())) {
addVisitorChannelByPortMapping(portMappingDO);
}
}
}
}
/**
* 更新
* 触发时机:修改端口映射
* @param oldPortMappingDO
* @param newPortMappingDO
*/
public void updateVisitorChannelByPortMapping(PortMappingDO oldPortMappingDO, PortMappingDO newPortMappingDO) {
if (null == oldPortMappingDO || null == newPortMappingDO) {
return;
}
removeVisitorChannelByPortMapping(oldPortMappingDO);
addVisitorChannelByPortMapping(newPortMappingDO);
}
/**
* 新增VisitorChannel
* 触发时机:新增端口映射、启用端口映射
* @param portMappingDO
*/
public void addVisitorChannelByPortMapping(PortMappingDO portMappingDO) {
if (null == portMappingDO) {
return;
}
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(portMappingDO.getLicenseId());
if (null == cmdChannel) {
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
return;
}
// 判断端口映射是否启用
if (EnableStatusEnum.DISABLE != EnableStatusEnum.of(portMappingDO.getEnable())) {
LicenseDO licenseDO = licenseMapper.findById(portMappingDO.getLicenseId());
// 判断license是否启用
if (null != licenseDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(licenseDO.getEnable())) {
UserDO userDO = userMapper.findById(licenseDO.getUserId());
// 判断用户是否启用
if (null != userDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(userDO.getEnable())) {
PortPoolDO portPoolDO = portPoolMapper.findByPort(portMappingDO.getServerPort());
// 判断端口池是否启用
if (null != portPoolDO && EnableStatusEnum.ENABLE == EnableStatusEnum.of(portPoolDO.getEnable())) {
// 未删除且未禁用,则开启代理
ProxyUtil.addProxyInfo(portMappingDO.getLicenseId(), ProxyMapping.build(portMappingDO));
ProxyUtil.addCmdChannel(portMappingDO.getLicenseId(), cmdChannel, Sets.newHashSet(portMappingDO.getServerPort()));
startUserPortServer(ProxyUtil.getAttachInfo(cmdChannel), Lists.newArrayList(portMappingDO));
}
}
}
}
}
/**
* 删除VisitorChannel
* 触发时机:删除端口映射、禁用端口映射
* @param portMappingDO
*/
public void removeVisitorChannelByPortMapping(PortMappingDO portMappingDO) {
if (null == portMappingDO) {
return;
}
Channel cmdChannel = ProxyUtil.getCmdChannelByLicenseId(portMappingDO.getLicenseId());
if (null == cmdChannel) {
// 如果不存在有效的cmdChannel,则无需更新VisitorChannel
return;
}
Channel visitorChannel = ProxyUtil.getVisitorChannelByServerPort(portMappingDO.getServerPort());
if (null != visitorChannel) {
Channel proxyChannel = visitorChannel.attr(Constants.NEXT_CHANNEL).get();
if (null != proxyChannel) {
proxyChannel.close();
}
visitorChannel.close();
}
ProxyUtil.removeProxyInfo(portMappingDO.getServerPort());
}
private void startUserPortServer(CmdChannelAttachInfo cmdChannelAttachInfo, List<PortMappingDO> portMappingList) {
if (CollectionUtil.isEmpty(portMappingList)) {
return;
}
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(serverBossGroup, serverWorkerGroup)
.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addFirst(new BytesMetricsHandler());
ch.pipeline().addLast(new VisitorChannelHandler());
}
});
for (PortMappingDO portMapping : portMappingList) {
try {
proxyMutualService.bindServerPort(cmdChannelAttachInfo, portMapping.getServerPort());
bootstrap.bind(portMapping.getServerPort()).get();
log.info("绑定用户端口: {}", portMapping.getServerPort());
} catch (Exception ex) {
// BindException表示该端口已经绑定过
if (!(ex.getCause() instanceof BindException)) {
throw new RuntimeException(ex);
}
}
}
}
}
@@ -0,0 +1,19 @@
package org.dromara.neutrinoproxy.server.service.bo;
import lombok.Data;
/**
* @author: aoshiguchen
* @date: 2023/3/26
*/
@Data
public class FlowBO {
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
}
@@ -0,0 +1,26 @@
package org.dromara.neutrinoproxy.server.service.bo;
import lombok.Data;
import java.util.Date;
/**
* 单日流量
* @author: aoshiguchen
* @date: 2023/3/26
*/
@Data
public class SingleDayFlowBO {
/**
* 日期
*/
private Date date;
/**
* 上行流量字节数
*/
private Long upFlowBytes;
/**
* 下行流量字节数
*/
private Long downFlowBytes;
}
@@ -0,0 +1,49 @@
package org.dromara.neutrinoproxy.server.util;
/**
* @author: aoshiguchen
* @date: 2023/3/19
*/
public class FormatUtil {
private static final String[] SIZE_UNINTS = {"B", "KB", "MB", "GB", "TB"};
private static final int SIZE_SYSTEM = 1024;
/**
* 根据字节数获取大小描述
* 1、小于1024字节的以B为单位
* 2、小于1024KB的以KB为单位
* 3、小于1024M的以MB为单位
* 4、小于1024G的以GB为单位
* 5、其他以TB为单位
* @param byteCount
* @return
*/
public static String getSizeDescByByteCount(long byteCount){
if(byteCount <= 0){
return "0B";
}
double res = byteCount;
int index = 0;
while (index < SIZE_UNINTS.length && res >= SIZE_SYSTEM){
res /= SIZE_SYSTEM;
index++;
}
if(index >= SIZE_UNINTS.length){
index = SIZE_UNINTS.length - 1;
res *= 1024;
}
return trimZero(String.format("%.2f", res)) + SIZE_UNINTS[index];
}
private static String trimZero(String s) {
if (s.indexOf(".") > 0) {
// 去掉多余的0
s = s.replaceAll("0+?$", "");
// 如最后一位是.则去掉
s = s.replaceAll("[.]$", "");
}
return s;
}
}
@@ -0,0 +1,50 @@
/**
* 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 org.dromara.neutrinoproxy.server.util;
import java.math.BigInteger;
import java.security.MessageDigest;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
public class Md5Util {
/**
* md5加密
* @param data
* @return
*/
public static String encode(String data) {
byte[] digest = null;
try {
MessageDigest md5 = MessageDigest.getInstance("md5");
digest = md5.digest(data.getBytes("utf-8"));
return new BigInteger(1, digest).toString(16);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,90 @@
package org.dromara.neutrinoproxy.server.util;
import cn.hutool.core.util.StrUtil;
import org.dromara.neutrinoproxy.server.constant.ExceptionConstant;
import org.dromara.neutrinoproxy.server.base.rest.ServiceException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
/**
*
* @author: aoshiguchen
* @date: 2022/8/1
*/
public class ParamCheckUtil {
public static void checkNotNull(Object obj, String name) {
if (null == obj) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_NULL, name);
}
}
public static void checkNotEmpty(String str, String name) {
if (StrUtil.isEmpty(str)) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_EMPTY, name);
}
}
public static void checkNotEmpty(Collection collection, String name) {
if (null == collection || collection.isEmpty()) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_EMPTY, name);
}
}
public static void checkNotEmpty(Map map, String name) {
if (null == map || map.isEmpty()) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_EMPTY, name);
}
}
public static void checkNotEmpty(Set set, String name) {
if (null == set || set.isEmpty()) {
throw ServiceException.create(ExceptionConstant.PARAMS_NOT_EMPTY, name);
}
}
public static void checkMustNull(Object obj, ExceptionConstant constant, Object... params) {
if (null != obj) {
throw ServiceException.create(constant, params);
}
}
public static void checkNotNull(Object obj, ExceptionConstant constant, Object... params) {
if (null == obj) {
throw ServiceException.create(constant, params);
}
}
public static void checkNotEmpty(String str, ExceptionConstant constant, Object... params) {
if (StrUtil.isEmpty(str)) {
throw ServiceException.create(constant, params);
}
}
public static void checkNotEmpty(Collection collection, ExceptionConstant constant, Object... params) {
if (null == collection || collection.isEmpty()) {
throw ServiceException.create(constant, params);
}
}
public static void checkNotEmpty(Map map, ExceptionConstant constant, Object... params) {
if (null == map || map.isEmpty()) {
throw ServiceException.create(constant, params);
}
}
public static void checkNotEmpty(Set set, ExceptionConstant constant, Object... params) {
if (null == set || set.isEmpty()) {
throw ServiceException.create(constant, params);
}
}
public static void checkExpression(boolean expression, ExceptionConstant constant, Object... params) {
if (!expression) {
throw ServiceException.create(constant, params);
}
}
}
@@ -0,0 +1,281 @@
package org.dromara.neutrinoproxy.server.util;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Sets;
import org.dromara.neutrinoproxy.core.ChannelAttribute;
import org.dromara.neutrinoproxy.server.proxy.domain.CmdChannelAttachInfo;
import org.dromara.neutrinoproxy.server.proxy.domain.ProxyMapping;
import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
*
* @author: aoshiguchen
* @date: 2022/8/30
*/
public class ProxyUtil {
public static final AttributeKey<ChannelAttribute> CHANNEL_ATTR_KEY = AttributeKey.valueOf("netty.channel.attr");
/**
* license -> 服务端口映射
*/
private static final Map<Integer, Set<Integer>> licenseToServerPortMap = new HashMap<>();
/**
* 代理信息映射
*/
private static final Map<Integer, String> proxyInfoMap = new ConcurrentHashMap<>();
/**
* 服务端口 -> 指令通道映射
*/
private static Map<Integer, Channel> serverPortToCmdChannelMap = new ConcurrentHashMap<>();
/**
* license -> 指令通道映射
*/
private static Map<Integer, Channel> licenseToCmdChannelMap = new ConcurrentHashMap<>();
/**
* 服务端口 -> 访问通道映射
*/
private static Map<Integer, Channel> serverPortToVisitorChannel = new ConcurrentHashMap<>();
/**
* cmdChannelAttachInfo.getUserChannelMap() 读写锁
*/
private static final ReadWriteLock userChannelMapLock = new ReentrantReadWriteLock();
/**
* 初始化代理信息
* @param licenseId licenseId
* @param proxyMappingList 代理映射集合
*/
public static void initProxyInfo(Integer licenseId, List<ProxyMapping> proxyMappingList) {
licenseToServerPortMap.put(licenseId, new HashSet<>());
addProxyInfo(licenseId, proxyMappingList);
}
public static void addProxyInfo(Integer licenseId, List<ProxyMapping> proxyMappingList) {
if (!CollectionUtil.isEmpty(proxyMappingList)) {
for (ProxyMapping proxyMapping : proxyMappingList) {
licenseToServerPortMap.get(licenseId).add(proxyMapping.getServerPort());
proxyInfoMap.put(proxyMapping.getServerPort(), proxyMapping.getLanInfo());
}
}
}
public static void addProxyInfo(Integer licenseId, ProxyMapping proxyMapping) {
if (null == licenseId || null == proxyMapping) {
return;
}
licenseToServerPortMap.get(licenseId).add(proxyMapping.getServerPort());
proxyInfoMap.put(proxyMapping.getServerPort(), proxyMapping.getLanInfo());
}
public static void removeProxyInfo(Integer serverPort) {
proxyInfoMap.remove(serverPort);
}
/**
* 根据licenseId获取服务端端口集合
* @param licenseId licenseId
* @return 服务端端口集合
*/
public static Set<Integer> getServerPortsByLicenseKey(Integer licenseId) {
return licenseToServerPortMap.get(licenseId);
}
/**
* 根据服务端端口获取客户端代理信息
* @param serverPort 服务端端口
* @return 客户端代理信息
*/
public static String getClientLanInfoByServerPort(Integer serverPort) {
return proxyInfoMap.get(serverPort);
}
/**
* 添加指令通道相关缓存信息
* @param licenseId licenseId
* @param cmdChannel 指令通道
* @param serverPorts 服务端端口集合
*/
public static void addCmdChannel(Integer licenseId, Channel cmdChannel, Set<Integer> serverPorts) {
if (!CollectionUtil.isEmpty(serverPorts)) {
for (int port : serverPorts) {
serverPortToCmdChannelMap.put(port, cmdChannel);
}
}
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
if (null == cmdChannelAttachInfo) {
cmdChannelAttachInfo = new CmdChannelAttachInfo()
.setIp(((InetSocketAddress)cmdChannel.remoteAddress()).getAddress().getHostAddress())
.setLicenseId(licenseId)
.setVisitorChannelMap(new HashMap<>(16))
.setServerPorts(Sets.newHashSet());
setAttachInfo(cmdChannel, cmdChannelAttachInfo);
}
if (!CollectionUtil.isEmpty(serverPorts)) {
cmdChannelAttachInfo.getServerPorts().addAll(serverPorts);
}
licenseToCmdChannelMap.put(licenseId, cmdChannel);
}
/**
* 删除指令通道相关缓存信息
* @param cmdChannel 指令通道
*/
public static void removeCmdChannel(Channel cmdChannel) {
if (null == cmdChannel || null == getAttachInfo(cmdChannel)) {
return;
}
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
Channel channel0 = licenseToCmdChannelMap.remove(cmdChannelAttachInfo.getLicenseId());
if (cmdChannel != channel0) {
licenseToCmdChannelMap.put(cmdChannelAttachInfo.getLicenseId(), cmdChannel);
}
for (int port : cmdChannelAttachInfo.getServerPorts()) {
Channel proxyChannel = serverPortToCmdChannelMap.remove(port);
if (proxyChannel == null) {
continue;
}
// 在执行断连之前新的连接已经连上来了
if (proxyChannel != cmdChannel) {
serverPortToCmdChannelMap.put(port, proxyChannel);
}
}
if (cmdChannel.isActive()) {
cmdChannel.close();
}
Map<String, Channel> userChannels = cmdChannelAttachInfo.getVisitorChannelMap();
Iterator<String> ite = userChannels.keySet().iterator();
while (ite.hasNext()) {
Channel userChannel = userChannels.get(ite.next());
if (userChannel.isActive()) {
userChannel.close();
}
}
}
public static Channel getCmdChannelByServerPort(Integer serverPort) {
return serverPortToCmdChannelMap.get(serverPort);
}
public static Channel getCmdChannelByLicenseId(Integer licenseId) {
return licenseToCmdChannelMap.get(licenseId);
}
/**
* 增加用户连接与代理客户端连接关系
*
* @param visitorId
* @param visitorChannel
*/
public static void addVisitorChannelToCmdChannel(Channel cmdChannel, String visitorId, Channel visitorChannel, Integer serverPort) {
InetSocketAddress sa = (InetSocketAddress) visitorChannel.localAddress();
String lanInfo = getClientLanInfoByServerPort(sa.getPort());
CmdChannelAttachInfo cmdChannelAttachInfo = getAttachInfo(cmdChannel);
setAttachInfo(visitorChannel, new VisitorChannelAttachInfo()
.setVisitorId(visitorId)
.setLanInfo(lanInfo)
.setServerPort(serverPort)
.setLicenseId(cmdChannelAttachInfo.getLicenseId())
.setIp(((InetSocketAddress)visitorChannel.remoteAddress()).getAddress().getHostAddress())
);
userChannelMapLock.writeLock().lock();
try {
cmdChannelAttachInfo.getVisitorChannelMap().put(visitorId, visitorChannel);
} finally {
userChannelMapLock.writeLock().unlock();
}
serverPortToVisitorChannel.put(serverPort, visitorChannel);
}
public static Channel removeVisitorChannelFromCmdChannel(Channel cmdChannel, String visitorId) {
if (null == getAttachInfo(cmdChannel) || null == ((CmdChannelAttachInfo)getAttachInfo(cmdChannel)).getVisitorChannelMap().get(visitorId)) {
return null;
}
userChannelMapLock.writeLock().lock();
try {
return ((CmdChannelAttachInfo)getAttachInfo(cmdChannel)).getVisitorChannelMap().remove(visitorId);
} finally {
userChannelMapLock.writeLock().unlock();
}
}
/**
* 根据代理客户端连接与用户编号获取用户连接
*
* @param visitorId
* @return
*/
public static Channel getVisitorChannel(Channel cmdChannel, String visitorId) {
if (null == cmdChannel || null == getAttachInfo(cmdChannel)) {
return null;
}
return ((CmdChannelAttachInfo)getAttachInfo(cmdChannel)).getVisitorChannelMap().get(visitorId);
}
/**
* 根据服务端口获取访问通道
* @param serverPort
* @return
*/
public static Channel getVisitorChannelByServerPort(Integer serverPort) {
return serverPortToVisitorChannel.get(serverPort);
}
/**
* 获取访问者ID
*
* @param visitorChannel
* @return
*/
public static String getVisitorIdByChannel(Channel visitorChannel) {
if (null == visitorChannel || null == getAttachInfo(visitorChannel)) {
return null;
}
return ((VisitorChannelAttachInfo)getAttachInfo(visitorChannel)).getVisitorId();
}
/**
* 获取代理控制客户端连接绑定的所有用户连接
*
* @param cmdChannel
* @return
*/
public static Map<String, Channel> getVisitorChannels(Channel cmdChannel) {
if (null == cmdChannel || null == getAttachInfo(cmdChannel)) {
return null;
}
return ((CmdChannelAttachInfo)getAttachInfo(cmdChannel)).getVisitorChannelMap();
}
private static void setAttachInfo(Channel channel, Object obj) {
if (null == channel) {
return;
}
channel.attr(CHANNEL_ATTR_KEY).set(ChannelAttribute.create()
.set("attachInfo", obj)
);
}
public static <T> T getAttachInfo(Channel channel) {
if (null == channel || null == channel.attr(CHANNEL_ATTR_KEY).get()) {
return null;
}
return channel.attr(CHANNEL_ATTR_KEY).get().get("attachInfo");
}
}