diff --git a/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java b/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java index ceced96..c835649 100644 --- a/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java +++ b/chsm-common/src/main/java/com/sunyard/chsm/service/TmkService.java @@ -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"); diff --git a/chsm-web-manage/pom.xml b/chsm-web-manage/pom.xml index 76c8cc3..76a18cb 100644 --- a/chsm-web-manage/pom.xml +++ b/chsm-web-manage/pom.xml @@ -70,7 +70,11 @@ cn.hutool hutool-core - + + org.snmp4j + snmp4j + 2.8.6 + commons-codec commons-codec diff --git a/chsm-web-manage/src/main/java/com/sunyard/chsm/dto/DeviceDTO.java b/chsm-web-manage/src/main/java/com/sunyard/chsm/dto/DeviceDTO.java index 91603e4..e555f1f 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/chsm/dto/DeviceDTO.java +++ b/chsm-web-manage/src/main/java/com/sunyard/chsm/dto/DeviceDTO.java @@ -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; } diff --git a/chsm-web-manage/src/main/java/com/sunyard/chsm/service/impl/DeviceServiceImpl.java b/chsm-web-manage/src/main/java/com/sunyard/chsm/service/impl/DeviceServiceImpl.java index 2f2ea12..c1d75f5 100644 --- a/chsm-web-manage/src/main/java/com/sunyard/chsm/service/impl/DeviceServiceImpl.java +++ b/chsm-web-manage/src/main/java/com/sunyard/chsm/service/impl/DeviceServiceImpl.java @@ -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 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) { diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceContext.java b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceContext.java index 885ec88..52361f8 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceContext.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceContext.java @@ -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; diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceManager.java b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceManager.java index 383c13c..c047ab2 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceManager.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/pool/DeviceManager.java @@ -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 ROUND_MAP = new HashMap<>(); - private Map> deviceMap = new HashMap<>(); + // private Map> deviceMap = new HashMap<>(); + private Map> serviceDeviceMap; + private final Map 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 contexts = new ArrayList<>(); - for (Long serviceId : serviceIds) { - Optional.ofNullable(deviceMap.get(serviceId)) - .ifPresent(contexts::addAll); - } + List 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> groupDeviceMap = devices.stream().collect(Collectors.groupingBy(Device::getGroupId)); + Map> groupDeviceMap = devices.stream() + .collect(Collectors.groupingBy(Device::getGroupId, Collectors.mapping(Device::getId, Collectors.toList()))); List serviceDeviceGroups = cryptoServiceDeviceGroupMapper .selectList(new LambdaQueryWrapper() .in(CryptoServiceDeviceGroup::getDeviceGroupId, groupDeviceMap.keySet())); if (CollectionUtils.isEmpty(serviceDeviceGroups)) { - deviceMap.clear(); + usedDeviceMap.clear(); return; } - Map> waitSyncMap = serviceDeviceGroups.stream() + serviceDeviceMap = serviceDeviceGroups.stream() .collect(Collectors.toMap(CryptoServiceDeviceGroup::getServiceId, it -> groupDeviceMap.get(it.getDeviceGroupId()))); - for (Map.Entry> 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 newSerials = entry.getValue().stream() - .map(Device::getDeviceSerial) - .collect(Collectors.toList()); - - List oldSerials = old.stream() - .map(DeviceContext::getDeviceSerial) - .collect(Collectors.toList()); - - List nc = old.stream() - .filter(it -> newSerials.contains(it.getDeviceSerial())) - .collect(Collectors.toList()); - - List 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 pool = new GenericObjectPool<>(tenantTMKContextFactory, config); context.setPool(pool); - return context; } catch (Exception ex) { log.warn("device conn error: {}", device, ex); diff --git a/chsm-web-server/src/main/java/com/sunyard/chsm/service/AsymKeyService.java b/chsm-web-server/src/main/java/com/sunyard/chsm/service/AsymKeyService.java index 3a88740..3efbe02 100644 --- a/chsm-web-server/src/main/java/com/sunyard/chsm/service/AsymKeyService.java +++ b/chsm-web-server/src/main/java/com/sunyard/chsm/service/AsymKeyService.java @@ -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; diff --git a/chsm-web-server/src/test/java/api/BaseTest.java b/chsm-web-server/src/test/java/api/BaseTest.java index 4b929b6..d230486 100644 --- a/chsm-web-server/src/test/java/api/BaseTest.java +++ b/chsm-web-server/src/test/java/api/BaseTest.java @@ -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;