This commit is contained in:
liulu 2024-12-27 14:57:18 +08:00
parent b6fc524b3f
commit 265d81a7f0
8 changed files with 143 additions and 63 deletions

View File

@ -178,10 +178,10 @@ public class TmkService {
public void checkSoftDeviceTmk() {
if (Objects.nonNull(getSoftDeviceEncTmk())) {
if (!isTmkInit() || !isEnableSoftDevice()) {
return;
}
if (!isTmkInit() || !isEnableSoftDevice()) {
if (Objects.nonNull(getSoftDeviceEncTmk())) {
return;
}
log.warn("enabled soft device but no tmk in soft");

View File

@ -70,7 +70,11 @@
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
<dependency>
<groupId>org.snmp4j</groupId>
<artifactId>snmp4j</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>

View File

@ -141,9 +141,9 @@ public abstract class DeviceDTO {
@Data
public static class Detail extends DeviceView {
private Double cpuRate;
private Double memoryRate;
private Double diskRate;
private String cpuRate;
private String memoryRate;
private String diskRate;
}

View File

@ -14,6 +14,14 @@ import com.sunyard.chsm.model.entity.Device;
import com.sunyard.chsm.service.DeviceService;
import com.sunyard.chsm.service.TmkService;
import lombok.extern.slf4j.Slf4j;
import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -22,6 +30,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
@ -110,14 +119,80 @@ public class DeviceServiceImpl implements DeviceService {
.map(ManufacturerModelEnum::getName)
.ifPresent(detail::setManufacturerModelText);
// todo
detail.setCpuRate(0.5D);
detail.setMemoryRate(0.5D);
detail.setDiskRate(0.5D);
try {
int port = 161;
String community = "public";
// 获取 CPU 使用率
String cpuOid = ".1.3.6.1.4.1.2021.11.10.0";
String cpuUsage = getSnmpData(exist.getServiceIp(), port, community, cpuOid);
detail.setCpuRate(cpuUsage + "%");
// 获取磁盘使用率
String diskUsageOid = ".1.3.6.1.4.1.2021.9.1.9.1";
String diskUsage = getSnmpData(exist.getServiceIp(), port, community, diskUsageOid);
detail.setDiskRate(diskUsage + "%");
// 获取内存使用率
double memoryUsage = getMemoryUsage(exist.getServiceIp(), port, community);
detail.setMemoryRate(NumberFormat.getIntegerInstance().format(memoryUsage) + "%");
} catch (Exception ex) {
log.warn("设备snmp协议连接异常:{}", exist.getServiceIp(), ex);
}
return detail;
}
public static double getMemoryUsage(String ip, int port, String community) throws Exception {
// OIDs for total and available memory
String totalMemoryOid = ".1.3.6.1.4.1.2021.4.5.0";
String freeMemoryOid = ".1.3.6.1.4.1.2021.4.6.0";
// 获取总内存和可用内存
String totalMemoryStr = getSnmpData(ip, port, community, totalMemoryOid);
String freeMemoryStr = getSnmpData(ip, port, community, freeMemoryOid);
// 转换为数值
double totalMemory = Double.parseDouble(totalMemoryStr);
double freeMemory = Double.parseDouble(freeMemoryStr);
// 计算使用率
return ((totalMemory - freeMemory) / totalMemory) * 100;
}
public static String getSnmpData(String ip, int port, String community, String oid) throws Exception {
String address = "udp:" + ip + "/" + port;
// 创建 SNMP 传输和会话
TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
Snmp snmp = new Snmp(transport);
transport.listen();
// 构造目标
Address targetAddress = GenericAddress.parse(address);
CommunityTarget target = new CommunityTarget();
target.setCommunity(new OctetString(community));
target.setAddress(targetAddress);
target.setRetries(2);
target.setTimeout(1500);
target.setVersion(SnmpConstants.version2c);
// 创建 PDU
PDU pdu = new PDU();
pdu.add(new VariableBinding(new OID(oid)));
pdu.setType(PDU.GET);
// 发送请求并接收响应
ResponseEvent event = snmp.send(pdu, target, null);
snmp.close();
// 解析响应
if (event != null && event.getResponse() != null) {
return event.getResponse().get(0).getVariable().toString();
} else {
throw new RuntimeException("SNMP Request Timeout or No Response");
}
}
@Override
public Long save(DeviceDTO.DeviceSave save) {

View File

@ -11,6 +11,7 @@ import org.apache.commons.pool2.impl.GenericObjectPool;
@Data
public class DeviceContext {
private Long id;
private String ip;
private Integer port;
private String manufacturer;

View File

@ -27,12 +27,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
@ -49,7 +45,9 @@ public class DeviceManager implements InitializingBean {
private static final Map<Long, AtomicInteger> ROUND_MAP = new HashMap<>();
private Map<Long, List<DeviceContext>> deviceMap = new HashMap<>();
// private Map<Long, List<DeviceContext>> deviceMap = new HashMap<>();
private Map<Long, List<Long>> serviceDeviceMap;
private final Map<Long, DeviceContext> usedDeviceMap = new ConcurrentHashMap<>();
private boolean enableSoftDevice = false;
private TMKContext softContext;
@ -79,14 +77,20 @@ public class DeviceManager implements InitializingBean {
if (atomicInteger.get() > Integer.MAX_VALUE - 10000) {
atomicInteger.set(1);
}
List<DeviceContext> contexts = new ArrayList<>();
for (Long serviceId : serviceIds) {
Optional.ofNullable(deviceMap.get(serviceId))
.ifPresent(contexts::addAll);
}
List<DeviceContext> contexts = serviceDeviceMap.entrySet().stream()
.filter(it -> serviceIds.contains(it.getKey()))
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.map(usedDeviceMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
DeviceContext device = getNextDevice(contexts, atomicInteger.getAndIncrement());
TMKContext tmkContext;
if (device == null) {
if (log.isDebugEnabled()) {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
log.debug("request: {}, use soft device 1", request.getRequestURI());
}
tmkContext = getSoftContext();
} else {
if (log.isDebugEnabled()) {
@ -98,6 +102,11 @@ public class DeviceManager implements InitializingBean {
tmkContext = pool.borrowObject(2000);
tmkContext.setPool(pool);
} catch (Exception e) {
usedDeviceMap.remove(device.getId());
if (log.isDebugEnabled()) {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
log.debug("request: {}, use soft device 2", request.getRequestURI());
}
tmkContext = getSoftContext();
}
}
@ -146,7 +155,6 @@ public class DeviceManager implements InitializingBean {
return null; // 理论上不会到这里
}
private void syncDevice() {
log.debug(">>>>>>>>>>>>>>> start sync device <<<<<<<<<<<<<<<");
enableSoftDevice = tmkService.isEnableSoftDevice();
@ -158,60 +166,52 @@ public class DeviceManager implements InitializingBean {
);
if (CollectionUtils.isEmpty(devices)) {
log.info("no device for sync ...");
deviceMap.clear();
usedDeviceMap.clear();
return;
}
Map<Long, List<Device>> groupDeviceMap = devices.stream().collect(Collectors.groupingBy(Device::getGroupId));
Map<Long, List<Long>> groupDeviceMap = devices.stream()
.collect(Collectors.groupingBy(Device::getGroupId, Collectors.mapping(Device::getId, Collectors.toList())));
List<CryptoServiceDeviceGroup> serviceDeviceGroups = cryptoServiceDeviceGroupMapper
.selectList(new LambdaQueryWrapper<CryptoServiceDeviceGroup>()
.in(CryptoServiceDeviceGroup::getDeviceGroupId, groupDeviceMap.keySet()));
if (CollectionUtils.isEmpty(serviceDeviceGroups)) {
deviceMap.clear();
usedDeviceMap.clear();
return;
}
Map<Long, List<Device>> waitSyncMap = serviceDeviceGroups.stream()
serviceDeviceMap = serviceDeviceGroups.stream()
.collect(Collectors.toMap(CryptoServiceDeviceGroup::getServiceId,
it -> groupDeviceMap.get(it.getDeviceGroupId())));
for (Map.Entry<Long, List<Device>> entry : waitSyncMap.entrySet()) {
deviceMap.compute(entry.getKey(), (k, old) -> {
if (CollectionUtils.isEmpty(old)) {
return entry.getValue().stream().map(this::mapToContext).filter(Objects::nonNull).collect(Collectors.toList());
for (Device device : devices) {
DeviceCheckRes checkRes = tmkService.checkDevice(device);
if (checkRes.isHasError()) {
log.warn("设备:{}, 检测异常:{}", device.getServiceIp(), checkRes.getMessage());
usedDeviceMap.remove(device.getId());
continue;
}
DeviceContext exist = usedDeviceMap.get(device.getId());
if (Objects.isNull(exist)) {
usedDeviceMap.remove(device.getId());
DeviceContext context = getDeviceContext(device, checkRes);
if (context != null) {
usedDeviceMap.put(device.getId(), context);
}
List<String> newSerials = entry.getValue().stream()
.map(Device::getDeviceSerial)
.collect(Collectors.toList());
List<String> oldSerials = old.stream()
.map(DeviceContext::getDeviceSerial)
.collect(Collectors.toList());
List<DeviceContext> nc = old.stream()
.filter(it -> newSerials.contains(it.getDeviceSerial()))
.collect(Collectors.toList());
List<Device> waitSync = entry.getValue().stream()
.filter(it -> !oldSerials.contains(it.getDeviceSerial()))
.collect(Collectors.toList());
nc.addAll(waitSync.stream().map(this::mapToContext).filter(Objects::nonNull).collect(Collectors.toList()));
return nc;
});
} else {
if (!Objects.equals(checkRes.getDeviceSerial(), exist.getDeviceSerial())
|| !Objects.equals(checkRes.getPubKey(), exist.getPubKey())) {
DeviceContext context = getDeviceContext(device, checkRes);
if (context != null) {
usedDeviceMap.put(device.getId(), context);
}
}
}
}
}
private DeviceContext mapToContext(Device device) {
private static DeviceContext getDeviceContext(Device device, DeviceCheckRes checkRes) {
try {
Assert.hasText(device.getEncTmk(), "TMK 状态异常");
DeviceCheckRes checkRes = tmkService.checkDevice(device);
if (!Objects.equals(checkRes.getDeviceSerial(), device.getDeviceSerial())
|| !Objects.equals(checkRes.getPubKey(), device.getPubKey())) {
return null;
}
DeviceContext context = new DeviceContext();
context.setId(device.getId());
context.setIp(device.getServiceIp());
context.setPort(device.getServicePort());
context.setModel(device.getManufacturerModel());
@ -234,7 +234,6 @@ public class DeviceManager implements InitializingBean {
TMKContextFactory tenantTMKContextFactory = new TMKContextFactory(checkRes.getSdfApiAdapter(), context);
GenericObjectPool<TMKContext> pool = new GenericObjectPool<>(tenantTMKContextFactory, config);
context.setPool(pool);
return context;
} catch (Exception ex) {
log.warn("device conn error: {}", device, ex);

View File

@ -435,7 +435,8 @@ public class AsymKeyService {
signedAndEnvelopedData.getSignerInfos()
);
ContentInfo contentInfo = new ContentInfo(Signed_Data, sd);
p7Verify(contentInfo.getEncoded(), null);
boolean verify = p7Verify(contentInfo.getEncoded(), null);
Assert.isTrue(verify, "签名验证失败");
AsymEnvelopeUnsealResp resp = new AsymEnvelopeUnsealResp();
resp.setPlainData(CodecUtils.encodeBase64(plainData));
return resp;

View File

@ -29,7 +29,7 @@ public abstract class BaseTest {
protected static final String keyTemplate = "sym-sm4-001";
protected static final String ak = "216205d408130d83d13c5072305b8b65";
protected static final String sk = "ae64515d1d5adec2cc6ae8726d0c1bbc";
protected static final String server = "http://127.0.0.1:8900";
protected static final String server = "http://172.16.18.46:8900";
protected static final RestTemplate restTemplate;
protected static final String token;