From 73388da7067d418eab52e555f105c3562056cf41 Mon Sep 17 00:00:00 2001 From: dc Date: Thu, 22 May 2025 18:08:28 +0800 Subject: [PATCH] =?UTF-8?q?GPU=E6=A8=A1=E5=9D=97=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 52 ++++++- ...cationOrchestrationServiceApplication.java | 2 + .../gpu/cache/CacheManager.java | 145 ++++++++++++++++++ .../gpu/cache/RedisCacheService.java | 126 +++++++++++++++ .../gpu/cache/task/CacheInitTask.java | 37 +++++ .../gpu/cache/task/CacheSyncTask.java | 64 ++++++++ .../gpu/config/CacheAopConfig.java | 57 +++++++ .../gpu/config/DataSourceConfig.java | 5 - .../gpu/config/MQConfig.java | 4 - .../gpu/config/RedisConfig.java | 65 ++++++++ .../gpu/controller/GpuResourceController.java | 37 ++++- .../gpu/dao/GpuResourceDao.java | 88 ++++++++++- .../gpu/event/CacheUpdateEvent.java | 8 + .../gpu/exception/CacheInitException.java | 10 ++ .../gpu/exception/GlobalExceptionHandler.java | 8 + .../exception/PermissionDeniedException.java | 9 ++ .../gpu/mapper/GpuMapper.java | 9 +- .../gpu/model/dto/GpuResponseDTO.java | 40 +++++ .../gpu/model/dto/GpuUpdateDTO.java | 26 +++- .../gpu/model/entity/GpuResource.java | 38 ++++- .../gpu/model/enums/ErrorCodeEnum.java | 12 +- .../gpu/model/vo/ResponseVO.java | 2 +- .../gpu/mq/listener/ResourceSyncListener.java | 4 - .../gpu/mq/producer/CacheUpdateProducer.java | 31 ---- .../gpu/service/GpuManageService.java | 8 + .../service/impl/GpuManageServiceImpl.java | 57 ++++++- .../gpu/utils/PermissionCheckUtil.java | 20 --- .../gpu/utils/ValidatorUtil.java | 27 ---- src/main/resources/application.properties | 21 ++- .../resources/mapper/GpuResourceMapper.xml | 19 +++ 30 files changed, 910 insertions(+), 121 deletions(-) create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/CacheManager.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/RedisCacheService.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheInitTask.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheSyncTask.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/CacheAopConfig.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/DataSourceConfig.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/MQConfig.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/RedisConfig.java create mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/CacheInitException.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/listener/ResourceSyncListener.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/producer/CacheUpdateProducer.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/PermissionCheckUtil.java delete mode 100644 src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/ValidatorUtil.java create mode 100644 src/main/resources/mapper/GpuResourceMapper.xml diff --git a/pom.xml b/pom.xml index 43327cf..b6eb38c 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,17 @@ org.springframework.boot spring-boot-starter-web - + + org.hibernate + hibernate-core + 5.6.15.Final + + + org.jboss.logging + jboss-logging + + + org.postgresql postgresql @@ -57,7 +67,12 @@ org.springframework.boot spring-boot-starter-data-jpa - 3.4.5 + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + + org.springframework.boot @@ -75,18 +90,47 @@ org.mybatis.spring.boot mybatis-spring-boot-starter - 3.0.4 + 2.3.1 org.apache.commons commons-lang3 - 3.12.0 + 3.17.0 org.mapstruct mapstruct 1.5.5.Final + + com.kingbase8 + kingbase8 + 9.0.0 + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.7 + + + org.springframework.boot + spring-boot-starter-redis + 1.4.7.RELEASE + + + com.mysql + mysql-connector-j + + + org.springframework.boot + spring-boot-starter-actuator + + + com.baomidou + mybatis-plus-generator + 3.5.6 + + diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/IntelligentApplicationOrchestrationServiceApplication.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/IntelligentApplicationOrchestrationServiceApplication.java index c592c40..520a423 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/IntelligentApplicationOrchestrationServiceApplication.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/IntelligentApplicationOrchestrationServiceApplication.java @@ -1,8 +1,10 @@ package com.bipt.intelligentapplicationorchestrationservice; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +@MapperScan("com.bipt.intelligentapplicationorchestrationservice.gpu.dao") @SpringBootApplication public class IntelligentApplicationOrchestrationServiceApplication { diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/CacheManager.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/CacheManager.java new file mode 100644 index 0000000..4b65b7f --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/CacheManager.java @@ -0,0 +1,145 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.cache; + +import com.bipt.intelligentapplicationorchestrationservice.gpu.dao.GpuResourceDao; +import com.bipt.intelligentapplicationorchestrationservice.gpu.exception.CacheInitException; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import jakarta.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.RedisConnectionFailureException; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; + +@Component +public class CacheManager { + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private GpuResourceDao gpuResourceDao; + + private final ReentrantLock lock = new ReentrantLock(); + + @Value("${cache.redis-key-prefix:gpu:}") + private String keyPrefix; + + @Value("${cache.ttl-base:7200}") + private int ttlBase; + + @Value("${cache.init-batch-size:500}") + private int initBatchSize; + + // 全量加载(带分页和分布式锁) + @PostConstruct + public void loadFullCache() { + if (tryLock()) { + try { + int page = 0; + while (true) { + List batch = gpuResourceDao.findByPage(page * initBatchSize, initBatchSize); + if (batch.isEmpty()) break; + + batch.forEach(this::setCacheWithTTL); + page++; + } + } finally { + unlock(); + } + } + } + + // 单条缓存刷新(带版本控制) + public void refreshCache(Long gpuId) { + GpuResource latest = gpuResourceDao.selectByIdWithLock(gpuId); + if (latest != null) { + setCacheWithTTL(latest); + } + } + + // 批量增量同步 + public void syncCache(LocalDateTime lastSyncTime) { + List updates = gpuResourceDao.findModifiedSince(lastSyncTime); + updates.forEach(entity -> { + if (entity.getIsDeleted()) { + redisTemplate.delete(buildKey(entity.getGPUId().toString())); + } else { + setCacheWithTTL(entity); + } + }); + } + + // 带随机TTL的缓存设置 + private void setCacheWithTTL(GpuResource entity) { + String key = buildKey(entity.getGPUId().toString()); + redisTemplate.opsForValue().set( + key, + entity, + ttlBase + (int)(Math.random() * 600), // 随机TTL防止雪崩 + TimeUnit.SECONDS + ); + } + + // 构建缓存键 + private String buildKey(String gpuId) { + return keyPrefix + gpuId; + } + + // 分布式锁操作 + private boolean tryLock() { + try { + return lock.tryLock(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } + } + + private void unlock() { + lock.unlock(); + } + // 分页加载入口 + public void loadFullCache(int batchSize) { + int page = 0; + while (true) { + List batch = gpuResourceDao.findByPage(page * batchSize, batchSize); + if (batch.isEmpty()) break; + + batch.forEach(this::refreshWithRetry); // 带重试的刷新逻辑 + page++; + } + } + + // 带重试机制的缓存刷新 + private void refreshWithRetry(GpuResource entity) { + try { + setCacheWithTTL(entity); + } catch (RedisConnectionFailureException ex) { + // 3次重试逻辑 + for (int i = 0; i < 3; i++) { + try { + Thread.sleep(1000); + setCacheWithTTL(entity); + return; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + throw new CacheInitException("缓存刷新失败: " + entity.getGPUId().toString()); + } + } + + // 获取当前缓存数量(调试用) + public long getCacheCount() { + return redisTemplate.keys(keyPrefix + "*").size(); + } + + public void evictCache(Long gpuId) { + String key = buildKey(gpuId.toString()); + redisTemplate.delete(key); + } +} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/RedisCacheService.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/RedisCacheService.java new file mode 100644 index 0000000..a3de985 --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/RedisCacheService.java @@ -0,0 +1,126 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.cache; + + +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.stereotype.Service; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Service +public class RedisCacheService { + + private final RedisTemplate redisTemplate; + + @Value("${cache.redis-key-prefix:gpu:}") + private String keyPrefix; + + @Value("${cache.ttl-base:7200}") + private int baseTTL; + private final RedisSerializer valueSerializer; + +// @Autowired +// public RedisCacheService(RedisTemplate redisTemplate) { +// this.redisTemplate = redisTemplate; +// } + + // 核心方法 ------------------------------------------------------------ + @Autowired + public RedisCacheService(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + this.valueSerializer = (RedisSerializer) redisTemplate.getValueSerializer(); + } + + /** + * 批量写入GPU资源数据(带管道优化) + * @param resources GPU资源列表 + */ + public void batchPut(List resources) { + redisTemplate.executePipelined((RedisCallback) connection -> { + resources.forEach(resource -> { + String key = buildKey(resource.getGPUId().toString()); + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + byte[] valueBytes = valueSerializer.serialize(resource); + connection.stringCommands().setEx( + keyBytes, + calculateTTL(), + valueBytes + ); + }); + return null; + }); + } + + /** + * 设置单条缓存(含随机TTL防雪崩) + * @param gpuId 资源ID + * @param resource 资源对象 + */ + public void put(String gpuId, GpuResource resource) { + String key = buildKey(gpuId); + redisTemplate.opsForValue().set( + key, + resource, + calculateTTL(), + TimeUnit.SECONDS + ); + } + + /** + * 获取单个缓存项 + * @param gpuId 资源ID + * @return 缓存对象或null + */ + public GpuResource get(String gpuId) { + return (GpuResource) redisTemplate.opsForValue().get(buildKey(gpuId)); + } + + /** + * 删除指定缓存 + * @param gpuId 资源ID + */ + public void delete(Long gpuId) { + redisTemplate.delete(buildKey(gpuId.toString())); + } + + // 辅助方法 ------------------------------------------------------------ + + private String buildKey(String gpuId) { + return keyPrefix + gpuId; + } + + private long calculateTTL() { + return baseTTL + (long)(Math.random() * 600); // 7200-7800秒随机值 + } + + /** + * 批量删除缓存(事务处理) + * @param gpuIds 资源ID列表 + */ + public void batchDelete(List gpuIds) { + redisTemplate.execute((RedisCallback) connection -> { + connection.multi(); + gpuIds.forEach(id -> connection.del(buildKey(id).getBytes())); + connection.exec(); + return null; + }); + } + + /** + * 缓存健康检查 + * @return 是否连通 + */ + public boolean healthCheck() { + try { + return "PONG".equals(redisTemplate.getConnectionFactory() + .getConnection().ping()); + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheInitTask.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheInitTask.java new file mode 100644 index 0000000..0135f36 --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheInitTask.java @@ -0,0 +1,37 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.cache.task; + +import com.bipt.intelligentapplicationorchestrationservice.gpu.cache.CacheManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +public class CacheInitTask { + + private final CacheManager cacheManager; + + @Value("${cache.init-batch-size:500}") + private int batchSize; + + @Autowired + public CacheInitTask(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + /** + * 应用启动后执行全量缓存加载 + * 使用@EventListener替代@PostConstruct确保数据库连接就绪 + */ + @EventListener(ApplicationReadyEvent.class) + public void initCacheOnStartup() { + try { + cacheManager.loadFullCache(batchSize); + System.out.println("✅ 缓存全量初始化完成 | Total loaded: " + cacheManager.getCacheCount()); + } catch (Exception e) { + System.err.println("❌ 缓存初始化失败: " + e.getMessage()); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheSyncTask.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheSyncTask.java new file mode 100644 index 0000000..e19843f --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/cache/task/CacheSyncTask.java @@ -0,0 +1,64 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.cache.task; + +import com.bipt.intelligentapplicationorchestrationservice.gpu.cache.CacheManager; +import com.bipt.intelligentapplicationorchestrationservice.gpu.dao.GpuResourceDao; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import java.time.LocalDateTime; +import java.util.List; + +//@Slf4j +@Component +public class CacheSyncTask { + private final GpuResourceDao gpuResourceDao; + private final CacheManager cacheManager; + private LocalDateTime lastSyncTime = LocalDateTime.MIN; + private static final Logger log = LoggerFactory.getLogger(CacheSyncTask.class); + + @Autowired + public CacheSyncTask(GpuResourceDao gpuResourceDao, CacheManager cacheManager) { + this.gpuResourceDao = gpuResourceDao; + this.cacheManager = cacheManager; + } + + /** + * 定时同步缓存(默认每10分钟) + */ + @Scheduled(fixedDelayString = "${cache.sync-interval:600000}") + public void syncCache() { + try { + LocalDateTime currentSyncTime = LocalDateTime.now(); + log.info("🔄 开始缓存同步 | 时间范围: {} - {}", lastSyncTime, currentSyncTime); + + // 1. 查询增量数据 + List modifiedGpus = gpuResourceDao.findModifiedSince(lastSyncTime); + if (modifiedGpus.isEmpty()) { + log.info("✅ 无数据变更,跳过本次同步"); + return; + } + + // 2. 处理数据变更 + modifiedGpus.forEach(gpu -> { + if (gpu.getIsDeleted()) { + cacheManager.evictCache(gpu.getGPUId()); + log.debug("🗑️ 删除缓存 | GPU ID: {}", gpu.getGPUId()); + } else { + cacheManager.refreshCache(gpu.getGPUId()); + log.debug("🔄 更新缓存 | GPU ID: {}", gpu.getGPUId()); + } + }); + + // 3. 更新同步时间戳 + lastSyncTime = currentSyncTime; + log.info("✅ 缓存同步完成 | 共处理 {} 条记录", modifiedGpus.size()); + + } catch (Exception e) { + log.error("❌ 缓存同步失败: {}", e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/CacheAopConfig.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/CacheAopConfig.java new file mode 100644 index 0000000..727cb4e --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/CacheAopConfig.java @@ -0,0 +1,57 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.config; + + +import com.bipt.intelligentapplicationorchestrationservice.gpu.cache.CacheManager; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.stereotype.Component; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; + +@Aspect +@Component +public class CacheAopConfig { + private final CacheManager cacheManager; + + public CacheAopConfig(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + // 定义写操作切点 + @Pointcut("@annotation(org.springframework.transaction.annotation.Transactional) && " + + "execution(* com.bipt.intelligentapplicationorchestrationservice.gpu.service..*.*(..))") + public void writeOperation() {} + + // 事务提交后操作 + @AfterReturning(pointcut = "writeOperation()", returning = "result") + public void afterWriteCommit(JoinPoint joinPoint, Object result) { + TransactionSynchronizationManager.registerSynchronization( + new TransactionSynchronization() { + @Override + public void afterCommit() { + processCacheUpdate(result); + } + }); + } + + private void processCacheUpdate(Object result) { + if (result instanceof GpuResource) { + GpuResource gpu = (GpuResource) result; + cacheManager.refreshCache(gpu.getGPUId()); + } else if (result instanceof Long) { // 处理删除操作返回ID的情况 + cacheManager.evictCache((Long) result); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/DataSourceConfig.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/DataSourceConfig.java deleted file mode 100644 index 1220c1d..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/DataSourceConfig.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.config; - -public class DataSourceConfig { - -} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/MQConfig.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/MQConfig.java deleted file mode 100644 index 0148e78..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/MQConfig.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.config; - -public class MQConfig { -} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/RedisConfig.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/RedisConfig.java new file mode 100644 index 0000000..befc309 --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/config/RedisConfig.java @@ -0,0 +1,65 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.config; + +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + @Value("${spring.data.redis.host}") + private String redisHost; + + @Value("${spring.data.redis.port}") + private int redisPort; + + @Value("${spring.data.redis.username}") // 若无需用户名可删除 + private String redisUsername; + + @Value("${spring.data.redis.password}") + private String redisPassword; + + @Value("${spring.data.redis.ssl:false}") + private boolean useSsl; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); + config.setHostName(redisHost); + config.setPort(redisPort); + config.setUsername(redisUsername); // Redis 6.0+ 支持用户名 + config.setPassword(RedisPassword.of(redisPassword)); + + LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() + .useSsl() // 启用 SSL + .disablePeerVerification() // 跳过证书验证(仅测试环境) + .build(); + + return new LettuceConnectionFactory(config, clientConfig); + } + + +// @Bean +// public RedisConnectionFactory redisConnectionFactory() { +// RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); +// config.setPassword(""); +// return new LettuceConnectionFactory(config); +// } + + @Bean + public RedisTemplate redisTemplate(){ + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(redisConnectionFactory()); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + return template; + } +} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/controller/GpuResourceController.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/controller/GpuResourceController.java index d00a6f5..595095d 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/controller/GpuResourceController.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/controller/GpuResourceController.java @@ -1,9 +1,15 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.controller; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuCreateDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuResponseDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuUpdateDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.vo.ResponseVO; import com.bipt.intelligentapplicationorchestrationservice.gpu.service.GpuManageService; +import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @RequestMapping @@ -11,5 +17,32 @@ public class GpuResourceController { @Autowired private GpuManageService gpuManageService; + @PostMapping + public ResponseVO addGpu(@Valid @RequestBody GpuCreateDTO dto){ + return gpuManageService.createGpuResource(dto); + } + @DeleteMapping("/{gpuId}") + public ResponseVO removeGpu(@PathVariable("gpuId") Long gpuId){ + return gpuManageService.deleteGpuResource(gpuId); + } + + @PutMapping("/{gpuId}") + public void updateGpuResource( + @PathVariable Long gpuId, + @Valid @RequestBody GpuUpdateDTO dto){ + dto.setGPUId(gpuId); + gpuManageService.updateGpuResource(dto); + } + + @GetMapping("/search") + public ResponseVO> searchGpuResources( + @RequestParam(required = false) String model, + @RequestParam(required = false) Integer memorySize, + @RequestParam(required = false) String ip){ + + List resources = gpuManageService.searchByCriteria(model, memorySize,ip); + + return ResponseVO.success(resources); + } } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/dao/GpuResourceDao.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/dao/GpuResourceDao.java index 92a93d7..a5f9d35 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/dao/GpuResourceDao.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/dao/GpuResourceDao.java @@ -1,19 +1,93 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.dao; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; -import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Options; -import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.*; +import org.apache.ibatis.jdbc.SQL; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; @Mapper public interface GpuResourceDao { - @Insert("INSERT INTO gpu_resource (GPUModel, GPUMemorySize, Ip)"+ + //---------------------- 基础CRUD ------------------------ + @Insert("INSERT INTO ipz.gpu_resource (GPUModel, GPUMemorySize, Ip) " + "VALUES (#{model}, #{memory}, #{ip})") @Options(useGeneratedKeys = true, keyProperty = "GPUId") Integer insert(GpuResource entity); - @Select("SELECT * FROM Ipz.public.gpu_resource WHERE GPUId = #{gpuId}") - GpuResource selectById(Long gpuId); + //物理删除 + @Delete("DELETE FROM ipz.gpu_resource WHERE GPUId = #{gpuId}") + Integer deleteById(@Param("gpuId") Long gpuId); + + // 逻辑删除 + @Update("UPDATE ipz.gpu_resource" + + " SET is_deleted = 1, update_time = NOW() " + + " WHERE GPUId = #{gpuId}") + Integer isDeleted(@Param("gpuId") Long gpuId); + + @Update("UPDATE ipz.gpu_resource " + + "SET GPUModel = #{model}, GPUMemorySize = #{memory}, Ip = #{ip} " + + "WHERE GPUId = #{GPUId}") + Integer updateById(GpuResource entity); + + @Select("SELECT * FROM ipz.gpu_resource WHERE GPUId = #{gpuId} AND is_deleted = 0") + GpuResource selectById(@Param("gpuId") Long gpuId); + + //---------------------- 缓存相关扩展 ------------------------ + + /** + * 分页全量查询(缓存初始化用) + * @param offset 起始位置 + * @param limit 每页数量 + */ + @Select("SELECT * FROM ipz.gpu_resource " + + "ORDER BY GPUId ASC LIMIT #{limit} OFFSET #{offset}") + List findByPage(@Param("offset") int offset, + @Param("limit") int limit); + + /** + * 增量数据查询(缓存同步用) + * @param since 起始时间 + */ + @Select("SELECT *, is_deleted FROM ipz.gpu_resource " + + "WHERE update_time > #{since} " + + "ORDER BY update_time ASC") + List findModifiedSince(@Param("since") LocalDateTime since); + + /** + * 带锁查询(防缓存击穿) + */ + @Select("SELECT * FROM ipz.gpu_resource " + + "WHERE GPUId = #{gpuId} FOR UPDATE NOWAIT") + GpuResource selectByIdWithLock(@Param("gpuId") Long gpuId); + + /** + * 动态条件查询(管理界面筛选用) + */ + @SelectProvider(type = GpuSqlBuilder.class, method = "buildDynamicQuery") + List selectByFields(@Param("params") Map params); +} + +// 动态SQL构造器 +class GpuSqlBuilder { + public static String buildDynamicQuery(Map params) { + return new SQL() {{ + SELECT("*"); + FROM("ipz.gpu_resource"); + if (params.containsKey("model")) { + WHERE("GPUModel LIKE #{params.model}"); + } + if (params.containsKey("memoryMin")) { + WHERE("GPUMemorySize >= #{params.memoryMin}"); + } + if (params.containsKey("ip")) { + WHERE("Ip = #{params.ip}"); + } + if (params.containsKey("isDeleted")) { + WHERE("is_deleted = #{params.isDeleted}"); + } + }}.toString(); + } } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/event/CacheUpdateEvent.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/event/CacheUpdateEvent.java index 5cc9d5e..ca1103b 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/event/CacheUpdateEvent.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/event/CacheUpdateEvent.java @@ -10,6 +10,14 @@ import java.time.Clock; @Getter @Setter public class CacheUpdateEvent extends ApplicationEvent { + public enum OperationType{ + FULL_SYNC, + INCREMENTAL_UPDATE, + INVALIDATE + } + + + private OperationType operationType; private final String eventType; private final Long resourceId; private final Long timestamp; diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/CacheInitException.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/CacheInitException.java new file mode 100644 index 0000000..3a13633 --- /dev/null +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/CacheInitException.java @@ -0,0 +1,10 @@ +package com.bipt.intelligentapplicationorchestrationservice.gpu.exception; + +public class CacheInitException extends RuntimeException{ + public CacheInitException(String message) { + super(message); + } + public CacheInitException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/GlobalExceptionHandler.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/GlobalExceptionHandler.java index 397b7d1..1ff8e44 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/GlobalExceptionHandler.java @@ -23,4 +23,12 @@ public class GlobalExceptionHandler { public ResponseVO handlePermissionDenied(PermissionDeniedException ex) { return ResponseVO.error(ex.getCode(), ex.getMessage()); } + + @ExceptionHandler(CacheInitException.class) + public ResponseVO handleCacheInitException(CacheInitException ex) { + return ResponseVO.error( + ErrorCodeEnum.CACHE_INIT_ERROR.getCode(), + "缓存初始化失败: " + ex.getMessage() + ); + } } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/PermissionDeniedException.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/PermissionDeniedException.java index 5b77fa7..bf77c61 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/PermissionDeniedException.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/exception/PermissionDeniedException.java @@ -6,6 +6,15 @@ import lombok.Getter; @Getter public class PermissionDeniedException extends RuntimeException { private final Integer code; + + public String getMessage() { + return message; + } + + public Integer getCode() { + return code; + } + private final String message; public PermissionDeniedException(ErrorCodeEnum errorCode) { diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mapper/GpuMapper.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mapper/GpuMapper.java index e11c3f4..a878c68 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mapper/GpuMapper.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mapper/GpuMapper.java @@ -3,12 +3,15 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.mapper; import ch.qos.logback.core.model.ComponentModel; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuCreateDTO; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuResponseDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuUpdateDTO; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; -import org.apache.ibatis.annotations.Mapper; +import org.mapstruct.Mapper; import org.mapstruct.MappingConstants; -@Mapper +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) public interface GpuMapper { GpuResource toEntity(GpuCreateDTO dto); - GpuResponseDTO toResponseDTO(GpuResource entity); + GpuResource toEntity(GpuUpdateDTO dto); + GpuResource toEntity(GpuResponseDTO dto); + GpuResponseDTO toDTO(GpuResource entity); } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuResponseDTO.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuResponseDTO.java index 31b6f58..6c6649c 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuResponseDTO.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuResponseDTO.java @@ -3,6 +3,7 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto; import lombok.Data; import java.time.LocalDateTime; +import java.util.Date; @Data public class GpuResponseDTO { @@ -11,7 +12,46 @@ public class GpuResponseDTO { private Integer GPUMemorySize; private String Ip; private LocalDateTime createTime; + // Builder类 + public static class Builder { + private Long id; + private String model; + private Integer memory; + private String ip; + private LocalDateTime createdTime; + public Builder id(Long id) { + this.id = id; + return this; + } + + public Builder model(String model) { + this.model = model; + return this; + } + + public Builder memory(Integer memory) { + this.memory = memory; + return this; + } + + public Builder ip(String ip) { + this.ip = ip; + return this; + } + + public Builder createdTime(LocalDateTime createdTime) { + this.createdTime = createdTime; + return this; + } + public GpuResponseDTO build() { + // 必填字段校验(如网页2的推荐) + if (id == null) { + throw new IllegalArgumentException("GPU ID必须填写"); + } + return new GpuResponseDTO(); + } + } public String getCreateTimeStr(){ return "GPU创建时间:" + createTime.toString(); } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuUpdateDTO.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuUpdateDTO.java index 03561d0..fee5710 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuUpdateDTO.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/dto/GpuUpdateDTO.java @@ -7,9 +7,31 @@ import lombok.*; @Data @AllArgsConstructor @NoArgsConstructor -@Setter -@Getter +//@Setter +//@Getter public class GpuUpdateDTO { + public @NotNull(message = "GPU ID cannot be null") Long getGPUId() { + return GPUId; + } + + public void setGPUId(@NotNull(message = "GPU ID cannot be null") Long GPUId) { + this.GPUId = GPUId; + } + + public void setGPUModel(@Pattern(regexp = "^([A-Z][A-Z0-9-]+)-\\w+", + message = "型号格式应为 [厂商(大写字母开头)]-[型号],如 Intel-Xe_GPU") String GPUModel) { + this.GPUModel = GPUModel; + } + + public void setGPUMemorySize(Integer GPUMemorySize) { + this.GPUMemorySize = GPUMemorySize; + } + + public void setIp(@Pattern(regexp = "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$", + message = "IP地址格式无效") String ip) { + Ip = ip; + } + @NotNull(message = "GPU ID cannot be null") private Long GPUId; diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/entity/GpuResource.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/entity/GpuResource.java index be31796..177b83a 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/entity/GpuResource.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/entity/GpuResource.java @@ -1,15 +1,15 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity; +import com.bipt.intelligentapplicationorchestrationservice.gpu.cache.RedisCacheService; import jakarta.persistence.*; -import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; import jakarta.validation.constraints.Pattern; +import java.time.LocalDateTime; import java.util.Date; @Setter -@Getter @Entity @Table(name = "Gpu_Resource") public class GpuResource { @@ -24,15 +24,42 @@ public class GpuResource { @Column(nullable = false) private Integer GPUMemorySize; + @Column(name = "is_deleted", nullable = false) + private Integer isDeleted = 0; + + public @Pattern(regexp = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$") String getIp() { + return Ip; + } + + public Long getGPUId() { + return GPUId; + } + + public String getGPUModel() { + return GPUModel; + } + + public Integer getGPUMemorySize() { + return GPUMemorySize; + } + + public LocalDateTime getCreateTime() { + return CreateTime; + } + + public Boolean getIsDeleted() { + return isDeleted != 0; + } + @Column(nullable = false, length = 15) @Pattern(regexp = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$") private String Ip; @Column(updatable = false) @CreationTimestamp - private Date CreateTime; + private LocalDateTime CreateTime; - public GpuResource(Long Id, String Model, Integer MemorySize, String ip, Date create_time) { + public GpuResource(Long Id, String Model, Integer MemorySize, String ip, LocalDateTime create_time) { this.GPUId = Id; this.GPUModel = Model; this.GPUMemorySize = MemorySize; @@ -40,4 +67,7 @@ public class GpuResource { this.CreateTime = create_time; } + public GpuResource() {} + + } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/enums/ErrorCodeEnum.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/enums/ErrorCodeEnum.java index 73b0fa2..6c30eaa 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/enums/ErrorCodeEnum.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/enums/ErrorCodeEnum.java @@ -18,7 +18,17 @@ public enum ErrorCodeEnum { GPU_NOT_FOUND(601, "GPU资源不存在"), DB_CONNECTION_FAILED(701, "数据库连接错误"), - VALIDATION_ERROR(801,"参数校验异常" ); + VALIDATION_ERROR(801,"参数校验异常" ), + + CACHE_INIT_ERROR(901, "缓存初始化失败"); + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } private final int code; private final String message; diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/vo/ResponseVO.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/vo/ResponseVO.java index 5bd2e8e..3e2adfb 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/vo/ResponseVO.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/model/vo/ResponseVO.java @@ -1,7 +1,7 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.model.vo; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.enums.ErrorCodeEnum; -import jakarta.validation.constraints.Null; + import java.io.Serializable; diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/listener/ResourceSyncListener.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/listener/ResourceSyncListener.java deleted file mode 100644 index 6726fd4..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/listener/ResourceSyncListener.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.mq.listener; - -public class ResourceSyncListener { -} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/producer/CacheUpdateProducer.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/producer/CacheUpdateProducer.java deleted file mode 100644 index 5afb0c5..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/mq/producer/CacheUpdateProducer.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.mq.producer; - -import com.bipt.intelligentapplicationorchestrationservice.gpu.event.CacheUpdateEvent; -import org.springframework.amqp.core.MessageDeliveryMode; -import org.springframework.amqp.core.MessagePostProcessor; -import org.springframework.amqp.core.MessageProperties; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.UUID; - -@Component -public class CacheUpdateProducer { - @Autowired - private RabbitTemplate rabbitTemplate; - - public void sendCacheUpdateMessage(String eventType, Long gpuId) { - - CacheUpdateEvent event = new CacheUpdateEvent(this, eventType, gpuId); - - MessagePostProcessor processor = message -> { - MessageProperties props = message.getMessageProperties(); - props.setMessageId(UUID.randomUUID().toString()); - props.setDeliveryMode(MessageDeliveryMode.PERSISTENT); - props.setExpiration("60000"); // 60秒TTL - return message; - }; - rabbitTemplate.convertAndSend("GPU_CACHE_QUEUE", event, processor); - } -} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/GpuManageService.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/GpuManageService.java index 2aa5dfa..987b02f 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/GpuManageService.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/GpuManageService.java @@ -1,8 +1,16 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.service; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuCreateDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuResponseDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuUpdateDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.vo.ResponseVO; +import java.util.List; + public interface GpuManageService { public ResponseVO createGpuResource(GpuCreateDTO dto); + public ResponseVO deleteGpuResource(Long gpuId); + public void updateGpuResource(GpuUpdateDTO entity); + public List searchByCriteria(String model, Integer memorySize, String ip); } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/impl/GpuManageServiceImpl.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/impl/GpuManageServiceImpl.java index e48f0c6..ff4a1ef 100644 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/impl/GpuManageServiceImpl.java +++ b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/service/impl/GpuManageServiceImpl.java @@ -3,29 +3,78 @@ package com.bipt.intelligentapplicationorchestrationservice.gpu.service.impl; import com.bipt.intelligentapplicationorchestrationservice.gpu.dao.GpuResourceDao; import com.bipt.intelligentapplicationorchestrationservice.gpu.mapper.GpuMapper; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuCreateDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuResponseDTO; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.dto.GpuUpdateDTO; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.entity.GpuResource; +import com.bipt.intelligentapplicationorchestrationservice.gpu.model.enums.ErrorCodeEnum; import com.bipt.intelligentapplicationorchestrationservice.gpu.model.vo.ResponseVO; -import com.bipt.intelligentapplicationorchestrationservice.gpu.mq.producer.CacheUpdateProducer; import com.bipt.intelligentapplicationorchestrationservice.gpu.service.GpuManageService; -import com.bipt.intelligentapplicationorchestrationservice.gpu.utils.ValidatorUtil; import jakarta.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + @Service public class GpuManageServiceImpl implements GpuManageService { @Autowired private GpuResourceDao gpuDao; - @Autowired - private CacheUpdateProducer mqProducer; @Autowired private GpuMapper gpuMapper; + @Autowired + private GpuResourceDao gpuResourceDao; @Transactional + //创建GPU资源 public ResponseVO createGpuResource(GpuCreateDTO dto) { GpuResource entity = gpuMapper.toEntity(dto); gpuDao.insert(entity); return ResponseVO.success(entity); } + + @Transactional + //删除GPU资源(逻辑删除) + public ResponseVO deleteGpuResource(Long gpuId) { + GpuResource entity = gpuDao.selectById(gpuId); + if (entity == null) { + return ResponseVO.error(ErrorCodeEnum.GPU_NOT_FOUND); + } + gpuDao.isDeleted(gpuId); + return ResponseVO.success(); + } + + @Transactional + //更新GPU资源 + public void updateGpuResource(GpuUpdateDTO dto) { + GpuResource entity = gpuMapper.toEntity(dto); + gpuDao.updateById(entity); + } +// private GpuResponseDTO convertToResponseDTO(GpuResource entity) { +// return new GpuResponseDTO.Builder() +// .id(entity.getGPUId()) +// .model(entity.getGPUModel()) +// .memory(entity.getGPUMemorySize()) +// .ip(entity.getIp()) +// .createdTime(entity.getCreateTime()) +// .build(); +// } + @Override + //模糊匹配查询 + public List searchByCriteria(String model, Integer memorySize, String ip) { + // PermissionCheckUtil.checkTenantAccess(); + + Map params = new HashMap<>(); + if(model != null) params.put("model","%" + model + "%"); + if(memorySize!=null) params.put("memorySize", memorySize); + if(ip!=null) params.put("ip", ip); + + List entities = gpuResourceDao.selectByFields(params); + + return entities.stream().map(gpuMapper::toDTO).collect(Collectors.toList()); + + } } diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/PermissionCheckUtil.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/PermissionCheckUtil.java deleted file mode 100644 index 170340f..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/PermissionCheckUtil.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.utils; - -import com.bipt.intelligentapplicationorchestrationservice.gpu.exception.PermissionDeniedException; -import com.bipt.intelligentapplicationorchestrationservice.gpu.model.enums.ErrorCodeEnum; -import org.springframework.dao.PermissionDeniedDataAccessException; -import org.springframework.stereotype.Component; - -@Component -public class PermissionCheckUtil { - public boolean hasGpuManagePermission(String userId) { - // 这里可以根据用户ID查询数据库或其他方式来判断用户是否有GPU管理权限 - // 这里只是一个示例,实际应用中需要根据具体情况进行实现 - if("admin".equals(userId)){ - return true; - } - else { - throw new PermissionDeniedException(ErrorCodeEnum.PERMISSION_DENIED, "用户" + userId + "无GPU管理权限"); - } - } -} diff --git a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/ValidatorUtil.java b/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/ValidatorUtil.java deleted file mode 100644 index a5bd26e..0000000 --- a/src/main/java/com/bipt/intelligentapplicationorchestrationservice/gpu/utils/ValidatorUtil.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.bipt.intelligentapplicationorchestrationservice.gpu.utils; - - - -import org.apache.commons.lang3.StringUtils; - -import java.security.InvalidParameterException; -import java.util.regex.Pattern; - -public final class ValidatorUtil { - private static final Pattern IP_PATTERN = Pattern.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$"); - private static final Pattern MODEL_PATTERN = Pattern.compile("^([A-Z][A-Z0-9-]+)-\\w+"); - - private ValidatorUtil(){} - - public static void validateGpuModel(String model){ - if(StringUtils.isBlank(model)||!MODEL_PATTERN.matcher(model).matches()){ - throw new InvalidParameterException("GPU型号格式应为[厂商]-[型号],如NVIDIA-A100"); - } - } - - public static void validateIp(String ip){ - if(StringUtils.isBlank(ip)||!IP_PATTERN.matcher(ip).matches()){ - throw new InvalidParameterException(); - } - } -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index bf600fa..cd0eea8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,10 +1,27 @@ spring.application.name=intelligent-application-orchestration-service -# ????? spring.datasource.url=jdbc:kingbase8://116.205.121.200:54321/Ipz spring.datasource.username=system spring.datasource.password=root spring.datasource.driver-class-name=com.kingbase8.Driver +spring.jpa.database-platform=org.hibernate.dialect.Kingbase8Dialect +#spring.datasource.url=jdbc:mysql://localhost:3306/Ipz +#spring.datasource.username=root +#spring.datasource.password=zxc25864 +#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +#spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.minimum-idle=5 -spring.datasource.hikari.connection-timeout=30000 \ No newline at end of file +spring.datasource.hikari.connection-timeout=30000 + +# Redis ???? +spring.data.redis.host=116.205.121.200 +spring.data.redis.port=6379 +spring.data.redis.username=default +spring.data.redis.password=your_strong_password +spring.data.redis.ssl.enabled=true + +mq.queue.cache-update=cache_update_queue + + + diff --git a/src/main/resources/mapper/GpuResourceMapper.xml b/src/main/resources/mapper/GpuResourceMapper.xml new file mode 100644 index 0000000..c4b2b60 --- /dev/null +++ b/src/main/resources/mapper/GpuResourceMapper.xml @@ -0,0 +1,19 @@ + + \ No newline at end of file