Commit 3aa797e5 authored by AfirSraftGarrier's avatar AfirSraftGarrier

Merge branch 'master' into for-yx

# Conflicts:
#	license/.gitignore
#	license/pom.xml
#	license/src/main/java/iot/sixiang/license/LicenseApplication.java
#	license/src/main/java/iot/sixiang/license/controller/DeviceController.java
#	license/src/main/java/iot/sixiang/license/controller/LoginController.java
#	license/src/main/java/iot/sixiang/license/device/DeviceManager.java
#	license/src/main/java/iot/sixiang/license/device/DeviceServerHandler.java
#	license/src/main/java/iot/sixiang/license/forward/ForwardClient.java
#	license/src/main/java/iot/sixiang/license/forward/ForwardManager.java
#	license/src/main/java/iot/sixiang/license/jwt/JwtFilter.java
#	license/src/main/java/iot/sixiang/license/model/ResResult.java
#	license/src/main/resources/application.yml
parents 971d4435 c5a340b5
...@@ -32,4 +32,4 @@ build/ ...@@ -32,4 +32,4 @@ build/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
application-test.yml *-acc.yml
\ No newline at end of file \ No newline at end of file
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
# -------------------- 平台应用相关,以pms开头 --------------------
DROP TABLE IF EXISTS `pms_use_log`;
CREATE TABLE `pms_use_log`
(
`id` int(10) NOT NULL AUTO_INCREMENT,
`sn` varchar(30) DEFAULT NULL COMMENT '设备编号',
`status` int(1) DEFAULT '1' COMMENT '状态 1:成功,0:失败',
`error_code` varchar(10) DEFAULT NULL COMMENT '如果失败,则这是失败的代号',
`message` varchar(200) DEFAULT NULL COMMENT '如果失败,则这里是失败的信息',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`deleted` int(1) DEFAULT '0' COMMENT '逻辑删除标识 1:删除,0:未删除',
PRIMARY KEY (`id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 0
DEFAULT CHARSET = utf8 COMMENT ='使用记录表';
ALTER TABLE `device`
ADD COLUMN `status` int(1) NULL DEFAULT NULL COMMENT '状态 0:未使用,1:已使用,2:失效' AFTER `app_id`;
ALTER TABLE `device`
ADD COLUMN `sn_bind` varchar(30) NULL DEFAULT NULL COMMENT '绑定的SN' AFTER `status`;
\ No newline at end of file
...@@ -10,7 +10,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry ...@@ -10,7 +10,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableAsync @EnableAsync
@ServletComponentScan(basePackages ="iot.sixiang.license") @ServletComponentScan(basePackages = "iot.sixiang.license")
@SpringBootApplication @SpringBootApplication
@EnableScheduling @EnableScheduling
@MapperScan(basePackages = "iot.sixiang.license.mapper") @MapperScan(basePackages = "iot.sixiang.license.mapper")
......
...@@ -64,27 +64,62 @@ public class AuthManager { ...@@ -64,27 +64,62 @@ public class AuthManager {
} }
} }
// 终端设备鉴权
public boolean authTerminalDevice(String appId, String sn, String sign) {
if (!allApply.containsKey(appId)) {
log.info("no valid appId...");
return false;
}
if (!deviceManager.getContainSn(sn)) {
log.info("no this sn...");
return false;
}
DeviceVo device = deviceManager.getDevice(sn);
int deviceId = device.getDeviceId();
if (deviceBlackMap.containsKey(deviceId)) {
log.info("in black...");
return false;
}
Apply apply = allApply.get(appId);
String appKey = apply.getAppKey();
String input = "app_id=" + appId + "&sn=" + sn;
String valSHA1 = HmacUtil.encrypt(input, appKey, HmacUtil.HMAC_SHA1).toUpperCase();
if (CommonUtil.toUpperCaseByEnglish(sign).equals(CommonUtil.toUpperCaseByEnglish(valSHA1))) {
return true;
} else {
log.info("sign no valid:" + input);
return false;
}
}
public boolean auth(String appId, String sn, String sign) { public boolean auth(String appId, String sn, String sign) {
if (!allApply.containsKey(appId)) { if (!allApply.containsKey(appId)) {
log.info("no valid appId...");
return false; return false;
} }
if (!deviceManager.getContainSn(sn)) { if (!deviceManager.getContainSn(sn)) {
log.info("no this sn...");
return false; return false;
} }
DeviceVo device = deviceManager.getDevice(sn); DeviceVo device = deviceManager.getDevice(sn);
// 未绑定
if (device.getSnBind() == null) {
log.info("bind sn null...");
return false;
}
int deviceId = device.getDeviceId(); int deviceId = device.getDeviceId();
if(deviceBlackMap.containsKey(deviceId)){ if (deviceBlackMap.containsKey(deviceId)) {
log.info("in black...");
return false; return false;
} }
Apply apply = allApply.get(appId); Apply apply = allApply.get(appId);
String appKey = apply.getAppKey(); String appKey = apply.getAppKey();
String input = "app_id=" + appId + "&sn=" + sn; String input = "app_id=" + appId + "&sn=" + sn + "&sn_bind=" + device.getSnBind();
String valSHA1 = HmacUtil.encrypt(input, appKey, HmacUtil.HMAC_SHA1).toUpperCase(); String valSHA1 = HmacUtil.encrypt(input, appKey, HmacUtil.HMAC_SHA1).toUpperCase();
if (CommonUtil.toUpperCaseByEnglish(sign).equals(CommonUtil.toUpperCaseByEnglish(valSHA1))) { if (CommonUtil.toUpperCaseByEnglish(sign).equals(CommonUtil.toUpperCaseByEnglish(valSHA1))) {
return true; return true;
} else { } else {
log.info("sign no valid:" + input);
return false; return false;
} }
} }
......
...@@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject; ...@@ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter; import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters; import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import io.swagger.annotations.*;
import iot.sixiang.license.device.DeviceManager; import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.entity.DeviceBlack; import iot.sixiang.license.entity.DeviceBlack;
import iot.sixiang.license.log.BusinessType; import iot.sixiang.license.log.BusinessType;
...@@ -17,10 +16,8 @@ import iot.sixiang.license.model.vo.DeviceDetailVo; ...@@ -17,10 +16,8 @@ import iot.sixiang.license.model.vo.DeviceDetailVo;
import iot.sixiang.license.model.vo.DeviceVo; import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.service.DeviceBlackService; import iot.sixiang.license.service.DeviceBlackService;
import iot.sixiang.license.service.DeviceService; import iot.sixiang.license.service.DeviceService;
import iot.sixiang.license.xss.XssUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
......
...@@ -14,7 +14,6 @@ import iot.sixiang.license.mapper.UserMapper; ...@@ -14,7 +14,6 @@ import iot.sixiang.license.mapper.UserMapper;
import iot.sixiang.license.model.BaseResult; import iot.sixiang.license.model.BaseResult;
import iot.sixiang.license.model.ResResult; import iot.sixiang.license.model.ResResult;
import iot.sixiang.license.model.dto.CheckCodeDto; import iot.sixiang.license.model.dto.CheckCodeDto;
import iot.sixiang.license.model.vo.LoginReqVo;
import iot.sixiang.license.model.vo.LoginVo; import iot.sixiang.license.model.vo.LoginVo;
import iot.sixiang.license.model.vo.UserResetPwdVo; import iot.sixiang.license.model.vo.UserResetPwdVo;
import iot.sixiang.license.service.UserService; import iot.sixiang.license.service.UserService;
...@@ -23,7 +22,10 @@ import iot.sixiang.license.util.EmailUtils; ...@@ -23,7 +22,10 @@ import iot.sixiang.license.util.EmailUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore; import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource; import javax.annotation.Resource;
......
package iot.sixiang.license.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import iot.sixiang.license.entity.PmsUseLog;
import iot.sixiang.license.entity.SysOperLog;
import iot.sixiang.license.log.BusinessType;
import iot.sixiang.license.log.MyLog;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.PageResult;
import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.service.PmsUseService;
import iot.sixiang.license.service.SysOperLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
@Slf4j
@RestController
@RequestMapping("/iot_license/pms_use_log")
@Api(value = "使用记录模块", tags = {"使用记录模块"})
public class PmsUseLogController {
@Autowired
private PmsUseService pmsUseService;
/**
* 分页查询使用记录
*
* @param pageNo
* @param pageSize
* @return
*/
@ApiOperation(value = "获取使用记录列表接口", notes = "用于获取使用记录列表")
@GetMapping("list")
@MyLog(title = "获取使用记录列表", optParam = "#{pageNo},#{pageSize},#{sn},#{status}", businessType = BusinessType.SELECT)
@ApiImplicitParams({
@ApiImplicitParam(name = "pageNo", value = "当前在第几页", required = true, dataType = "int"),
@ApiImplicitParam(name = "pageSize", value = "每页显示多少条", required = true, dataType = "int"),
@ApiImplicitParam(name = "sn", value = "设备编号"),
@ApiImplicitParam(name = "status", value = "状态 1:成功,0:失败", dataType = "int")
})
public PageResult<PmsUseLog> getPmsUseLogList(@RequestParam(value = "pageNo", defaultValue = "0") int pageNo,
@RequestParam(value = "pageSize", defaultValue = "0") int pageSize,
@RequestParam(value = "sn", required = false) String sn,
@RequestParam(value = "status", required = false) Integer status) {
PageInfoModel<PmsUseLog> records = pmsUseService.getPmsUseLogList(pageNo, pageSize, sn, status);
int total = records.getTotal();
int pages = total / pageSize;//pages为总页数
int mod = total % pageSize;
if (mod != 0) {
pages = pages + 1;
}
List<PmsUseLog> result = records.getResult();
return new PageResult(200, "查找成功", pageNo, pages, total, result);
}
}
package iot.sixiang.license.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import iot.sixiang.license.model.BaseResult;
import iot.sixiang.license.model.ResResult;
import iot.sixiang.license.model.dto.GetTerminalDeviceTokenDTO;
import iot.sixiang.license.model.dto.ReportErrorMsgDTO;
import iot.sixiang.license.model.dto.TerminalDevieBindDTO;
import iot.sixiang.license.service.TerminalDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/iot_license/terminal_device")
@Api(value = "终端设备模块", tags = {"终端设备模块"})
public class TerminalDeviceController {
@Autowired
TerminalDeviceService terminalDeviceService;
@GetMapping("/get_token")
@ApiOperation(value = "终端设备获取token", notes = "终端设备获取token")
public ResResult getToken(GetTerminalDeviceTokenDTO getTerminalDeviceTokenDTO) {
return terminalDeviceService.getToken(getTerminalDeviceTokenDTO);
}
@PostMapping("/report_error_msg")
@ApiOperation(value = "终端设备上报错误信息", notes = "终端设备上报错误信息")
public BaseResult reportErrorMsg(@RequestBody List<ReportErrorMsgDTO> reportErrorMsgDTO) {
return terminalDeviceService.reportErrorMsg(reportErrorMsgDTO);
}
@PostMapping("/bind")
@ApiOperation(value = "终端设备绑定接口", notes = "终端设备绑定接口")
public BaseResult terminalDevieBind(@RequestBody TerminalDevieBindDTO terminalDevieBindDTO) {
return terminalDeviceService.terminalDeviceBind(terminalDevieBindDTO);
}
}
...@@ -18,6 +18,7 @@ import java.util.Iterator; ...@@ -18,6 +18,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@Component @Component
@Slf4j @Slf4j
public class DeviceManager { public class DeviceManager {
...@@ -53,7 +54,7 @@ public class DeviceManager { ...@@ -53,7 +54,7 @@ public class DeviceManager {
public void initDevices() { public void initDevices() {
allDevice = new HashMap<>(); allDevice = new HashMap<>();
PageInfoModel<DeviceVo> records = deviceService.getDeviceList(1, 10000, "", ""); PageInfoModel<DeviceVo> records = deviceService.getDeviceList(1, 10000, "", "", null, null);
List<DeviceVo> deviceList = records.getResult(); List<DeviceVo> deviceList = records.getResult();
for (DeviceVo deviceVo : deviceList) { for (DeviceVo deviceVo : deviceList) {
...@@ -73,12 +74,12 @@ public class DeviceManager { ...@@ -73,12 +74,12 @@ public class DeviceManager {
return allDevice; return allDevice;
} }
public synchronized void putSession(String appId, SessionContext session) { public synchronized void putSession(String sn, SessionContext session) {
sessionContexts.put(appId, session); sessionContexts.put(sn, session);
} }
public SessionContext getSessionContextByAppId(String appId) { public SessionContext getSessionContextBySN(String sn) {
return sessionContexts.get(appId); return sessionContexts.get(sn);
} }
public SessionContext getSessionByChannelId(String channelId) { public SessionContext getSessionByChannelId(String channelId) {
...@@ -150,7 +151,7 @@ public class DeviceManager { ...@@ -150,7 +151,7 @@ public class DeviceManager {
} }
public PageInfoModel<DeviceDetailVo> getDeviceDetailList(int pageNo, int pageSize, String appName, String userName) { public PageInfoModel<DeviceDetailVo> getDeviceDetailList(int pageNo, int pageSize, String appName, String userName) {
PageInfoModel<DeviceVo> records = deviceService.getDeviceList(pageNo, pageSize, appName, userName); PageInfoModel<DeviceVo> records = deviceService.getDeviceList(pageNo, pageSize, appName, userName, null, null);
List<DeviceVo> deviceVos = records.getResult(); List<DeviceVo> deviceVos = records.getResult();
PageInfoModel<DeviceDetailVo> detailVoPageInfoModel = new PageInfoModel<>(); PageInfoModel<DeviceDetailVo> detailVoPageInfoModel = new PageInfoModel<>();
List<DeviceDetailVo> detailVos = new ArrayList<>(); List<DeviceDetailVo> detailVos = new ArrayList<>();
...@@ -168,7 +169,7 @@ public class DeviceManager { ...@@ -168,7 +169,7 @@ public class DeviceManager {
int status = session.getStatus(); int status = session.getStatus();
String online = session.getOnline(); String online = session.getOnline();
String offline = session.getOffline(); String offline = session.getOffline();
detailVo.setStatus(status); detailVo.setCurStatus(status);
detailVo.setOnline(online); detailVo.setOnline(online);
detailVo.setOffline(offline); detailVo.setOffline(offline);
} }
......
...@@ -13,6 +13,7 @@ import iot.sixiang.license.event.DeviceClientInactiveEvent; ...@@ -13,6 +13,7 @@ import iot.sixiang.license.event.DeviceClientInactiveEvent;
import iot.sixiang.license.event.EventPublisher; import iot.sixiang.license.event.EventPublisher;
import iot.sixiang.license.event.ForwardClientRequestEvent; import iot.sixiang.license.event.ForwardClientRequestEvent;
import iot.sixiang.license.model.SessionContext; import iot.sixiang.license.model.SessionContext;
import iot.sixiang.license.service.PmsUseService;
import iot.sixiang.license.third_lib.LibHelper; import iot.sixiang.license.third_lib.LibHelper;
import iot.sixiang.license.util.CommonUtil; import iot.sixiang.license.util.CommonUtil;
import iot.sixiang.license.util.HexUtil; import iot.sixiang.license.util.HexUtil;
...@@ -21,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -21,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@Component @Component
...@@ -29,6 +31,8 @@ import java.net.InetSocketAddress; ...@@ -29,6 +31,8 @@ import java.net.InetSocketAddress;
public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> { public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
@Autowired @Autowired
EventPublisher eventPublisher; EventPublisher eventPublisher;
@Resource
private PmsUseService pmsUseService;
public DeviceServerHandler() { public DeviceServerHandler() {
super(); super();
...@@ -128,11 +132,18 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> { ...@@ -128,11 +132,18 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
log.info("设备鉴权信息和结果,{},{},{},{} ", appId, sn, sign, license); log.info("设备鉴权信息和结果,{},{},{},{} ", appId, sn, sign, license);
String channelId = channel.id().asLongText(); String channelId = channel.id().asLongText();
if (license) { if (license) {
// 创建一条使用记录
int useLogId = pmsUseService.createUseLog(sn);
if (useLogId <= 0) {
log.info("创建使用日志不成功...");
return false;
}
SessionContext session = new SessionContext(); SessionContext session = new SessionContext();
session.setRemoteIp(remoteIp); session.setRemoteIp(remoteIp);
session.setRemotePort(remotePort); session.setRemotePort(remotePort);
session.setAppId(appId); session.setAppId(appId);
session.setSn(sn); session.setSn(sn);
session.setUseLogId(useLogId);
session.setChannelId(channelId); session.setChannelId(channelId);
session.setClientChannel(channel); session.setClientChannel(channel);
session.setAuthStatus(true); session.setAuthStatus(true);
...@@ -140,12 +151,14 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> { ...@@ -140,12 +151,14 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
session.setOnline(CommonUtil.getSystemTime()); session.setOnline(CommonUtil.getSystemTime());
DeviceManager deviceManager = SpringUtil.getBean(DeviceManager.class); DeviceManager deviceManager = SpringUtil.getBean(DeviceManager.class);
deviceManager.putSession(appId, session); deviceManager.putSession(sn, session);
// 创建透传的客户端 // 创建透传的客户端
CreateForwardClientEvent event = new CreateForwardClientEvent(); CreateForwardClientEvent event = new CreateForwardClientEvent();
event.setAppId(appId); event.setSn(sn);
eventPublisher.publishEvent(event); eventPublisher.publishEvent(event);
} else {
pmsUseService.createFailUseLog(sn, "鉴权失败");
} }
return license; return license;
} }
......
...@@ -34,9 +34,15 @@ public class Device implements Serializable { ...@@ -34,9 +34,15 @@ public class Device implements Serializable {
@ApiModelProperty("设备编号") @ApiModelProperty("设备编号")
private String sn; private String sn;
@ApiModelProperty("绑定的SN")
private String snBind;
@ApiModelProperty("应用Id") @ApiModelProperty("应用Id")
private String appId; private String appId;
@ApiModelProperty("状态 0:未使用,1:已使用,2:失效")
private Integer status;
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private Date createTime; private Date createTime;
......
package iot.sixiang.license.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* Created by M=54G
* Date 11/23/22 3:12 PM
* Description
*/
@Data
public class PmsUseLog {
@ApiModelProperty("记录标识")
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("设备编号")
private String sn;
@ApiModelProperty("状态 1:成功,0:失败")
private Integer status;
@ApiModelProperty("如果失败,则这是失败的代号")
private String errorCode;
@ApiModelProperty("如果失败,则这里是失败的信息")
private String message;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("更新时间")
private Date updateTime;
@ApiModelProperty("逻辑删除标识 1:删除,0:未删除")
private Integer deleted;
}
...@@ -5,5 +5,5 @@ import lombok.Data; ...@@ -5,5 +5,5 @@ import lombok.Data;
@Data @Data
public class CreateForwardClientEvent extends BaseEvent { public class CreateForwardClientEvent extends BaseEvent {
private String appId; private String sn;
} }
...@@ -23,14 +23,14 @@ public class CreateForwardClientEventHandler { ...@@ -23,14 +23,14 @@ public class CreateForwardClientEventHandler {
@EventListener @EventListener
public void handlerEvent(CreateForwardClientEvent event) { public void handlerEvent(CreateForwardClientEvent event) {
String appId = event.getAppId(); String sn = event.getSn();
Server balanceServer = balanceManager.getBalanceServer(); Server balanceServer = balanceManager.getBalanceServer();
if (balanceServer != null) { if (balanceServer != null) {
String serverIp = balanceServer.getServerIp(); String serverIp = balanceServer.getServerIp();
Integer port = balanceServer.getPort(); Integer port = balanceServer.getPort();
forwardManager.startTcpClient(serverIp, port, appId); forwardManager.startTcpClient(serverIp, port, sn);
} else { } else {
log.error("balanceServer is null"); log.error("balanceServer is null...");
} }
} }
} }
...@@ -4,7 +4,6 @@ import lombok.Data; ...@@ -4,7 +4,6 @@ import lombok.Data;
@Data @Data
public class DeviceClientBeForcedOfflineEvent extends BaseEvent { public class DeviceClientBeForcedOfflineEvent extends BaseEvent {
private String appId; private String sn;
} }
...@@ -20,17 +20,17 @@ public class DeviceClientBeForcedOfflineEventHandler { ...@@ -20,17 +20,17 @@ public class DeviceClientBeForcedOfflineEventHandler {
@EventListener @EventListener
public void handlerEvent(DeviceClientBeForcedOfflineEvent event) { public void handlerEvent(DeviceClientBeForcedOfflineEvent event) {
String appId = event.getAppId(); String sn = event.getSn();
SessionContext deviceSessionContext = deviceManager.getSessionContextByAppId(appId); SessionContext deviceSessionContext = deviceManager.getSessionContextBySN(sn);
if (deviceSessionContext != null) { if (deviceSessionContext != null) {
SocketChannel deviceClientChannel = deviceSessionContext.getClientChannel(); SocketChannel deviceClientChannel = deviceSessionContext.getClientChannel();
if (deviceClientChannel != null) { if (deviceClientChannel != null) {
deviceClientChannel.close(); deviceClientChannel.close();
log.debug("device client be forced offline success ..." + appId); log.debug("device client be forced offline success ..." + sn);
} }
} else { } else {
log.debug("device client be forced offline undo ..." + appId); log.debug("device client be forced offline undo ..." + sn);
} }
} }
......
...@@ -16,7 +16,6 @@ public class DeviceClientInactiveEventHandler { ...@@ -16,7 +16,6 @@ public class DeviceClientInactiveEventHandler {
EventPublisher eventPublisher; EventPublisher eventPublisher;
public DeviceClientInactiveEventHandler() { public DeviceClientInactiveEventHandler() {
} }
@EventListener @EventListener
...@@ -25,24 +24,21 @@ public class DeviceClientInactiveEventHandler { ...@@ -25,24 +24,21 @@ public class DeviceClientInactiveEventHandler {
SessionContext session = deviceManager.getSessionByChannelId(channelId); SessionContext session = deviceManager.getSessionByChannelId(channelId);
if (session == null) { if (session == null) {
log.debug("device client inactive undo ..."); log.info("device client inactive undo ...");
return; return;
} else { } else {
String appId = session.getAppId(); String sn = session.getSn();
// boolean result = deviceManager.removeSessionByChannelId(channelId); // boolean result = deviceManager.removeSessionByChannelId(channelId);
boolean result = deviceManager.changeSessionOffline(channelId); boolean result = deviceManager.changeSessionOffline(channelId);
if (result) { if (result) {
// TODO device client 离线需要强制中断该设备对应的forward client // device client 离线需要强制中断该设备对应的forward client
ForwardClientBeForcedOfflineEvent forwardClientBeForcedOfflineEvent = new ForwardClientBeForcedOfflineEvent(); ForwardClientBeForcedOfflineEvent forwardClientBeForcedOfflineEvent = new ForwardClientBeForcedOfflineEvent();
forwardClientBeForcedOfflineEvent.setAppId(appId); forwardClientBeForcedOfflineEvent.setSn(sn);
eventPublisher.publishEvent(forwardClientBeForcedOfflineEvent); eventPublisher.publishEvent(forwardClientBeForcedOfflineEvent);
log.debug("device client inactive success ..."); log.info("device client inactive success ...");
} }
} }
} }
} }
......
...@@ -5,6 +5,6 @@ import lombok.Data; ...@@ -5,6 +5,6 @@ import lombok.Data;
@Data @Data
public class DeviceClientLicenseEvent extends BaseEvent { public class DeviceClientLicenseEvent extends BaseEvent {
private String appId; private String sn;
private DeviceProtocol protocol; private DeviceProtocol protocol;
} }
...@@ -22,10 +22,10 @@ public class DeviceClientLicenseEventHandler { ...@@ -22,10 +22,10 @@ public class DeviceClientLicenseEventHandler {
@EventListener @EventListener
public void handlerEvent(DeviceClientLicenseEvent event) { public void handlerEvent(DeviceClientLicenseEvent event) {
String appId = event.getAppId(); String appId = event.getSn();
DeviceProtocol protocol = event.getProtocol(); DeviceProtocol protocol = event.getProtocol();
SessionContext session = deviceManager.getSessionContextByAppId(appId); SessionContext session = deviceManager.getSessionContextBySN(appId);
if (session == null) { if (session == null) {
log.debug("device client license undo ..."); log.debug("device client license undo ...");
return; return;
......
...@@ -4,6 +4,6 @@ import lombok.Data; ...@@ -4,6 +4,6 @@ import lombok.Data;
@Data @Data
public class ForwardClientBeForcedOfflineEvent extends BaseEvent { public class ForwardClientBeForcedOfflineEvent extends BaseEvent {
private String appId; private String sn;
} }
...@@ -11,7 +11,6 @@ import org.springframework.stereotype.Component; ...@@ -11,7 +11,6 @@ import org.springframework.stereotype.Component;
@Component @Component
@Slf4j @Slf4j
public class ForwardClientBeForcedOfflineEventHandler { public class ForwardClientBeForcedOfflineEventHandler {
@Autowired @Autowired
ForwardManager forwardManager; ForwardManager forwardManager;
...@@ -22,18 +21,16 @@ public class ForwardClientBeForcedOfflineEventHandler { ...@@ -22,18 +21,16 @@ public class ForwardClientBeForcedOfflineEventHandler {
@EventListener @EventListener
public void handlerEvent(ForwardClientBeForcedOfflineEvent event) { public void handlerEvent(ForwardClientBeForcedOfflineEvent event) {
String appId = event.getAppId(); String sn = event.getSn();
SessionContext forwardSessionContext = forwardManager.getSessionContextByAppId(appId); SessionContext forwardSessionContext = forwardManager.getSessionContextBySN(sn);
if (forwardSessionContext != null) { if (forwardSessionContext != null) {
SocketChannel forwardClientChannel = forwardSessionContext.getClientChannel(); SocketChannel forwardClientChannel = forwardSessionContext.getClientChannel();
if (forwardClientChannel != null) { if (forwardClientChannel != null) {
forwardClientChannel.close(); forwardClientChannel.close();
log.debug("forward client be forced offline success ..." + appId); log.debug("forward client be forced offline success ..." + sn);
} }
} else { } else {
log.debug("forward client be forced offline undo ..." + appId); log.debug("forward client be forced offline undo ..." + sn);
} }
} }
} }
...@@ -5,9 +5,8 @@ import lombok.Data; ...@@ -5,9 +5,8 @@ import lombok.Data;
@Data @Data
public class ForwardClientConnectEvent extends BaseEvent { public class ForwardClientConnectEvent extends BaseEvent {
private String appId; private String sn;
private String channelId; private String channelId;
private SocketChannel channel; private SocketChannel channel;
} }
...@@ -16,35 +16,28 @@ public class ForwardClientConnectEventHandler { ...@@ -16,35 +16,28 @@ public class ForwardClientConnectEventHandler {
@Autowired @Autowired
EventPublisher eventPublisher; EventPublisher eventPublisher;
public ForwardClientConnectEventHandler() { public ForwardClientConnectEventHandler() {
} }
@EventListener @EventListener
public void handlerEvent(ForwardClientConnectEvent event) { public void handlerEvent(ForwardClientConnectEvent event) {
String sn = event.getSn();
String appId = event.getAppId();
String channelId = event.getChannelId(); String channelId = event.getChannelId();
SocketChannel channel = event.getChannel(); SocketChannel channel = event.getChannel();
SessionContext session = new SessionContext(); SessionContext session = new SessionContext();
// session.setRemoteIp(remoteIp); // session.setRemoteIp(remoteIp);
// session.setRemotePort(remotePort); // session.setRemotePort(remotePort);
session.setAppId(appId); session.setSn(sn);
// session.setAppKey(appKey); // session.setAppKey(appKey);
// session.setToken(token); // session.setToken(token);
session.setChannelId(channelId); session.setChannelId(channelId);
session.setClientChannel(channel); session.setClientChannel(channel);
forwardManager.putSession(appId, session); forwardManager.putSession(sn, session);
log.debug("forward client connect:" + event); log.debug("forward client connect:" + event);
} }
} }
...@@ -30,12 +30,12 @@ public class ForwardClientInactiveEventHandler { ...@@ -30,12 +30,12 @@ public class ForwardClientInactiveEventHandler {
log.debug("forward client inactive undo ..."); log.debug("forward client inactive undo ...");
return; return;
} else { } else {
String appId = session.getAppId(); String sn = session.getSn();
boolean result = forwardManager.removeSessionByChannelId(channelId); boolean result = forwardManager.removeSessionByChannelId(channelId);
if (result) { if (result) {
// forward client 离线需要强制中断该设备对应的 device client // forward client 离线需要强制中断该设备对应的 device client
DeviceClientBeForcedOfflineEvent deviceClientBeForcedOfflineEvent = new DeviceClientBeForcedOfflineEvent(); DeviceClientBeForcedOfflineEvent deviceClientBeForcedOfflineEvent = new DeviceClientBeForcedOfflineEvent();
deviceClientBeForcedOfflineEvent.setAppId(appId); deviceClientBeForcedOfflineEvent.setSn(sn);
eventPublisher.publishEvent(deviceClientBeForcedOfflineEvent); eventPublisher.publishEvent(deviceClientBeForcedOfflineEvent);
log.debug("forward client inactive success ..."); log.debug("forward client inactive success ...");
} }
......
...@@ -30,10 +30,10 @@ public class ForwardClientRequestEventHandler { ...@@ -30,10 +30,10 @@ public class ForwardClientRequestEventHandler {
DeviceProtocol protocol = event.getProtocol(); DeviceProtocol protocol = event.getProtocol();
SessionContext deviceSessionContext = deviceManager.getSessionByChannelId(deviceChannelId); SessionContext deviceSessionContext = deviceManager.getSessionByChannelId(deviceChannelId);
String appId = deviceSessionContext.getAppId(); String sn = deviceSessionContext.getSn();
SessionContext forwardSessionContext = forwardManager.getSessionContextByAppId(appId); SessionContext forwardSessionContext = forwardManager.getSessionContextBySN(sn);
log.debug("forward client request:" + appId + "," + forwardSessionContext); log.info("forward client request:" + sn + "," + forwardSessionContext);
SocketChannel clientChannel = forwardSessionContext.getClientChannel(); SocketChannel clientChannel = forwardSessionContext.getClientChannel();
clientChannel.writeAndFlush(protocol); clientChannel.writeAndFlush(protocol);
} }
......
...@@ -5,11 +5,14 @@ import iot.sixiang.license.device.DeviceManager; ...@@ -5,11 +5,14 @@ import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.device.DeviceProtocol; import iot.sixiang.license.device.DeviceProtocol;
import iot.sixiang.license.forward.ForwardManager; import iot.sixiang.license.forward.ForwardManager;
import iot.sixiang.license.model.SessionContext; import iot.sixiang.license.model.SessionContext;
import iot.sixiang.license.service.PmsUseService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component @Component
@Slf4j @Slf4j
public class ForwardMessageResponseEventHandler { public class ForwardMessageResponseEventHandler {
...@@ -19,32 +22,33 @@ public class ForwardMessageResponseEventHandler { ...@@ -19,32 +22,33 @@ public class ForwardMessageResponseEventHandler {
ForwardManager forwardManager; ForwardManager forwardManager;
@Autowired @Autowired
EventPublisher eventPublisher; EventPublisher eventPublisher;
@Resource
private PmsUseService pmsUseService;
public ForwardMessageResponseEventHandler() { public ForwardMessageResponseEventHandler() {
} }
@EventListener @EventListener
public void handlerEvent(ForwardMessageResponseEvent event) { public void handlerEvent(ForwardMessageResponseEvent event) {
String channelId = event.getChannelId(); String channelId = event.getChannelId();
SocketChannel channel = event.getChannel(); //SocketChannel channel = event.getChannel();
DeviceProtocol protocol = event.getProtocol(); DeviceProtocol protocol = event.getProtocol();
SessionContext forwardSessionContext = forwardManager.getSessionByChannelId(channelId); SessionContext forwardSessionContext = forwardManager.getSessionByChannelId(channelId);
String appId = forwardSessionContext.getAppId(); String sn = forwardSessionContext.getSn();
SessionContext deviceSessionContext = deviceManager.getSessionContextByAppId(appId); SessionContext deviceSessionContext = deviceManager.getSessionContextBySN(sn);
if (deviceSessionContext != null) { if (deviceSessionContext != null) {
SocketChannel deviceClientChannel = deviceSessionContext.getClientChannel(); SocketChannel deviceClientChannel = deviceSessionContext.getClientChannel();
log.debug("forward client response..." + appId + ",forward session:" + deviceSessionContext); log.info("forward client response..." + sn + ",forward session:" + deviceSessionContext);
deviceClientChannel.writeAndFlush(protocol); deviceClientChannel.writeAndFlush(protocol);
} else { } else {
log.debug("forward client response undo ..." + appId); log.info("forward client response undo ..." + sn);
} }
// 说明已经成功
if (protocol.getCmd() == 0xF2) {
pmsUseService.success(deviceSessionContext.getUseLogId());
}
} }
} }
...@@ -7,7 +7,6 @@ import iot.sixiang.license.consts.Consts; ...@@ -7,7 +7,6 @@ import iot.sixiang.license.consts.Consts;
import iot.sixiang.license.net.BaseChannelInitializer; import iot.sixiang.license.net.BaseChannelInitializer;
public class ForwardChannelInitializer extends BaseChannelInitializer { public class ForwardChannelInitializer extends BaseChannelInitializer {
private ForwardClientHandler handler; private ForwardClientHandler handler;
static final EventExecutorGroup workGroup = new DefaultEventExecutorGroup(Consts.FORWARD_THREAD_NUM); static final EventExecutorGroup workGroup = new DefaultEventExecutorGroup(Consts.FORWARD_THREAD_NUM);
...@@ -18,10 +17,8 @@ public class ForwardChannelInitializer extends BaseChannelInitializer { ...@@ -18,10 +17,8 @@ public class ForwardChannelInitializer extends BaseChannelInitializer {
@Override @Override
protected void initChannel(SocketChannel ch) throws Exception { protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("decoder", new ForwardDecoder()); ch.pipeline().addLast("decoder", new ForwardDecoder());
ch.pipeline().addLast("encoder", new ForwardEncoder()); ch.pipeline().addLast("encoder", new ForwardEncoder());
ch.pipeline().addLast(workGroup, "handler", handler); ch.pipeline().addLast(workGroup, "handler", handler);
} }
} }
...@@ -5,12 +5,14 @@ import io.netty.channel.ChannelOption; ...@@ -5,12 +5,14 @@ import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.net.TcpClient; import iot.sixiang.license.net.TcpClient;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.Resource;
@Component @Component
@Slf4j @Slf4j
...@@ -21,6 +23,8 @@ public class ForwardClient { ...@@ -21,6 +23,8 @@ public class ForwardClient {
@Autowired @Autowired
ForwardClientHandler handler; ForwardClientHandler handler;
@Resource
private DeviceManager deviceManager;
public ForwardClient() { public ForwardClient() {
} }
...@@ -44,9 +48,12 @@ public class ForwardClient { ...@@ -44,9 +48,12 @@ public class ForwardClient {
public void startTcp(String host, int port, String appId) { public void startTcp(String host, int port, String appId) {
log.debug("桥接客户端,开始连接桥接服务:{},{},{}", host, port, appId); log.debug("桥接客户端,开始连接桥接服务:{},{},{}", host, port, appId);
ForwardConnectionListener listener = new ForwardConnectionListener(); ForwardConnectionListener listener = new ForwardConnectionListener();
listener.setAppId(appId); listener.setSn(sn);
listener.setHost(host); listener.setHost(host);
listener.setPort(port); listener.setPort(port);
listener.setDeviceManager(this.deviceManager);
channelInitializer = new ForwardChannelInitializer(handler);
client = new TcpClient(host, port, channelInitializer, listener, bootstrap); client = new TcpClient(host, port, channelInitializer, listener, bootstrap);
client.start(); client.start();
} }
......
...@@ -8,11 +8,14 @@ import iot.sixiang.license.device.DeviceProtocol; ...@@ -8,11 +8,14 @@ import iot.sixiang.license.device.DeviceProtocol;
import iot.sixiang.license.event.EventPublisher; import iot.sixiang.license.event.EventPublisher;
import iot.sixiang.license.event.ForwardClientInactiveEvent; import iot.sixiang.license.event.ForwardClientInactiveEvent;
import iot.sixiang.license.event.ForwardMessageResponseEvent; import iot.sixiang.license.event.ForwardMessageResponseEvent;
import iot.sixiang.license.service.PmsUseService;
import iot.sixiang.license.util.HexUtil; import iot.sixiang.license.util.HexUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component @Component
@ChannelHandler.Sharable @ChannelHandler.Sharable
@Slf4j @Slf4j
...@@ -30,6 +33,7 @@ public class ForwardClientHandler extends SimpleChannelInboundHandler<Object> { ...@@ -30,6 +33,7 @@ public class ForwardClientHandler extends SimpleChannelInboundHandler<Object> {
log.info("read message..."); log.info("read message...");
SocketChannel channel = (SocketChannel) ctx.channel(); SocketChannel channel = (SocketChannel) ctx.channel();
DeviceProtocol protocol = (DeviceProtocol) msg; DeviceProtocol protocol = (DeviceProtocol) msg;
String channelId = channel.id().asLongText(); String channelId = channel.id().asLongText();
log.info("桥接客户端,channelRead0:{},{}", channelId, HexUtil.bytes2hex(protocol.getContent())); log.info("桥接客户端,channelRead0:{},{}", channelId, HexUtil.bytes2hex(protocol.getContent()));
......
...@@ -2,11 +2,13 @@ package iot.sixiang.license.forward; ...@@ -2,11 +2,13 @@ package iot.sixiang.license.forward;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.device.DeviceProtocol; import iot.sixiang.license.device.DeviceProtocol;
import iot.sixiang.license.event.DeviceClientBeForcedOfflineEvent; import iot.sixiang.license.event.DeviceClientBeForcedOfflineEvent;
import iot.sixiang.license.event.DeviceClientLicenseEvent; import iot.sixiang.license.event.DeviceClientLicenseEvent;
import iot.sixiang.license.event.EventPublisher; import iot.sixiang.license.event.EventPublisher;
import iot.sixiang.license.event.ForwardClientConnectEvent; import iot.sixiang.license.event.ForwardClientConnectEvent;
import iot.sixiang.license.model.SessionContext;
import iot.sixiang.license.net.BaseConnectionListener; import iot.sixiang.license.net.BaseConnectionListener;
import iot.sixiang.license.operate.OperateManager; import iot.sixiang.license.operate.OperateManager;
import iot.sixiang.license.service.AlarmService; import iot.sixiang.license.service.AlarmService;
...@@ -15,13 +17,18 @@ import lombok.extern.slf4j.Slf4j; ...@@ -15,13 +17,18 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class ForwardConnectionListener extends BaseConnectionListener { public class ForwardConnectionListener extends BaseConnectionListener {
private DeviceManager deviceManager;
public void setDeviceManager(DeviceManager deviceManager) {
this.deviceManager = deviceManager;
}
@Override @Override
public void operationComplete(ChannelFuture channelFuture) { public void operationComplete(ChannelFuture channelFuture) {
AlarmService alarmService = SpringUtil.getBean(AlarmService.class); AlarmService alarmService = SpringUtil.getBean(AlarmService.class);
if (!channelFuture.isSuccess()) { if (!channelFuture.isSuccess()) {
// 失败进行告警 // 失败进行告警
log.debug("桥接客户端,连接服务器失败:{},{},{}", this.host, this.port, this.appId); log.debug("桥接客户端,连接服务器失败:{},{},{}", this.host, this.port, this.sn);
int typeId = 1; int typeId = 1;
String title = "连接服器失败"; String title = "连接服器失败";
...@@ -30,37 +37,46 @@ public class ForwardConnectionListener extends BaseConnectionListener { ...@@ -30,37 +37,46 @@ public class ForwardConnectionListener extends BaseConnectionListener {
// forward client连接失败,则强制踢掉设备客户端 // forward client连接失败,则强制踢掉设备客户端
DeviceClientBeForcedOfflineEvent deviceClientBeForcedOfflineEvent = new DeviceClientBeForcedOfflineEvent(); DeviceClientBeForcedOfflineEvent deviceClientBeForcedOfflineEvent = new DeviceClientBeForcedOfflineEvent();
deviceClientBeForcedOfflineEvent.setAppId(this.appId); deviceClientBeForcedOfflineEvent.setSn(this.sn);
EventPublisher eventPublisher = SpringUtil.getBean(EventPublisher.class); EventPublisher eventPublisher = SpringUtil.getBean(EventPublisher.class);
eventPublisher.publishEvent(deviceClientBeForcedOfflineEvent); eventPublisher.publishEvent(deviceClientBeForcedOfflineEvent);
} else { } else {
log.debug("桥接客户端,连接服务器成功:{},{},{}", this.host, this.port, this.appId); log.debug("桥接客户端,连接服务器成功:{},{},{}", this.host, this.port, this.sn);
OperateManager operateManager = SpringUtil.getBean(OperateManager.class); OperateManager operateManager = SpringUtil.getBean(OperateManager.class);
operateManager.autoIncrement(); operateManager.autoIncrement();
SocketChannel channel = (SocketChannel) channelFuture.channel(); SocketChannel channel = (SocketChannel) channelFuture.channel();
String channelId = channel.id().asLongText(); String channelId = channel.id().asLongText();
ForwardClientConnectEvent forwardClientConnectEvent = new ForwardClientConnectEvent(); ForwardClientConnectEvent forwardClientConnectEvent = new ForwardClientConnectEvent();
forwardClientConnectEvent.setAppId(this.appId); forwardClientConnectEvent.setSn(this.sn);
forwardClientConnectEvent.setChannelId(channelId); forwardClientConnectEvent.setChannelId(channelId);
forwardClientConnectEvent.setChannel(channel); forwardClientConnectEvent.setChannel(channel);
EventPublisher eventPublisher = SpringUtil.getBean(EventPublisher.class); EventPublisher eventPublisher = SpringUtil.getBean(EventPublisher.class);
eventPublisher.publishEvent(forwardClientConnectEvent); eventPublisher.publishEvent(forwardClientConnectEvent);
// 将日志记录数据返回
SessionContext deviceSessionContext = deviceManager.getSessionContextBySN(this.sn);
int useLogId = deviceSessionContext.getUseLogId();
log.info("use log id:" + useLogId);
short stx = 21930; short stx = 21930;
byte ack = 0x0; byte ack = 0x0;
int len = 3; int len = 6;
byte cmd = 0x1; byte cmd = 0x1;
byte[] content = new byte[1]; byte[] content = new byte[4];
content[0] = 0x7e; content[0] = 0x7e;
content[1] = (byte) useLogId;
content[2] = (byte) (useLogId >> 8);
content[3] = (byte) (useLogId >> 16);
byte end = 0x1; byte end = 0x1;
DeviceProtocol protocol = new DeviceProtocol(stx, len, cmd, ack, content, end); DeviceProtocol protocol = new DeviceProtocol(stx, len, cmd, ack, content, end);
DeviceClientLicenseEvent deviceClientLicenseEvent = new DeviceClientLicenseEvent(); DeviceClientLicenseEvent deviceClientLicenseEvent = new DeviceClientLicenseEvent();
deviceClientLicenseEvent.setAppId(appId); deviceClientLicenseEvent.setSn(sn);
deviceClientLicenseEvent.setProtocol(protocol); deviceClientLicenseEvent.setProtocol(protocol);
eventPublisher.publishEvent(deviceClientLicenseEvent); eventPublisher.publishEvent(deviceClientLicenseEvent);
......
...@@ -43,7 +43,7 @@ public class ForwardDecoder extends ByteToMessageDecoder { ...@@ -43,7 +43,7 @@ public class ForwardDecoder extends ByteToMessageDecoder {
return; return;
} }
// buffer.resetReaderIndex();//复位 // buffer.resetReaderIndex();//复位
// 读取data数据 // 读取data数据
byte[] content = new byte[real_len - cmd_ack_len]; byte[] content = new byte[real_len - cmd_ack_len];
...@@ -55,6 +55,4 @@ public class ForwardDecoder extends ByteToMessageDecoder { ...@@ -55,6 +55,4 @@ public class ForwardDecoder extends ByteToMessageDecoder {
DeviceProtocol protocol = new DeviceProtocol(stx, real_len, cmd, ack, content, end); DeviceProtocol protocol = new DeviceProtocol(stx, real_len, cmd, ack, content, end);
out.add(protocol); out.add(protocol);
} }
} }
\ No newline at end of file
...@@ -8,10 +8,8 @@ import lombok.extern.slf4j.Slf4j; ...@@ -8,10 +8,8 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class ForwardEncoder extends MessageToByteEncoder<DeviceProtocol> { public class ForwardEncoder extends MessageToByteEncoder<DeviceProtocol> {
@Override @Override
protected void encode(ChannelHandlerContext tcx, DeviceProtocol msg, ByteBuf out) { protected void encode(ChannelHandlerContext tcx, DeviceProtocol msg, ByteBuf out) {
out.writeShort(msg.getStx()); out.writeShort(msg.getStx());
out.writeShortLE(msg.getLen()); out.writeShortLE(msg.getLen());
out.writeByte(msg.getCmd()); out.writeByte(msg.getCmd());
......
...@@ -22,20 +22,19 @@ public class ForwardManager { ...@@ -22,20 +22,19 @@ public class ForwardManager {
public ForwardManager() { public ForwardManager() {
sessionContexts = new HashMap<String, SessionContext>(); sessionContexts = new HashMap<>();
} }
public void startTcpClient(String serviceIP, int port, String appId) { public void startTcpClient(String serviceIP, int port, String sn) {
client.startTcp(serviceIP, port, appId); client.startTcp(serviceIP, port, sn);
} }
public synchronized void putSession(String appId, SessionContext session) { public synchronized void putSession(String sn, SessionContext session) {
sessionContexts.put(appId, session); sessionContexts.put(sn, session);
} }
public SessionContext getSessionContextByAppId(String appId) { public SessionContext getSessionContextBySN(String sn) {
return sessionContexts.get(appId); return sessionContexts.get(sn);
} }
public SessionContext getSessionByChannelId(String channelId) { public SessionContext getSessionByChannelId(String channelId) {
......
...@@ -4,10 +4,14 @@ import com.auth0.jwt.interfaces.Claim; ...@@ -4,10 +4,14 @@ import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import iot.sixiang.license.xss.XssUtil; import iot.sixiang.license.xss.XssUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.servlet.*; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
...@@ -27,6 +31,9 @@ public class JwtFilter implements Filter { ...@@ -27,6 +31,9 @@ public class JwtFilter implements Filter {
private static final String url8 = "/webjars/"; private static final String url8 = "/webjars/";
private static final String url9 = "/check_code"; private static final String url9 = "/check_code";
private static final String url10 = "/reset_pwd"; private static final String url10 = "/reset_pwd";
private static final String url11 = "/get_token";
private static final String url12 = "/report_error_msg";
private static final String url13 = "/bind";
@Override @Override
public void init(FilterConfig filterConfig) { public void init(FilterConfig filterConfig) {
...@@ -51,8 +58,8 @@ public class JwtFilter implements Filter { ...@@ -51,8 +58,8 @@ public class JwtFilter implements Filter {
boolean check = true; boolean check = true;
String uri = request.getRequestURI(); String uri = request.getRequestURI();
if (uri.contains(url1) || uri.contains(url2) || uri.contains(url3) || uri.contains(url4) || uri.contains(url7) || uri.contains(url8) || uri.contains(url9) || uri.contains(url10)) { if (uri.contains(url1) || uri.contains(url2) || uri.contains(url3) || uri.contains(url4) || uri.contains(url7) || uri.contains(url8) || uri.contains(url9) || uri.contains(url11)) {
if (uri.contains(url1)) { if (uri.contains(url1) || uri.contains(url2)) {
uri = XssUtil.checkXSS(uri); uri = XssUtil.checkXSS(uri);
UserUtils.setUri(uri); UserUtils.setUri(uri);
} }
...@@ -64,20 +71,27 @@ public class JwtFilter implements Filter { ...@@ -64,20 +71,27 @@ public class JwtFilter implements Filter {
} }
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
request.setAttribute("msg", "token不能为空"); request.setAttribute("msg", "认证信息不能为空");
request.getRequestDispatcher("/iot_license/fail").forward(request, response); request.getRequestDispatcher("/iot_license/fail").forward(request, response);
return;
} else { } else {
DecodedJWT jwt = JwtUtil.verifyToken(token); DecodedJWT jwt = JwtUtil.verifyToken(token);
if (jwt == null) { if (jwt == null) {
request.setAttribute("msg", "非法token"); request.setAttribute("msg", "认证信息非法");
request.getRequestDispatcher("/iot_license/fail").forward(request, response); request.getRequestDispatcher("/iot_license/fail").forward(request, response);
return;
} else { } else {
Map<String, Claim> userData = jwt.getClaims(); Map<String, Claim> userData = jwt.getClaims();
if (userData == null) { if (userData == null) {
request.setAttribute("msg", "非法token"); request.setAttribute("msg", "认证信息非法");
request.getRequestDispatcher("/iot_license/fail").forward(request, response); request.getRequestDispatcher("/iot_license/fail").forward(request, response);
return; return;
} }
// 终端设备放行
if (uri.contains(url12) || uri.contains(url13)) {
filterChain.doFilter(request, response);
return;
}
String userId = userData.get("userId").asString(); String userId = userData.get("userId").asString();
String userName = userData.get("userName").asString(); String userName = userData.get("userName").asString();
String password = ""; String password = "";
......
package iot.sixiang.license.mapper; package iot.sixiang.license.mapper;
import iot.sixiang.license.entity.Device;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import iot.sixiang.license.entity.Device;
import iot.sixiang.license.model.vo.DeviceVo; import iot.sixiang.license.model.vo.DeviceVo;
import java.util.List; import java.util.List;
/** /**
* <p>
* Mapper 接口 * Mapper 接口
* </p>
* *
* @author m33 * @author m33
* @since 2022-06-08 * @since 2022-06-08
*/ */
public interface DeviceMapper extends BaseMapper<Device> { public interface DeviceMapper extends BaseMapper<Device> {
List<DeviceVo> getDeviceList(String appName, String userName, String sn, Integer status);
List<DeviceVo> getDeviceList(String appName, String userName);
boolean addDevice(String sn, String appId); boolean addDevice(String sn, String appId);
} }
package iot.sixiang.license.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import iot.sixiang.license.entity.PmsUseLog;
import iot.sixiang.license.model.vo.DeviceVo;
import java.util.List;
/**
* Created by M=54G
* Date 11/23/22 3:12 PM
* Description
*/
public interface PmsUseLogMapper extends BaseMapper<PmsUseLog> {
List<PmsUseLog> getPmsUseLogList(String sn, Integer status);
}
...@@ -75,7 +75,6 @@ public class ResResult<T> { ...@@ -75,7 +75,6 @@ public class ResResult<T> {
*/ */
public static ResResult failed() { public static ResResult failed() {
return new ResResult(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg()); return new ResResult(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg());
} }
public ResResult setCodeValue(long code) { public ResResult setCodeValue(long code) {
......
...@@ -11,6 +11,7 @@ public class SessionContext { ...@@ -11,6 +11,7 @@ public class SessionContext {
private String appId; private String appId;
private String appKey; private String appKey;
private String sn; private String sn;
private int useLogId;// 使用日志标识
private boolean authStatus;//授权验证状态 private boolean authStatus;//授权验证状态
private int status;//当前状态,0 offline,1 online private int status;//当前状态,0 offline,1 online
private String online;//上线时间 private String online;//上线时间
......
package iot.sixiang.license.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class GetTerminalDeviceTokenDTO {
@ApiModelProperty("应用id")
private String appId;
@ApiModelProperty("设备编号")
private String sn;
@ApiModelProperty("签名")
private String sign;
}
package iot.sixiang.license.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ReportErrorMsgDTO {
@ApiModelProperty("错误标识id")
private Integer id;
@ApiModelProperty("错误码")
private String errorCode;
@ApiModelProperty("错误信息")
private String errorMsg;
}
package iot.sixiang.license.model.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class TerminalDevieBindDTO {
@ApiModelProperty("设备编码")
private String sn;
@ApiModelProperty("绑定的SN")
private String snBind;
}
...@@ -8,7 +8,7 @@ import lombok.Data; ...@@ -8,7 +8,7 @@ import lombok.Data;
public class DeviceDetailVo extends DeviceVo { public class DeviceDetailVo extends DeviceVo {
@ApiModelProperty("当前状态,0 offline,1 online") @ApiModelProperty("当前状态,0 offline,1 online")
private int status; private int curStatus;
@ApiModelProperty("上线时间") @ApiModelProperty("上线时间")
private String online; private String online;
......
...@@ -11,7 +11,6 @@ import java.util.Date; ...@@ -11,7 +11,6 @@ import java.util.Date;
*/ */
@Data @Data
public class DeviceVo implements Serializable { public class DeviceVo implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("设备Id") @ApiModelProperty("设备Id")
...@@ -26,6 +25,12 @@ public class DeviceVo implements Serializable { ...@@ -26,6 +25,12 @@ public class DeviceVo implements Serializable {
@ApiModelProperty("设备编号") @ApiModelProperty("设备编号")
private String sn; private String sn;
@ApiModelProperty("绑定的设备编号")
private String snBind;
@ApiModelProperty("状态 0:未使用,1:已使用,2:失效")
private Integer status;
@ApiModelProperty("设备状态 0:正常 1:禁用") @ApiModelProperty("设备状态 0:正常 1:禁用")
private int blackFlag; private int blackFlag;
...@@ -34,5 +39,4 @@ public class DeviceVo implements Serializable { ...@@ -34,5 +39,4 @@ public class DeviceVo implements Serializable {
@ApiModelProperty("更新时间") @ApiModelProperty("更新时间")
private Date updateTime; private Date updateTime;
} }
...@@ -28,6 +28,9 @@ public class ResourceVo { ...@@ -28,6 +28,9 @@ public class ResourceVo {
@ApiModelProperty("设备编号") @ApiModelProperty("设备编号")
private String sn; private String sn;
@ApiModelProperty("设备状态")
private String status;
@ApiModelProperty("应用id") @ApiModelProperty("应用id")
private String appId; private String appId;
} }
\ No newline at end of file
...@@ -10,6 +10,16 @@ import lombok.Data; ...@@ -10,6 +10,16 @@ import lombok.Data;
@Data @Data
public class UserVo extends User { public class UserVo extends User {
@ApiModelProperty("设备数量") @ApiModelProperty("总设备")
public int deviceCount; public int totalDevice;
@ApiModelProperty("已使用设备")
public int inUseDevice;
@ApiModelProperty("未使用设备")
public int unUseDevice;
@ApiModelProperty("失效设备")
public int failedDevice;
} }
...@@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j; ...@@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
@Data @Data
@Slf4j @Slf4j
public class BaseConnectionListener implements ChannelFutureListener { public class BaseConnectionListener implements ChannelFutureListener {
public String appId; public String sn;
public String host; public String host;
public int port; public int port;
......
...@@ -79,6 +79,10 @@ public class ResourceManager { ...@@ -79,6 +79,10 @@ public class ResourceManager {
cell = row.createCell((short)4); //第五个单元格 cell = row.createCell((short)4); //第五个单元格
cell.setCellValue("sn"); cell.setCellValue("sn");
cell.setCellStyle(styleRow); cell.setCellStyle(styleRow);
cell = row.createCell((short)5); //第六个单元格
cell.setCellValue("状态");
cell.setCellStyle(styleRow);
//第五步插入数据 //第五步插入数据
List<ResourceVo> resourceList = resourceService.getResource(userId); List<ResourceVo> resourceList = resourceService.getResource(userId);
for (int i = 0; i < resourceList.size(); i++) { for (int i = 0; i < resourceList.size(); i++) {
...@@ -106,9 +110,13 @@ public class ResourceManager { ...@@ -106,9 +110,13 @@ public class ResourceManager {
cell = row.createCell((short)4); // 第五个单元格 cell = row.createCell((short)4); // 第五个单元格
cell.setCellValue(resourceVo.getSn()); cell.setCellValue(resourceVo.getSn());
cell.setCellStyle(style); cell.setCellStyle(style);
cell = row.createCell((short)5); // 第六个单元格
cell.setCellValue(resourceVo.getStatus());
cell.setCellStyle(style);
} }
//在填完所有值以后,对每一列设置自适应宽度 //在填完所有值以后,对每一列设置自适应宽度
for (int n = 0; n < 5; n++) { for (int n = 0; n < 6; n++) {
sheet.autoSizeColumn(n); sheet.autoSizeColumn(n);
} }
wb.write(os); wb.write(os);
......
...@@ -3,19 +3,19 @@ package iot.sixiang.license.service; ...@@ -3,19 +3,19 @@ package iot.sixiang.license.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import iot.sixiang.license.entity.Device; import iot.sixiang.license.entity.Device;
import iot.sixiang.license.model.PageInfoModel; import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.dto.TerminalDevieBindDTO;
import iot.sixiang.license.model.vo.DeviceVo; import iot.sixiang.license.model.vo.DeviceVo;
/** /**
* <p>
* 服务类 * 服务类
* </p>
* *
* @author m33 * @author m33
* @since 2022-06-08 * @since 2022-06-08
*/ */
public interface DeviceService extends IService<Device> { public interface DeviceService extends IService<Device> {
PageInfoModel<DeviceVo> getDeviceList(int pageNo, int pageSize, String appName, String userName, String sn, Integer status);
PageInfoModel<DeviceVo> getDeviceList(int pageNo, int pageSize, String appName, String userName);
boolean addDevice(String appId, int count); boolean addDevice(String appId, int count);
Boolean terminalDevieBind(TerminalDevieBindDTO terminalDevieBindDTO);
} }
package iot.sixiang.license.service;
import iot.sixiang.license.entity.PmsUseLog;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.dto.ReportErrorMsgDTO;
/**
* Created by M=54G
* Date 11/23/22 3:09 PM
* Description
*/
public interface PmsUseService {
int createUseLog(String sn);
void createFailUseLog(String sn, String message);
void success(int useLogId);
PageInfoModel<PmsUseLog> getPmsUseLogList(int pageNo, int pageSize, String sn, Integer status);
boolean reportErrorMsg(ReportErrorMsgDTO reportErrorMsgDTO);
boolean deletePmsUseLogById(Integer id);
}
package iot.sixiang.license.service;
import iot.sixiang.license.model.BaseResult;
import iot.sixiang.license.model.ResResult;
import iot.sixiang.license.model.dto.GetTerminalDeviceTokenDTO;
import iot.sixiang.license.model.dto.ReportErrorMsgDTO;
import iot.sixiang.license.model.dto.TerminalDevieBindDTO;
import java.util.List;
public interface TerminalDeviceService {
ResResult getToken(GetTerminalDeviceTokenDTO getTerminalDeviceTokenDTO);
BaseResult reportErrorMsg(List<ReportErrorMsgDTO> reportErrorMsgDTO);
BaseResult terminalDeviceBind(TerminalDevieBindDTO terminalDevieBindDTO);
}
package iot.sixiang.license.service.impl; package iot.sixiang.license.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import iot.sixiang.license.consts.ResultCode; import iot.sixiang.license.consts.ResultCode;
import iot.sixiang.license.device.DeviceManager; import iot.sixiang.license.device.DeviceManager;
...@@ -7,6 +8,7 @@ import iot.sixiang.license.entity.Device; ...@@ -7,6 +8,7 @@ import iot.sixiang.license.entity.Device;
import iot.sixiang.license.handler.IotLicenseException; import iot.sixiang.license.handler.IotLicenseException;
import iot.sixiang.license.mapper.DeviceMapper; import iot.sixiang.license.mapper.DeviceMapper;
import iot.sixiang.license.model.PageInfoModel; import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.dto.TerminalDevieBindDTO;
import iot.sixiang.license.model.vo.DeviceVo; import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.service.DeviceService; import iot.sixiang.license.service.DeviceService;
import iot.sixiang.license.util.CommonUtil; import iot.sixiang.license.util.CommonUtil;
...@@ -17,29 +19,27 @@ import org.springframework.stereotype.Service; ...@@ -17,29 +19,27 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* <p>
* 服务实现类 * 服务实现类
* </p>
* *
* @author m33 * @author m33
* @since 2022-06-08 * @since 2022-06-08
*/ */
@Service @Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService { public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
@Resource @Resource
private DeviceMapper deviceMapper; private DeviceMapper deviceMapper;
@Override @Override
public PageInfoModel<DeviceVo> getDeviceList(int pageNo, int pageSize, String appName, String userName) { public PageInfoModel<DeviceVo> getDeviceList(int pageNo, int pageSize, String appName, String userName, String sn, Integer status) {
if(pageNo == 0 || pageSize == 0) { if (pageNo == 0 || pageSize == 0) {
throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(),ResultCode.VALIDATE_FAILED.getMsg()); throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(), ResultCode.VALIDATE_FAILED.getMsg());
} }
List<DeviceVo> deviceTypes = deviceMapper.getDeviceList(appName,userName); List<DeviceVo> deviceTypes = deviceMapper.getDeviceList(appName, userName, sn, status);
deviceTypes = deviceTypes.stream().sorted(Comparator.comparing(DeviceVo::getCreateTime, Comparator.reverseOrder())).collect(Collectors.toList()); deviceTypes = deviceTypes.stream().sorted(Comparator.comparing(DeviceVo::getCreateTime, Comparator.reverseOrder())).collect(Collectors.toList());
List<DeviceVo> result = new ArrayList<>(); List<DeviceVo> result = new ArrayList<>();
int begin = (pageNo - 1) * pageSize; int begin = (pageNo - 1) * pageSize;
...@@ -54,8 +54,8 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme ...@@ -54,8 +54,8 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
@Override @Override
public boolean addDevice(String appId, int count) { public boolean addDevice(String appId, int count) {
if(StringUtils.isEmpty(appId) || count == 0) { if (StringUtils.isEmpty(appId) || count == 0) {
throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(),ResultCode.VALIDATE_FAILED.getMsg()); throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(), ResultCode.VALIDATE_FAILED.getMsg());
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
String sn = CommonUtil.genRandomNum(18); String sn = CommonUtil.genRandomNum(18);
...@@ -68,4 +68,32 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme ...@@ -68,4 +68,32 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
deviceManager.initDevices(); deviceManager.initDevices();
return true; return true;
} }
@Override
public Boolean terminalDevieBind(TerminalDevieBindDTO terminalDevieBindDTO) {
String sn = terminalDevieBindDTO.getSn();
String snBind = terminalDevieBindDTO.getSnBind();
LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Device::getSn, sn).last("limit 1");
Device device = deviceMapper.selectOne(queryWrapper);
if (device != null) {
if (!StringUtils.isEmpty(device.getSnBind())) {
if (device.getSnBind().equals(snBind)) {
return true;
} else {
throw new IotLicenseException(403, "sn已被绑定");
}
}
device.setSnBind(snBind);
device.setStatus(1);
device.setUpdateTime(new Date());
int res = deviceMapper.updateById(device);
if (res >= 0) {
return true;
} else {
return false;
}
}
return false;
}
} }
package iot.sixiang.license.service.impl;
import iot.sixiang.license.consts.ResultCode;
import iot.sixiang.license.entity.PmsUseLog;
import iot.sixiang.license.handler.IotLicenseException;
import iot.sixiang.license.mapper.PmsUseLogMapper;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.dto.ReportErrorMsgDTO;
import iot.sixiang.license.service.PmsUseService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by M=54G
* Date 11/23/22 3:10 PM
* Description
*/
@Service
public class PmsUseServiceImpl implements PmsUseService {
@Resource
private PmsUseLogMapper pmsUseLogMapper;
@Override
public int createUseLog(String sn) {
PmsUseLog pmsUseLog = getPmsUseLog(sn);
pmsUseLogMapper.insert(pmsUseLog);
return pmsUseLog.getId();
}
@Override
public void createFailUseLog(String sn, String message) {
PmsUseLog pmsUseLog = getPmsUseLog(sn);
pmsUseLog.setStatus(0);
pmsUseLog.setMessage(message);
pmsUseLogMapper.insert(pmsUseLog);
}
@Override
public void success(int useLogId) {
PmsUseLog pmsUseLog = new PmsUseLog();
pmsUseLog.setId(useLogId);
pmsUseLog.setStatus(1);
pmsUseLogMapper.updateById(pmsUseLog);
}
@Override
public PageInfoModel<PmsUseLog> getPmsUseLogList(int pageNo, int pageSize, String sn, Integer status) {
if (pageNo == 0 || pageSize == 0) {
throw new IotLicenseException(ResultCode.VALIDATE_FAILED.getCode(), ResultCode.VALIDATE_FAILED.getMsg());
}
List<PmsUseLog> pmsUseLogs = pmsUseLogMapper.getPmsUseLogList(sn, status);
List<PmsUseLog> result = new ArrayList<>();
int begin = (pageNo - 1) * pageSize;
if (begin >= 0 && pmsUseLogs.size() > 0) {
result = pmsUseLogs.stream().skip(begin).limit(pageSize).collect(Collectors.toList());
}
PageInfoModel<PmsUseLog> pmsUseLogPageInfoModel = new PageInfoModel<>();
pmsUseLogPageInfoModel.setTotal(pmsUseLogs.size());
pmsUseLogPageInfoModel.setResult(result);
return pmsUseLogPageInfoModel;
}
@Override
public boolean reportErrorMsg(ReportErrorMsgDTO reportErrorMsgDTO) {
Integer id = reportErrorMsgDTO.getId();
String errorCode = reportErrorMsgDTO.getErrorCode();
String errorMsg = reportErrorMsgDTO.getErrorMsg();
PmsUseLog pmsUseLog = new PmsUseLog();
pmsUseLog.setId(id);
pmsUseLog.setStatus(0);
pmsUseLog.setErrorCode(errorCode);
pmsUseLog.setMessage(errorMsg);
pmsUseLog.setUpdateTime(new Date());
int res = pmsUseLogMapper.updateById(pmsUseLog);
return res > 0;
}
@Override
public boolean deletePmsUseLogById(Integer id) {
PmsUseLog pmsUseLog = new PmsUseLog();
pmsUseLog.setId(id);
pmsUseLog.setStatus(0);
pmsUseLog.setUpdateTime(new Date());
pmsUseLog.setDeleted(1);
int res = pmsUseLogMapper.updateById(pmsUseLog);
return res > 0;
}
private PmsUseLog getPmsUseLog(String sn) {
PmsUseLog pmsUseLog = new PmsUseLog();
Date date = new Date();
pmsUseLog.setCreateTime(date);
pmsUseLog.setUpdateTime(date);
pmsUseLog.setSn(sn);
return pmsUseLog;
}
}
package iot.sixiang.license.service.impl;
import iot.sixiang.license.auth.AuthManager;
import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.handler.IotLicenseException;
import iot.sixiang.license.jwt.JwtUtil;
import iot.sixiang.license.jwt.LoginUser;
import iot.sixiang.license.model.BaseResult;
import iot.sixiang.license.model.ResResult;
import iot.sixiang.license.model.dto.GetTerminalDeviceTokenDTO;
import iot.sixiang.license.model.dto.ReportErrorMsgDTO;
import iot.sixiang.license.model.dto.TerminalDevieBindDTO;
import iot.sixiang.license.service.DeviceService;
import iot.sixiang.license.service.PmsUseService;
import iot.sixiang.license.service.TerminalDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
@Slf4j
@Service
public class TerminalDeviceServiceImpl implements TerminalDeviceService {
@Autowired
private AuthManager authManager;
@Autowired
private DeviceService deviceService;
@Autowired
private PmsUseService pmsUseService;
@Resource
private DeviceManager deviceManager;
@Override
public ResResult getToken(GetTerminalDeviceTokenDTO getTerminalDeviceTokenDTO) {
String appId = getTerminalDeviceTokenDTO.getAppId();
String sn = getTerminalDeviceTokenDTO.getSn();
String sign = getTerminalDeviceTokenDTO.getSign();
if (StringUtils.isEmpty(appId)) {
throw new IotLicenseException(403, "应用id不能为空");
}
if (StringUtils.isEmpty(sn)) {
throw new IotLicenseException(403, "终端编号不能为空");
}
if (StringUtils.isEmpty(sign)) {
throw new IotLicenseException(403, "签名不能为空");
}
boolean authResult = authManager.authTerminalDevice(appId, sn, sign);
if (authResult) {
LoginUser user = new LoginUser();
user.setUserId(appId);
user.setUserName(sn);
String token = JwtUtil.createToken(user);
return ResResult.success().record(token);
} else {
return ResResult.validate_failed();
}
}
@Override
public BaseResult reportErrorMsg(List<ReportErrorMsgDTO> reportErrorMsgDTOs) {
if (reportErrorMsgDTOs == null || reportErrorMsgDTOs.size() == 0) {
return BaseResult.validate_failed();
}
reportErrorMsgDTOs.sort(Comparator.comparingInt(ReportErrorMsgDTO::getId));
for (int i = 0; i < reportErrorMsgDTOs.size() - 1; i++) {
ReportErrorMsgDTO reportErrorMsgDTO = reportErrorMsgDTOs.get(i);
Integer id = reportErrorMsgDTO.getId();
if (id == null || id == 0) {
return BaseResult.validate_failed();
}
pmsUseService.deletePmsUseLogById(id);
}
ReportErrorMsgDTO reportErrorMsgDTO = reportErrorMsgDTOs.get(reportErrorMsgDTOs.size() - 1);
if (reportErrorMsgDTO.getId() == null || reportErrorMsgDTO.getId() == 0 || reportErrorMsgDTO.getErrorCode() == null) {
return BaseResult.validate_failed();
} else {
if ("0".equals(reportErrorMsgDTO.getErrorCode())) {
pmsUseService.success(reportErrorMsgDTO.getId());
return BaseResult.success();
} else {
boolean res = pmsUseService.reportErrorMsg(reportErrorMsgDTO);
if (res) {
return BaseResult.success();
} else {
return BaseResult.failed();
}
}
}
}
@Override
public BaseResult terminalDeviceBind(TerminalDevieBindDTO terminalDevieBindDTO) {
String sn = terminalDevieBindDTO.getSn();
String snBind = terminalDevieBindDTO.getSnBind();
if (StringUtils.isEmpty(sn) || StringUtils.isEmpty(snBind)) {
return BaseResult.validate_failed();
}
Boolean res = deviceService.terminalDevieBind(terminalDevieBindDTO);
if (res) {
deviceManager.initDevices();
return BaseResult.success();
} else {
return BaseResult.failed();
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" scanPeriod="10 seconds">
<!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 -->
<!-- <logger name="iot.sixiang.license" level="debug" />-->
<!--控制台输出的格式设置 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 控制台输出的日志 的格式 -->
<encoder>
<pattern>
%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger{96}:%line - %msg%n
</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 只是DEBUG级别以上的日志才显示 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!--文件输出的格式设置 -->
<appender name="ALL_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志日常打印文件 -->
<file>logs/license.log</file>
<!-- 配置日志所生成的目录以及生成文件名的规则 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/license.log-%d{yyyy-MM-dd}.%i</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为365天,365天之前的都将被清理掉 -->
<maxHistory>365</maxHistory>
<!-- 日志总保存量为10GB -->
<totalSizeCap>100GB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--文件达到 最大128MB时会被压缩和切割 -->
<maxFileSize>40 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<!-- 文件输出的日志 的格式 -->
<encoder>
<pattern>
%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger{96}:%line - %msg%n
</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- Safely log to the same file from multiple JVMs. Degrades performance! -->
<prudent>false</prudent>
</appender>
<!--文件输出的格式设置 -->
<appender name="MSG_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志日常打印文件 -->
<file>logs/message.log</file>
<!-- 配置日志所生成的目录以及生成文件名的规则 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/message.log-%d{yyyy-MM-dd}.%i</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为365天,365天之前的都将被清理掉 -->
<maxHistory>365</maxHistory>
<!-- 日志总保存量为10GB -->
<totalSizeCap>100GB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--文件达到 最大128MB时会被压缩和切割 -->
<maxFileSize>40 MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!-- 此日志文档只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 文件输出的日志 的格式 -->
<encoder>
<pattern>
%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %5level %logger{96}:%line - %msg%n
</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- Safely log to the same file from multiple JVMs. Degrades performance! -->
<prudent>false</prudent>
</appender>
<!-- Enable FILE and STDOUT appenders for all log messages. By default,
only log at level INFO and above. -->
<!--这里选择INFO就代表,进行INFO级别输出记录,那么在控制台也好,log文件也好只记录INFO及以上级别的日志,这里相当于第一道设置-->
<root level="info">
<appender-ref ref="STDOUT" />
<appender-ref ref="ALL_FILE" />
<appender-ref ref="MSG_FILE" />
</root>
</configuration>
\ No newline at end of file
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<mapper namespace="iot.sixiang.license.mapper.DeviceMapper"> <mapper namespace="iot.sixiang.license.mapper.DeviceMapper">
<select id="getDeviceList" resultType="iot.sixiang.license.model.vo.DeviceVo"> <select id="getDeviceList" resultType="iot.sixiang.license.model.vo.DeviceVo">
SELECT de.device_id,app_name,user_name,sn,de.create_time,de.update_time,de.device_id IN (select device_id from device_black) AS blackFlag FROM device AS de SELECT de.device_id,app_name,user_name,sn,sn_bind,de.status,de.create_time,de.update_time,de.device_id IN (select
device_id from device_black) AS blackFlag FROM device AS de
JOIN apply AS app ON de.app_id = app.app_id JOIN apply AS app ON de.app_id = app.app_id
JOIN USER AS us ON us.user_id = app.user_id JOIN USER AS us ON us.user_id = app.user_id
where 1=1 where 1=1
...@@ -13,10 +14,17 @@ ...@@ -13,10 +14,17 @@
<if test="null != userName and '' != userName"> <if test="null != userName and '' != userName">
and user_name like concat('%',#{userName},'%') and user_name like concat('%',#{userName},'%')
</if> </if>
<if test="null != sn and '' != sn">
and sn like concat('%',#{sn},'%')
</if>
<if test="null != status">
and status = #{status}
</if>
</select> </select>
<insert id="addDevice" parameterType="iot.sixiang.license.entity.Device"> <insert id="addDevice" parameterType="iot.sixiang.license.entity.Device">
insert into device(sn, app_id, create_time, update_time) values (#{sn},#{appId}, now(), now()) insert into device(sn, app_id, create_time, update_time)
values (#{sn}, #{appId}, now(), now())
</insert> </insert>
</mapper> </mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="iot.sixiang.license.mapper.PmsUseLogMapper">
<select id="getPmsUseLogList" resultType="iot.sixiang.license.entity.PmsUseLog">
SELECT * FROM pms_use_log
where 1=1
<if test="null != sn and '' != sn">
and sn like concat('%',#{sn},'%')
</if>
<if test="null != status">
and status = #{status}
</if>
and deleted = 0
order by create_time desc
</select>
</mapper>
\ No newline at end of file
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<mapper namespace="iot.sixiang.license.mapper.ResourceMapper"> <mapper namespace="iot.sixiang.license.mapper.ResourceMapper">
<select id="getResource" resultType="iot.sixiang.license.model.vo.ResourceVo"> <select id="getResource" resultType="iot.sixiang.license.model.vo.ResourceVo">
SELECT a.user_name,a.password,a.company,b.app_name,b.app_key,c.sn, b.app_id SELECT a.user_name,a.password,a.company,b.app_name,b.app_key,c.sn, b.app_id,
(CASE c.`status` WHEN 1 THEN '已使用' WHEN 2 THEN '失效' ELSE '未使用' END) `status`
FROM USER a, apply b, device c WHERE a.user_id = b.user_id FROM USER a, apply b, device c WHERE a.user_id = b.user_id
AND b.app_id = c.app_id AND a.user_id = #{userId} AND b.app_id = c.app_id AND a.user_id = #{userId}
</select> </select>
......
...@@ -15,7 +15,14 @@ ...@@ -15,7 +15,14 @@
</update> </update>
<select id="getUserList" resultType="iot.sixiang.license.model.vo.UserVo"> <select id="getUserList" resultType="iot.sixiang.license.model.vo.UserVo">
SELECT user.user_id, user_name, PASSWORD, company, user.create_time, user.update_time ,COUNT(device.`device_id`) deviceCount FROM USER LEFT JOIN apply ON user.user_id = apply.user_id LEFT JOIN device ON apply.app_id = device.app_id SELECT user.user_id, user_name, password, company, user.create_time, user.update_time,
COUNT(device.`device_id`) totalDevice,
COUNT(if(device.device_id is NOT NULL, if (device.`status` = 0 or device.`status` is NULL, 1, NULL), NULL)) unUseDevice,
COUNT(if(device.device_id is NOT NULL and device.`status` = 1, 1, NULL)) inUseDevice,
COUNT(if(device.device_id is NOT NULL and device.`status` = 2, 1, NULL)) failedDevice
FROM USER
LEFT JOIN apply ON user.user_id = apply.user_id
LEFT JOIN device ON apply.app_id = device.app_id
where 1=1 where 1=1
<if test="null != userName and '' != userName"> <if test="null != userName and '' != userName">
and user_name like concat('%',#{userName},'%') and user_name like concat('%',#{userName},'%')
......
package iot.sixiang.license;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
/**
* Created by M=54G
* Date 9/14/22 3:08 PM
* Description
*/
@SpringBootTest
@ActiveProfiles({"test-acc"})
@Slf4j
public class BaseTest {
protected void log(Object object) {
log.info(JSON.toJSONString(object));
}
}
\ No newline at end of file
...@@ -22,14 +22,47 @@ import java.util.Random; ...@@ -22,14 +22,47 @@ import java.util.Random;
*/ */
public class DeviceControllerTest { public class DeviceControllerTest {
@Test
void terminalDeviceSign() {
String appId = "7j26zr7en9fiyoyvjz";
String sn = "8HOE8JH4EFSEV28534";
// String snBind = "snabcd";
String appKey = "2";
String string = "app_id=" + appId + "&sn=" + sn;
String sign = HmacUtil.encrypt(string, appKey, HmacUtil.HMAC_SHA1);
System.out.println("token appId:" + appId);
System.out.println("token sn:" + sn);
System.out.println("token sign:" + sign);
}
@Test
void tokenSign() {
String appId = "ebsh71dp5t1ck948l5";
String sn = "ERE54S619LNYMPKVN9";
String snBind = "snabcd";
String appKey = "110801";
String string = "app_id=" + appId + "&sn=" + sn + "&sn_bind=" + snBind;
String sign = HmacUtil.encrypt(string, appKey, HmacUtil.HMAC_SHA1);
System.out.println("token appId:" + appId);
System.out.println("token sn:" + sn);
System.out.println("token sign:" + sign);
}
@Test @Test
void auth() { void auth() {
String appId = "ebsh71dp5t1ck948l5"; String appId = "ebsh71dp5t1ck948l5";
String sn = "ERE54S619LNYMPKVN9"; String sn = "ERE54S619LNYMPKVN9";
String snBind = "snabcd";
String appKey = "110801"; String appKey = "110801";
//byte[] baseKeyBytes = "nAOq38p4bGQyF4FG".getBytes(); //byte[] baseKeyBytes = "nAOq38p4bGQyF4FG".getBytes();
//System.out.println(baseKeyBytes.length); //System.out.println(baseKeyBytes.length);
byte[] allBytes = getAuthSendBytes(appId, sn, appKey); byte[] allBytes = getAuthSendBytes(appId, sn, snBind, appKey);
System.out.println(bytes2Hex(allBytes)); System.out.println(bytes2Hex(allBytes));
} }
...@@ -39,8 +72,9 @@ public class DeviceControllerTest { ...@@ -39,8 +72,9 @@ public class DeviceControllerTest {
int serverPort = 18889; int serverPort = 18889;
String appId = "ebsh71dp5t1ck948l5"; String appId = "ebsh71dp5t1ck948l5";
String sn = "ERE54S619LNYMPKVN9"; String sn = "ERE54S619LNYMPKVN9";
String snBind = "ZA2207G5NQ";
String appKey = "110801"; String appKey = "110801";
socket(serverIp, serverPort, appId, sn, appKey); socket(serverIp, serverPort, appId, sn, snBind, appKey);
} }
@Test @Test
...@@ -49,18 +83,19 @@ public class DeviceControllerTest { ...@@ -49,18 +83,19 @@ public class DeviceControllerTest {
int serverPort = 18889; int serverPort = 18889;
String appId = "mny3i9pgg0xxs520qf"; String appId = "mny3i9pgg0xxs520qf";
String sn = "IU23404BR1CQJOC63Q"; String sn = "IU23404BR1CQJOC63Q";
String snBind = "snabcd";
String appKey = "20221114"; String appKey = "20221114";
socket(serverIp, serverPort, appId, sn, appKey); socket(serverIp, serverPort, appId, sn, snBind, appKey);
} }
@SneakyThrows @SneakyThrows
void socket(String serverIp, int serverPort, String appId, String sn, String appKey) { void socket(String serverIp, int serverPort, String appId, String sn, String snBind, String appKey) {
Socket socket = new Socket(serverIp, serverPort); Socket socket = new Socket(serverIp, serverPort);
socket.setKeepAlive(true); socket.setKeepAlive(true);
System.out.println("connect success..."); System.out.println("connect success...");
// 事先组装好要发送的鉴权信息 // 事先组装好要发送的鉴权信息
byte[] authSendBytes = getAuthSendBytes(appId, sn, appKey); byte[] authSendBytes = getAuthSendBytes(appId, sn, snBind, appKey);
OutputStream outputStream = socket.getOutputStream(); OutputStream outputStream = socket.getOutputStream();
...@@ -103,7 +138,7 @@ public class DeviceControllerTest { ...@@ -103,7 +138,7 @@ public class DeviceControllerTest {
return requestBytes; return requestBytes;
} }
private byte[] getAuthSendBytes(String appId, String sn, String appKey) { private byte[] getAuthSendBytes(String appId, String sn, String snBind, String appKey) {
byte[] stxBytes = {(byte) 0x55, (byte) 0xaa}; byte[] stxBytes = {(byte) 0x55, (byte) 0xaa};
// 这部分生成内容 // 这部分生成内容
...@@ -118,7 +153,7 @@ public class DeviceControllerTest { ...@@ -118,7 +153,7 @@ public class DeviceControllerTest {
for (int i = 0; i < randomBytes.length; i++) { for (int i = 0; i < randomBytes.length; i++) {
sm4KeyBytes[i] = (byte) (randomBytes[i] ^ baseKeyBytes[i]); sm4KeyBytes[i] = (byte) (randomBytes[i] ^ baseKeyBytes[i]);
} }
String string = "app_id=" + appId + "&sn=" + sn; String string = "app_id=" + appId + "&sn=" + sn + "&sn_bind=" + snBind;
String sign = HmacUtil.encrypt(string, appKey, HmacUtil.HMAC_SHA1); String sign = HmacUtil.encrypt(string, appKey, HmacUtil.HMAC_SHA1);
// 组装 // 组装
AuthData authData = new AuthData(); AuthData authData = new AuthData();
......
package iot.sixiang.license.service;
import iot.sixiang.license.BaseTest;
import org.junit.jupiter.api.Test;
import javax.annotation.Resource;
/**
* Created by M=54G
* Date 11/23/22 3:39 PM
* Description
*/
public class PmsUseServiceTest extends BaseTest {
@Resource
private PmsUseService pmsUseService;
@Test
void addLog() {
log(pmsUseService.createUseLog("abcd"));
}
@Test
void updateLog() {
pmsUseService.success(1);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment