初次提交代码

This commit is contained in:
2026-01-11 15:33:22 +08:00
commit 6603c6f4a1
455 changed files with 32175 additions and 0 deletions
@@ -0,0 +1,162 @@
package com.Modules.Device;
import com.common.entity.DeviceDevice;
import com.haobang.config.AppConfig;
import com.kafka.kafkaProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.common.service.DeviceDeviceService;
import com.common.service.DeviceUnknownService;
import com.common.service.DeviceCollectTaskService;
import com.haobang.util.SpringContextUtil;
import java.time.format.DateTimeFormatter;
import java.util.List;
import com.common.entity.DeviceUnknown;
import com.common.entity.DeviceCollectTask;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import com.common.service.DeviceReceiveLogService;
import com.common.entity.DeviceReceiveLog;
import org.springframework.cache.CacheManager;
public class DeviceProcess {
private static final Logger logger = LoggerFactory.getLogger(DeviceProcess.class);
@Autowired
public static DeviceDeviceService deviceDeviceService =SpringContextUtil.getBean(DeviceDeviceService.class);
@Autowired
public static DeviceUnknownService deviceUnknownService =SpringContextUtil.getBean(DeviceUnknownService.class);
@Autowired
public static DeviceCollectTaskService deviceCollectTaskService =SpringContextUtil.getBean(DeviceCollectTaskService.class);
@Autowired
public static DeviceReceiveLogService deviceReceiveLogService =SpringContextUtil.getBean(DeviceReceiveLogService.class);
@Autowired
private DeviceDevice deviceDevice ;
@Autowired
private DeviceReceiveLog devicelog;
private String sourceIP;
public DeviceProcess(String source_ip) {
sourceIP=source_ip;
List<DeviceDevice> deviceList = deviceDeviceService.getByIpSafely(source_ip);
if (deviceList.size() >0)
{
deviceDevice= deviceList.get(0);
}
}
public DeviceDevice getDeviceDevice()
{
if(deviceDevice!=null) return this.deviceDevice;
return null;
}
public DeviceReceiveLog getDeviceReceiveLog()
{
if(devicelog!=null) return this.devicelog;
return null;
}
public int getDeviceID(String source_ip)
{
//默认deviceId =-1
int deviceId=-1 ;
List<DeviceDevice> deviceList= deviceDeviceService.getByIpSafely(source_ip);
if(deviceList.isEmpty()) {
logger.error("设备请求的Host IP非系统注册,请联系管理员添加设备信息!");
return deviceId;
}
if(deviceList.size()>1)
{
logger.error("设备请求的Host IP注册超过一条记录,请联系管理员处理!");
return deviceId;
}
return deviceList.get(0).getId();
}
public boolean IsBelongDeviceCollectTask( )
{
//当前判断是否归属
if(deviceDevice!=null )
{
int deviceCollectId =AppConfig.getDeviceCollectId();
if(deviceDevice.getDeviceCollectId()!=deviceCollectId)
{
logger.error("设备请求的Host IP不属于当前采集探针任务,请联系管理员核实!");
return false;
}
}
return true;
}
public boolean saveDeviceUnknow(String networkProtocol)
{
DeviceUnknown deviceUnknown =new DeviceUnknown() ;
List<DeviceUnknown> deviceList =deviceUnknownService.getDevicesByIp(this.sourceIP);
// 获取当前时间
LocalDateTime currentTime = LocalDateTime.now();
try
{
//已有deviceUnknow记录则更新最后发现时间
if(deviceList.size()>0)
{
deviceUnknownService.updateLastTime( deviceList.get(0).getId(),currentTime );
System.out.println("更新未知设备的最后发现时间,IP:"+this.sourceIP);
}
else {
//创建未知设备记录
DeviceCollectTask deviceCollectTask= deviceCollectTaskService.getById(AppConfig.getDeviceCollectId());
deviceUnknown.setDeviceCollectId( AppConfig.getDeviceCollectId());
deviceUnknown.setDeviceIp( this.sourceIP);
deviceUnknown.setFirstTime(currentTime);
if(deviceCollectTask!=null) deviceUnknown.setDeviceCollectName(deviceCollectTask.getTaskName());
deviceUnknown.setNetworkProtocol( networkProtocol );
deviceUnknown.setOrganizationId(0);
deviceUnknownService.createDevice(deviceUnknown);
logger.info("请求的Host IP :{}为未知,已创建记录 ",this.sourceIP);
}
}
catch(Exception e) {
logger.error("saveDeviceUnknow exception", e);
}
return true;
}
public boolean saveDeviceReceiveLog(String syslog ,boolean isSuccess ) {
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 定义格式化器,包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
// 转换为字符串
String timeString = now.format(formatter);
try {
// 创建设备接收日志对象
devicelog= DeviceReceiveLog.builder()
.deviceId(deviceDevice.getId())
.deviceCollectId(AppConfig.getDeviceCollectId())
.deviceIp(deviceDevice.getIp())
.receiveTime(now)
.receiveTimeStr(timeString)
.syslogMessage(syslog)
.pushSuccess(isSuccess)
.build();
deviceReceiveLogService.insertLog(devicelog);
} catch (Exception e) {
logger.error("saveDeviceReceiveLog exception", e);
return false;
}
return true;
}
}
@@ -0,0 +1,4 @@
package com.Modules.DeviceCollect;
public class DeviceCollectProcess {
}
@@ -0,0 +1,39 @@
package com;
import com.haobang.config.SyslogConfig;
import com.kafka.kafkaProducer;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.netty.SyslogServer;
import com.haobang.config.AppConfig;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import com.netty.SyslogServerBoth;
@MapperScan("com.common.mapper")
@SpringBootApplication
public class SyslogServeMainApp {
private static final Logger logger = LoggerFactory.getLogger(SyslogServeMainApp.class);
public static void main(String[] args) {
SpringApplication.run(SyslogServeMainApp.class, args);
try {
//System.out.println("syslogConfig TcpPort: "+ AppConfig.getSyslogTcpPort());
int tcpPort = args.length > 0 ? Integer.parseInt(args[0]) : AppConfig.getSyslogTcpPort() ;
int udpPort = args.length > 1 ? Integer.parseInt(args[1]) : AppConfig.getSyslogUdpPort();
//SyslogServer server = new SyslogServer(tcpPort, udpPort);
SyslogServerBoth server = new SyslogServerBoth(tcpPort, udpPort);
logger.info("Application SyslogServer start !");
server.start();
}catch ( Exception ex)
{
System.out.println("Application Catch Error message: "+ex.getMessage());
logger.error("Application Catch Error message: "+ex.getMessage());
}
}
}
@@ -0,0 +1,22 @@
package com.common.controller;
import com.common.entity.DeviceDevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.data.redis.core.RedisTemplate;
@RestController
@RequestMapping("/api/cache")
public class CacheController {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@GetMapping("/key/{key}")
public DeviceDevice getCacheValue(@PathVariable String key) {
// 这里先尝试作为字符串键获取
System.out.println("key:" +key);
//System.out.println(redisTemplate.opsForHash().entries(key).toString());
return (DeviceDevice) redisTemplate.opsForValue().get(key);
}
}
@@ -0,0 +1,136 @@
package com.common.controller;
import com.common.entity.DeviceCollectTask;
import com.common.service.DeviceCollectTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/collect-tasks")
public class DeviceCollectTaskController {
@Autowired
private DeviceCollectTaskService deviceCollectTaskService;
/**
* 根据ID查询采集任务
*/
@GetMapping("/{id}")
public ResponseEntity<DeviceCollectTask> getById(@PathVariable Integer id) {
DeviceCollectTask task = deviceCollectTaskService.getById(id);
return ResponseEntity.ok(task);
}
/**
* 查询所有采集任务
*/
@GetMapping
public ResponseEntity<List<DeviceCollectTask>> getAll() {
List<DeviceCollectTask> tasks = deviceCollectTaskService.getAll();
return ResponseEntity.ok(tasks);
}
/**
* 根据设备ID查询采集任务
*/
@GetMapping("/device/{deviceId}")
public ResponseEntity<List<DeviceCollectTask>> getByDeviceId(@PathVariable Integer deviceId) {
List<DeviceCollectTask> tasks = deviceCollectTaskService.getByDeviceId(deviceId);
return ResponseEntity.ok(tasks);
}
/**
* 多条件查询采集任务
*/
@PostMapping("/search")
public ResponseEntity<List<DeviceCollectTask>> search(@RequestBody DeviceCollectTask condition) {
List<DeviceCollectTask> tasks = deviceCollectTaskService.getByCondition(condition);
return ResponseEntity.ok(tasks);
}
/**
* 新增采集任务
*/
@PostMapping
public ResponseEntity<DeviceCollectTask> create(@RequestBody DeviceCollectTask task) {
deviceCollectTaskService.create(task);
return ResponseEntity.ok(task);
}
/**
* 更新采集任务
*/
@PutMapping("/{id}")
public ResponseEntity<DeviceCollectTask> update(@PathVariable Integer id,
@RequestBody DeviceCollectTask task) {
task.setId(id);
DeviceCollectTask updatedTask = deviceCollectTaskService.update(task);
return ResponseEntity.ok(updatedTask);
}
/**
* 删除采集任务
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Integer id) {
deviceCollectTaskService.delete(id);
return ResponseEntity.noContent().build();
}
/**
* 标记任务成功
*/
@PostMapping("/{id}/success")
public ResponseEntity<Void> markSuccess(@PathVariable Integer id) {
deviceCollectTaskService.markSuccess(id);
return ResponseEntity.ok().build();
}
/**
* 标记任务失败
*/
@PostMapping("/{id}/failed")
public ResponseEntity<Void> markFailed(@PathVariable Integer id) {
deviceCollectTaskService.markFailed(id);
return ResponseEntity.ok().build();
}
/**
* 更新EPM指标
*/
@PutMapping("/{id}/epm")
public ResponseEntity<Void> updateEpm(@PathVariable Integer id,
@RequestParam Integer epm) {
deviceCollectTaskService.updateEpm(id, epm);
return ResponseEntity.ok().build();
}
/**
* 查询成功的任务
*/
@GetMapping("/success")
public ResponseEntity<List<DeviceCollectTask>> getSuccessTasks() {
List<DeviceCollectTask> tasks = deviceCollectTaskService.getSuccessTasks();
return ResponseEntity.ok(tasks);
}
/**
* 查询失败的任务
*/
@GetMapping("/failed")
public ResponseEntity<List<DeviceCollectTask>> getFailedTasks() {
List<DeviceCollectTask> tasks = deviceCollectTaskService.getFailedTasks();
return ResponseEntity.ok(tasks);
}
/**
* 获取设备最新任务
*/
@GetMapping("/device/{deviceId}/latest")
public ResponseEntity<DeviceCollectTask> getLatestByDeviceId(@PathVariable Integer deviceId) {
DeviceCollectTask task = deviceCollectTaskService.getLatestByDeviceId(deviceId);
return ResponseEntity.ok(task);
}
}
@@ -0,0 +1,49 @@
package com.common.controller;
import com.common.entity.DeviceDevice;
import com.common.service.DeviceDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/devices")
public class DeviceDeviceController {
@Autowired
private DeviceDeviceService deviceDeviceService;
@GetMapping("/{id}")
public DeviceDevice getById(@PathVariable Integer id) {
System.out.println("device_id"+id.toString());
DeviceDevice deviceDevice=deviceDeviceService.getById(id);
System.out.println("deviceDeviceService"+deviceDevice.toString());
return deviceDeviceService.getById(id);
}
@GetMapping
public List<DeviceDevice> getAll() {
return deviceDeviceService.getAll();
}
@GetMapping("/search")
public List<DeviceDevice> searchByName(@RequestParam String name) {
return deviceDeviceService.getByNameLike(name);
}
@GetMapping("/ip/{ip}")
public List<DeviceDevice> getByIp(@PathVariable String ip) {
List<DeviceDevice> deviceDevicelist =deviceDeviceService.getByIpSafely(ip);
System.out.println("deviceDeviceService"+deviceDevicelist.get(0).toString());
return deviceDeviceService.getByIpSafely(ip);
}
@GetMapping("/monitoring")
public List<DeviceDevice> getMonitoringDevices() {
return deviceDeviceService.getMonitoringDevices();
}
}
@@ -0,0 +1,135 @@
package com.common.controller;
import com.common.entity.DeviceUnknown;
import com.common.service.DeviceUnknownService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/device-unknown")
@RequiredArgsConstructor
@Validated
public class DeviceUnknownController {
private final DeviceUnknownService deviceUnknownService;
/**
* 创建设备记录
*/
@PostMapping
public ResponseEntity<Map<String, Object>> createDevice(@Valid @RequestBody DeviceUnknown device) {
Long id = deviceUnknownService.createDevice(device);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("id", id);
result.put("message", "设备记录创建成功");
return ResponseEntity.ok(result);
}
/**
* 批量创建设备记录
*/
@PostMapping("/batch")
public ResponseEntity<Map<String, Object>> batchCreateDevices(@Valid @RequestBody List<DeviceUnknown> devices) {
int count = deviceUnknownService.batchCreateDevices(devices);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("count", count);
result.put("message", "批量创建设备记录成功");
return ResponseEntity.ok(result);
}
/**
* 根据ID获取设备信息
*/
@GetMapping("/{id}")
public ResponseEntity<Map<String, Object>> getDeviceById(@PathVariable Long id) {
DeviceUnknown device = deviceUnknownService.getDeviceById(id);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", device);
return ResponseEntity.ok(result);
}
/**
* 根据IP查询设备
*/
@GetMapping("/ip/{deviceIp}")
public ResponseEntity<Map<String, Object>> getDevicesByIp(@PathVariable String deviceIp) {
List<DeviceUnknown> devices = deviceUnknownService.getDevicesByIp(deviceIp);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", devices);
result.put("total", devices.size());
return ResponseEntity.ok(result);
}
/**
* 根据组织ID查询设备
*/
@GetMapping("/organization/{organizationId}")
public ResponseEntity<Map<String, Object>> getDevicesByOrganizationId(@PathVariable Integer organizationId) {
List<DeviceUnknown> devices = deviceUnknownService.getDevicesByOrganizationId(organizationId);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", devices);
result.put("total", devices.size());
return ResponseEntity.ok(result);
}
/**
* 分页查询设备
*/
@GetMapping("/page")
public ResponseEntity<Map<String, Object>> getDevicesByPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
List<DeviceUnknown> devices = deviceUnknownService.getDevicesByPage(pageNum, pageSize);
long total = deviceUnknownService.getTotalCount();
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("data", devices);
result.put("pageNum", pageNum);
result.put("pageSize", pageSize);
result.put("total", total);
result.put("pages", (int) Math.ceil((double) total / pageSize));
return ResponseEntity.ok(result);
}
/**
* 更新设备信息
*/
@PutMapping("/{id}")
public ResponseEntity<Map<String, Object>> updateDevice(
@PathVariable Long id,
@Valid @RequestBody DeviceUnknown device) {
device.setId(id);
boolean success = deviceUnknownService.updateDevice(device);
Map<String, Object> result = new HashMap<>();
result.put("success", success);
result.put("message", success ? "设备更新成功" : "设备更新失败");
return ResponseEntity.ok(result);
}
/**
* 删除设备
*/
@DeleteMapping("/{id}")
public ResponseEntity<Map<String, Object>> deleteDevice(@PathVariable Long id) {
boolean success = deviceUnknownService.deleteDevice(id);
Map<String, Object> result = new HashMap<>();
result.put("success", success);
result.put("message", success ? "设备删除成功" : "设备删除失败");
return ResponseEntity.ok(result);
}
}
@@ -0,0 +1,99 @@
package com.common.entity;
import java.time.OffsetDateTime;
public class DeviceCollectTask {
private Integer id;
private OffsetDateTime createdAt;
private OffsetDateTime updatedAt;
private OffsetDateTime deletedAt;
private Integer deviceId;
private Integer method;
private String taskName;
private OffsetDateTime firstTime;
private OffsetDateTime lastSuccessTime;
private OffsetDateTime lastFailedTime;
private Integer detailId;
private Integer epm;
private Integer epmPeak;
private Integer processArchitecture;
private Integer taskCount;
private OffsetDateTime recentDiscoverTime;
private Integer epmUpperLimit;
// Getter and Setter 方法
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public OffsetDateTime getCreatedAt() { return createdAt; }
public void setCreatedAt(OffsetDateTime createdAt) { this.createdAt = createdAt; }
public OffsetDateTime getUpdatedAt() { return updatedAt; }
public void setUpdatedAt(OffsetDateTime updatedAt) { this.updatedAt = updatedAt; }
public OffsetDateTime getDeletedAt() { return deletedAt; }
public void setDeletedAt(OffsetDateTime deletedAt) { this.deletedAt = deletedAt; }
public Integer getDeviceId() { return deviceId; }
public void setDeviceId(Integer deviceId) { this.deviceId = deviceId; }
public Integer getMethod() { return method; }
public void setMethod(Integer method) { this.method = method; }
public String getTaskName() { return taskName; }
public void setTaskName(String taskName) { this.taskName = taskName; }
public OffsetDateTime getFirstTime() { return firstTime; }
public void setFirstTime(OffsetDateTime firstTime) { this.firstTime = firstTime; }
public OffsetDateTime getLastSuccessTime() { return lastSuccessTime; }
public void setLastSuccessTime(OffsetDateTime lastSuccessTime) { this.lastSuccessTime = lastSuccessTime; }
public OffsetDateTime getLastFailedTime() { return lastFailedTime; }
public void setLastFailedTime(OffsetDateTime lastFailedTime) { this.lastFailedTime = lastFailedTime; }
public Integer getDetailId() { return detailId; }
public void setDetailId(Integer detailId) { this.detailId = detailId; }
public Integer getEpm() { return epm; }
public void setEpm(Integer epm) { this.epm = epm; }
public Integer getEpmPeak() { return epmPeak; }
public void setEpmPeak(Integer epmPeak) { this.epmPeak = epmPeak; }
public Integer getProcessArchitecture() { return processArchitecture; }
public void setProcessArchitecture(Integer processArchitecture) { this.processArchitecture = processArchitecture; }
public Integer getTaskCount() { return taskCount; }
public void setTaskCount(Integer taskCount) { this.taskCount = taskCount; }
public OffsetDateTime getRecentDiscoverTime() { return recentDiscoverTime; }
public void setRecentDiscoverTime(OffsetDateTime recentDiscoverTime) { this.recentDiscoverTime = recentDiscoverTime; }
public Integer getEpmUpperLimit() { return epmUpperLimit; }
public void setEpmUpperLimit(Integer epmUpperLimit) { this.epmUpperLimit = epmUpperLimit; }
@Override
public String toString() {
return "DeviceCollectTask{" +
"id=" + id +
", createdAt=" + createdAt +
", updatedAt=" + updatedAt +
", deletedAt=" + deletedAt +
", deviceId=" + deviceId +
", method=" + method +
", taskName='" + taskName + '\'' +
", firstTime=" + firstTime +
", lastSuccessTime=" + lastSuccessTime +
", lastFailedTime=" + lastFailedTime +
", detailId=" + detailId +
", epm=" + epm +
", epmPeak=" + epmPeak +
", processArchitecture=" + processArchitecture +
", taskCount=" + taskCount +
", recentDiscoverTime=" + recentDiscoverTime +
", epmUpperLimit=" + epmUpperLimit +
'}';
}
}
@@ -0,0 +1,376 @@
package com.common.entity;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
public class DeviceDevice {
public Integer id;
public LocalDateTime createdAt;
public LocalDateTime updatedAt;
public LocalDateTime deletedAt;
public String name;
public String ip;
public Integer deviceGroup;
public Integer deviceType;
public String vendor;
public String productName;
public Integer organizationId;
public LocalDateTime lastReceiveTime;
public Integer agentId;
public Integer detailId;
public Integer controlAgentId;
public LocalDateTime licenseStartTime;
public LocalDateTime licenseEndTime;
public Boolean isMonitoring;
public Long securityScopeId;
public Long ownerId;
public Long sshConfigId;
public Short status;
public Long createdById;
public Integer decodeType;
public Integer missPolicy;
public String tenantId;
public LocalDateTime createTime;
public LocalDateTime updateTime;
public Long createBy;
public Long updateBy;
public String delFlag;
public String managerName;
public Integer todayParseCount;
public Integer todayNonLogCount;
public Long createDept;
public Integer deviceCollectId;
// Getter and Setter methods
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(LocalDateTime updatedAt) {
this.updatedAt = updatedAt;
}
public LocalDateTime getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(LocalDateTime deletedAt) {
this.deletedAt = deletedAt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Integer getDeviceGroup() {
return deviceGroup;
}
public void setDeviceGroup(Integer deviceGroup) {
this.deviceGroup = deviceGroup;
}
public Integer getDeviceType() {
return deviceType;
}
public void setDeviceType(Integer deviceType) {
this.deviceType = deviceType;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getOrganizationId() {
return organizationId;
}
public void setOrganizationId(Integer organizationId) {
this.organizationId = organizationId;
}
public LocalDateTime getLastReceiveTime() {
return lastReceiveTime;
}
public void setLastReceiveTime(LocalDateTime lastReceiveTime) {
this.lastReceiveTime = lastReceiveTime;
}
public Integer getAgentId() {
return agentId;
}
public void setAgentId(Integer agentId) {
this.agentId = agentId;
}
public Integer getDetailId() {
return detailId;
}
public void setDetailId(Integer detailId) {
this.detailId = detailId;
}
public Integer getControlAgentId() {
return controlAgentId;
}
public void setControlAgentId(Integer controlAgentId) {
this.controlAgentId = controlAgentId;
}
public LocalDateTime getLicenseStartTime() {
return licenseStartTime;
}
public void setLicenseStartTime(LocalDateTime licenseStartTime) {
this.licenseStartTime = licenseStartTime;
}
public LocalDateTime getLicenseEndTime() {
return licenseEndTime;
}
public void setLicenseEndTime(LocalDateTime licenseEndTime) {
this.licenseEndTime = licenseEndTime;
}
public Boolean getIsMonitoring() {
return isMonitoring;
}
public void setIsMonitoring(Boolean isMonitoring) {
this.isMonitoring = isMonitoring;
}
public Long getSecurityScopeId() {
return securityScopeId;
}
public void setSecurityScopeId(Long securityScopeId) {
this.securityScopeId = securityScopeId;
}
public Long getOwnerId() {
return ownerId;
}
public void setOwnerId(Long ownerId) {
this.ownerId = ownerId;
}
public Long getSshConfigId() {
return sshConfigId;
}
public void setSshConfigId(Long sshConfigId) {
this.sshConfigId = sshConfigId;
}
public Short getStatus() {
return status;
}
public void setStatus(Short status) {
this.status = status;
}
public Long getCreatedById() {
return createdById;
}
public void setCreatedById(Long createdById) {
this.createdById = createdById;
}
public Integer getDecodeType() {
return decodeType;
}
public void setDecodeType(Integer decodeType) {
this.decodeType = decodeType;
}
public Integer getMissPolicy() {
return missPolicy;
}
public void setMissPolicy(Integer missPolicy) {
this.missPolicy = missPolicy;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
public Long getCreateBy() {
return createBy;
}
public void setCreateBy(Long createBy) {
this.createBy = createBy;
}
public Long getUpdateBy() {
return updateBy;
}
public void setUpdateBy(Long updateBy) {
this.updateBy = updateBy;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public String getManagerName() {
return managerName;
}
public void setManagerName(String managerName) {
this.managerName = managerName;
}
public Integer getTodayParseCount() {
return todayParseCount;
}
public void setTodayParseCount(Integer todayParseCount) {
this.todayParseCount = todayParseCount;
}
public Integer getTodayNonLogCount() {
return todayNonLogCount;
}
public void setTodayNonLogCount(Integer todayNonLogCount) {
this.todayNonLogCount = todayNonLogCount;
}
public Long getCreateDept() {
return createDept;
}
public void setCreateDept(Long createDept) {
this.createDept = createDept;
}
public Integer getDeviceCollectId() {
return deviceCollectId;
}
public void setDeviceCollectId(Integer deviceCollectId) {
this.deviceCollectId = deviceCollectId;
}
@Override
public String toString() {
return "DeviceDevice{" +
"id=" + id +
", createdAt=" + createdAt +
", updatedAt=" + updatedAt +
", deletedAt=" + deletedAt +
", name='" + name + '\'' +
", ip='" + ip + '\'' +
", deviceGroup=" + deviceGroup +
", deviceType=" + deviceType +
", vendor='" + vendor + '\'' +
", productName='" + productName + '\'' +
", organizationId=" + organizationId +
", lastReceiveTime=" + lastReceiveTime +
", agentId=" + agentId +
", detailId=" + detailId +
", controlAgentId=" + controlAgentId +
", licenseStartTime=" + licenseStartTime +
", licenseEndTime=" + licenseEndTime +
", isMonitoring=" + isMonitoring +
", securityScopeId=" + securityScopeId +
", ownerId=" + ownerId +
", sshConfigId=" + sshConfigId +
", status=" + status +
", createdById=" + createdById +
", decodeType=" + decodeType +
", missPolicy=" + missPolicy +
", tenantId='" + tenantId + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", createBy=" + createBy +
", updateBy=" + updateBy +
", delFlag='" + delFlag + '\'' +
", managerName='" + managerName + '\'' +
", todayParseCount=" + todayParseCount +
", todayNonLogCount=" + todayNonLogCount +
", createDept=" + createDept +
", deviceCollectId=" + deviceCollectId +
'}';
}
}
@@ -0,0 +1,68 @@
package com.common.entity;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.Builder;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DeviceReceiveLog {
/**
* 主键ID
*/
private Long id;
/**
* 记录创建时间(UTC时间)
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;
/**
* 采集探针ID
*/
private Integer deviceCollectId;
/**
* 设备ID
*/
private Integer deviceId;
/**
* 设备IPPostgreSQL inet类型,用String处理)
*/
private String deviceIp;
/**
* 日志收到时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime receiveTime;
/**
* 接收时间字符串(冗余字段)
*/
private String receiveTimeStr;
/**
* 原始syslog消息
*/
private String syslogMessage;
/**
* 是否推送成功
*/
private boolean pushSuccess;
/**
* 分页参数(非表字段)
*/
private Integer pageNum;
private Integer pageSize;
}
@@ -0,0 +1,70 @@
package com.common.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
@Data
public class DeviceUnknown {
/**
* 主键ID
*/
private Long id;
/**
* 记录创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdAt;
/**
* 采集探针ID
*/
@NotNull(message = "采集探针ID不能为空")
private Integer deviceCollectId;
/**
* 采集探针名称
*/
@NotBlank(message = "采集探针名称不能为空")
private String deviceCollectName;
/**
* 设备IP
*/
@NotBlank(message = "设备IP不能为空")
private String deviceIp;
/**
* 首次发现时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@NotNull(message = "首次发现时间不能为空")
private LocalDateTime firstTime;
/**
* 最后发现时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@NotNull(message = "最后发现时间不能为空")
private LocalDateTime lastTime;
/**
* 组织ID
*/
//@NotNull(message = "组织ID不能为空")
private Integer organizationId;
/**
* 网络协议 (TCP|UDP)
*/
private String networkProtocol = "TCP";
/**
* 来源方式 (SYSTEM|USER)
*/
private String sourceMethod = "SYSTEM";
}
@@ -0,0 +1,143 @@
package com.common.mapper;
import com.common.entity.DeviceCollectTask;
import org.apache.ibatis.annotations.*;
import java.util.List;
import java.util.Map;
@Mapper
public interface DeviceCollectTaskMapper {
/**
* 根据ID查询采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE id = #{id}")
DeviceCollectTask selectById(Integer id);
/**
* 查询所有采集任务
*/
@Select("SELECT * FROM device_collect_task")
List<DeviceCollectTask> selectAll();
/**
* 根据设备ID查询采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE device_id = #{deviceId}")
List<DeviceCollectTask> selectByDeviceId(Integer deviceId);
/**
* 根据方法类型查询采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE method = #{method}")
List<DeviceCollectTask> selectByMethod(Integer method);
/**
* 根据任务名称模糊查询
*/
@Select("SELECT * FROM device_collect_task WHERE task_name LIKE CONCAT('%', #{taskName}, '%')")
List<DeviceCollectTask> selectByTaskNameLike(String taskName);
/**
* 查询成功的采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE last_success_time IS NOT NULL")
List<DeviceCollectTask> selectSuccessTasks();
/**
* 查询失败的采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE last_failed_time IS NOT NULL")
List<DeviceCollectTask> selectFailedTasks();
/**
* 多条件组合查询
*/
List<DeviceCollectTask> selectByCondition(DeviceCollectTask condition);
/**
* 插入采集任务
*/
@Insert("INSERT INTO device_collect_task (created_at, updated_at, device_id, method, task_name, " +
"first_time, last_success_time, last_failed_time, detail_id, epm, epm_peak, " +
"process_architecture, task_count, recent_discover_time, epm_upper_limit) " +
"VALUES (NOW(), NOW(), #{deviceId}, #{method}, #{taskName}, #{firstTime}, " +
"#{lastSuccessTime}, #{lastFailedTime}, #{detailId}, #{epm}, #{epmPeak}, " +
"#{processArchitecture}, #{taskCount}, #{recentDiscoverTime}, #{epmUpperLimit})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(DeviceCollectTask task);
/**
* 更新采集任务
*/
@Update("UPDATE device_collect_task SET " +
"updated_at = NOW(), " +
"device_id = #{deviceId}, " +
"method = #{method}, " +
"task_name = #{taskName}, " +
"first_time = #{firstTime}, " +
"last_success_time = #{lastSuccessTime}, " +
"last_failed_time = #{lastFailedTime}, " +
"detail_id = #{detailId}, " +
"epm = #{epm}, " +
"epm_peak = #{epmPeak}, " +
"process_architecture = #{processArchitecture}, " +
"task_count = #{taskCount}, " +
"recent_discover_time = #{recentDiscoverTime}, " +
"epm_upper_limit = #{epmUpperLimit} " +
"WHERE id = #{id}")
int update(DeviceCollectTask task);
/**
* 删除采集任务
*/
@Delete("DELETE FROM device_collect_task WHERE id = #{id}")
int deleteById(Integer id);
/**
* 根据设备ID删除采集任务
*/
@Delete("DELETE FROM device_collect_task WHERE device_id = #{deviceId}")
int deleteByDeviceId(Integer deviceId);
/**
* 更新任务成功状态
*/
@Update("UPDATE device_collect_task SET " +
"last_success_time = NOW(), " +
"updated_at = NOW(), " +
"task_count = COALESCE(task_count, 0) + 1 " +
"WHERE id = #{id}")
int updateSuccessStatus(Integer id);
/**
* 更新任务失败状态
*/
@Update("UPDATE device_collect_task SET " +
"last_failed_time = NOW(), " +
"updated_at = NOW() " +
"WHERE id = #{id}")
int updateFailedStatus(Integer id);
/**
* 更新EPM指标
*/
@Update("UPDATE device_collect_task SET " +
"epm = #{epm}, " +
"epm_peak = GREATEST(COALESCE(epm_peak, 0), #{epm}), " +
"updated_at = NOW() " +
"WHERE id = #{id}")
int updateEpm(@Param("id") Integer id, @Param("epm") Integer epm);
/**
* 统计设备采集任务数量
*/
@Select("SELECT COUNT(*) FROM device_collect_task WHERE device_id = #{deviceId}")
int countByDeviceId(Integer deviceId);
/**
* 获取设备的最新采集任务
*/
@Select("SELECT * FROM device_collect_task WHERE device_id = #{deviceId} ORDER BY updated_at DESC LIMIT 1")
DeviceCollectTask selectLatestByDeviceId(Integer deviceId);
}
@@ -0,0 +1,93 @@
package com.common.mapper;
import com.common.entity.DeviceDevice;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface DeviceDeviceMapper {
/**
* 根据ID查询设备
*/
DeviceDevice selectById(Integer id);
/**
* 查询所有设备
*/
List<DeviceDevice> selectAll();
/**
* 根据IP地址查询设备
*/
List<DeviceDevice> selectByIp(String ip);
/**
* 根据设备名称模糊查询
*/
List<DeviceDevice> selectByNameLike(String name);
/**
* 根据设备组查询
*/
List<DeviceDevice> selectByDeviceGroup(Integer deviceGroup);
/**
* 根据设备类型查询
*/
List<DeviceDevice> selectByDeviceType(Integer deviceType);
/**
* 根据组织ID查询
*/
List<DeviceDevice> selectByOrganizationId(Integer organizationId);
/**
* 根据状态查询设备
*/
List<DeviceDevice> selectByStatus(Short status);
/**
* 多条件组合查询
*/
List<DeviceDevice> selectByCondition(DeviceDevice condition);
/**
* 动态条件查询
*/
List<DeviceDevice> selectByMap(Map<String, Object> params);
/**
* 分页查询
*/
List<DeviceDevice> selectByPage(@Param("offset") int offset, @Param("limit") int limit);
/**
* 统计设备数量
*/
Long count();
/**
* 根据条件统计数量
*/
Long countByCondition(DeviceDevice condition);
/**
* 查询监控中的设备
*/
List<DeviceDevice> selectMonitoringDevices();
/**
* 查询未删除的设备(del_flag = '0'
*/
List<DeviceDevice> selectActiveDevices();
/**
* 根据厂商查询设备
*/
List<DeviceDevice> selectByVendor(String vendor);
}
@@ -0,0 +1,78 @@
package com.common.mapper;
import com.common.entity.DeviceReceiveLog;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Mapper
public interface DeviceReceiveLogMapper {
/**
* 插入单条记录
*/
int insert(DeviceReceiveLog log);
/**
* 批量插入记录
*/
int batchInsert(@Param("list") List<DeviceReceiveLog> logs);
/**
* 根据ID查询
*/
DeviceReceiveLog selectById(@Param("id") Long id);
/**
* 根据设备ID查询
*/
List<DeviceReceiveLog> selectByDeviceId(@Param("deviceId") Integer deviceId);
/**
* 根据采集探针ID查询
*/
List<DeviceReceiveLog> selectByCollectId(@Param("collectId") Integer collectId);
/**
* 根据IP地址查询
*/
List<DeviceReceiveLog> selectByDeviceIp(@Param("deviceIp") String deviceIp);
/**
* 根据时间范围查询
*/
List<DeviceReceiveLog> selectByTimeRange(
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
/**
* 多条件组合查询
*/
List<DeviceReceiveLog> selectByCondition(DeviceReceiveLog condition);
/**
* 统计设备接收日志数量
*/
Long countByCondition(DeviceReceiveLog condition);
/**
* 根据时间范围删除旧数据
*/
int deleteByTimeRange(
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime);
/**
* 获取最近N条记录
*/
List<DeviceReceiveLog> selectRecent(@Param("limit") Integer limit);
/**
* 按设备分组统计日志数量
*/
List<Map<String, Object>> countByDeviceGroup();
}
@@ -0,0 +1,110 @@
package com.common.mapper;
import com.common.entity.DeviceUnknown;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.time.LocalDateTime;
@Mapper
public interface DeviceUnknownMapper {
/**
* 插入设备记录
* @param device 设备对象
* @return 影响行数
*/
int insert(DeviceUnknown device);
/**
* 批量插入设备记录
* @param devices 设备列表
* @return 影响行数
*/
int batchInsert(@Param("devices") List<DeviceUnknown> devices);
/**
* 根据ID查询设备
* @param id 设备ID
* @return 设备对象
*/
DeviceUnknown selectById(@Param("id") Long id);
/**
* 根据IP查询设备
* @param deviceIp 设备IP
* @return 设备列表
*/
List<DeviceUnknown> selectByIp(@Param("deviceIp") String deviceIp);
/**
* 根据组织ID查询设备
* @param organizationId 组织ID
* @return 设备列表
*/
List<DeviceUnknown> selectByOrganizationId(@Param("organizationId") Integer organizationId);
/**
* 查询所有设备
* @return 设备列表
*/
List<DeviceUnknown> selectAll();
/**
* 分页查询设备
* @param offset 偏移量
* @param limit 每页数量
* @return 设备列表
*/
List<DeviceUnknown> selectPage(@Param("offset") int offset, @Param("limit") int limit);
/**
* 根据条件查询设备
* @param device 查询条件
* @return 设备列表
*/
List<DeviceUnknown> selectByCondition(DeviceUnknown device);
/**
* 根据ID更新设备信息
* @param device 设备对象
* @return 影响行数
*/
int updateById(DeviceUnknown device);
/**
* 更新最后发现时间
* @param id 设备ID
* @param lastTime 最后发现时间
* @return 影响行数
*/
int updateLastTime(@Param("id") Long id, @Param("lastTime") LocalDateTime lastTime);
/**
* 根据ID删除设备
* @param id 设备ID
* @return 影响行数
*/
int deleteById(@Param("id") Long id);
/**
* 根据组织ID删除设备
* @param organizationId 组织ID
* @return 影响行数
*/
int deleteByOrganizationId(@Param("organizationId") Integer organizationId);
/**
* 统计设备数量
* @return 设备总数
*/
Long count();
/**
* 根据条件统计设备数量
* @param device 查询条件
* @return 设备数量
*/
Long countByCondition(DeviceUnknown device);
}
@@ -0,0 +1,136 @@
package com.common.service;
import com.common.entity.DeviceCollectTask;
import com.common.mapper.DeviceCollectTaskMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@CacheConfig(cacheNames = "collectTask")
public class DeviceCollectTaskService {
@Autowired
private DeviceCollectTaskMapper deviceCollectTaskMapper;
/**
* 根据ID查询采集任务 - 缓存
*/
@Cacheable(key = "'id:' + #id")
public DeviceCollectTask getById(Integer id) {
return deviceCollectTaskMapper.selectById(id);
}
/**
* 查询所有采集任务 - 缓存
*/
@Cacheable(key = "'all'")
public List<DeviceCollectTask> getAll() {
return deviceCollectTaskMapper.selectAll();
}
/**
* 根据设备ID查询采集任务 - 缓存
*/
@Cacheable(key = "'device:' + #deviceId")
public List<DeviceCollectTask> getByDeviceId(Integer deviceId) {
return deviceCollectTaskMapper.selectByDeviceId(deviceId);
}
/**
* 根据方法类型查询采集任务
*/
public List<DeviceCollectTask> getByMethod(Integer method) {
return deviceCollectTaskMapper.selectByMethod(method);
}
/**
* 多条件组合查询
*/
public List<DeviceCollectTask> getByCondition(DeviceCollectTask condition) {
return deviceCollectTaskMapper.selectByCondition(condition);
}
/**
* 新增采集任务 - 清除相关缓存
*/
@CacheEvict(allEntries = true)
public int create(DeviceCollectTask task) {
return deviceCollectTaskMapper.insert(task);
}
/**
* 更新采集任务 - 更新缓存
*/
@CachePut(key = "'id:' + #task.id")
@CacheEvict(key = "'device:' + #task.deviceId")
public DeviceCollectTask update(DeviceCollectTask task) {
deviceCollectTaskMapper.update(task);
return deviceCollectTaskMapper.selectById(task.getId());
}
/**
* 删除采集任务 - 清除缓存
*/
@CacheEvict(key = "'id:' + #id")
public int delete(Integer id) {
return deviceCollectTaskMapper.deleteById(id);
}
/**
* 标记任务成功 - 更新缓存
*/
@CacheEvict(key = "'id:' + #id")
public int markSuccess(Integer id) {
return deviceCollectTaskMapper.updateSuccessStatus(id);
}
/**
* 标记任务失败 - 更新缓存
*/
@CacheEvict(key = "'id:' + #id")
public int markFailed(Integer id) {
return deviceCollectTaskMapper.updateFailedStatus(id);
}
/**
* 更新EPM指标 - 更新缓存
*/
@CacheEvict(key = "'id:' + #id")
public int updateEpm(Integer id, Integer epm) {
return deviceCollectTaskMapper.updateEpm(id, epm);
}
/**
* 查询成功的任务
*/
public List<DeviceCollectTask> getSuccessTasks() {
return deviceCollectTaskMapper.selectSuccessTasks();
}
/**
* 查询失败的任务
*/
public List<DeviceCollectTask> getFailedTasks() {
return deviceCollectTaskMapper.selectFailedTasks();
}
/**
* 获取设备的最新采集任务
*/
@Cacheable(key = "'latest:device:' + #deviceId")
public DeviceCollectTask getLatestByDeviceId(Integer deviceId) {
return deviceCollectTaskMapper.selectLatestByDeviceId(deviceId);
}
/**
* 统计设备任务数量
*/
public int countByDeviceId(Integer deviceId) {
return deviceCollectTaskMapper.countByDeviceId(deviceId);
}
}
@@ -0,0 +1,31 @@
package com.common.service;
import com.common.entity.DeviceDevice;
import java.util.List;
import java.util.Map;
public interface DeviceDeviceService {
DeviceDevice getByIdSafely(Integer id);
List<DeviceDevice> getByIpSafely(String ip);
DeviceDevice getById(Integer id);
List<DeviceDevice> getAll();
List<DeviceDevice> getByIp(String ip);
List<DeviceDevice> getByNameLike(String name);
List<DeviceDevice> getByCondition(DeviceDevice condition);
List<DeviceDevice> getByMap(Map<String, Object> params);
List<DeviceDevice> getByPage(int pageNum, int pageSize);
Long getCount();
List<DeviceDevice> getMonitoringDevices();
List<DeviceDevice> getActiveDevices();
}
@@ -0,0 +1,35 @@
package com.common.service;
import com.common.entity.DeviceReceiveLog;
import com.github.pagehelper.PageInfo;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface DeviceReceiveLogService {
// 插入操作
Long insertLog(DeviceReceiveLog log);
int batchInsertLogs(List<DeviceReceiveLog> logs);
// 查询操作
DeviceReceiveLog getById(Long id);
List<DeviceReceiveLog> getByDeviceId(Integer deviceId);
List<DeviceReceiveLog> getByCollectId(Integer collectId);
List<DeviceReceiveLog> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime);
List<DeviceReceiveLog> getByCondition(DeviceReceiveLog condition);
PageInfo<DeviceReceiveLog> getByConditionPage(DeviceReceiveLog condition, Integer pageNum, Integer pageSize);
// 统计操作
Long countByCondition(DeviceReceiveLog condition);
List<Map<String, Object>> getDeviceLogStatistics();
// 删除操作
int deleteOldLogs(LocalDateTime beforeTime);
// 获取最近日志
List<DeviceReceiveLog> getRecentLogs(Integer limit);
}
@@ -0,0 +1,108 @@
package com.common.service;
import com.common.entity.DeviceUnknown;
import java.util.List;
import java.time.LocalDateTime;
public interface DeviceUnknownService {
/**
* 创建设备记录
* @param device 设备信息
* @return 创建的设备ID
*/
Long createDevice(DeviceUnknown device);
/**
* 批量创建设备记录
* @param devices 设备列表
* @return 成功创建的记录数
*/
int batchCreateDevices(List<DeviceUnknown> devices);
/**
* 根据ID获取设备信息
* @param id 设备ID
* @return 设备信息
*/
DeviceUnknown getDeviceById(Long id);
/**
* 根据IP获取设备列表
* @param deviceIp 设备IP
* @return 设备列表
*/
List<DeviceUnknown> getDevicesByIp(String deviceIp);
/**
* 根据组织ID获取设备列表
* @param organizationId 组织ID
* @return 设备列表
*/
List<DeviceUnknown> getDevicesByOrganizationId(Integer organizationId);
/**
* 获取所有设备列表
* @return 设备列表
*/
List<DeviceUnknown> getAllDevices();
/**
* 分页查询设备列表
* @param pageNum 页码
* @param pageSize 每页大小
* @return 设备列表
*/
List<DeviceUnknown> getDevicesByPage(int pageNum, int pageSize);
/**
* 根据条件查询设备列表
* @param device 查询条件
* @return 设备列表
*/
List<DeviceUnknown> searchDevices(DeviceUnknown device);
/**
* 更新设备信息
* @param device 设备信息
* @return 是否成功
*/
boolean updateDevice(DeviceUnknown device);
/**
* 更新设备的最后发现时间
* @param id 设备ID
* @param lastTime 最后发现时间
* @return 是否成功
*/
boolean updateLastTime(Long id, LocalDateTime lastTime);
/**
* 删除设备
* @param id 设备ID
* @return 是否成功
*/
boolean deleteDevice(Long id);
/**
* 根据组织ID删除设备
* @param organizationId 组织ID
* @return 删除的记录数
*/
int deleteDevicesByOrganizationId(Integer organizationId);
/**
* 获取设备总数
* @return 设备总数
*/
long getTotalCount();
/**
* 根据条件获取设备数量
* @param device 查询条件
* @return 设备数量
*/
long getCountByCondition(DeviceUnknown device);
}
@@ -0,0 +1,103 @@
package com.common.service.impl;
import com.common.entity.DeviceDevice;
import com.common.mapper.DeviceDeviceMapper;
import com.common.service.DeviceDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import com.haobang.util.SafeCacheUtil;
@CacheConfig(cacheNames = "device")
@Service
public class DeviceDeviceServiceImpl implements DeviceDeviceService {
@Autowired
private DeviceDeviceMapper deviceDeviceMapper;
@Autowired
private SafeCacheUtil safeCacheUtil;
/**
* 使用安全的缓存方法
*/
@Cacheable( key = "'device:id:' +#id")
@Override
public DeviceDevice getByIdSafely(Integer id) {
String cacheKey = "device:id:" + id;
return safeCacheUtil.getSafe(cacheKey, DeviceDevice.class,
() -> deviceDeviceMapper.selectById(id));
}
/**
* 使用安全的列表缓存方法
*/
@Cacheable( key = "'device:ip:' + #ip")
@Override
public List<DeviceDevice> getByIpSafely(String ip) {
String cacheKey = "device:ip:" + ip;
return safeCacheUtil.getSafeList(cacheKey, DeviceDevice.class,
() -> deviceDeviceMapper.selectByIp(ip));
}
@Cacheable( key = "'device:id:' +#id")
@Override
public DeviceDevice getById(Integer id) {
System.out.println("exec deviceDeviceMapper.selectById :" + id.toString());
return deviceDeviceMapper.selectById(id);
}
@Override
public List<DeviceDevice> getAll() {
return deviceDeviceMapper.selectAll();
}
@Cacheable( key = "'device:ip:' + #ip")
@Override
public List<DeviceDevice> getByIp(String ip) {
return deviceDeviceMapper.selectByIp(ip);
}
@Override
public List<DeviceDevice> getByNameLike(String name) {
return deviceDeviceMapper.selectByNameLike(name);
}
@Override
public List<DeviceDevice> getByCondition(DeviceDevice condition) {
return deviceDeviceMapper.selectByCondition(condition);
}
@Override
public List<DeviceDevice> getByMap(Map<String, Object> params) {
return deviceDeviceMapper.selectByMap(params);
}
@Override
public List<DeviceDevice> getByPage(int pageNum, int pageSize) {
int offset = (pageNum - 1) * pageSize;
return deviceDeviceMapper.selectByPage(offset, pageSize);
}
@Override
public Long getCount() {
return deviceDeviceMapper.count();
}
@Override
public List<DeviceDevice> getMonitoringDevices() {
return deviceDeviceMapper.selectMonitoringDevices();
}
@Override
public List<DeviceDevice> getActiveDevices() {
return deviceDeviceMapper.selectActiveDevices();
}
}
@@ -0,0 +1,159 @@
package com.common.service.impl;
import com.common.entity.DeviceReceiveLog;
import com.common.mapper.DeviceReceiveLogMapper;
import com.common.service.DeviceReceiveLogService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceReceiveLogServiceImpl implements DeviceReceiveLogService {
private final DeviceReceiveLogMapper deviceReceiveLogMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long insertLog(DeviceReceiveLog log) {
// 设置默认时间
if (log.getCreatedAt() == null) {
log.setCreatedAt(LocalDateTime.now());
}
if (log.getReceiveTimeStr() == null && log.getReceiveTime() != null) {
log.setReceiveTimeStr(log.getReceiveTime().toString());
}
deviceReceiveLogMapper.insert(log);
// log.info("插入设备接收日志成功,ID: {}", log.getId());
return log.getId();
}
@Override
@Transactional(rollbackFor = Exception.class)
public int batchInsertLogs(List<DeviceReceiveLog> logs) {
if (logs == null || logs.isEmpty()) {
return 0;
}
// 批量处理,每1000条提交一次
int batchSize = 1000;
int totalInserted = 0;
for (int i = 0; i < logs.size(); i += batchSize) {
int end = Math.min(i + batchSize, logs.size());
List<DeviceReceiveLog> batchList = logs.subList(i, end);
// 设置默认值
batchList.forEach(log -> {
if (log.getCreatedAt() == null) {
log.setCreatedAt(LocalDateTime.now());
}
if (log.getReceiveTimeStr() == null && log.getReceiveTime() != null) {
log.setReceiveTimeStr(log.getReceiveTime().toString());
}
});
int inserted = deviceReceiveLogMapper.batchInsert(batchList);
totalInserted += inserted;
log.info("批量插入进度: {}/{}", end, logs.size());
}
return totalInserted;
}
@Override
public DeviceReceiveLog getById(Long id) {
return deviceReceiveLogMapper.selectById(id);
}
@Override
public List<DeviceReceiveLog> getByDeviceId(Integer deviceId) {
return deviceReceiveLogMapper.selectByDeviceId(deviceId);
}
@Override
public List<DeviceReceiveLog> getByCollectId(Integer collectId) {
return deviceReceiveLogMapper.selectByCollectId(collectId);
}
@Override
public List<DeviceReceiveLog> getByTimeRange(LocalDateTime startTime, LocalDateTime endTime) {
if (startTime == null || endTime == null) {
throw new IllegalArgumentException("时间范围不能为空");
}
if (startTime.isAfter(endTime)) {
throw new IllegalArgumentException("开始时间不能晚于结束时间");
}
return deviceReceiveLogMapper.selectByTimeRange(startTime, endTime);
}
@Override
public List<DeviceReceiveLog> getByCondition(DeviceReceiveLog condition) {
return deviceReceiveLogMapper.selectByCondition(condition);
}
@Override
public PageInfo<DeviceReceiveLog> getByConditionPage(DeviceReceiveLog condition, Integer pageNum, Integer pageSize) {
if (pageNum == null || pageNum < 1) {
pageNum = 1;
}
if (pageSize == null || pageSize < 1) {
pageSize = 10;
}
PageHelper.startPage(pageNum, pageSize);
List<DeviceReceiveLog> list = deviceReceiveLogMapper.selectByCondition(condition);
return new PageInfo<>(list);
}
@Override
public Long countByCondition(DeviceReceiveLog condition) {
return deviceReceiveLogMapper.countByCondition(condition);
}
@Override
public List<Map<String, Object>> getDeviceLogStatistics() {
return deviceReceiveLogMapper.countByDeviceGroup();
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteOldLogs(LocalDateTime beforeTime) {
if (beforeTime == null) {
throw new IllegalArgumentException("删除时间点不能为空");
}
LocalDateTime endTime = LocalDateTime.now().minusDays(30); // 默认保留30天
if (beforeTime.isAfter(endTime)) {
log.warn("删除时间点{}晚于默认保留时间{},使用默认时间", beforeTime, endTime);
beforeTime = endTime;
}
int deleted = deviceReceiveLogMapper.deleteByTimeRange(
LocalDateTime.of(2000, 1, 1, 0, 0), // 很早的时间
beforeTime
);
log.info("删除{}天前的日志,共删除{}条", beforeTime, deleted);
return deleted;
}
@Override
public List<DeviceReceiveLog> getRecentLogs(Integer limit) {
if (limit == null || limit < 1) {
limit = 50; // 默认返回50条
}
return deviceReceiveLogMapper.selectRecent(limit);
}
}
@@ -0,0 +1,286 @@
package com.common.service.impl;
import com.common.entity.DeviceUnknown;
import com.common.mapper.DeviceUnknownMapper;
import com.common.service.DeviceUnknownService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.cache.CacheManager;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.Cacheable;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "deviceunknown")
public class DeviceUnknownServiceImpl implements DeviceUnknownService {
private final DeviceUnknownMapper deviceUnknownMapper;
@Autowired
private CacheManager cacheManager;
@Override
@Transactional
public Long createDevice(DeviceUnknown device) {
// 设置默认值
if (device.getCreatedAt() == null) {
device.setCreatedAt(LocalDateTime.now());
}
if (device.getNetworkProtocol() == null) {
device.setNetworkProtocol("TCP");
}
if (device.getSourceMethod() == null) {
device.setSourceMethod("SYSTEM");
}
try {
int result = deviceUnknownMapper.insert(device);
if (result > 0) {
log.info("设备记录创建成功,ID: {}", device.getId());
//清除缓存IP:XXXX
clearDeviceCache(device.getDeviceIp());
List<DeviceUnknown> devlist=this.getDevicesByIp(device.getDeviceIp());
return device.getId();
}
return null;
} catch (Exception e) {
log.error("创建设备记录失败: {}", e.getMessage(), e);
throw new RuntimeException("创建设备记录失败", e);
}
}
/**
* 清除缓存
*/
public void clearDeviceCache(String deviceIp) {
Cache cache = cacheManager.getCache("deviceunknown");
if (cache != null) {
System.out.println("清除缓存"+"ip:" + deviceIp);
cache.evict("ip:" + deviceIp);
}
}
@Override
@Transactional
public int batchCreateDevices(List<DeviceUnknown> devices) {
if (CollectionUtils.isEmpty(devices)) {
return 0;
}
// 设置默认值
devices.forEach(device -> {
if (device.getCreatedAt() == null) {
device.setCreatedAt(LocalDateTime.now());
}
if (device.getNetworkProtocol() == null) {
device.setNetworkProtocol("TCP");
}
if (device.getSourceMethod() == null) {
device.setSourceMethod("SYSTEM");
}
});
try {
int result = deviceUnknownMapper.batchInsert(devices);
log.info("批量插入设备记录成功,数量: {}", result);
return result;
} catch (Exception e) {
log.error("批量插入设备记录失败: {}", e.getMessage(), e);
throw new RuntimeException("批量插入设备记录失败", e);
}
}
@Override
public DeviceUnknown getDeviceById(Long id) {
if (id == null || id <= 0) {
throw new IllegalArgumentException("设备ID不能为空");
}
try {
return deviceUnknownMapper.selectById(id);
} catch (Exception e) {
log.error("查询设备记录失败,ID: {}, 错误: {}", id, e.getMessage(), e);
throw new RuntimeException("查询设备记录失败", e);
}
}
@Cacheable( key = "'ip:' +#deviceIp")
@Override
public List<DeviceUnknown> getDevicesByIp(String deviceIp) {
if (deviceIp == null || deviceIp.trim().isEmpty()) {
throw new IllegalArgumentException("设备IP不能为空");
}
try {
return deviceUnknownMapper.selectByIp(deviceIp);
} catch (Exception e) {
log.error("根据IP查询设备记录失败,IP: {}, 错误: {}", deviceIp, e.getMessage(), e);
throw new RuntimeException("根据IP查询设备记录失败", e);
}
}
@Override
public List<DeviceUnknown> getDevicesByOrganizationId(Integer organizationId) {
if (organizationId == null || organizationId <= 0) {
throw new IllegalArgumentException("组织ID不能为空");
}
try {
return deviceUnknownMapper.selectByOrganizationId(organizationId);
} catch (Exception e) {
log.error("根据组织ID查询设备记录失败,组织ID: {}, 错误: {}", organizationId, e.getMessage(), e);
throw new RuntimeException("根据组织ID查询设备记录失败", e);
}
}
@Override
public List<DeviceUnknown> getAllDevices() {
try {
return deviceUnknownMapper.selectAll();
} catch (Exception e) {
log.error("查询所有设备记录失败: {}", e.getMessage(), e);
throw new RuntimeException("查询所有设备记录失败", e);
}
}
@Override
public List<DeviceUnknown> getDevicesByPage(int pageNum, int pageSize) {
if (pageNum <= 0) {
pageNum = 1;
}
if (pageSize <= 0) {
pageSize = 10;
}
int offset = (pageNum - 1) * pageSize;
try {
return deviceUnknownMapper.selectPage(offset, pageSize);
} catch (Exception e) {
log.error("分页查询设备记录失败,页码: {}, 页大小: {}, 错误: {}",
pageNum, pageSize, e.getMessage(), e);
throw new RuntimeException("分页查询设备记录失败", e);
}
}
@Override
public List<DeviceUnknown> searchDevices(DeviceUnknown device) {
try {
return deviceUnknownMapper.selectByCondition(device);
} catch (Exception e) {
log.error("条件查询设备记录失败: {}", e.getMessage(), e);
throw new RuntimeException("条件查询设备记录失败", e);
}
}
@Override
@Transactional
public boolean updateDevice(DeviceUnknown device) {
if (device == null || device.getId() == null) {
throw new IllegalArgumentException("设备信息或ID不能为空");
}
try {
int result = deviceUnknownMapper.updateById(device);
if (result > 0) {
log.info("更新设备记录成功,ID: {}", device.getId());
return true;
}
log.warn("未找到要更新的设备记录,ID: {}", device.getId());
return false;
} catch (Exception e) {
log.error("更新设备记录失败,ID: {}, 错误: {}", device.getId(), e.getMessage(), e);
throw new RuntimeException("更新设备记录失败", e);
}
}
@Override
@Transactional
public boolean updateLastTime(Long id, LocalDateTime lastTime) {
if (id == null || lastTime == null) {
throw new IllegalArgumentException("设备ID和最后发现时间不能为空");
}
try {
int result = deviceUnknownMapper.updateLastTime(id, lastTime);
if (result > 0) {
log.info("更新设备最后发现时间成功,ID: {}", id);
return true;
}
log.warn("未找到要更新最后发现时间的设备记录,ID: {}", id);
return false;
} catch (Exception e) {
log.error("更新设备最后发现时间失败,ID: {}, 错误: {}", id, e.getMessage(), e);
throw new RuntimeException("更新设备最后发现时间失败", e);
}
}
@Override
@Transactional
public boolean deleteDevice(Long id) {
if (id == null || id <= 0) {
throw new IllegalArgumentException("设备ID不能为空");
}
try {
int result = deviceUnknownMapper.deleteById(id);
if (result > 0) {
log.info("删除设备记录成功,ID: {}", id);
return true;
}
log.warn("未找到要删除的设备记录,ID: {}", id);
return false;
} catch (Exception e) {
log.error("删除设备记录失败,ID: {}, 错误: {}", id, e.getMessage(), e);
throw new RuntimeException("删除设备记录失败", e);
}
}
@Override
@Transactional
public int deleteDevicesByOrganizationId(Integer organizationId) {
if (organizationId == null || organizationId <= 0) {
throw new IllegalArgumentException("组织ID不能为空");
}
try {
int result = deviceUnknownMapper.deleteByOrganizationId(organizationId);
log.info("根据组织ID删除设备记录成功,组织ID: {}, 删除数量: {}", organizationId, result);
return result;
} catch (Exception e) {
log.error("根据组织ID删除设备记录失败,组织ID: {}, 错误: {}",
organizationId, e.getMessage(), e);
throw new RuntimeException("根据组织ID删除设备记录失败", e);
}
}
@Override
public long getTotalCount() {
try {
Long count = deviceUnknownMapper.count();
return count != null ? count : 0L;
} catch (Exception e) {
log.error("统计设备总数失败: {}", e.getMessage(), e);
throw new RuntimeException("统计设备总数失败", e);
}
}
@Override
public long getCountByCondition(DeviceUnknown device) {
try {
Long count = deviceUnknownMapper.countByCondition(device);
return count != null ? count : 0L;
} catch (Exception e) {
log.error("条件统计设备数量失败: {}", e.getMessage(), e);
throw new RuntimeException("条件统计设备数量失败", e);
}
}
}
@@ -0,0 +1,106 @@
package com.config;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import java.util.Collections;
import org.springframework.cache.annotation.EnableCaching;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
@Configuration
@EnableCaching // 启用缓存
public class CacheConfig {
/**
* 配置支持类型信息的 ObjectMapper
*/
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 注册 Java 8 日期时间支持
mapper.registerModule(new JavaTimeModule());
// 禁用将日期序列化为时间戳
mapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 启用类型信息,解决 LinkedHashMap 转换问题
PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.common.entity.") // 允许你的实体类包
.allowIfSubType("java.util.ArrayList") // 允许 ArrayList
.allowIfSubType("java.util.LinkedList") // 允许 LinkedList
.allowIfBaseType("java.util.List") // 允许 List 接口
.allowIfBaseType("java.lang.Object") // 允许 Object 类型
.build();
// 激活默认类型信息
mapper.activateDefaultTyping(
ptv,
ObjectMapper.DefaultTyping.NON_FINAL,
com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY
);
return mapper;
}
/**
* Redis 缓存配置
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration() {
ObjectMapper mapper = objectMapper();
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(serializer));
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
ObjectMapper mapper = objectMapper();
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);
RedisCacheConfiguration deviceConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(serializer));
RedisCacheConfiguration collectTaskConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1))
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(serializer));
return RedisCacheManager.builder(factory)
.cacheDefaults(redisCacheConfiguration())
.withInitialCacheConfigurations(Collections.singletonMap(
"device", deviceConfig
))
.withInitialCacheConfigurations(Collections.singletonMap(
"collectTask",collectTaskConfig
))
.transactionAware()
.build();
}
}
@@ -0,0 +1,58 @@
package com.config;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 Jackson2JsonRedisSerializer 并指定类型
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.activateDefaultTyping(
mapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
);
serializer.setObjectMapper(mapper);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
/**
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setValueSerializer(serializer);
// Hash的key和value也分别设置序列化器
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
**/
}
@@ -0,0 +1,132 @@
package com.haobang.config;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import java.io.File;
import com.typesafe.config.ConfigValueFactory;
import java.util.Map;
public class AppConfig {
private static final Config config;
static {
// 加载配置文件
File configFile = new File("application.properties");
Config loadedConfig;
if (configFile.exists()) {
loadedConfig = ConfigFactory.parseFile(configFile);
} else {
loadedConfig = ConfigFactory.load("application.properties");
}
// 解析环境变量占位符
config = resolveEnvironmentVariables(loadedConfig);
}
/**
* 解析环境变量占位符
*/
private static Config resolveEnvironmentVariables(Config originalConfig) {
Config resolvedConfig = originalConfig;
// 遍历所有配置项,查找需要解析的占位符
for (Map.Entry<String, com.typesafe.config.ConfigValue> entry : originalConfig.entrySet()) {
String key = entry.getKey();
String value = originalConfig.getString(key);
if (value.contains("${")) {
String resolvedValue = resolvePlaceholder(value);
resolvedConfig = resolvedConfig.withValue(
key,
ConfigValueFactory.fromAnyRef(resolvedValue)
);
}
}
return resolvedConfig;
}
/**
* 解析单个占位符值
* 格式: ${ENV_VAR:default_value}
*/
private static String resolvePlaceholder(String value) {
if (!value.startsWith("${") || !value.endsWith("}")) {
return value;
}
String placeholder = value.substring(2, value.length() - 1);
String[] parts = placeholder.split(":");
if (parts.length == 0) {
return value; // 无效格式,返回原值
}
String envVarName = parts[0].trim();
String defaultValue = parts.length > 1 ? parts[1].trim() : "";
// 1. 从系统环境变量获取
String envValue = System.getenv(envVarName);
if (envValue != null && !envValue.trim().isEmpty()) {
return envValue.trim();
}
// 2. 从系统属性获取 (java -D参数)
String sysValue = System.getProperty(envVarName);
if (sysValue != null && !sysValue.trim().isEmpty()) {
return sysValue.trim();
}
// 3. 返回默认值
return defaultValue;
}
// Syslog 配置
public static int getSyslogTcpPort() {
return config.getInt("syslog.tcp.port");
}
public static int getSyslogUdpPort() {
return config.getInt("syslog.udp.port");
}
public static int getSyslogMaxFrameLength() {
return config.getInt("syslog.max.frame.length");
}
public static int getSyslogBufferSize() {
return config.getInt("syslog.buffer.size");
}
// app service 配置
public static String getAppServieDeviceId() {
return config.getString("app.service.device_id");
}
public static String getAppServieDeviceName() { return config.getString("app.service.device_name");
}
public static String getAppServieVendor() {
return config.getString("app.service.vendor");
}
public static String getAppServieProductName() {
return config.getString("app.service.product_name");
}
public static String getAppServieDataType() {
return config.getString("app.service.data_type");
}
// kafka 配置
public static String getKafkaProducerBootstrap() {
return config.getString("spring.kafka.producer.bootstrap-servers");
}
public static String getKafkaProducerTopic() {
return config.getString("spring.kafka.producer.topic");
}
public static int getDeviceCollectId() {
return config.getInt("app.service.device_collect_id");
}
}
@@ -0,0 +1,63 @@
package com.haobang.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
@ConfigurationProperties(prefix = "syslog")
public class SyslogConfig {
// 读取字符串属性
@Value("${syslog.tcp.port}")
private int tcpPort;
// 读取字符串属性
@Value("${syslog.udp.port}")
private int udpPort;
// 读取字符串属性
@Value("${syslog.max.frame.length}")
private int maxFrameLength;
// 读取字符串属性
@Value("${syslog.buffer.size}")
private int bufferSize;
// Getter 和 Setter 方法
public int getTcpPort() {
return tcpPort;
}
public void setTcpPort(int tcpPort) {
this.tcpPort = tcpPort;
}
public int getUdpPort() {
return udpPort;
}
public void setUdpPort(int udpPort) {
this.udpPort = udpPort;
}
public int getMaxFrameLength() {
return maxFrameLength;
}
public void setMaxFrameLength(int maxFrameLength) {
this.maxFrameLength = maxFrameLength;
}
public int getBufferSize() {
return bufferSize;
}
public void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
}
@Override
public String toString() {
return String.format("SyslogConfig[tcpPort=%d, udpPort=%d, maxFrameLength=%d, bufferSize=%d]",
tcpPort, udpPort, maxFrameLength, bufferSize);
}
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,58 @@
package com.haobang.syslog;
import org.graylog2.syslog4j.SyslogConstants;
import org.graylog2.syslog4j.server.*;
import java.net.SocketAddress;
public class MySyslogServer {
private static final String HOST = "127.0.0.1";
private static final int PORT = 514;
//514
private void receiveSyslogMessage() throws InterruptedException {
SyslogServerIF server = SyslogServer.getInstance(SyslogConstants.UDP);
SyslogServerConfigIF config = server.getConfig();
config.setHost(HOST);
config.setPort(PORT);
config.addEventHandler(new SyslogServerSessionEventHandlerIF() {
@Override
public Object sessionOpened(SyslogServerIF syslogServerIF, SocketAddress socketAddress) {
return null;
}
@Override
public void event(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress,
SyslogServerEventIF syslogServerEventIF) {
System.out.println("receive from:" + socketAddress + "\tmessage" + syslogServerEventIF.getMessage());
}
@Override
public void exception(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress, Exception e) {
}
@Override
public void sessionClosed(Object o, SyslogServerIF syslogServerIF, SocketAddress socketAddress, boolean b) {
}
@Override
public void initialize(SyslogServerIF syslogServerIF) {
}
@Override
public void destroy(SyslogServerIF syslogServerIF) {
}
});
SyslogServer.getThreadedInstance(SyslogConstants.UDP);
Thread.sleep(100000);
}
public static void main(String[] args) throws InterruptedException {
new MySyslogServer().receiveSyslogMessage();
}
}
@@ -0,0 +1,47 @@
package com.haobang.syslog;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class TestSyslogServer {
public static void main(String[] args) throws Throwable {
// TODO Auto-generated method stub
DatagramSocket datagramSocket = new DatagramSocket(514);
while (true) {
DatagramPacket packet = new DatagramPacket(new byte[1000], 1000);
try {
//不会造成死循环,因为receive是阻塞式方法,若发送方不发送数据,则阻塞在该处
datagramSocket.receive(packet);
String msg = new String(packet.getData(), 0, packet.getLength());
//handelMessage(msg);
System.out.println(packet.getAddress() + "/" + packet.getPort() + ":" + msg);
packet.setData("I am server!!!".getBytes());
datagramSocket.send(packet);
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void handelMessage(String messageFragment){
StringBuilder currentMessage = new StringBuilder();
boolean isSplitMessage = messageFragment.endsWith("..."); // 根据拆分标志判断消息是否被拆分
if (isSplitMessage) {
// 拆分的消息片段,将其合并到当前消息
currentMessage.append(messageFragment.substring(0, messageFragment.length() - 3));
} else {
// 完整的消息,处理并重置当前消息
currentMessage.append(messageFragment);
handleCompleteMessage(currentMessage.toString());
currentMessage.setLength(0);
}
}
public static void handleCompleteMessage(String completeMessage){
System.out.println("接收到完整消息:" + completeMessage);
}
}
@@ -0,0 +1,118 @@
package com.haobang.util;
import com.common.entity.DeviceDevice;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.haobang.config.AppConfig;
import java.util.LinkedHashMap;
import java.util.Map;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DeviceInfoUtil {
/**
* 补充设备配置信息 key value值
* @param strSyslog
* @return
*/
public static String getFullLogString(String strSyslog)
{
ObjectMapper objectMapper = new ObjectMapper();
// 创建设备配置信息MAP
// 获取当前时间(精度到毫秒)
LocalDateTime now = LocalDateTime.now();
// 定义格式化器,包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
// 转换为字符串
String timeString = now.format(formatter);
Map<String, String> map = new LinkedHashMap<>();
map.put("receive_time",timeString);
map.put("device_id", AppConfig.getAppServieDeviceId());
map.put("device_name", AppConfig.getAppServieDeviceName());
map.put("vendor", AppConfig.getAppServieVendor());
map.put("data_type", AppConfig.getAppServieDataType());
map.put("device_collect_id", Long.toString(AppConfig.getDeviceCollectId()));
String formattedString = formatDeviceInfo(map);
//return formattedString + "" + strSyslog.substring(34);
//测试环境截取34位之后字符串
return formattedString + strSyslog;
}
/**
* 补充设备配置信息 key value值
* @param strSyslog
* @return
*/
public static String getFullLogString(DeviceDevice deviceDevice,String strSyslog)
{
ObjectMapper objectMapper = new ObjectMapper();
// 创建设备配置信息MAP
// 获取当前时间(精度到毫秒)
LocalDateTime now = LocalDateTime.now();
// 定义格式化器,包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
// 转换为字符串
String timeString = now.format(formatter);
Map<String, String> map = new LinkedHashMap<>();
map.put("receive_time",timeString);
map.put("device_id",deviceDevice.getId().toString());
map.put("device_name", deviceDevice.getName());
map.put("vendor", deviceDevice.getVendor());
map.put("data_type", AppConfig.getAppServieDataType());
map.put("device_collect_id", Long.toString(AppConfig.getDeviceCollectId()));
String formattedString = formatDeviceInfo(map);
//return formattedString + "" + strSyslog.substring(34);
//测试环境截取34位之后字符串
return formattedString + strSyslog;
}
public static String getFullLogString(DeviceDevice deviceDevice,String strSyslog,String receive_time)
{
ObjectMapper objectMapper = new ObjectMapper();
// 创建设备配置信息MAP
// 获取当前时间(精度到毫秒)
LocalDateTime now = LocalDateTime.now();
// 定义格式化器,包含毫秒
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
// 转换为字符串
String timeString = now.format(formatter);
Map<String, String> map = new LinkedHashMap<>();
map.put("receive_time",receive_time);
map.put("device_id",deviceDevice.getId().toString());
map.put("device_name", deviceDevice.getName());
map.put("vendor", deviceDevice.getVendor());
map.put("data_type", AppConfig.getAppServieDataType());
map.put("device_collect_id", Long.toString(AppConfig.getDeviceCollectId()));
String formattedString = formatDeviceInfo(map);
//return formattedString + "" + strSyslog.substring(34);
//测试环境截取34位之后字符串
return formattedString + strSyslog;
}
public static String formatDeviceInfo(Map<String, String> deviceData) {
if (deviceData == null || deviceData.isEmpty()) {
return "[]"; // 返回空括号表示无数据
}
StringBuilder sb = new StringBuilder();
sb.append("["); // 开始字符
// 使用 LinkedHashMap 保持插入顺序
boolean firstEntry = true;
for (Map.Entry<String, String> entry : deviceData.entrySet()) {
if (!firstEntry) {
sb.append(" "); // 键值对之间用空格分隔
}
sb.append(entry.getKey())
.append("=")
.append(entry.getValue());
firstEntry = false;
}
sb.append("]"); // 结束字符
return sb.toString();
}
}
@@ -0,0 +1,108 @@
package com.haobang.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.LinkedHashMap;
import java.util.List ;
import java.util.stream.Collectors;
@Component
public class SafeCacheUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ObjectMapper objectMapper;
/**
* 安全的缓存获取方法
*/
@SuppressWarnings("unchecked")
public <T> T getSafe(String key, Class<T> clazz, Supplier<T> loader) {
try {
Object cached = redisTemplate.opsForValue().get(key);
if (cached == null) {
// 缓存不存在,从数据源加载
T value = loader.get();
if (value != null) {
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
}
return value;
}
// 类型匹配,直接返回
if (clazz.isInstance(cached)) {
return (T) cached;
}
// 类型不匹配,尝试转换
if (cached instanceof LinkedHashMap) {
return objectMapper.convertValue(cached, clazz);
}
// 无法转换,重新加载
T value = loader.get();
if (value != null) {
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
}
return value;
} catch (Exception e) {
// 缓存出错,降级到数据源
return loader.get();
}
}
/**
* 安全的列表缓存获取
*/
@SuppressWarnings("unchecked")
public <T> List<T> getSafeList(String key, Class<T> elementClass, Supplier<List<T>> loader) {
try {
Object cached = redisTemplate.opsForValue().get(key);
if (cached == null) {
List<T> value = loader.get();
if (value != null && !value.isEmpty()) {
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
}
return value;
}
// 已经是正确的类型
if (cached instanceof List &&
!((List<?>) cached).isEmpty() &&
elementClass.isInstance(((List<?>) cached).get(0))) {
return (List<T>) cached;
}
// 需要转换
if (cached instanceof List) {
List<LinkedHashMap> rawList = (List<LinkedHashMap>) cached;
List<T> convertedList = rawList.stream()
.map(item -> objectMapper.convertValue(item, elementClass))
.collect(Collectors.toList());
// 更新缓存为正确格式
redisTemplate.opsForValue().set(key, convertedList, 30, TimeUnit.MINUTES);
return convertedList;
}
// 无法处理,重新加载
List<T> value = loader.get();
if (value != null && !value.isEmpty()) {
redisTemplate.opsForValue().set(key, value, 30, TimeUnit.MINUTES);
}
return value;
} catch (Exception e) {
return loader.get();
}
}
}
@@ -0,0 +1,34 @@
package com.haobang.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return applicationContext.getBean(name, clazz);
}
// 专门获取 Mapper 的方法
public static <T> T getMapper(Class<T> mapperClass) {
return applicationContext.getBean(mapperClass);
}
}
@@ -0,0 +1,45 @@
package com.haobang.util;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class TimeUtils {
private static final DateTimeFormatter DEFAULT_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
/**
* 获取当前时间的字符串表示(包含毫秒)
*/
public static String getCurrentTimeString() {
return LocalDateTime.now().format(DEFAULT_FORMATTER);
}
/**
* 获取指定格式的当前时间字符串
*/
public static String getCurrentTimeString(String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return LocalDateTime.now().format(formatter);
}
/**
* 获取时间戳格式的字符串(无分隔符)
*/
public static String getTimestampString() {
return getCurrentTimeString("yyyyMMddHHmmssSSS");
}
/**
* 获取当前时间戳(毫秒)
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis();
}
// 使用示例
public static void main(String[] args) {
System.out.println("默认格式: " + getCurrentTimeString());
System.out.println("时间戳格式: " + getTimestampString());
System.out.println("自定义格式: " + getCurrentTimeString("yyyy/MM/dd HH:mm:ss.SSS"));
}
}
@@ -0,0 +1,62 @@
package com.kafka;
import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.serialization.StringDeserializer;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class kafkaConsumer {
public static void main(String[] args) {
// 配置消费者属性
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.222.130:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group");
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
// 可选配置
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); // 从最早的消息开始消费
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true"); // 自动提交偏移量
props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000"); // 自动提交间隔
// 创建消费者实例
Consumer<String, String> consumer = new KafkaConsumer<>(props);
try {
// 订阅主题
consumer.subscribe(Collections.singletonList("test-topic"));
System.out.println("开始消费消息...");
// 持续消费消息
while (true) {
// 拉取消息(等待最多100毫秒)
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.printf(
"收到消息: 主题=%s, 分区=%d, 偏移量=%d, 键=%s, 值=%s%n",
record.topic(),
record.partition(),
record.offset(),
record.key(),
record.value()
);
// 这里可以添加业务处理逻辑
}
// 手动提交偏移量(如果禁用自动提交)
// consumer.commitSync();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭消费者
consumer.close();
}
}
}
@@ -0,0 +1,170 @@
package com.kafka;
import com.common.entity.DeviceDevice;
import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringSerializer;
import java.util.LinkedHashMap;
import java.util.Properties;
import com.haobang.config.AppConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.haobang.util.DeviceInfoUtil;
public class kafkaProducer {
private static final Logger logger = LoggerFactory.getLogger(kafkaProducer.class);
public static void main(String[] args) {
// System.out.println(getFullLogString("syslogmessage"));
// 配置生产者属性
Properties props = new Properties();
//props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.222.130:9092");
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, AppConfig.getKafkaProducerBootstrap());
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
// 可选配置:提高可靠性
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.RETRIES_CONFIG, 3);
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
// 创建生产者实例
Producer<String, String> producer = new KafkaProducer<>(props);
try {
// 发送10条消息
//for (int i = 0; i < 1; i++) {
String key = "key-" + "1";
String value = "message-" + "1" + " at " + System.currentTimeMillis();
// 创建生产者记录
ProducerRecord<String, String> record =
new ProducerRecord<>(AppConfig.getKafkaProducerTopic(), key, value);
// 发送消息(异步方式)
producer.send(record, new Callback() {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception == null) {
System.out.println("消息发送成功: " +
"主题=" + metadata.topic() +
", 分区=" + metadata.partition() +
", 偏移量=" + metadata.offset());
} else {
System.err.println("消息发送失败: " + exception.getMessage());
}
}
});
// 同步发送方式(如果需要)
// RecordMetadata metadata = producer.send(record).get();
// System.out.println("同步发送成功: " + metadata.offset());
// }
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭生产者
producer.close();
}
}
/**
* * syslog 文本消息
* * @param strSyslog
*/
public static void messagePush(DeviceDevice deviceDevice, String strSyslog,String strReceiveTime)
{
// 配置生产者属性
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, AppConfig.getKafkaProducerBootstrap());
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
// 可选配置:提高可靠性
props.put(ProducerConfig.ACKS_CONFIG, "all");
props.put(ProducerConfig.RETRIES_CONFIG, 3);
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);
// 创建生产者实例
Producer<String, String> producer = new KafkaProducer<>(props);
try {
String key = "key-" + System.currentTimeMillis();
//String value = DeviceInfoUtil.getFullLogString(strSyslog);
//采用动态获取Syslog 请求的设备信息
String value = DeviceInfoUtil.getFullLogString(deviceDevice,strSyslog,strReceiveTime);
// 创建生产者记录
ProducerRecord<String, String> record =
new ProducerRecord<>(AppConfig.getKafkaProducerTopic(), key, value);
// 发送消息(异步方式)
producer.send(record, new Callback() {
@Override
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception == null) {
System.out.println("消息发送成功: " +
"主题=" + metadata.topic() +
", 分区=" + metadata.partition() +
", 偏移量=" + metadata.offset());
} else {
System.err.println("消息发送失败: " + exception.getMessage());
logger.error("消息发送失败: " + exception.getMessage());
}
}
});
// 同步发送方式(如果需要)
// RecordMetadata metadata = producer.send(record).get();
// System.out.println("同步发送成功: " + metadata.offset());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭生产者
producer.close();
}
}
/**
* 生成json字符串,补充设备配置信息
* @param strSyslog
* @return
*/
private static String getLogJsonString(String strSyslog)
{
ObjectMapper objectMapper = new ObjectMapper();
// 创建设备配置信息MAP
Map<String, Object> map = new LinkedHashMap<>();
map.put("device_id",AppConfig.getAppServieDeviceId() );
map.put("device_name", AppConfig.getAppServieDeviceName());
map.put("vendor", AppConfig.getAppServieVendor());
map.put("data_type", AppConfig.getAppServieDataType());
// 添加syslogMessage
map.put("syslogMessage", strSyslog);
try {
//生成json消息字符串
String json = objectMapper.writeValueAsString(map);
return json;
}
catch(Exception ex)
{
logger.error("kafkaProducer getLogJsonString()生成json字符串 异常: syslog: "+ strSyslog);
logger.error("Exception: : "+ ex.getMessage());
}
return null;
}
}
@@ -0,0 +1,75 @@
package com.netty;
import java.util.Date;
/**
* Syslog 消息实体类
*/
public class SyslogMessage {
private Integer facility;
private Integer severity;
private Date timestamp;
private String hostname;
private String message;
// 构造函数
public SyslogMessage() {}
// Getter 和 Setter 方法
public Integer getFacility() {
return facility;
}
public void setFacility(Integer facility) {
this.facility = facility;
}
public Integer getSeverity() {
return severity;
}
public void setSeverity(Integer severity) {
this.severity = severity;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
// 这里可以添加时间戳解析逻辑
// 简化实现,直接使用当前时间
this.timestamp = new Date();
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String toString() {
return "SyslogMessage{" +
"facility=" + facility +
", severity=" + severity +
", timestamp=" + timestamp +
", hostname='" + hostname + '\'' +
", message='" + message + '\'' +
'}';
}
}
@@ -0,0 +1,149 @@
package com.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import com.kafka.kafkaProducer;
import com.Modules.Device.DeviceProcess;
/**
* Syslog 消息处理器
*/
public class SyslogMessageHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = LoggerFactory.getLogger(SyslogMessageHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
String message;
String source;
String source_ip;
String networkProtocol;
int source_port;
if (msg instanceof DatagramPacket) {
// UDP 消息处理
DatagramPacket packet = (DatagramPacket) msg;
message = packet.content().toString(io.netty.util.CharsetUtil.UTF_8);
source_ip=packet.sender().getAddress().getHostAddress();
source_port=packet.sender().getPort();
source = packet.sender().getAddress().getHostAddress() + ":" + packet.sender().getPort();
networkProtocol="UDP";
logger.info("Received syslog from {}: {}", source, message);
} else if (msg instanceof String) {
// TCP 消息处理
message = (String) msg;
InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
source = remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort();
source_ip=remoteAddress.getAddress().getHostAddress();
source_port=remoteAddress.getPort();
networkProtocol="TCP";
logger.info("Received syslog from {}: {}", source, message);
} else {
logger.warn("Received unknown message type: {}", msg.getClass().getName());
return;
}
DeviceProcess deviceProcess = new DeviceProcess(source_ip);
try {
//日志推送的设备信息进行鉴权处理
int deviceId = deviceProcess.getDeviceID(source_ip);
if (deviceId < 0) {
logger.info("syslog message 的请求设备IP:{}非系统注册,暂不做处理!",source_ip);
//创建未知设备
deviceProcess.saveDeviceUnknow(networkProtocol);
return;
}
if (!deviceProcess.IsBelongDeviceCollectTask()) {
logger.info("syslog message 的请求设备IP:{}不归属当前采集探针,暂不做处理!",source_ip);
return;
}
//插入PG库接收记录
deviceProcess.saveDeviceReceiveLog(message,true);
kafkaProducer.messagePush(deviceProcess.getDeviceDevice(), message, deviceProcess.getDeviceReceiveLog().getReceiveTimeStr());
} catch (Exception e) {
//记录日志推送失败
deviceProcess.saveDeviceReceiveLog(message,false);
logger.warn("Failed to Push syslog message", e);
}
// 处理 Syslog 消息
//processSyslogMessage(message.trim(), source);
}
private void processSyslogMessage(String message, String source) {
// 这里可以添加 Syslog 消息解析逻辑
// 根据 RFC 3164 或 RFC 5424 解析消息
System.out.println("Received syslog from "+ source +", msg:"+ message);
logger.info("Received syslog from {}: {}", source, message);
try {
SyslogMessage syslogMsg = parseSyslogMessage(message);
logger.info("Parsed syslog - Facility: {}, Severity: {}, Timestamp: {}, Host: {}, Message: {}",
syslogMsg.getFacility(),
syslogMsg.getSeverity(),
syslogMsg.getTimestamp(),
syslogMsg.getHostname(),
syslogMsg.getMessage());
// 这里可以添加消息存储或其他处理逻辑
// storeToDatabase(syslogMsg);
} catch (Exception e) {
logger.warn("Failed to parse syslog message: {}", message, e);
}
}
/**
* 简单的 Syslog 消息解析(RFC 3164 格式)
*/
private SyslogMessage parseSyslogMessage(String message) {
SyslogMessage syslogMsg = new SyslogMessage();
// 尝试解析 PRI 部分
if (message.startsWith("<")) {
int priEnd = message.indexOf(">");
if (priEnd > 0) {
String priStr = message.substring(1, priEnd);
try {
int pri = Integer.parseInt(priStr);
int facility = pri >> 3;
int severity = pri & 0x07;
syslogMsg.setFacility(facility);
syslogMsg.setSeverity(severity);
message = message.substring(priEnd + 1).trim();
} catch (NumberFormatException e) {
// 忽略 PRI 解析错误
}
}
}
// 尝试解析时间戳和主机名
// 这是一个简化的解析,实际实现可能需要更复杂的逻辑
String[] parts = message.split(" ", 5);
if (parts.length >= 4) {
// 假设前三个部分是时间戳,第四个部分是主机名
String timestamp = parts[0] + " " + parts[1] + " " + parts[2];
syslogMsg.setTimestamp(timestamp);
syslogMsg.setHostname(parts[3]);
if (parts.length == 5) {
syslogMsg.setMessage(parts[4]);
}
} else {
syslogMsg.setMessage(message);
}
return syslogMsg;
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
logger.error("Exception in channel handler", cause);
ctx.close();
}
}
@@ -0,0 +1,84 @@
package com.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Syslog 服务器主类,支持 TCP 和 UDP 协议
*/
public class SyslogServer {
private static final Logger logger = LoggerFactory.getLogger(SyslogServer.class);
private final int tcpPort;
private final int udpPort;
public SyslogServer(int tcpPort, int udpPort) {
this.tcpPort = tcpPort;
this.udpPort = udpPort;
}
public void start() throws InterruptedException {
// 启动 TCP 服务器
startTcpServer();
// 启动 UDP 服务器
startUdpServer();
}
private void startTcpServer() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new SyslogTcpChannelInitializer())
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(tcpPort).sync();
logger.info("TCP Syslog server started on port {}", tcpPort);
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
private void startUdpServer() throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioDatagramChannel.class)
.handler(new SyslogUdpChannelInitializer())
.option(ChannelOption.SO_BROADCAST, true);
ChannelFuture f = b.bind(udpPort).sync();
logger.info("UDP Syslog server started on port {}", udpPort);
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int tcpPort = args.length > 0 ? Integer.parseInt(args[0]) : 514;
int udpPort = args.length > 1 ? Integer.parseInt(args[1]) : 514;
SyslogServer server = new SyslogServer(tcpPort, udpPort);
server.start();
}
}
@@ -0,0 +1,202 @@
package com.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Syslog 服务器主类,支持 TCP 和 UDP 协议
*/
public class SyslogServerBoth {
private static final Logger logger = LoggerFactory.getLogger(SyslogServer.class);
private final int tcpPort;
private final int udpPort;
// 共享的EventLoopGroup以优化资源使用
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private EventLoopGroup udpGroup;
private ChannelFuture tcpChannelFuture;
private ChannelFuture udpChannelFuture;
private final ExecutorService serverExecutor = Executors.newFixedThreadPool(2);
public SyslogServerBoth(int tcpPort, int udpPort) {
this.tcpPort = tcpPort;
this.udpPort = udpPort;
}
public void start() throws InterruptedException {
logger.info("Starting Syslog server with TCP port {} and UDP port {}", tcpPort, udpPort);
// 创建共享的EventLoopGroup
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
udpGroup = new NioEventLoopGroup();
final CountDownLatch latch = new CountDownLatch(2);
try {
// 启动UDP服务器(使用独立的线程)
serverExecutor.submit(() -> {
try {
startUdpServer();
latch.countDown();
} catch (Exception e) {
logger.error("UDP server failed to start", e);
latch.countDown();
throw new RuntimeException(e);
}
});
// 启动TCP服务器(使用独立的线程)
serverExecutor.submit(() -> {
try {
startTcpServer();
latch.countDown();
} catch (Exception e) {
logger.error("TCP server failed to start", e);
latch.countDown();
throw new RuntimeException(e);
}
});
// 等待两个服务器都启动完成
latch.await();
logger.info("Both TCP and UDP Syslog servers are running");
// 注册关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
// 保持主线程运行
Thread.currentThread().join();
} catch (Exception e) {
logger.error("Failed to start servers", e);
shutdown();
}
}
private void startTcpServer() throws InterruptedException {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new SyslogTcpChannelInitializer())
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
tcpChannelFuture = b.bind(tcpPort).sync();
logger.info("TCP Syslog server started on port {}", tcpPort);
// 添加关闭监听器
tcpChannelFuture.channel().closeFuture().addListener(future -> {
if (future.isSuccess()) {
logger.info("TCP server channel closed");
}
});
}
private void startUdpServer() throws InterruptedException {
Bootstrap b = new Bootstrap();
b.group(udpGroup)
.channel(NioDatagramChannel.class)
.handler(new SyslogUdpChannelInitializer())
.option(ChannelOption.SO_BROADCAST, true);
udpChannelFuture = b.bind(udpPort).sync();
logger.info("UDP Syslog server started on port {}", udpPort);
// 添加关闭监听器
udpChannelFuture.channel().closeFuture().addListener(future -> {
if (future.isSuccess()) {
logger.info("UDP server channel closed");
}
});
}
/**
* 优雅关闭服务器
*/
public void shutdown() {
logger.info("Shutting down Syslog servers...");
try {
// 关闭TCP服务器
if (tcpChannelFuture != null) {
tcpChannelFuture.channel().close().sync();
}
// 关闭UDP服务器
if (udpChannelFuture != null) {
udpChannelFuture.channel().close().sync();
}
// 关闭EventLoopGroup
if (bossGroup != null) {
bossGroup.shutdownGracefully().sync();
}
if (workerGroup != null) {
workerGroup.shutdownGracefully().sync();
}
if (udpGroup != null) {
udpGroup.shutdownGracefully().sync();
}
// 关闭线程池
serverExecutor.shutdown();
logger.info("Syslog servers shutdown complete");
} catch (Exception e) {
logger.error("Error during shutdown", e);
}
}
/**
* 检查服务器是否在运行
*/
public boolean isRunning() {
return (tcpChannelFuture != null && tcpChannelFuture.channel().isActive()) ||
(udpChannelFuture != null && udpChannelFuture.channel().isActive());
}
public static void main(String[] args) throws Exception {
int tcpPort = 514;
int udpPort = 514;
// 解析命令行参数
if (args.length >= 1) {
tcpPort = Integer.parseInt(args[0]);
}
if (args.length >= 2) {
udpPort = Integer.parseInt(args[1]);
}
// 如果两个端口相同,UDP端口自动+1避免冲突
if (tcpPort == udpPort) {
udpPort = tcpPort + 1;
logger.warn("TCP and UDP ports cannot be the same. UDP port changed to {}", udpPort);
}
SyslogServerBoth server = new SyslogServerBoth(tcpPort, udpPort);
// 注册全局异常处理器
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
logger.error("Uncaught exception in thread {}", t.getName(), e);
});
server.start();
}
}
@@ -0,0 +1,36 @@
package com.netty;
import com.haobang.config.AppConfig;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
/**
* TCP 通道初始化器
*/
public class SyslogTcpChannelInitializer extends ChannelInitializer<SocketChannel> {
private static final int MAX_FRAME_LENGTH = AppConfig.getSyslogMaxFrameLength();
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 添加基于分隔符的帧解码器,处理以换行符结尾的 Syslog 消息
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
MAX_FRAME_LENGTH,
Delimiters.lineDelimiter()));
// 添加字符串解码器和编码器
pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
// 添加业务处理器
pipeline.addLast("handler", new SyslogMessageHandler());
}
}
@@ -0,0 +1,25 @@
package com.netty;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.DatagramChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
/**
* UDP 通道初始化器
*/
public class SyslogUdpChannelInitializer extends ChannelInitializer<DatagramChannel> {
@Override
protected void initChannel(DatagramChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 添加字符串解码器和编码器
pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
// 添加业务处理器
pipeline.addLast("handler", new SyslogMessageHandler());
}
}
@@ -0,0 +1,57 @@
#Server Configuration
server.port=8189
server.servlet.context-path=/syslogserve
#server.address=0.0.0.0
server.tomcat.uri-encoding=UTF-8
server.error.include-message=always
server.error.include-binding-errors=always
# Syslog Server Configuration
syslog.tcp.port=514
syslog.udp.port=514
syslog.max.frame.length=262144
syslog.buffer.size=1000
# APP Service Configuration
app.service.device_id=1
app.service.device_name=honeypot
app.service.vendor=changting
app.service.product_name=diting
#采集探针ID
app.service.device_collect_id=${DEVICE_COLLECT_ID:1}
# syslog message data_type
app.service.data_type=json
# kafka Configuration
spring.kafka.producer.bootstrap-servers=192.168.222.130:9092
spring.kafka.producer.topic =test-topic
#database Configuration
spring.datasource.url=jdbc:postgresql://117.72.68.72:54329/ecosys
spring.datasource.username=postgres
spring.datasource.password=TnLanWaidYSwTSG5
spring.datasource.driver-class-name=org.postgresql.Driver
# mybatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.common.entity
mybatis.configuration.map-underscore-to-camel-case=true
# 开发环境缓存配置
spring.redis.host=localhost
spring.redis.port=6379
# 密码(如果没有设置密码,可以省略)
spring.redis.password=
spring.redis.database=0
spring.redis.timeout=2000
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# 开发环境缓存时间较短,方便调试
spring.cache.redis.time-to-live=600000
@@ -0,0 +1,56 @@
#Server Configuration [zhongcheng]
server.port=8189
server.servlet.context-path=/syslogserve
#server.address=0.0.0.0
server.tomcat.uri-encoding=UTF-8
server.error.include-message=always
server.error.include-binding-errors=always
# Syslog Server Configuration
syslog.tcp.port=514
syslog.udp.port=514
syslog.max.frame.length=262144
syslog.buffer.size=1000
# APP Service Configuration
app.service.device_id=1
app.service.device_name=honeypot
app.service.vendor=changting
app.service.product_name=diting
# syslog message data_type
app.service.data_type=json
#采集探针ID
#app.service.device_collect_id=${DEVICE_COLLECT_ID:2}
app.service.device_collect_id=${DEVICE_COLLECT_ID:1}
# kafka Configuration
spring.kafka.producer.bootstrap-servers=10.11.2.142:9092
spring.kafka.producer.topic =agent-syslog-topic
#database Configuration
spring.datasource.url=jdbc:postgresql://10.11.2.141:5432/ecosys
spring.datasource.username=ecosys
spring.datasource.password=wsYDPjrpNZPrkPrR
spring.datasource.driver-class-name=org.postgresql.Driver
# mybatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.common.entity
mybatis.configuration.map-underscore-to-camel-case=true
# 生产环境缓存配置
spring.redis.host=10.11.2.142
spring.redis.port=6379
# 密码(如果没有设置密码,可以省略)
spring.redis.password=redis_edP6N6
spring.redis.database=0
spring.redis.timeout=5000
#spring.redis.password=${REDIS_PASSWORD:default_prod_password}
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=5000
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=5
# 生产环境缓存时间较长
spring.cache.redis.time-to-live=3600000
@@ -0,0 +1,55 @@
#Server Configuration [192.168.4.26]
server.port=8189
server.servlet.context-path=/syslogserve
#server.address=0.0.0.0
server.tomcat.uri-encoding=UTF-8
server.error.include-message=always
server.error.include-binding-errors=always
# Syslog Server Configuration
syslog.tcp.port=514
syslog.udp.port=514
syslog.max.frame.length=262144
syslog.buffer.size=1000
# APP Service Configuration
app.service.device_id=1
app.service.device_name=honeypot
app.service.vendor=changting
app.service.product_name=diting
# syslog message data_type
app.service.data_type=json
#采集探针ID
app.service.device_collect_id=${DEVICE_COLLECT_ID:1}
# kafka Configuration
spring.kafka.producer.bootstrap-servers=192.168.4.26:9092
spring.kafka.producer.topic =agent-syslog-topic
#database Configuration
spring.datasource.url=jdbc:postgresql://192.168.4.26:5432/ecosys
spring.datasource.username=postgres
spring.datasource.password=caZ2TcmXNSW8L2Ap
spring.datasource.driver-class-name=org.postgresql.Driver
# mybatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.common.entity
mybatis.configuration.map-underscore-to-camel-case=true
# 生产环境缓存配置
spring.redis.host=192.168.4.26
spring.redis.port=6379
# 密码(如果没有设置密码,可以省略)
spring.redis.password=123456
spring.redis.database=0
spring.redis.timeout=5000
#spring.redis.password=${REDIS_PASSWORD:default_prod_password}
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=5000
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=5
# 生产环境缓存时间较长
spring.cache.redis.time-to-live=3600000
@@ -0,0 +1,59 @@
#Server Configuration
server.port=8189
server.servlet.context-path=/syslogserve
#server.address=0.0.0.0
server.tomcat.uri-encoding=UTF-8
server.error.include-message=always
server.error.include-binding-errors=always
# Syslog Server Configuration
syslog.tcp.port=514
syslog.udp.port=514
syslog.max.frame.length=65536
syslog.buffer.size=1000
# APP Service Configuration
app.service.device_id=1
app.service.device_name=honeypot
app.service.vendor=changting
app.service.product_name=diting
# syslog message data_type
app.service.data_type=json
#采集探针ID
app.service.device_collect_id=1
# kafka Configuration
spring.kafka.producer.bootstrap-servers=192.168.4.32:9092
spring.kafka.producer.topic =agent-syslog-topic
#database Configuration
spring.datasource.url=jdbc:postgresql://192.168.4.32:5432/ecosys
spring.datasource.username=user_eSER8N
spring.datasource.password=password_QCYKj6
spring.datasource.driver-class-name=org.postgresql.Driver
# mybatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.common.entity
mybatis.configuration.map-underscore-to-camel-case=true
# 生产环境缓存配置
spring.redis.host=192.168.4.32
spring.redis.port=6379
# 密码(如果没有设置密码,可以省略)
spring.redis.password=password_QCYKj6
spring.redis.database=0
spring.redis.timeout=5000
#spring.redis.password=${REDIS_PASSWORD:default_prod_password}
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=5000
spring.redis.lettuce.pool.max-idle=10
spring.redis.lettuce.pool.min-idle=5
# 生产环境缓存时间较长
spring.cache.redis.time-to-live=3600000
@@ -0,0 +1,57 @@
#Server Configuration
server.port=8189
server.servlet.context-path=/syslogserve
#server.address=0.0.0.0
server.tomcat.uri-encoding=UTF-8
server.error.include-message=always
server.error.include-binding-errors=always
# Syslog Server Configuration
syslog.tcp.port=514
syslog.udp.port=514
syslog.max.frame.length=262144
syslog.buffer.size=1000
# APP Service Configuration
app.service.device_id=1
app.service.device_name=honeypot
app.service.vendor=changting
app.service.product_name=diting
#采集探针ID
app.service.device_collect_id=${DEVICE_COLLECT_ID:1}
# syslog message data_type
app.service.data_type=json
# kafka Configuration
spring.kafka.producer.bootstrap-servers=192.168.222.130:9092
spring.kafka.producer.topic =test-topic
#database Configuration
spring.datasource.url=jdbc:postgresql://117.72.68.72:54329/ecosys
spring.datasource.username=postgres
spring.datasource.password=TnLanWaidYSwTSG5
spring.datasource.driver-class-name=org.postgresql.Driver
# mybatis Configuration
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.common.entity
mybatis.configuration.map-underscore-to-camel-case=true
# 开发环境缓存配置
spring.redis.host=localhost
spring.redis.port=6379
# 密码(如果没有设置密码,可以省略)
spring.redis.password=
spring.redis.database=0
spring.redis.timeout=2000
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# 开发环境缓存时间较短,方便调试
spring.cache.redis.time-to-live=600000
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration >
<!-- 定义日志输出格式 -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 控制台输出 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 文件输出,每天滚动 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/syslog-serve.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天滚动 -->
<fileNamePattern>logs/syslog-serve.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保留的日志文件的最大天数 -->
<maxHistory>1</maxHistory>
<!-- 所有归档日志文件的总大小上限 -->
<totalSizeCap>15GB</totalSizeCap>
<!-- 启动时是否清理过期日志 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 设置日志级别 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
<!-- 可以设置特定包的日志级别 -->
<!-- 例如,将com.example包的日志级别设置为DEBUG -->
<!-- 专门屏蔽ProducerConfig的INFO日志 -->
<logger name="org.apache.kafka.clients.producer.ProducerConfig" level="WARN"/>
<!-- 更通用地屏蔽整个Kafka客户端包的INFO日志 -->
<logger name="org.apache.kafka.clients" level="WARN"/>
<!-- 方法1: 设置 Kafka 相关包为 WARN 级别 -->
<logger name="org.apache.kafka" level="WARN"/>
<logger name="kafka" level="WARN"/>
<!-- 方法2: 更精确地控制特定类 -->
<logger name="org.apache.kafka.common.utils.AppInfoParser" level="ERROR"/>
<logger name="org.apache.kafka.common.metrics.Metrics" level="ERROR"/>
</configuration>
@@ -0,0 +1,67 @@
<?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="com.common.mapper.DeviceCollectTaskMapper">
<resultMap id="BaseResultMap" type="com.common.entity.DeviceCollectTask">
<id column="id" property="id" />
<result column="created_at" property="createdAt" />
<result column="updated_at" property="updatedAt" />
<result column="deleted_at" property="deletedAt" />
<result column="device_id" property="deviceId" />
<result column="method" property="method" />
<result column="task_name" property="taskName" />
<result column="first_time" property="firstTime" />
<result column="last_success_time" property="lastSuccessTime" />
<result column="last_failed_time" property="lastFailedTime" />
<result column="detail_id" property="detailId" />
<result column="epm" property="epm" />
<result column="epm_peak" property="epmPeak" />
<result column="process_architecture" property="processArchitecture" />
<result column="task_count" property="taskCount" />
<result column="recent_discover_time" property="recentDiscoverTime" />
<result column="epm_upper_limit" property="epmUpperLimit" />
</resultMap>
<sql id="Base_Column_List">
id, created_at, updated_at, deleted_at, device_id, method, task_name,
first_time, last_success_time, last_failed_time, detail_id, epm, epm_peak,
process_architecture, task_count, recent_discover_time, epm_upper_limit
</sql>
<!-- 多条件组合查询 -->
<select id="selectByCondition" parameterType="com.common.entity.DeviceCollectTask" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM device_collect_task
<where>
<if test="deviceId != null">
AND device_id = #{deviceId}
</if>
<if test="method != null">
AND method = #{method}
</if>
<if test="taskName != null and taskName != ''">
AND task_name LIKE CONCAT('%', #{taskName}, '%')
</if>
<if test="detailId != null">
AND detail_id = #{detailId}
</if>
<if test="processArchitecture != null">
AND process_architecture = #{processArchitecture}
</if>
<if test="epmUpperLimit != null">
AND epm_upper_limit = #{epmUpperLimit}
</if>
<!-- 时间范围查询 -->
<if test="firstTime != null">
AND first_time >= #{firstTime}
</if>
<if test="lastSuccessTime != null">
AND last_success_time >= #{lastSuccessTime}
</if>
</where>
ORDER BY updated_at DESC
</select>
</mapper>
@@ -0,0 +1,238 @@
<?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="com.common.mapper.DeviceDeviceMapper">
<!-- 基础结果映射 -->
<resultMap id="BaseResultMap" type="com.common.entity.DeviceDevice">
<id column="id" property="id" />
<result column="created_at" property="createdAt" />
<result column="updated_at" property="updatedAt" />
<result column="deleted_at" property="deletedAt" />
<result column="name" property="name" />
<result column="ip" property="ip" />
<result column="device_group" property="deviceGroup" />
<result column="device_type" property="deviceType" />
<result column="vendor" property="vendor" />
<result column="product_name" property="productName" />
<result column="organization_id" property="organizationId" />
<result column="last_receive_time" property="lastReceiveTime" />
<result column="agent_id" property="agentId" />
<result column="detail_id" property="detailId" />
<result column="control_agent_id" property="controlAgentId" />
<result column="license_start_time" property="licenseStartTime" />
<result column="license_end_time" property="licenseEndTime" />
<result column="is_monitoring" property="isMonitoring" />
<result column="security_scope_id" property="securityScopeId" />
<result column="owner_id" property="ownerId" />
<result column="ssh_config_id" property="sshConfigId" />
<result column="status" property="status" />
<result column="created_by_id" property="createdById" />
<result column="decode_type" property="decodeType" />
<result column="miss_policy" property="missPolicy" />
<result column="tenant_id" property="tenantId" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="create_by" property="createBy" />
<result column="update_by" property="updateBy" />
<result column="del_flag" property="delFlag" />
<result column="manager_name" property="managerName" />
<result column="today_parse_count" property="todayParseCount" />
<result column="today_non_log_count" property="todayNonLogCount" />
<result column="create_dept" property="createDept" />
<result column="device_collect_id" property="deviceCollectId" />
</resultMap>
<!-- 基础查询列 -->
<sql id="Base_Column_List">
id, created_at::timestamp , updated_at::timestamp, deleted_at::timestamp, name, ip, device_group, device_type,
vendor, product_name, organization_id, last_receive_time::timestamp, agent_id, detail_id,
control_agent_id, license_start_time::timestamp, license_end_time::timestamp, is_monitoring,
security_scope_id, owner_id, ssh_config_id, status, created_by_id, decode_type,
miss_policy, tenant_id, create_time::timestamp, update_time::timestamp, create_by, update_by, del_flag,
manager_name, today_parse_count, today_non_log_count, create_dept, device_collect_id
</sql>
<!-- 根据ID查询 -->
<select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE id = #{id}
</select>
<!-- 查询所有设备 -->
<select id="selectAll" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
</select>
<!-- 根据IP查询 -->
<select id="selectByIp" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE ip = #{ip} and del_flag='0'
</select>
<!-- 根据名称模糊查询 -->
<select id="selectByNameLike" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE name LIKE CONCAT('%', #{name}, '%')
</select>
<!-- 根据设备组查询 -->
<select id="selectByDeviceGroup" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE device_group = #{deviceGroup}
</select>
<!-- 根据设备类型查询 -->
<select id="selectByDeviceType" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE device_type = #{deviceType}
</select>
<!-- 根据组织ID查询 -->
<select id="selectByOrganizationId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE organization_id = #{organizationId}
</select>
<!-- 根据状态查询 -->
<select id="selectByStatus" parameterType="java.lang.Short" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE status = #{status}
</select>
<!-- 多条件组合查询 -->
<select id="selectByCondition" parameterType="com.common.entity.DeviceDevice" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="ip != null and ip != ''">
AND ip = #{ip}
</if>
<if test="deviceGroup != null">
AND device_group = #{deviceGroup}
</if>
<if test="deviceType != null">
AND device_type = #{deviceType}
</if>
<if test="vendor != null and vendor != ''">
AND vendor = #{vendor}
</if>
<if test="organizationId != null">
AND organization_id = #{organizationId}
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="isMonitoring != null">
AND is_monitoring = #{isMonitoring}
</if>
</where>
ORDER BY created_at DESC
</select>
<!-- 动态条件查询 -->
<select id="selectByMap" parameterType="java.util.Map" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
<where>
<if test="name != null">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="ip != null">
AND ip = #{ip}
</if>
<if test="deviceGroup != null">
AND device_group = #{deviceGroup}
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="vendor != null">
AND vendor = #{vendor}
</if>
<if test="startTime != null">
AND created_at >= #{startTime}
</if>
<if test="endTime != null">
AND created_at &lt;= #{endTime}
</if>
</where>
</select>
<!-- 分页查询 -->
<select id="selectByPage" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
ORDER BY id
LIMIT #{limit} OFFSET #{offset}
</select>
<!-- 统计总数 -->
<select id="count" resultType="java.lang.Long">
SELECT COUNT(*) FROM device_device
</select>
<!-- 根据条件统计 -->
<select id="countByCondition" parameterType="com.common.entity.DeviceDevice" resultType="java.lang.Long">
SELECT COUNT(*) FROM device_device
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
<if test="isMonitoring != null">
AND is_monitoring = #{isMonitoring}
</if>
</where>
</select>
<!-- 查询监控中的设备 -->
<select id="selectMonitoringDevices" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE is_monitoring = true
</select>
<!-- 查询未删除的设备 -->
<select id="selectActiveDevices" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE del_flag = '0'
</select>
<!-- 根据厂商查询 -->
<select id="selectByVendor" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM device_device
WHERE vendor = #{vendor}
</select>
</mapper>
@@ -0,0 +1,175 @@
<?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="com.common.mapper.DeviceReceiveLogMapper">
<!-- 结果映射 -->
<resultMap id="BaseResultMap" type="DeviceReceiveLog">
<id column="id" property="id" />
<result column="created_at" property="createdAt" />
<result column="device_collect_id" property="deviceCollectId" />
<result column="device_id" property="deviceId" />
<result column="device_ip" property="deviceIp" />
<result column="receive_time" property="receiveTime" />
<result column="receive_time_str" property="receiveTimeStr" />
<result column="syslog_message" property="syslogMessage" />
<result column="push_success" property="pushSuccess" />
</resultMap>
<!-- 插入单条记录 -->
<insert id="insert" parameterType="DeviceReceiveLog" useGeneratedKeys="true" keyProperty="id">
INSERT INTO device_receive_log (
created_at,
device_collect_id,
device_id,
device_ip,
receive_time,
receive_time_str,
syslog_message,
push_success
) VALUES (
COALESCE(#{createdAt}, NOW() AT TIME ZONE 'utc'),
#{deviceCollectId},
#{deviceId},
#{deviceIp}::inet,
#{receiveTime},
#{receiveTimeStr},
#{syslogMessage},
#{pushSuccess}
)
</insert>
<!-- 批量插入(高性能) -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO device_receive_log (
created_at,
device_collect_id,
device_id,
device_ip,
receive_time,
receive_time_str,
syslog_message,
push_success
) VALUES
<foreach collection="list" item="item" separator=",">
(
COALESCE(#{item.createdAt}, NOW() AT TIME ZONE 'utc'),
#{item.deviceCollectId},
#{item.deviceId},
#{item.deviceIp}::inet,
#{item.receiveTime},
#{item.receiveTimeStr},
#{item.syslogMessage},
#{item.pushSuccess}
)
</foreach>
</insert>
<!-- 根据ID查询 -->
<select id="selectById" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
WHERE id = #{id}
</select>
<!-- 根据设备ID查询 -->
<select id="selectByDeviceId" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
WHERE device_id = #{deviceId}
ORDER BY receive_time DESC
</select>
<!-- 根据采集探针ID查询 -->
<select id="selectByCollectId" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
WHERE device_collect_id = #{collectId}
ORDER BY receive_time DESC
</select>
<!-- 根据IP地址查询(使用PostgreSQL的inet操作符) -->
<select id="selectByDeviceIp" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
WHERE device_ip >>= #{deviceIp}::inet
ORDER BY receive_time DESC
</select>
<!-- 根据时间范围查询(利用created_at索引) -->
<select id="selectByTimeRange" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
WHERE created_at BETWEEN #{startTime} AND #{endTime}
ORDER BY created_at DESC
</select>
<!-- 多条件组合查询(动态SQL -->
<select id="selectByCondition" parameterType="DeviceReceiveLog" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
<where>
<if test="deviceId != null">
AND device_id = #{deviceId}
</if>
<if test="deviceCollectId != null">
AND device_collect_id = #{deviceCollectId}
</if>
<if test="deviceIp != null and deviceIp != ''">
AND device_ip >>= #{deviceIp}::inet
</if>
<if test="receiveTime != null">
AND receive_time >= #{receiveTime}
</if>
<if test="syslogMessage != null and syslogMessage != ''">
AND syslog_message LIKE CONCAT('%', #{syslogMessage}, '%')
</if>
<if test="pushSuccess != null and pushSuccess != ''">
AND push_success = #{pushSuccess}
</if>
</where>
ORDER BY created_at DESC
</select>
<!-- 统计数量 -->
<select id="countByCondition" parameterType="DeviceReceiveLog" resultType="java.lang.Long">
SELECT COUNT(*) FROM device_receive_log
<where>
<if test="deviceId != null">
AND device_id = #{deviceId}
</if>
<if test="deviceCollectId != null">
AND device_collect_id = #{deviceCollectId}
</if>
<if test="deviceIp != null and deviceIp != ''">
AND device_ip >>= #{deviceIp}::inet
</if>
<if test="receiveTime != null">
AND receive_time >= #{receiveTime}
</if>
<if test="pushSuccess != null">
AND push_success >= #{pushSuccess}
</if>
</where>
</select>
<!-- 删除时间范围内的数据 -->
<delete id="deleteByTimeRange">
DELETE FROM device_receive_log
WHERE created_at BETWEEN #{startTime} AND #{endTime}
</delete>
<!-- 获取最近N条记录 -->
<select id="selectRecent" resultMap="BaseResultMap">
SELECT * FROM device_receive_log
ORDER BY created_at DESC
LIMIT #{limit}
</select>
<!-- 按设备分组统计 -->
<select id="countByDeviceGroup" resultType="java.util.Map">
SELECT
device_id,
COUNT(*) as log_count,
MIN(receive_time) as first_receive_time,
MAX(receive_time) as last_receive_time
FROM device_receive_log
GROUP BY device_id
ORDER BY log_count DESC
</select>
</mapper>
@@ -0,0 +1,294 @@
<?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="com.common.mapper.DeviceUnknownMapper">
<!-- 通用查询结果映射 -->
<resultMap id="BaseResultMap" type="com.common.entity.DeviceUnknown">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="created_at" property="createdAt" jdbcType="TIMESTAMP"/>
<result column="device_collect_id" property="deviceCollectId" jdbcType="INTEGER"/>
<result column="device_collect_name" property="deviceCollectName" jdbcType="VARCHAR"/>
<result column="device_ip" property="deviceIp" jdbcType="VARCHAR"/>
<result column="first_time" property="firstTime" jdbcType="TIMESTAMP"/>
<result column="last_time" property="lastTime" jdbcType="TIMESTAMP"/>
<result column="organization_id" property="organizationId" jdbcType="INTEGER"/>
<result column="network_protocol" property="networkProtocol" jdbcType="VARCHAR"/>
<result column="source_method" property="sourceMethod" jdbcType="VARCHAR"/>
</resultMap>
<!-- 插入设备记录 -->
<insert id="insert" parameterType="com.common.entity.DeviceUnknown"
useGeneratedKeys="true" keyProperty="id" keyColumn="id">
INSERT INTO device_unknown (
created_at,
device_collect_id,
device_collect_name,
device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
) VALUES (
COALESCE(#{createdAt}, NOW() AT TIME ZONE 'utc'),
#{deviceCollectId},
#{deviceCollectName},
#{deviceIp}::inet,
#{firstTime},
#{lastTime},
#{organizationId},
#{networkProtocol},
#{sourceMethod}
)
</insert>
<!-- 批量插入设备记录 -->
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO device_unknown (
created_at,
device_collect_id,
device_collect_name,
device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
) VALUES
<foreach collection="devices" item="device" separator=",">
(
COALESCE(#{device.createdAt}, NOW() AT TIME ZONE 'utc'),
#{device.deviceCollectId},
#{device.deviceCollectName},
#{device.deviceIp}::inet,
#{device.firstTime},
#{device.lastTime},
#{device.organizationId},
#{device.networkProtocol},
#{device.sourceMethod}
)
</foreach>
</insert>
<!-- 根据ID查询设备 -->
<select id="selectById" resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
WHERE id = #{id}
</select>
<!-- 根据IP查询设备 -->
<select id="selectByIp" resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
WHERE device_ip = #{deviceIp}::inet
ORDER BY last_time DESC
</select>
<!-- 根据组织ID查询设备 -->
<select id="selectByOrganizationId" resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
WHERE organization_id = #{organizationId}
ORDER BY last_time DESC
</select>
<!-- 查询所有设备 -->
<select id="selectAll" resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
ORDER BY last_time DESC
</select>
<!-- 分页查询设备 -->
<select id="selectPage" resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
ORDER BY last_time DESC
LIMIT #{limit} OFFSET #{offset}
</select>
<!-- 根据条件查询设备 -->
<select id="selectByCondition" parameterType="com.common.entity.DeviceUnknown"
resultMap="BaseResultMap">
SELECT
id,
created_at,
device_collect_id,
device_collect_name,
device_ip::text as device_ip,
first_time,
last_time,
organization_id,
network_protocol,
source_method
FROM device_unknown
<where>
<if test="deviceCollectId != null">
AND device_collect_id = #{deviceCollectId}
</if>
<if test="deviceCollectName != null and deviceCollectName != ''">
AND device_collect_name ILIKE CONCAT('%', #{deviceCollectName}, '%')
</if>
<if test="deviceIp != null and deviceIp != ''">
AND device_ip = #{deviceIp}::inet
</if>
<if test="organizationId != null">
AND organization_id = #{organizationId}
</if>
<if test="networkProtocol != null and networkProtocol != ''">
AND network_protocol = #{networkProtocol}
</if>
<if test="sourceMethod != null and sourceMethod != ''">
AND source_method = #{sourceMethod}
</if>
<if test="firstTime != null">
AND first_time >= #{firstTime}
</if>
<if test="lastTime != null">
AND last_time >= #{lastTime}
</if>
</where>
ORDER BY last_time DESC
</select>
<!-- 根据ID更新设备信息 -->
<update id="updateById" parameterType="com.common.entity.DeviceUnknown">
UPDATE device_unknown
<set>
<if test="deviceCollectId != null">
device_collect_id = #{deviceCollectId},
</if>
<if test="deviceCollectName != null and deviceCollectName != ''">
device_collect_name = #{deviceCollectName},
</if>
<if test="deviceIp != null and deviceIp != ''">
device_ip = #{deviceIp}::inet,
</if>
<if test="firstTime != null">
first_time = #{firstTime},
</if>
<if test="lastTime != null">
last_time = #{lastTime},
</if>
<if test="organizationId != null">
organization_id = #{organizationId},
</if>
<if test="networkProtocol != null and networkProtocol != ''">
network_protocol = #{networkProtocol},
</if>
<if test="sourceMethod != null and sourceMethod != ''">
source_method = #{sourceMethod},
</if>
</set>
WHERE id = #{id}
</update>
<!-- 更新最后发现时间 -->
<update id="updateLastTime">
UPDATE device_unknown
SET last_time = #{lastTime}
WHERE id = #{id}
</update>
<!-- 根据ID删除设备 -->
<delete id="deleteById">
DELETE FROM device_unknown
WHERE id = #{id}
</delete>
<!-- 根据组织ID删除设备 -->
<delete id="deleteByOrganizationId">
DELETE FROM device_unknown
WHERE organization_id = #{organizationId}
</delete>
<!-- 统计设备数量 -->
<select id="count" resultType="java.lang.Long">
SELECT COUNT(*) FROM device_unknown
</select>
<!-- 根据条件统计设备数量 -->
<select id="countByCondition" parameterType="com.common.entity.DeviceUnknown"
resultType="java.lang.Long">
SELECT COUNT(*) FROM device_unknown
<where>
<if test="deviceCollectId != null">
AND device_collect_id = #{deviceCollectId}
</if>
<if test="deviceCollectName != null and deviceCollectName != ''">
AND device_collect_name ILIKE CONCAT('%', #{deviceCollectName}, '%')
</if>
<if test="deviceIp != null and deviceIp != ''">
AND device_ip = #{deviceIp}::inet
</if>
<if test="organizationId != null">
AND organization_id = #{organizationId}
</if>
<if test="networkProtocol != null and networkProtocol != ''">
AND network_protocol = #{networkProtocol}
</if>
<if test="sourceMethod != null and sourceMethod != ''">
AND source_method = #{sourceMethod}
</if>
<if test="firstTime != null">
AND first_time >= #{firstTime}
</if>
<if test="lastTime != null">
AND last_time >= #{lastTime}
</if>
</where>
</select>
</mapper>