@@ -11,8 +11,8 @@ Nacos + Fegin + Gateway + (Spring Security + JWT + OAuth2) | |||||
初始化sql位置 /sql | 初始化sql位置 /sql | ||||
**地址:** 127.0.0.1:3306 | |||||
**用户名:** test **密码:** test | |||||
**地址:** 10.5.29.66:3306 | |||||
**用户名:** test **密码:** zj12345678 | |||||
### Nacos | ### Nacos | ||||
@@ -24,7 +24,7 @@ Nacos + Fegin + Gateway + (Spring Security + JWT + OAuth2) | |||||
**详见:** https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html | **详见:** https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html | ||||
**地址:** http://127.0.0.1:8848/nacos/#/login | |||||
**地址:** http://10.105.1.133:8848/nacos/#/login | |||||
**用户名:** nacos **密码:** nacos | **用户名:** nacos **密码:** nacos | ||||
@@ -19,6 +19,8 @@ package org.dubhe.admin; | |||||
import org.mybatis.spring.annotation.MapperScan; | import org.mybatis.spring.annotation.MapperScan; | ||||
import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||
import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
import org.springframework.scheduling.annotation.EnableAsync; | |||||
import org.springframework.scheduling.annotation.EnableScheduling; | |||||
/** | /** | ||||
@@ -27,6 +29,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
*/ | */ | ||||
@SpringBootApplication(scanBasePackages = "org.dubhe") | @SpringBootApplication(scanBasePackages = "org.dubhe") | ||||
@MapperScan(basePackages = {"org.dubhe.**.dao"}) | @MapperScan(basePackages = {"org.dubhe.**.dao"}) | ||||
@EnableScheduling | |||||
@EnableAsync | |||||
public class AdminApplication { | public class AdminApplication { | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
SpringApplication.run(AdminApplication.class, args); | SpringApplication.run(AdminApplication.class, args); | ||||
@@ -0,0 +1,68 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.async; | |||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
import org.dubhe.admin.client.SystemNamespaceClient; | |||||
import org.dubhe.admin.dao.UserConfigMapper; | |||||
import org.dubhe.admin.dao.UserGpuConfigMapper; | |||||
import org.dubhe.admin.domain.entity.UserConfig; | |||||
import org.dubhe.admin.domain.entity.UserGpuConfig; | |||||
import org.dubhe.biz.base.dto.NamespaceDeleteDTO; | |||||
import org.dubhe.biz.base.exception.BusinessException; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.scheduling.annotation.Async; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.Set; | |||||
/** | |||||
* @description 异步清理用户资源 | |||||
* @date 2021-11-25 | |||||
*/ | |||||
@Component | |||||
public class CleanupUserResourcesAsync { | |||||
@Autowired | |||||
private UserConfigMapper userConfigMapper; | |||||
@Autowired | |||||
private UserGpuConfigMapper userGpuConfigMapper; | |||||
@Autowired | |||||
private SystemNamespaceClient systemNamespaceClient; | |||||
@Async("adminExecutor") | |||||
public void cleanUserResource(Set<Long> ids, String accessToken){ | |||||
//删除用户资源配置 | |||||
QueryWrapper<UserConfig> userConfigWrapper = new QueryWrapper<>(); | |||||
userConfigWrapper.in("user_id",ids); | |||||
userConfigMapper.delete(userConfigWrapper); | |||||
QueryWrapper<UserGpuConfig> userGpuConfigWrapper = new QueryWrapper<>(); | |||||
userGpuConfigWrapper.in("user_id",ids); | |||||
userGpuConfigMapper.delete(userGpuConfigWrapper); | |||||
//删除用户namespace | |||||
NamespaceDeleteDTO namespaceDeleteDTO = new NamespaceDeleteDTO(); | |||||
namespaceDeleteDTO.setIds(ids); | |||||
DataResponseBody dataResponseBody = systemNamespaceClient.deleteNamespace(namespaceDeleteDTO, accessToken); | |||||
if (!dataResponseBody.succeed()) { | |||||
throw new BusinessException("远程调用k8s删除namespace失败"); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,42 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client; | |||||
import org.dubhe.admin.client.fallback.GpuConfigClientFallback; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.dto.GpuConfigDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.cloud.openfeign.FeignClient; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.RequestBody; | |||||
/** | |||||
* @description 远程调用k8sGPU资源配额 Client | |||||
* @date 2021-9-7 | |||||
*/ | |||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S, contextId = "gpuConfigClient",fallback = GpuConfigClientFallback.class) | |||||
public interface GpuConfigClient { | |||||
/** | |||||
* 更新k8sGPU资源配额 | |||||
* | |||||
* @param gpuConfigDTO k8sGPU资源配额 | |||||
* @return | |||||
*/ | |||||
@PostMapping(value = "/gpuConfig/update") | |||||
DataResponseBody updateGpuConfig(@RequestBody GpuConfigDTO gpuConfigDTO); | |||||
} |
@@ -0,0 +1,60 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client; | |||||
import org.dubhe.admin.client.fallback.ResourceNamespaceClientFallback; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import org.springframework.cloud.openfeign.FeignClient; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* @description 远程调用 | |||||
* @date 2021-11-19 | |||||
*/ | |||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S, contextId = "ResourceNamespaceClient", fallback = ResourceNamespaceClientFallback.class) | |||||
public interface ResourceNamespaceClient { | |||||
/** | |||||
* 查看用户资源用量峰值 | |||||
* | |||||
* @param resourceType 资源类型 | |||||
* @param sumDay 统计时间段 | |||||
* @return List<UserAllotVO> 用户资源用量峰值VO 实体类 | |||||
*/ | |||||
@GetMapping("/namespace/ResourceUsage") | |||||
DataResponseBody<List<UserAllotVO>> getResourceNamespace(@RequestParam(value = "resourceType") Integer resourceType, | |||||
@RequestParam(value = "sumDay") String sumDay); | |||||
/** | |||||
* 查询用户某段时间内的资源用量峰值 | |||||
* | |||||
* @param resourceType 资源类型 | |||||
* @param sumDay 统计时间段 | |||||
* @param namespaces 用户命名空间 | |||||
* @return String 资源用量峰值 | |||||
*/ | |||||
@GetMapping("/namespace/ResourceByUser") | |||||
DataResponseBody<Map<Long, String>> getResourceUsageByUser(@RequestParam(value = "resourceType") Integer resourceType, | |||||
@RequestParam(value = "sumDay") String sumDay, | |||||
@RequestParam(value = "namespaces") String namespaces); | |||||
} |
@@ -17,8 +17,8 @@ | |||||
package org.dubhe.admin.client; | package org.dubhe.admin.client; | ||||
import org.dubhe.admin.client.fallback.ResourceQuotaClientFallback; | import org.dubhe.admin.client.fallback.ResourceQuotaClientFallback; | ||||
import org.dubhe.admin.domain.dto.UserConfigDTO; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | import org.dubhe.biz.base.constant.ApplicationNameConst; | ||||
import org.dubhe.biz.base.dto.ResourceQuotaDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.springframework.cloud.openfeign.FeignClient; | import org.springframework.cloud.openfeign.FeignClient; | ||||
import org.springframework.web.bind.annotation.PostMapping; | import org.springframework.web.bind.annotation.PostMapping; | ||||
@@ -28,14 +28,16 @@ import org.springframework.web.bind.annotation.RequestBody; | |||||
* @description 远程调用资源配额 Client | * @description 远程调用资源配额 Client | ||||
* @date 2021-7-21 | * @date 2021-7-21 | ||||
*/ | */ | ||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S,fallback = ResourceQuotaClientFallback.class) | |||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S, contextId = "resourceQuotaClient", fallback = ResourceQuotaClientFallback.class) | |||||
public interface ResourceQuotaClient { | public interface ResourceQuotaClient { | ||||
/** | /** | ||||
* 更新 ResourceQuota | * 更新 ResourceQuota | ||||
* | * | ||||
* @param userConfigDTO 用户配置信息 | |||||
* @param resourceQuotaDTO 用户配置信息 | |||||
* @return | * @return | ||||
*/ | */ | ||||
@PostMapping(value = "/resourceQuota/update") | @PostMapping(value = "/resourceQuota/update") | ||||
DataResponseBody updateResourceQuota(@RequestBody UserConfigDTO userConfigDTO); | |||||
DataResponseBody updateResourceQuota(@RequestBody ResourceQuotaDTO resourceQuotaDTO); | |||||
} | } |
@@ -0,0 +1,42 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client; | |||||
import org.dubhe.admin.client.fallback.SystemNamespaceClientFallback; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.dto.NamespaceDeleteDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.cloud.openfeign.FeignClient; | |||||
import org.springframework.web.bind.annotation.DeleteMapping; | |||||
import org.springframework.web.bind.annotation.RequestBody; | |||||
import org.springframework.web.bind.annotation.RequestHeader; | |||||
/** | |||||
* @description 命名空间状态管理feign远程调用 | |||||
* @date 2021-11-26 | |||||
*/ | |||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S, contextId = "systemNamespaceClient", fallback = SystemNamespaceClientFallback.class) | |||||
public interface SystemNamespaceClient { | |||||
/** | |||||
* 删除用户namespace | |||||
* @param namespaceDeleteDTO 用户id | |||||
* @return DataResponseBody | |||||
*/ | |||||
@DeleteMapping(value="/namespace") | |||||
DataResponseBody deleteNamespace(@RequestBody NamespaceDeleteDTO namespaceDeleteDTO, @RequestHeader("Authorization") String accessToken); | |||||
} |
@@ -0,0 +1,45 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client; | |||||
import org.dubhe.admin.client.fallback.SystemNodeClientFallback; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.dto.QueryUserK8sResourceDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.QueryUserResourceSpecsVO; | |||||
import org.springframework.cloud.openfeign.FeignClient; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.RequestBody; | |||||
import java.util.List; | |||||
/** | |||||
* @description 远程查询用户k8s资源是否可用 | |||||
* @date 2021-9-7 | |||||
*/ | |||||
@FeignClient(value = ApplicationNameConst.SERVER_K8S, contextId = "systemNodeClient", fallback = SystemNodeClientFallback.class) | |||||
public interface SystemNodeClient { | |||||
/** | |||||
* 查询用户k8s可用资源 | |||||
* | |||||
* @param queryUserK8sResources 用户k8s可用资源查询条件 | |||||
* @return List<QueryUserResourceSpecsVO> 用户k8s可用资源列表 | |||||
*/ | |||||
@PostMapping("/node/queryUserResource") | |||||
DataResponseBody<List<QueryUserResourceSpecsVO>> queryUserK8sResource(@RequestBody List<QueryUserK8sResourceDTO> queryUserK8sResources); | |||||
} |
@@ -0,0 +1,33 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.fallback; | |||||
import org.dubhe.admin.client.GpuConfigClient; | |||||
import org.dubhe.biz.base.dto.GpuConfigDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | |||||
/** | |||||
* @description GpuConfigClient 熔断处理 | |||||
* @date 2021-9-7 | |||||
*/ | |||||
public class GpuConfigClientFallback implements GpuConfigClient { | |||||
@Override | |||||
public DataResponseBody updateGpuConfig(GpuConfigDTO gpuConfigDTO) { | |||||
return DataResponseFactory.failed("Call GpuConfig server updateGpuConfig error"); | |||||
} | |||||
} |
@@ -0,0 +1,42 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.fallback; | |||||
import org.dubhe.admin.client.ResourceNamespaceClient; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* @description | |||||
* @date 2021-11-19 | |||||
*/ | |||||
public class ResourceNamespaceClientFallback implements ResourceNamespaceClient { | |||||
@Override | |||||
public DataResponseBody<List<UserAllotVO>> getResourceNamespace(Integer resourceType, String sumDay) { | |||||
return DataResponseFactory.failed("Call MetricsApi.getNamespaceUsageRate error"); | |||||
} | |||||
@Override | |||||
public DataResponseBody<Map<Long, String>> getResourceUsageByUser(Integer resourceType, String sumDay, String namespaces) { | |||||
return DataResponseFactory.failed("Call MetricsApi.getResourceUsageByUser error"); | |||||
} | |||||
} |
@@ -17,7 +17,7 @@ | |||||
package org.dubhe.admin.client.fallback; | package org.dubhe.admin.client.fallback; | ||||
import org.dubhe.admin.client.ResourceQuotaClient; | import org.dubhe.admin.client.ResourceQuotaClient; | ||||
import org.dubhe.admin.domain.dto.UserConfigDTO; | |||||
import org.dubhe.biz.base.dto.ResourceQuotaDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | ||||
@@ -27,7 +27,7 @@ import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | |||||
*/ | */ | ||||
public class ResourceQuotaClientFallback implements ResourceQuotaClient { | public class ResourceQuotaClientFallback implements ResourceQuotaClient { | ||||
@Override | @Override | ||||
public DataResponseBody updateResourceQuota(UserConfigDTO userConfigDTO) { | |||||
public DataResponseBody updateResourceQuota(ResourceQuotaDTO resourceQuotaDTO) { | |||||
return DataResponseFactory.failed("Call ResourceQuota server updateResourceQuota error"); | return DataResponseFactory.failed("Call ResourceQuota server updateResourceQuota error"); | ||||
} | } | ||||
} | } |
@@ -0,0 +1,35 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.fallback; | |||||
import org.dubhe.admin.client.SystemNamespaceClient; | |||||
import org.dubhe.biz.base.dto.NamespaceDeleteDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | |||||
/** | |||||
* @description 命名空间状态管理feign远程调用熔断处理 | |||||
* @date 2021-11-26 | |||||
*/ | |||||
public class SystemNamespaceClientFallback implements SystemNamespaceClient { | |||||
@Override | |||||
public DataResponseBody deleteNamespace(NamespaceDeleteDTO namespaceDeleteDTO, String accessToken) { | |||||
return DataResponseFactory.failed("Call SystemNamespace server deleteNamespace error"); | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.fallback; | |||||
import org.dubhe.admin.client.SystemNodeClient; | |||||
import org.dubhe.biz.base.dto.QueryUserK8sResourceDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.QueryUserResourceSpecsVO; | |||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | |||||
import java.util.List; | |||||
/** | |||||
* @description SystemNodeClient 熔断处理 | |||||
* @date 2021-9-7 | |||||
*/ | |||||
public class SystemNodeClientFallback implements SystemNodeClient { | |||||
@Override | |||||
public DataResponseBody<List<QueryUserResourceSpecsVO>> queryUserK8sResource(List<QueryUserK8sResourceDTO> queryUserK8sResources) { | |||||
return DataResponseFactory.failed("Call SystemNode server queryUserK8sResource error"); | |||||
} | |||||
} |
@@ -0,0 +1,60 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.template; | |||||
import cn.hutool.http.HttpStatus; | |||||
import com.alibaba.fastjson.JSON; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.dto.GpuConfigDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.http.HttpEntity; | |||||
import org.springframework.http.HttpHeaders; | |||||
import org.springframework.http.MediaType; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.web.client.RestTemplate; | |||||
/** | |||||
* @description 远程调用k8sGPU资源配额 Client | |||||
* @date 2021-11-16 | |||||
*/ | |||||
@Component | |||||
public class GpuConfigTemplateClient { | |||||
@Autowired | |||||
private RestTemplate restTemplate; | |||||
/** | |||||
* 更新k8sGPU资源配额 | |||||
* | |||||
* @param gpuConfigDTO k8sGPU资源配额 | |||||
* @return DataResponseBody | |||||
*/ | |||||
public DataResponseBody updateGpuConfig(GpuConfigDTO gpuConfigDTO, String token) { | |||||
HttpHeaders headers = new HttpHeaders(); | |||||
headers.add(HttpHeaders.AUTHORIZATION, token); | |||||
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE)); | |||||
HttpEntity<String> httpEntity = new HttpEntity<>(JSON.toJSONString(gpuConfigDTO), headers); | |||||
ResponseEntity<DataResponseBody> responseEntity = restTemplate.postForEntity("http://" + ApplicationNameConst.SERVER_K8S + "/gpuConfig/update", httpEntity, DataResponseBody.class); | |||||
if (HttpStatus.HTTP_OK != responseEntity.getStatusCodeValue()) { | |||||
return null; | |||||
} | |||||
DataResponseBody restResult = responseEntity.getBody(); | |||||
return restResult; | |||||
} | |||||
} |
@@ -0,0 +1,91 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.template; | |||||
import cn.hutool.crypto.asymmetric.KeyType; | |||||
import cn.hutool.crypto.asymmetric.RSA; | |||||
import cn.hutool.http.HttpStatus; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.constant.AuthConst; | |||||
import org.dubhe.biz.base.exception.BusinessException; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.log.enums.LogEnum; | |||||
import org.dubhe.biz.log.utils.LogUtil; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.http.HttpEntity; | |||||
import org.springframework.http.HttpHeaders; | |||||
import org.springframework.http.MediaType; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.util.LinkedMultiValueMap; | |||||
import org.springframework.util.MultiValueMap; | |||||
import org.springframework.web.client.RestTemplate; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* @description 模拟登录获取token | |||||
* @date 2021-11-11 | |||||
*/ | |||||
@Component | |||||
public class ObtainAccessToken { | |||||
@Autowired | |||||
private RestTemplate restTemplate; | |||||
@Value("${rsa.private_key}") | |||||
private String privateKey; | |||||
/** | |||||
* 模拟登录获取token | |||||
* @return String token | |||||
*/ | |||||
public String generateToken(String username,String userPassword) { | |||||
String password = null; | |||||
try { | |||||
RSA rsa = new RSA(privateKey, null); | |||||
password = new String(rsa.decrypt(userPassword, KeyType.PrivateKey)); | |||||
} catch (Exception e) { | |||||
LogUtil.error(LogEnum.BIZ_SYS, "rsa 密钥解析失败, originPassword:{} , 密钥:{},异常:{}", userPassword, KeyType.PrivateKey, e); | |||||
throw new BusinessException("密钥解析失败"); | |||||
} | |||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); | |||||
params.add("grant_type", AuthConst.GRANT_TYPE); | |||||
params.add("client_id", AuthConst.CLIENT_ID); | |||||
params.add("client_secret", AuthConst.CLIENT_SECRET); | |||||
params.add("username", username); | |||||
params.add("password", password); | |||||
params.add("scope", "all"); | |||||
HttpHeaders headers = new HttpHeaders(); | |||||
// 需求需要传参为application/x-www-form-urlencoded格式 | |||||
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE)); | |||||
HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(params, headers); | |||||
ResponseEntity<DataResponseBody> responseEntity = restTemplate.postForEntity("http://" + ApplicationNameConst.SERVER_AUTHORIZATION + "/oauth/token", httpEntity, DataResponseBody.class); | |||||
if (HttpStatus.HTTP_OK != responseEntity.getStatusCodeValue()) { | |||||
return null; | |||||
} | |||||
DataResponseBody restResult = responseEntity.getBody(); | |||||
Map map = new LinkedHashMap(); | |||||
if (restResult.succeed()) { | |||||
map = (Map) restResult.getData(); | |||||
} | |||||
// 返回 token | |||||
return (String) map.get("token"); | |||||
} | |||||
} |
@@ -0,0 +1,60 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.client.template; | |||||
import cn.hutool.http.HttpStatus; | |||||
import com.alibaba.fastjson.JSON; | |||||
import org.dubhe.biz.base.constant.ApplicationNameConst; | |||||
import org.dubhe.biz.base.dto.ResourceQuotaDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.http.HttpEntity; | |||||
import org.springframework.http.HttpHeaders; | |||||
import org.springframework.http.MediaType; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.web.client.RestTemplate; | |||||
/** | |||||
* @description 远程调用资源配额 | |||||
* @date 2021-11-16 | |||||
*/ | |||||
@Component | |||||
public class ResourceQuotaTemplateClient { | |||||
@Autowired | |||||
private RestTemplate restTemplate; | |||||
/** | |||||
* 更新 ResourceQuota | |||||
* | |||||
* @param resourceQuotaDTO 用户配置信息 | |||||
* @return DataResponseBody | |||||
*/ | |||||
public DataResponseBody updateResourceQuota(ResourceQuotaDTO resourceQuotaDTO, String token) { | |||||
HttpHeaders headers = new HttpHeaders(); | |||||
headers.add(HttpHeaders.AUTHORIZATION, token); | |||||
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE)); | |||||
HttpEntity<String> httpEntity = new HttpEntity<>(JSON.toJSONString(resourceQuotaDTO), headers); | |||||
ResponseEntity<DataResponseBody> responseEntity = restTemplate.postForEntity("http://" + ApplicationNameConst.SERVER_K8S + "/resourceQuota/update", httpEntity, DataResponseBody.class); | |||||
if (HttpStatus.HTTP_OK != responseEntity.getStatusCodeValue()) { | |||||
return null; | |||||
} | |||||
DataResponseBody restResult = responseEntity.getBody(); | |||||
return restResult; | |||||
} | |||||
} |
@@ -0,0 +1,79 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.config; | |||||
import org.dubhe.biz.log.enums.LogEnum; | |||||
import org.dubhe.biz.log.utils.LogUtil; | |||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.scheduling.annotation.AsyncConfigurer; | |||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | |||||
import java.util.concurrent.Executor; | |||||
import java.util.concurrent.ThreadPoolExecutor; | |||||
/** | |||||
* @description 线程池配置类 | |||||
* @date 2020-07-17 | |||||
*/ | |||||
@Configuration | |||||
public class AdminPoolConfig implements AsyncConfigurer { | |||||
@Value("${basepool.corePoolSize:40}") | |||||
private Integer corePoolSize; | |||||
@Value("${basepool.maximumPoolSize:60}") | |||||
private Integer maximumPoolSize; | |||||
@Value("${basepool.keepAliveTime:120}") | |||||
private Integer keepAliveTime; | |||||
@Value("${basepool.blockQueueSize:20}") | |||||
private Integer blockQueueSize; | |||||
/** | |||||
* 异步处理线程池 | |||||
* @return Executor 线程实例 | |||||
*/ | |||||
@Bean("adminExecutor") | |||||
@Override | |||||
public Executor getAsyncExecutor() { | |||||
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); | |||||
//核心线程数 | |||||
taskExecutor.setCorePoolSize(corePoolSize); | |||||
taskExecutor.setAllowCoreThreadTimeOut(true); | |||||
//最大线程数 | |||||
taskExecutor.setMaxPoolSize(maximumPoolSize); | |||||
//超时时间 | |||||
taskExecutor.setKeepAliveSeconds(keepAliveTime); | |||||
//配置队列大小 | |||||
taskExecutor.setQueueCapacity(blockQueueSize); | |||||
//配置线程池前缀 | |||||
taskExecutor.setThreadNamePrefix("async-admin-"); | |||||
//拒绝策略 | |||||
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy()); | |||||
taskExecutor.initialize(); | |||||
return taskExecutor; | |||||
} | |||||
@Override | |||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { | |||||
LogUtil.error(LogEnum.SYS_ERR, "start capturing the exception information of asynchronous task management admin-----》》》"); | |||||
return (ex, method, params) -> { | |||||
LogUtil.error(LogEnum.SYS_ERR, "async admin task failed,the name of admin is {}, params are {}, exception is {}", method.getName(), params, ex); | |||||
}; | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.dao; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
import org.dubhe.admin.domain.entity.GpuResource; | |||||
/** | |||||
* @description GPU资源管理mapper接口 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
public interface GpuResourceMapper extends BaseMapper<GpuResource> { | |||||
} |
@@ -17,10 +17,15 @@ | |||||
package org.dubhe.admin.dao; | package org.dubhe.admin.dao; | ||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import org.apache.ibatis.annotations.Param; | |||||
import org.apache.ibatis.annotations.Select; | import org.apache.ibatis.annotations.Select; | ||||
import org.dubhe.admin.domain.entity.UserConfig; | import org.dubhe.admin.domain.entity.UserConfig; | ||||
import org.dubhe.admin.domain.vo.UserLimitConfigVO; | |||||
import org.dubhe.biz.base.vo.UserAllotResourceVO; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import java.util.List; | import java.util.List; | ||||
import org.apache.ibatis.annotations.Param; | |||||
/** | /** | ||||
* @description 用户配置 Mapper | * @description 用户配置 Mapper | ||||
@@ -33,4 +38,43 @@ public interface UserConfigMapper extends BaseMapper<UserConfig> { | |||||
* @param userConfig 用户配置 | * @param userConfig 用户配置 | ||||
*/ | */ | ||||
Long insertOrUpdate(UserConfig userConfig); | Long insertOrUpdate(UserConfig userConfig); | ||||
/** | |||||
* 统计内存、CPU配额 | |||||
*/ | |||||
@Select("select sum(memory_limit) memoryAllotTotal,sum(cpu_limit) cpuAllotTotal from user_config where deleted=0;") | |||||
UserAllotResourceVO selectResourceSum(); | |||||
/** | |||||
* 统计CPU配额Top10 | |||||
*/ | |||||
@Select("select u.username,uc.cpu_limit allotTotal from user_config uc, user u where uc.user_id=u.id and uc.deleted=0 order by cpu_limit desc limit 10;") | |||||
List<UserAllotVO> selectCpuAllotTotal(); | |||||
/** | |||||
* 统计内存配额Top10 | |||||
*/ | |||||
@Select("select u.username,uc.memory_limit allotTotal from user_config uc, user u where uc.user_id=u.id and uc.deleted=0 order by memory_limit desc limit 10;") | |||||
List<UserAllotVO> selectMemoryAllotTotal(); | |||||
/** | |||||
* 根据用户id查询资源配额(cpu、memory) | |||||
* | |||||
* @param userId 用户ID | |||||
* @return 资源配额实体 | |||||
*/ | |||||
@Select("select * from user_config where user_id=#{userId} AND deleted=0") | |||||
UserConfig selectLimitSumByUser(@Param("userId") Long userId); | |||||
/** | |||||
* 分页查询资源列表 | |||||
* | |||||
* @param page 分页对象 | |||||
* @param sort 排序字段 | |||||
* @param order 排序方式 | |||||
* @return 用户配额列表 | |||||
*/ | |||||
List<UserLimitConfigVO> selectLimitSum(Page page, | |||||
@Param("sort") String sort, | |||||
@Param("order") String order); | |||||
} | } |
@@ -0,0 +1,81 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.dao; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
import org.apache.ibatis.annotations.Param; | |||||
import org.apache.ibatis.annotations.Select; | |||||
import org.dubhe.admin.domain.entity.UserGpuConfig; | |||||
import org.dubhe.biz.base.vo.GpuAllotVO; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户GPU配置 Mapper | |||||
* @date 2021-9-2 | |||||
*/ | |||||
public interface UserGpuConfigMapper extends BaseMapper<UserGpuConfig> { | |||||
/** | |||||
* 批量添加用户GPU配置 | |||||
* | |||||
* @param userGpuConfigs 用户GPU配置实体集合 | |||||
*/ | |||||
void insertBatchs(List<UserGpuConfig> userGpuConfigs); | |||||
/** | |||||
* 根据userId查询用户GPU配置记录数 | |||||
* @param userId 用户id | |||||
* @return Integer 用户GPU配置记录数 | |||||
*/ | |||||
@Select("select count(*) from user_gpu_config where user_id= #{userId}") | |||||
Integer selectCountByUserId(@Param("userId") Long userId); | |||||
/** | |||||
* 统计GPU型号配额总量 | |||||
* | |||||
* @return GPU具体型号资源配额 | |||||
*/ | |||||
@Select("select gpu_model gpuModel,sum(gpu_limit)allotTotal from user_gpu_config where deleted=0 group by gpu_model") | |||||
List<GpuAllotVO> selectGpuAllotSum(); | |||||
/** | |||||
* GPU配额TOP10统计 | |||||
*/ | |||||
@Select("SELECT u.username,gc.user_id,SUM(gc.gpu_limit)gpuLimit FROM user_gpu_config gc, user u WHERE gc.user_id=u.id AND gc.deleted=0" + | |||||
" GROUP BY gc.user_id ORDER BY gpuLimit DESC LIMIT 10") | |||||
List<UserGpuConfig> selectAllotTotal(); | |||||
/** | |||||
* 查询某用户具体的GPU型号配额 | |||||
* | |||||
* @param userId 用户ID | |||||
* @return GPU型号配额 | |||||
*/ | |||||
@Select("select gpu_model gpuModel,sum(gpu_limit)allotTotal from user_gpu_config where user_id=#{userId} and deleted=0 group by gpuModel") | |||||
List<GpuAllotVO> selectGpuModelTotal(@Param("userId") Long userId); | |||||
/** | |||||
* 根据用户id查询GPU配额总量 | |||||
* | |||||
* @param userId 用户ID | |||||
* @return GPU配额总量 | |||||
*/ | |||||
@Select("SELECT IFNULL(SUM(gpu_limit),0)gpuSum FROM user_gpu_config WHERE user_id=#{userId} AND deleted=0") | |||||
int selectGpuLimitSum(@Param("userId") Long userId); | |||||
} |
@@ -110,6 +110,13 @@ public interface UserMapper extends BaseMapper<User> { | |||||
*/ | */ | ||||
Set<String> queryPermissionByUserId(Long userId); | Set<String> queryPermissionByUserId(Long userId); | ||||
/** | |||||
* 查找用户所在的用户组名 | |||||
* | |||||
* @param userId 用户id | |||||
* @return 用户组名 | |||||
*/ | |||||
String queryUserGroupNameByUserId(Long userId); | |||||
/** | /** | ||||
* 查询实体及关联对象 | * 查询实体及关联对象 | ||||
@@ -144,4 +151,13 @@ public interface UserMapper extends BaseMapper<User> { | |||||
@ResultMap(value = "userMapperResults") | @ResultMap(value = "userMapperResults") | ||||
IPage<User> selectCollPageByRoleId(Page<User> page, @Param("ew") Wrapper<User> queryWrapper, Long roleId); | IPage<User> selectCollPageByRoleId(Page<User> page, @Param("ew") Wrapper<User> queryWrapper, Long roleId); | ||||
/** | |||||
* 根据用户id查找用户名 | |||||
* | |||||
* @param userId 用户id | |||||
* @return 用户名 | |||||
*/ | |||||
@Select("SELECT username FROM user WHERE id=#{userId} and enabled=1 AND deleted=0 ") | |||||
String findUserNameById(@Param("userId") Long userId); | |||||
} | } |
@@ -32,6 +32,6 @@ public class AuthCodeQueryDTO extends PageQueryBase implements Serializable { | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
@ApiModelProperty(value = "权限组名称") | @ApiModelProperty(value = "权限组名称") | ||||
private String authCode; | |||||
private String keyword; | |||||
} | } |
@@ -0,0 +1,57 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.hibernate.validator.constraints.Length; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.Pattern; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description GPU资源创建 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuResourceCreateDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "GPU类型(例如:NVIDIA)", required = true) | |||||
@NotBlank(message = "GPU类型") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU类型错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_TYPE, message = "支持字母、数字、汉字、英文横杠、英文.号、空白字符和英文斜杠") | |||||
private String gpuType; | |||||
@ApiModelProperty(value = "GPU型号(例如:v100)", required = true) | |||||
@NotBlank(message = "GPU型号") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU型号错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_MODEL, message = "支持小写字母、数字、英文横杠、英文.号和英文斜杠") | |||||
private String gpuModel; | |||||
@ApiModelProperty(value = "k8s GPU资源标签key值(例如:nvidia.com/gpu)", required = true) | |||||
@NotBlank(message = "k8s GPU资源标签key值") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU型号错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_K8S, message = "支持小写字母、数字、英文横杠、英文.号和英文斜杠") | |||||
private String k8sLabelKey; | |||||
} |
@@ -0,0 +1,40 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
import java.util.Set; | |||||
/** | |||||
* @description GPU资源删除 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuResourceDeleteDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "id", required = true) | |||||
@NotNull(message = "id不能为空") | |||||
private Set<Long> ids; | |||||
} |
@@ -0,0 +1,45 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.dubhe.biz.db.base.PageQueryBase; | |||||
import org.hibernate.validator.constraints.Length; | |||||
import javax.validation.constraints.Pattern; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description GPU资源查询 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuResourceQueryDTO extends PageQueryBase implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "GPU类型(例如:NVIDIA)") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU类型错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_TYPE, message = "支持字母、数字、汉字、英文横杠、英文.号、空白字符和英文斜杠") | |||||
private String gpuType; | |||||
} |
@@ -0,0 +1,64 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.hibernate.validator.constraints.Length; | |||||
import javax.validation.constraints.Min; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | |||||
import javax.validation.constraints.Pattern; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description GPU资源修改 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuResourceUpdateDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "id", required = true) | |||||
@NotNull(message = "id不能为null") | |||||
@Min(value = MagicNumConstant.ONE, message = "id必须大于1") | |||||
private Long id; | |||||
@ApiModelProperty(value = "GPU类型(例如:NVIDIA)", required = true) | |||||
@NotBlank(message = "GPU类型") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU类型错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_TYPE, message = "支持字母、数字、汉字、英文横杠、英文.号、空白字符和英文斜杠") | |||||
private String gpuType; | |||||
@ApiModelProperty(value = "GPU型号(例如:v100)", required = true) | |||||
@NotBlank(message = "GPU型号") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU型号错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_MODEL, message = "支持小写字母、数字、英文横杠、英文.号、空白字符和英文斜杠") | |||||
private String gpuModel; | |||||
@ApiModelProperty(value = "k8s GPU资源标签key值(例如:nvidia.com/gpu)", required = true) | |||||
@NotBlank(message = "k8s GPU资源标签key值") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU型号错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_K8S, message = "支持小写字母、数字、英文横杠、英文.号和英文斜杠") | |||||
private String k8sLabelKey; | |||||
} |
@@ -36,8 +36,9 @@ public class MenuQueryDTO { | |||||
@Query(propName = "create_time", type = Query.Type.BETWEEN) | @Query(propName = "create_time", type = Query.Type.BETWEEN) | ||||
private List<Timestamp> createTime; | private List<Timestamp> createTime; | ||||
@Query(propName = "deleted", type = Query.Type.EQ) | @Query(propName = "deleted", type = Query.Type.EQ) | ||||
private Boolean deleted = false; | private Boolean deleted = false; | ||||
@Query(type = Query.Type.ORDER_BY) | |||||
private String sort = "sort"; | |||||
} | } |
@@ -0,0 +1,65 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import javax.validation.constraints.Max; | |||||
import javax.validation.constraints.Min; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description 查询用户资源规格 | |||||
* @date 2021-09-07 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class QueryUserResourceSpecsDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "用户id") | |||||
@Min(value = MagicNumConstant.ONE, message = "用户id,不能小于1") | |||||
private Long userId; | |||||
@ApiModelProperty(value = "所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving,4:dubhe-tadl,5:dubhe-optimize))", required = true) | |||||
@NotNull(message = "所属业务场景不能为空") | |||||
@Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | |||||
@Max(value = MagicNumConstant.FIVE, message = "所属业务场景错误") | |||||
private Integer module; | |||||
@ApiModelProperty("规格类型(0为CPU, 1为GPU)") | |||||
@NotNull(message = "规格类型(0为CPU, 1为GPU)不能为空") | |||||
private Boolean resourcesPoolType; | |||||
@ApiModelProperty(value = "节点个数") | |||||
@Min(value = MagicNumConstant.ONE, message = "节点个数,默认为1个") | |||||
private Integer resourcesPoolNode; | |||||
@ApiModelProperty(value = "GPU型号(例如:v100)") | |||||
private String gpuModel; | |||||
@ApiModelProperty(value = "k8s GPU资源标签key值(例如:nvidia.com/gpu)") | |||||
private String k8sLabelKey; | |||||
@ApiModelProperty(value = "多GPU,true:GPU数大于1核,false:GPU数等于1核") | |||||
private Boolean multiGpu; | |||||
} |
@@ -42,10 +42,10 @@ public class ResourceSpecsCreateDTO implements Serializable { | |||||
@Pattern(regexp = StringConstant.REGEXP_SPECS, message = "规格名称支持字母、数字、汉字、英文横杠、下划线和空白字符") | @Pattern(regexp = StringConstant.REGEXP_SPECS, message = "规格名称支持字母、数字、汉字、英文横杠、下划线和空白字符") | ||||
private String specsName; | private String specsName; | ||||
@ApiModelProperty(value = "所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving)", required = true) | |||||
@ApiModelProperty(value = "所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving, 4:dubhe-tadl, 5:dubhe-optimize)", required = true) | |||||
@NotNull(message = "所属业务场景不能为空") | @NotNull(message = "所属业务场景不能为空") | ||||
@Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | @Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | ||||
@Max(value = MagicNumConstant.THREE, message = "所属业务场景错误") | |||||
@Max(value = MagicNumConstant.FIVE, message = "所属业务场景错误") | |||||
private Integer module; | private Integer module; | ||||
@ApiModelProperty(value = "CPU数量,单位:核", required = true) | @ApiModelProperty(value = "CPU数量,单位:核", required = true) | ||||
@@ -37,6 +37,9 @@ public class ResourceSpecsQueryDTO extends PageQueryBase implements Serializable | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
@ApiModelProperty(value = "多GPU,true:GPU数大于1核,false:GPU数等于1核") | |||||
private Boolean multiGpu; | |||||
@ApiModelProperty("规格名称") | @ApiModelProperty("规格名称") | ||||
@Length(max = MagicNumConstant.THIRTY_TWO, message = "规格名称错误") | @Length(max = MagicNumConstant.THIRTY_TWO, message = "规格名称错误") | ||||
private String specsName; | private String specsName; | ||||
@@ -44,8 +47,8 @@ public class ResourceSpecsQueryDTO extends PageQueryBase implements Serializable | |||||
@ApiModelProperty("规格类型(0为CPU, 1为GPU)") | @ApiModelProperty("规格类型(0为CPU, 1为GPU)") | ||||
private Boolean resourcesPoolType; | private Boolean resourcesPoolType; | ||||
@ApiModelProperty("所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving)") | |||||
@ApiModelProperty("所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving,4:dubhe-tadl,5:dubhe-optimize)") | |||||
@Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | @Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | ||||
@Max(value = MagicNumConstant.THREE, message = "所属业务场景错误") | |||||
@Max(value = MagicNumConstant.FIVE, message = "所属业务场景错误") | |||||
private Integer module; | private Integer module; | ||||
} | } |
@@ -49,10 +49,10 @@ public class ResourceSpecsUpdateDTO implements Serializable { | |||||
@Pattern(regexp = StringConstant.REGEXP_SPECS, message = "规格名称支持字母、数字、汉字、英文横杠、下划线和空白字符") | @Pattern(regexp = StringConstant.REGEXP_SPECS, message = "规格名称支持字母、数字、汉字、英文横杠、下划线和空白字符") | ||||
private String specsName; | private String specsName; | ||||
@ApiModelProperty(value = "所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving)", required = true) | |||||
@ApiModelProperty(value = "所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving, 4:dubhe-tadl, 5:dubhe-optimize)", required = true) | |||||
@NotNull(message = "所属业务场景不能为空") | @NotNull(message = "所属业务场景不能为空") | ||||
@Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | @Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | ||||
@Max(value = MagicNumConstant.THREE, message = "所属业务场景错误") | |||||
@Max(value = MagicNumConstant.FIVE, message = "所属业务场景错误") | |||||
private Integer module; | private Integer module; | ||||
@ApiModelProperty(value = "CPU数量,单位:核") | @ApiModelProperty(value = "CPU数量,单位:核") | ||||
@@ -0,0 +1,46 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.hibernate.validator.constraints.Length; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.Pattern; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description 用户GPU资源查询 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class UserGpuResourceQueryDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty(value = "GPU类型(例如:NVIDIA)") | |||||
@NotBlank(message = "GPU类型") | |||||
@Length(max = MagicNumConstant.SIXTY_FOUR, message = "GPU类型错误-输入长度不能超过64个字符") | |||||
@Pattern(regexp = StringConstant.REGEXP_GPU_TYPE, message = "支持字母、数字、汉字、英文横杠、英文.号、空白字符和英文斜杠") | |||||
private String gpuType; | |||||
} |
@@ -0,0 +1,35 @@ | |||||
package org.dubhe.admin.domain.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.dto.UserGpuConfigDTO; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.util.List; | |||||
/** | |||||
* @date 2021-11-24 | |||||
* @description 用户组用户统一配置DTO | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class UserGroupConfigSaveDTO { | |||||
private static final long serialVersionUID = 1L; | |||||
@NotNull(message = "用户组ID 不能为空") | |||||
private Long groupId; | |||||
@NotNull(message = "Notebook 延迟删除时间配置不能为空") | |||||
private Integer notebookDelayDeleteTime; | |||||
@NotNull(message = "CPU 资源限制配置不能为空") | |||||
private Integer cpuLimit; | |||||
@NotNull(message = "内存资源限制配置不能为空") | |||||
private Integer memoryLimit; | |||||
private Long defaultImageId; | |||||
private List<UserGpuConfigDTO> gpuResources; | |||||
} |
@@ -0,0 +1,31 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import org.dubhe.biz.db.base.PageQueryBase; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description 用户资源列表 | |||||
* @date 2021-11-25 | |||||
*/ | |||||
public class UserResourceListDTO extends PageQueryBase implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
} |
@@ -0,0 +1,41 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.dto; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* @description 用户资源统计DTO | |||||
* @date 2021-11-17 | |||||
*/ | |||||
@Data | |||||
public class UserResourceQueryDTO { | |||||
@ApiModelProperty("资源统计类型") | |||||
@NotNull | |||||
private Integer statType; | |||||
@ApiModelProperty("资源类型") | |||||
@NotNull | |||||
private Integer resourceType; | |||||
@ApiModelProperty("统计时间段") | |||||
private String sumDay; | |||||
} |
@@ -0,0 +1,63 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.entity; | |||||
import com.baomidou.mybatisplus.annotation.IdType; | |||||
import com.baomidou.mybatisplus.annotation.TableField; | |||||
import com.baomidou.mybatisplus.annotation.TableId; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.db.entity.BaseEntity; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* @description GPU资源实体类 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
@TableName("gpu_resource") | |||||
public class GpuResource extends BaseEntity { | |||||
/** | |||||
* 主键ID | |||||
*/ | |||||
@TableId(value = "id", type = IdType.AUTO) | |||||
@NotNull(groups = {Update.class}) | |||||
private Long id; | |||||
/** | |||||
* GPU类型(例如:NVIDIA) | |||||
*/ | |||||
@TableField(value = "gpu_type") | |||||
private String gpuType; | |||||
/** | |||||
* GPU型号(例如:v100) | |||||
*/ | |||||
@TableField(value = "gpu_model") | |||||
private String gpuModel; | |||||
/** | |||||
* k8s GPU资源标签key值(例如:nvidia.com/gpu) | |||||
*/ | |||||
@TableField(value = "k8s_label_key") | |||||
private String k8sLabelKey; | |||||
} |
@@ -39,6 +39,12 @@ public class UserConfig extends BaseEntity { | |||||
@TableId(value = "user_id") | @TableId(value = "user_id") | ||||
private Long userId; | private Long userId; | ||||
@TableField(exist = false) | |||||
private String userName; | |||||
@TableField(exist = false) | |||||
private String nickName; | |||||
@TableId(value = "notebook_delay_delete_time") | @TableId(value = "notebook_delay_delete_time") | ||||
private Integer notebookDelayDeleteTime; | private Integer notebookDelayDeleteTime; | ||||
@@ -48,6 +54,6 @@ public class UserConfig extends BaseEntity { | |||||
@TableId(value = "memory_limit") | @TableId(value = "memory_limit") | ||||
private Integer memoryLimit; | private Integer memoryLimit; | ||||
@TableId(value = "gpu_limit") | |||||
private Integer gpuLimit; | |||||
@TableId(value = "default_image_id") | |||||
private Long defaultImageId; | |||||
} | } |
@@ -0,0 +1,80 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.entity; | |||||
import com.baomidou.mybatisplus.annotation.IdType; | |||||
import com.baomidou.mybatisplus.annotation.TableField; | |||||
import com.baomidou.mybatisplus.annotation.TableId; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.db.entity.BaseEntity; | |||||
import javax.validation.constraints.NotNull; | |||||
/** | |||||
* @description 用户GPU配置实体 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
@TableName("user_gpu_config") | |||||
public class UserGpuConfig extends BaseEntity { | |||||
/** | |||||
* 主键ID | |||||
*/ | |||||
@TableId(value = "id", type = IdType.AUTO) | |||||
@NotNull(groups = {Update.class}) | |||||
private Long id; | |||||
/** | |||||
* 用户id | |||||
*/ | |||||
@TableId(value = "user_id") | |||||
private Long userId; | |||||
/** | |||||
* 用户名 | |||||
*/ | |||||
@TableField(exist = false) | |||||
private String userName; | |||||
/** | |||||
* GPU类型(例如:NVIDIA) | |||||
*/ | |||||
@TableField(value = "gpu_type") | |||||
private String gpuType; | |||||
/** | |||||
* GPU型号(例如:v100) | |||||
*/ | |||||
@TableField(value = "gpu_model") | |||||
private String gpuModel; | |||||
/** | |||||
* k8s GPU资源标签key值(例如:nvidia.com/gpu) | |||||
*/ | |||||
@TableField(value = "k8s_label_key") | |||||
private String k8sLabelKey; | |||||
/** | |||||
* 用户显卡资源限制配置,单位:卡 | |||||
*/ | |||||
@TableId(value = "gpu_limit") | |||||
private Integer gpuLimit; | |||||
} |
@@ -0,0 +1,59 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.vo; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import java.io.Serializable; | |||||
import java.sql.Timestamp; | |||||
/** | |||||
* @description GPU资源查询结果封装类 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuResourceQueryVO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@ApiModelProperty("主键ID") | |||||
private Long id; | |||||
@ApiModelProperty("GPU类型(例如:NVIDIA)") | |||||
private String gpuType; | |||||
@ApiModelProperty("GPU型号(例如:v100)") | |||||
private String gpuModel; | |||||
@ApiModelProperty("k8s GPU资源标签key值(例如:nvidia.com/gpu)") | |||||
private String k8sLabelKey; | |||||
@ApiModelProperty("创建人") | |||||
private Long createUserId; | |||||
@ApiModelProperty("创建时间") | |||||
private Timestamp createTime; | |||||
@ApiModelProperty("更新人") | |||||
private Long updateUserId; | |||||
@ApiModelProperty("更新时间") | |||||
private Timestamp updateTime; | |||||
} |
@@ -20,13 +20,14 @@ import lombok.Data; | |||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
/** | /** | ||||
* @description 菜单VO | * @description 菜单VO | ||||
* @date 2020-06-01 | * @date 2020-06-01 | ||||
*/ | */ | ||||
@Data | @Data | ||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) | |||||
@JsonInclude(JsonInclude.Include.NON_NULL) | |||||
public class MenuVo implements Serializable { | public class MenuVo implements Serializable { | ||||
private static final long serialVersionUID = 7145999097655311261L; | private static final long serialVersionUID = 7145999097655311261L; | ||||
@@ -38,7 +39,7 @@ public class MenuVo implements Serializable { | |||||
private String component; | private String component; | ||||
private MenuMetaVo meta; | |||||
private Map<String,Object> meta; | |||||
private List<MenuVo> children; | private List<MenuVo> children; | ||||
} | } |
@@ -0,0 +1,39 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.vo; | |||||
import lombok.Data; | |||||
/** | |||||
* @description | |||||
* @date 2021-11-26 | |||||
*/ | |||||
@Data | |||||
public class UserLimitConfigVO { | |||||
private Long userId; | |||||
private String userName; | |||||
private String nickName; | |||||
private String gpu; | |||||
private String cpu; | |||||
private String mem; | |||||
} |
@@ -0,0 +1,91 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.domain.vo; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.vo.GpuAllotVO; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户资源分页列表VO | |||||
* @date 2021-11-23 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class UserResourceResVO { | |||||
@ApiModelProperty("编号") | |||||
private Long id; | |||||
@ApiModelProperty("用户名") | |||||
private String userName; | |||||
@ApiModelProperty("账户名(昵称)") | |||||
private String nickName; | |||||
@ApiModelProperty("GPU配额") | |||||
private String gpu; | |||||
@ApiModelProperty("GPU具体型号配额") | |||||
private List<GpuAllotVO> gpuModelAllots; | |||||
@ApiModelProperty("7天内GPU峰值使用率") | |||||
private String gpu7; | |||||
@ApiModelProperty("7天内GPU峰值使用量") | |||||
private String gpu7unit; | |||||
@ApiModelProperty("15天内GPU峰值使用率") | |||||
private String gpu15; | |||||
@ApiModelProperty("15天内GPU峰值使用量") | |||||
private String gpu15unit; | |||||
@ApiModelProperty("内存配额") | |||||
private String mem; | |||||
@ApiModelProperty("7天内内存峰值使用率") | |||||
private String mem7; | |||||
@ApiModelProperty("7天内内存峰值使用量") | |||||
private String mem7unit; | |||||
@ApiModelProperty("15天内内存峰值使用率") | |||||
private String mem15; | |||||
@ApiModelProperty("15天内内存峰值使用量") | |||||
private String mem15unit; | |||||
@ApiModelProperty("CPU配额") | |||||
private String cpu; | |||||
@ApiModelProperty("7天内CPU峰值使用率") | |||||
private String cpu7; | |||||
@ApiModelProperty("7天内CPU峰值使用量") | |||||
private String cpu7unit; | |||||
@ApiModelProperty("15天内CPU峰值使用率") | |||||
private String cpu15; | |||||
@ApiModelProperty("15天内CPU峰值使用量") | |||||
private String cpu15unit; | |||||
} |
@@ -0,0 +1,54 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.enums; | |||||
/** | |||||
* @description | |||||
* @date 2021-11-17 | |||||
*/ | |||||
public enum ResourceTypeEnum { | |||||
GPU_TYPE(1, "gpu"), | |||||
CPU_TYPE(2, "cpu"), | |||||
MEMORY_TYPE(3, "memory"); | |||||
private Integer code; | |||||
private String desc; | |||||
ResourceTypeEnum(Integer code, String desc) { | |||||
this.code = code; | |||||
this.desc = desc; | |||||
} | |||||
public Integer getCode() { | |||||
return code; | |||||
} | |||||
public String getDesc() { | |||||
return desc; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "[" + this.code + "]" + this.desc; | |||||
} | |||||
public static boolean isGpuType(Integer code) { | |||||
return GPU_TYPE.code.equals(code); | |||||
} | |||||
} |
@@ -0,0 +1,50 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.enums; | |||||
/** | |||||
* @description 资源统计类型 | |||||
* @date 2021-11-17 | |||||
*/ | |||||
public enum StatTypeEnum { | |||||
ALLOT_TYPE(1, "统计资源配额"), | |||||
USAGE_RATE_TYPE(2, "统计资源使用率峰值"), | |||||
USAGE_TYPE(3, "统计资源用量峰值"); | |||||
private Integer code; | |||||
private String desc; | |||||
StatTypeEnum(Integer code, String desc) { | |||||
this.code = code; | |||||
this.desc = desc; | |||||
} | |||||
public Integer getCode() { | |||||
return code; | |||||
} | |||||
public String getDesc() { | |||||
return desc; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "[" + this.code + "]" + this.desc; | |||||
} | |||||
} |
@@ -42,7 +42,7 @@ public class EmailEventListener { | |||||
@EventListener | @EventListener | ||||
@Async("taskExecutor") | |||||
@Async | |||||
public void onApplicationEvent(EmailEvent event) { | public void onApplicationEvent(EmailEvent event) { | ||||
EmailDTO emailDTO = (EmailDTO) event.getSource(); | EmailDTO emailDTO = (EmailDTO) event.getSource(); | ||||
sendMail(emailDTO.getReceiverMailAddress(), emailDTO.getSubject(), emailDTO.getCode()); | sendMail(emailDTO.getReceiverMailAddress(), emailDTO.getSubject(), emailDTO.getCode()); | ||||
@@ -41,7 +41,7 @@ public class EmailEventPublisher { | |||||
* | * | ||||
* @param dto | * @param dto | ||||
*/ | */ | ||||
@Async("taskExecutor") | |||||
@Async | |||||
public void sentEmailEvent(final EmailDTO dto) { | public void sentEmailEvent(final EmailDTO dto) { | ||||
try { | try { | ||||
EmailEvent emailEvent = new EmailEvent(dto); | EmailEvent emailEvent = new EmailEvent(dto); | ||||
@@ -0,0 +1,89 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.rest; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.service.GpuResourceService; | |||||
import org.dubhe.biz.base.constant.Permissions; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.security.access.prepost.PreAuthorize; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import javax.validation.Valid; | |||||
/** | |||||
* @description GPU资源管理 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Api(tags = "系统:GPU资源管理") | |||||
@RestController | |||||
@RequestMapping("/gpuResource") | |||||
public class GpuResourceController { | |||||
@Autowired | |||||
private GpuResourceService gpuResourceService; | |||||
@ApiOperation("查询GPU资源") | |||||
@GetMapping | |||||
public DataResponseBody getGpuResource(GpuResourceQueryDTO gpuResourceQueryDTO) { | |||||
return new DataResponseBody(gpuResourceService.getGpuResource(gpuResourceQueryDTO)); | |||||
} | |||||
@ApiOperation("查询用户GPU类型") | |||||
@GetMapping("/getUserGpuType") | |||||
public DataResponseBody getUserGpuType() { | |||||
return new DataResponseBody(gpuResourceService.getUserGpuType()); | |||||
} | |||||
@ApiOperation("根据用户GPU类型查询用户GPU资源") | |||||
@GetMapping("/getUserGpuModel") | |||||
public DataResponseBody getUserGpuResource(UserGpuResourceQueryDTO userGpuResourceQueryDTO) { | |||||
return new DataResponseBody(gpuResourceService.getUserGpuResource(userGpuResourceQueryDTO)); | |||||
} | |||||
@ApiOperation("查询GPU类型") | |||||
@GetMapping("/getGpuType") | |||||
public DataResponseBody getGpuType() { | |||||
return new DataResponseBody(gpuResourceService.getGpuType()); | |||||
} | |||||
@ApiOperation("新增GPU资源") | |||||
@PostMapping | |||||
@PreAuthorize(Permissions.GPU_CREATE) | |||||
public DataResponseBody create(@Valid @RequestBody GpuResourceCreateDTO gpuResourceCreateDTO) { | |||||
return new DataResponseBody(gpuResourceService.create(gpuResourceCreateDTO)); | |||||
} | |||||
@ApiOperation("修改GPU资源") | |||||
@PutMapping | |||||
@PreAuthorize(Permissions.GPU_EDIT) | |||||
public DataResponseBody update(@Valid @RequestBody GpuResourceUpdateDTO gpuResourceUpdateDTO) { | |||||
return new DataResponseBody(gpuResourceService.update(gpuResourceUpdateDTO)); | |||||
} | |||||
@ApiOperation("删除GPU资源") | |||||
@DeleteMapping | |||||
@PreAuthorize(Permissions.GPU_DELETE) | |||||
public DataResponseBody delete(@Valid @RequestBody GpuResourceDeleteDTO gpuResourceDeleteDTO) { | |||||
gpuResourceService.delete(gpuResourceDeleteDTO); | |||||
return new DataResponseBody(); | |||||
} | |||||
} |
@@ -25,10 +25,12 @@ import org.dubhe.admin.domain.dto.ResourceSpecsUpdateDTO; | |||||
import org.dubhe.admin.service.ResourceSpecsService; | import org.dubhe.admin.service.ResourceSpecsService; | ||||
import org.dubhe.biz.base.constant.Permissions; | import org.dubhe.biz.base.constant.Permissions; | ||||
import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | ||||
import org.dubhe.admin.domain.dto.QueryUserResourceSpecsDTO; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.security.access.prepost.PreAuthorize; | import org.springframework.security.access.prepost.PreAuthorize; | ||||
import org.springframework.validation.annotation.Validated; | |||||
import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
import javax.validation.Valid; | import javax.validation.Valid; | ||||
@@ -47,16 +49,30 @@ public class ResourceSpecsController { | |||||
@ApiOperation("查询资源规格") | @ApiOperation("查询资源规格") | ||||
@GetMapping | @GetMapping | ||||
public DataResponseBody getResourceSpecs(ResourceSpecsQueryDTO resourceSpecsQueryDTO) { | |||||
public DataResponseBody getResourceSpecs(@Validated ResourceSpecsQueryDTO resourceSpecsQueryDTO) { | |||||
return new DataResponseBody(resourceSpecsService.getResourceSpecs(resourceSpecsQueryDTO)); | return new DataResponseBody(resourceSpecsService.getResourceSpecs(resourceSpecsQueryDTO)); | ||||
} | } | ||||
@ApiOperation("查询资源规格(远程调用)") | |||||
@ApiOperation("查询资源规格(训练远程调用)") | |||||
@GetMapping("/queryResourceSpecs") | @GetMapping("/queryResourceSpecs") | ||||
public DataResponseBody<QueryResourceSpecsVO> queryResourceSpecs(QueryResourceSpecsDTO queryResourceSpecsDTO) { | |||||
public DataResponseBody<QueryResourceSpecsVO> queryResourceSpecs(@Validated QueryResourceSpecsDTO queryResourceSpecsDTO) { | |||||
return new DataResponseBody(resourceSpecsService.queryResourceSpecs(queryResourceSpecsDTO)); | return new DataResponseBody(resourceSpecsService.queryResourceSpecs(queryResourceSpecsDTO)); | ||||
} | } | ||||
@ApiOperation("查询用户资源规格") | |||||
@GetMapping("/queryUserResourceSpecs") | |||||
public DataResponseBody<QueryResourceSpecsVO> getUserResourceSpecs(@Validated QueryUserResourceSpecsDTO queryUserResourceSpecsDTO) { | |||||
return new DataResponseBody(resourceSpecsService.getUserResourceSpecs(queryUserResourceSpecsDTO)); | |||||
} | |||||
@ApiOperation("查询资源规格(tadl远程调用)") | |||||
@GetMapping("/queryTadlResourceSpecs") | |||||
public DataResponseBody<QueryResourceSpecsVO> queryTadlResourceSpecs(Long id) { | |||||
return new DataResponseBody(resourceSpecsService.queryTadlResourceSpecs(id)); | |||||
} | |||||
@ApiOperation("新增资源规格") | @ApiOperation("新增资源规格") | ||||
@PostMapping | @PostMapping | ||||
@PreAuthorize(Permissions.SPECS_CREATE) | @PreAuthorize(Permissions.SPECS_CREATE) | ||||
@@ -78,7 +78,6 @@ public class UserCenterController { | |||||
List<RoleSmallDTO> roles = roleService.getRoleByUserId(curUserId); | List<RoleSmallDTO> roles = roleService.getRoleByUserId(curUserId); | ||||
List<MenuDTO> menuDtoList = menuService.findByRoles(roles); | List<MenuDTO> menuDtoList = menuService.findByRoles(roles); | ||||
List<MenuDTO> menuDtos = (List<MenuDTO>) menuService.buildTree(menuDtoList).get("result"); | List<MenuDTO> menuDtos = (List<MenuDTO>) menuService.buildTree(menuDtoList).get("result"); | ||||
return new DataResponseBody(menuService.buildMenus(menuDtos)); | return new DataResponseBody(menuService.buildMenus(menuDtos)); | ||||
} | } | ||||
@@ -19,7 +19,6 @@ package org.dubhe.admin.rest; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
import org.dubhe.admin.domain.dto.UserConfigDTO; | |||||
import org.dubhe.admin.domain.dto.UserCreateDTO; | import org.dubhe.admin.domain.dto.UserCreateDTO; | ||||
import org.dubhe.admin.domain.dto.UserDeleteDTO; | import org.dubhe.admin.domain.dto.UserDeleteDTO; | ||||
import org.dubhe.admin.domain.dto.UserQueryDTO; | import org.dubhe.admin.domain.dto.UserQueryDTO; | ||||
@@ -27,12 +26,23 @@ import org.dubhe.admin.domain.dto.UserUpdateDTO; | |||||
import org.dubhe.admin.service.UserService; | import org.dubhe.admin.service.UserService; | ||||
import org.dubhe.biz.base.constant.Permissions; | import org.dubhe.biz.base.constant.Permissions; | ||||
import org.dubhe.biz.base.context.UserContext; | import org.dubhe.biz.base.context.UserContext; | ||||
import org.dubhe.biz.base.dto.UserConfigSaveDTO; | |||||
import org.dubhe.biz.base.dto.UserDTO; | import org.dubhe.biz.base.dto.UserDTO; | ||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.security.access.prepost.PreAuthorize; | import org.springframework.security.access.prepost.PreAuthorize; | ||||
import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||
import org.springframework.web.bind.annotation.*; | |||||
import org.springframework.web.bind.annotation.DeleteMapping; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.PathVariable; | |||||
import org.springframework.web.bind.annotation.PostMapping; | |||||
import org.springframework.web.bind.annotation.PutMapping; | |||||
import org.springframework.web.bind.annotation.RequestBody; | |||||
import org.springframework.web.bind.annotation.RequestHeader; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RequestParam; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import javax.validation.Valid; | import javax.validation.Valid; | ||||
@@ -81,22 +91,23 @@ public class UserController { | |||||
@ApiOperation("删除用户") | @ApiOperation("删除用户") | ||||
@DeleteMapping | @DeleteMapping | ||||
@PreAuthorize(Permissions.USER_DELETE) | @PreAuthorize(Permissions.USER_DELETE) | ||||
public DataResponseBody delete(@Valid @RequestBody UserDeleteDTO userDeleteDTO) { | |||||
userService.delete(userDeleteDTO.getIds()); | |||||
public DataResponseBody delete(@Valid @RequestBody UserDeleteDTO userDeleteDTO, @RequestHeader("Authorization") String accessToken) { | |||||
userService.delete(userDeleteDTO.getIds(), accessToken); | |||||
return new DataResponseBody(); | return new DataResponseBody(); | ||||
} | } | ||||
@ApiOperation("根据用户ID查询用户配置") | @ApiOperation("根据用户ID查询用户配置") | ||||
@GetMapping(value = "/getUserConfig") | @GetMapping(value = "/getUserConfig") | ||||
public DataResponseBody getUserConfig(@RequestParam(value = "userId") Long userId) { | |||||
public DataResponseBody<UserConfigVO> getUserConfig(@RequestParam(value = "userId") Long userId) { | |||||
return new DataResponseBody(userService.findUserConfig(userId)); | return new DataResponseBody(userService.findUserConfig(userId)); | ||||
} | } | ||||
@ApiOperation("新增或修改用户配置") | @ApiOperation("新增或修改用户配置") | ||||
@PutMapping(value = "/setUserConfig") | @PutMapping(value = "/setUserConfig") | ||||
@PreAuthorize(Permissions.USER_CONFIG_EDIT) | @PreAuthorize(Permissions.USER_CONFIG_EDIT) | ||||
public DataResponseBody setUserConfig(@Validated @RequestBody UserConfigDTO userConfigDTO) { | |||||
return new DataResponseBody(userService.createOrUpdateUserConfig(userConfigDTO)); | |||||
public DataResponseBody setUserConfig(@Validated @RequestBody UserConfigSaveDTO userConfigSaveDTO) { | |||||
userService.saveUserConfig(userConfigSaveDTO, null); | |||||
return new DataResponseBody(); | |||||
} | } | ||||
/** | /** | ||||
@@ -121,7 +132,7 @@ public class UserController { | |||||
@ApiOperation("根据用户昵称搜索用户列表") | @ApiOperation("根据用户昵称搜索用户列表") | ||||
@GetMapping(value = "/findByNickName") | @GetMapping(value = "/findByNickName") | ||||
public DataResponseBody<List<UserDTO>> findByNickName(@RequestParam(value = "nickName",required = false) String nickName) { | |||||
public DataResponseBody<List<UserDTO>> findByNickName(@RequestParam(value = "nickName", required = false) String nickName) { | |||||
return new DataResponseBody(userService.findByNickName(nickName)); | return new DataResponseBody(userService.findByNickName(nickName)); | ||||
} | } | ||||
@@ -130,4 +141,20 @@ public class UserController { | |||||
public DataResponseBody<List<UserDTO>> getUserList(@RequestParam(value = "ids") List<Long> ids) { | public DataResponseBody<List<UserDTO>> getUserList(@RequestParam(value = "ids") List<Long> ids) { | ||||
return new DataResponseBody(userService.getUserList(ids)); | return new DataResponseBody(userService.getUserList(ids)); | ||||
} | } | ||||
@ApiOperation("重置密码") | |||||
@PostMapping(value = "/resetPassword/{userId}") | |||||
@PreAuthorize(Permissions.USER_RESET_PASSWORD) | |||||
public DataResponseBody resetPassword(@PathVariable Long userId) { | |||||
return userService.resetPassword(userId); | |||||
} | |||||
@ApiOperation("获取用户资源配额总量") | |||||
@GetMapping("/userAllot") | |||||
@PreAuthorize(Permissions.SYSTEM_NODE) | |||||
public DataResponseBody getUserAllotTotal() { | |||||
return userService.getAllotResources(); | |||||
} | |||||
} | } |
@@ -18,6 +18,7 @@ package org.dubhe.admin.rest; | |||||
import io.swagger.annotations.Api; | import io.swagger.annotations.Api; | ||||
import io.swagger.annotations.ApiOperation; | import io.swagger.annotations.ApiOperation; | ||||
import org.dubhe.admin.domain.dto.UserGroupConfigSaveDTO; | |||||
import org.dubhe.admin.domain.dto.UserGroupDTO; | import org.dubhe.admin.domain.dto.UserGroupDTO; | ||||
import org.dubhe.admin.domain.dto.UserGroupDeleteDTO; | import org.dubhe.admin.domain.dto.UserGroupDeleteDTO; | ||||
import org.dubhe.admin.domain.dto.UserGroupQueryDTO; | import org.dubhe.admin.domain.dto.UserGroupQueryDTO; | ||||
@@ -32,9 +33,11 @@ import org.springframework.security.access.prepost.PreAuthorize; | |||||
import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||
import org.springframework.web.bind.annotation.DeleteMapping; | import org.springframework.web.bind.annotation.DeleteMapping; | ||||
import org.springframework.web.bind.annotation.GetMapping; | import org.springframework.web.bind.annotation.GetMapping; | ||||
import org.springframework.web.bind.annotation.PathVariable; | |||||
import org.springframework.web.bind.annotation.PostMapping; | import org.springframework.web.bind.annotation.PostMapping; | ||||
import org.springframework.web.bind.annotation.PutMapping; | import org.springframework.web.bind.annotation.PutMapping; | ||||
import org.springframework.web.bind.annotation.RequestBody; | import org.springframework.web.bind.annotation.RequestBody; | ||||
import org.springframework.web.bind.annotation.RequestHeader; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | import org.springframework.web.bind.annotation.RequestMapping; | ||||
import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||
@@ -118,8 +121,8 @@ public class UserGroupController { | |||||
@DeleteMapping("/delete") | @DeleteMapping("/delete") | ||||
@ApiOperation("批量删除组用户") | @ApiOperation("批量删除组用户") | ||||
@PreAuthorize(Permissions.USER_GROUP_DELETE_USER) | @PreAuthorize(Permissions.USER_GROUP_DELETE_USER) | ||||
public DataResponseBody delUser(@Validated @RequestBody UserGroupUpdDTO userGroupUpdDTO) { | |||||
userGroupService.delUser(userGroupUpdDTO); | |||||
public DataResponseBody delUser(@Validated @RequestBody UserGroupUpdDTO userGroupUpdDTO, @RequestHeader("Authorization") String accessToken) { | |||||
userGroupService.delUser(userGroupUpdDTO, accessToken); | |||||
return new DataResponseBody(); | return new DataResponseBody(); | ||||
} | } | ||||
@@ -130,4 +133,21 @@ public class UserGroupController { | |||||
userGroupService.updateUserRole(userRoleUpdateDTO); | userGroupService.updateUserRole(userRoleUpdateDTO); | ||||
return new DataResponseBody(); | return new DataResponseBody(); | ||||
} | } | ||||
@PutMapping("/resetPassword/{groupId}") | |||||
@ApiOperation("批量重置组成员密码") | |||||
@PreAuthorize(Permissions.USER_GROUP_RESET_USER_PASSWORD) | |||||
public DataResponseBody resetUserPassword(@PathVariable Long groupId) { | |||||
userGroupService.resetUserPassword(groupId); | |||||
return new DataResponseBody(); | |||||
} | |||||
@ApiOperation("批量新增或修改组成员配置") | |||||
@PutMapping(value = "/setUserConfig") | |||||
@PreAuthorize(Permissions.USER_GROUP_CONFIG_EDIT) | |||||
public DataResponseBody setUserConfig(@Validated @RequestBody UserGroupConfigSaveDTO userGroupConfigSaveDTO) { | |||||
userGroupService.saveUserConfig(userGroupConfigSaveDTO); | |||||
return new DataResponseBody(); | |||||
} | |||||
} | } |
@@ -0,0 +1,58 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.rest; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import org.dubhe.admin.domain.dto.UserResourceListDTO; | |||||
import org.dubhe.admin.domain.dto.UserResourceQueryDTO; | |||||
import org.dubhe.admin.service.UserResourceService; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.validation.annotation.Validated; | |||||
import org.springframework.web.bind.annotation.GetMapping; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户资源控制层 | |||||
* @date 2021-11-23 | |||||
*/ | |||||
@Api(tags = "控制台:用户统计") | |||||
@RestController | |||||
@RequestMapping("/resource") | |||||
public class UserResourceController { | |||||
@Autowired | |||||
private UserResourceService userResourceService; | |||||
@ApiOperation("用户Top统计") | |||||
@GetMapping("/total") | |||||
public DataResponseBody<List<UserAllotVO>> getUserResourceTotal(@Validated UserResourceQueryDTO resourceQueryDTO) { | |||||
return new DataResponseBody(userResourceService.getResourceTotal(resourceQueryDTO)); | |||||
} | |||||
@ApiOperation("用户资源统计列表") | |||||
@GetMapping("/list") | |||||
public DataResponseBody getUserResourceList(UserResourceListDTO UserResourceListDTO) { | |||||
return new DataResponseBody(userResourceService.getResourceList(UserResourceListDTO)); | |||||
} | |||||
} |
@@ -0,0 +1,77 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.service; | |||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.domain.entity.GpuResource; | |||||
import org.dubhe.admin.domain.vo.GpuResourceQueryVO; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Set; | |||||
/** | |||||
* @description GPU资源管理 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
public interface GpuResourceService { | |||||
/** | |||||
* 查询GPU资源 | |||||
* @param gpuResourceQueryDTO 查询GPU资源请求实体 | |||||
* @return List<GpuResource> gpuResourceSpecs GPU资源列表 | |||||
*/ | |||||
Map<String, Object> getGpuResource(GpuResourceQueryDTO gpuResourceQueryDTO); | |||||
/** | |||||
* 新增GPU资源 | |||||
* @param gpuResourceCreateDTO 新增GPU资源实体 | |||||
* @return List<Long> 新增GPU资源id | |||||
*/ | |||||
List<Long> create(GpuResourceCreateDTO gpuResourceCreateDTO); | |||||
/** | |||||
* 修改GPU资源 | |||||
* @param gpuResourceUpdateDTO 修改GPU资源实体 | |||||
* @return List<Long> 修改GPU资源id | |||||
*/ | |||||
List<Long> update(GpuResourceUpdateDTO gpuResourceUpdateDTO); | |||||
/** | |||||
* GPU资源删除 | |||||
* @param gpuResourceDeleteDTO GPU资源删除id集合 | |||||
*/ | |||||
void delete(GpuResourceDeleteDTO gpuResourceDeleteDTO); | |||||
/** | |||||
* 查询GPU类型 | |||||
* @return List<string> GPU类型列表 | |||||
*/ | |||||
List<String> getGpuType(); | |||||
/** | |||||
* 查询用户GPU类型 | |||||
* @return Set<string> GPU类型列表 | |||||
*/ | |||||
Set<String> getUserGpuType(); | |||||
/** | |||||
* 根据用户GPU类型查询用户GPU资源 | |||||
* @return List<GpuResource> 用户GPU资源列表 | |||||
*/ | |||||
List<GpuResource> getUserGpuResource(UserGpuResourceQueryDTO userGpuResourceQueryDTO); | |||||
} |
@@ -16,9 +16,14 @@ | |||||
*/ | */ | ||||
package org.dubhe.admin.service; | package org.dubhe.admin.service; | ||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsCreateDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsDeleteDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsQueryDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsUpdateDTO; | |||||
import org.dubhe.biz.base.vo.QueryUserResourceSpecsVO; | |||||
import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | ||||
import org.dubhe.admin.domain.dto.QueryUserResourceSpecsDTO; | |||||
import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
@@ -62,4 +67,18 @@ public interface ResourceSpecsService { | |||||
* @return QueryResourceSpecsVO 资源规格返回结果实体类 | * @return QueryResourceSpecsVO 资源规格返回结果实体类 | ||||
*/ | */ | ||||
QueryResourceSpecsVO queryResourceSpecs(QueryResourceSpecsDTO queryResourceSpecsDTO); | QueryResourceSpecsVO queryResourceSpecs(QueryResourceSpecsDTO queryResourceSpecsDTO); | ||||
/** | |||||
* 查询用户资源规格 | |||||
* @param queryUserResourceSpecsDTO 查询用户资源规格请求实体 | |||||
* @return List<QueryUserResourceSpecsVO> 用户资源规格返回结果实体类集合 | |||||
*/ | |||||
List<QueryUserResourceSpecsVO> getUserResourceSpecs(QueryUserResourceSpecsDTO queryUserResourceSpecsDTO); | |||||
/** | |||||
* 查询资源规格 | |||||
* @param id 资源规格id | |||||
* @return QueryResourceSpecsVO 资源规格返回结果实体类 | |||||
*/ | |||||
QueryResourceSpecsVO queryTadlResourceSpecs(Long id); | |||||
} | } |
@@ -101,7 +101,7 @@ public interface UserGroupService { | |||||
* | * | ||||
* @param userGroupUpdDTO 批量删除用户组用户DTO | * @param userGroupUpdDTO 批量删除用户组用户DTO | ||||
*/ | */ | ||||
void delUser(UserGroupUpdDTO userGroupUpdDTO); | |||||
void delUser(UserGroupUpdDTO userGroupUpdDTO, String accessToken); | |||||
/** | /** | ||||
* 批量修改用户组用户的角色 | * 批量修改用户组用户的角色 | ||||
@@ -109,4 +109,19 @@ public interface UserGroupService { | |||||
* @param userRoleUpdateDTO | * @param userRoleUpdateDTO | ||||
*/ | */ | ||||
void updateUserRole(UserRoleUpdateDTO userRoleUpdateDTO); | void updateUserRole(UserRoleUpdateDTO userRoleUpdateDTO); | ||||
/** | |||||
* 批量重置用户组用户的密码 | |||||
* | |||||
* @param groupId | |||||
*/ | |||||
void resetUserPassword(Long groupId); | |||||
/** | |||||
* 批量修改用户组用户的设置 | |||||
* | |||||
* @param userGroupConfigSaveDTO | |||||
*/ | |||||
void saveUserConfig(UserGroupConfigSaveDTO userGroupConfigSaveDTO); | |||||
} | } |
@@ -0,0 +1,48 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.service; | |||||
import org.dubhe.admin.domain.dto.UserResourceListDTO; | |||||
import org.dubhe.admin.domain.dto.UserResourceQueryDTO; | |||||
import org.dubhe.admin.domain.vo.UserResourceResVO; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
/** | |||||
* @description 用户资源统计接口层 | |||||
* @date 2021-11-23 | |||||
*/ | |||||
public interface UserResourceService { | |||||
/** | |||||
* 用户资源统计 | |||||
* | |||||
* @param resourceQueryDTO 查询DTO实体 | |||||
* @return List<UserAllotVO> 用户资源Top数据 | |||||
*/ | |||||
List<UserAllotVO> getResourceTotal(UserResourceQueryDTO resourceQueryDTO); | |||||
/** | |||||
* 用户资源统计列表 | |||||
* | |||||
* @return List<UserResourceResVO> 用户资源列表VO实体 | |||||
*/ | |||||
Map<String, Object> getResourceList(UserResourceListDTO resourceListDTO); | |||||
} |
@@ -18,13 +18,21 @@ package org.dubhe.admin.service; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import com.baomidou.mybatisplus.extension.service.IService; | import com.baomidou.mybatisplus.extension.service.IService; | ||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.domain.dto.AuthUserDTO; | |||||
import org.dubhe.admin.domain.dto.UserCenterUpdateDTO; | |||||
import org.dubhe.admin.domain.dto.UserCreateDTO; | |||||
import org.dubhe.admin.domain.dto.UserEmailUpdateDTO; | |||||
import org.dubhe.admin.domain.dto.UserQueryDTO; | |||||
import org.dubhe.admin.domain.dto.UserRegisterDTO; | |||||
import org.dubhe.admin.domain.dto.UserRegisterMailDTO; | |||||
import org.dubhe.admin.domain.dto.UserResetPasswordDTO; | |||||
import org.dubhe.admin.domain.dto.UserUpdateDTO; | |||||
import org.dubhe.admin.domain.entity.User; | import org.dubhe.admin.domain.entity.User; | ||||
import org.dubhe.admin.domain.vo.UserConfigCreateVO; | |||||
import org.dubhe.admin.domain.vo.UserConfigVO; | |||||
import org.dubhe.biz.base.dto.TeamDTO; | import org.dubhe.biz.base.dto.TeamDTO; | ||||
import org.dubhe.biz.base.dto.UserConfigSaveDTO; | |||||
import org.dubhe.biz.base.dto.UserDTO; | import org.dubhe.biz.base.dto.UserDTO; | ||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.dubhe.cloud.authconfig.service.AdminUserService; | import org.dubhe.cloud.authconfig.service.AdminUserService; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
@@ -69,7 +77,7 @@ public interface UserService extends AdminUserService, IService<User> { | |||||
* | * | ||||
* @param ids 用户ID列表 | * @param ids 用户ID列表 | ||||
*/ | */ | ||||
void delete(Set<Long> ids); | |||||
void delete(Set<Long> ids, String accessToken); | |||||
/** | /** | ||||
* 根据用户名称获取用户信息 | * 根据用户名称获取用户信息 | ||||
@@ -235,8 +243,21 @@ public interface UserService extends AdminUserService, IService<User> { | |||||
/** | /** | ||||
* 创建或更新用户配置 | * 创建或更新用户配置 | ||||
* | * | ||||
* @param userConfigDTO 用户配置 | |||||
* @return org.dubhe.admin.domain.vo.UserConfigCreateVO 用户配置 VO | |||||
* @param userConfigSaveDTO 用户配置 | |||||
*/ | */ | ||||
UserConfigCreateVO createOrUpdateUserConfig(UserConfigDTO userConfigDTO); | |||||
void saveUserConfig(UserConfigSaveDTO userConfigSaveDTO, String token); | |||||
/** | |||||
* 重置密码 | |||||
* | |||||
* @return 重置密码结果集 | |||||
*/ | |||||
DataResponseBody resetPassword(Long userId); | |||||
/** | |||||
* 获取用户分配的资源总量 | |||||
* | |||||
* @return 资源配额总量统计 | |||||
*/ | |||||
DataResponseBody getAllotResources(); | |||||
} | } |
@@ -79,8 +79,8 @@ public class AuthCodeServiceImpl extends ServiceImpl<AuthCodeMapper, Auth> imple | |||||
Page page = authCodeQueryDTO.toPage(); | Page page = authCodeQueryDTO.toPage(); | ||||
QueryWrapper<Auth> queryWrapper = new QueryWrapper<>(); | QueryWrapper<Auth> queryWrapper = new QueryWrapper<>(); | ||||
if (StringUtils.isNotEmpty(authCodeQueryDTO.getAuthCode())) { | |||||
queryWrapper.and(x -> x.eq("id", authCodeQueryDTO.getAuthCode()).or().like("authCOde", authCodeQueryDTO.getAuthCode())); | |||||
if (StringUtils.isNotEmpty(authCodeQueryDTO.getKeyword())) { | |||||
queryWrapper.and(x -> x.eq("id", authCodeQueryDTO.getKeyword()).or().like("authCOde", authCodeQueryDTO.getKeyword())); | |||||
} | } | ||||
//排序 | //排序 | ||||
@@ -0,0 +1,223 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.service.impl; | |||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import org.apache.commons.collections4.CollectionUtils; | |||||
import org.dubhe.admin.dao.GpuResourceMapper; | |||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.domain.entity.GpuResource; | |||||
import org.dubhe.admin.domain.vo.GpuResourceQueryVO; | |||||
import org.dubhe.admin.service.GpuResourceService; | |||||
import org.dubhe.admin.service.UserService; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.dubhe.biz.base.context.UserContext; | |||||
import org.dubhe.biz.base.exception.BusinessException; | |||||
import org.dubhe.biz.base.service.UserContextService; | |||||
import org.dubhe.biz.base.utils.StringUtils; | |||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.dubhe.biz.base.vo.UserGpuConfigVO; | |||||
import org.dubhe.biz.db.utils.PageUtil; | |||||
import org.dubhe.biz.log.enums.LogEnum; | |||||
import org.dubhe.biz.log.utils.LogUtil; | |||||
import org.springframework.beans.BeanUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.util.*; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* @description GPU资源管理 | |||||
* @date 2021-08-20 | |||||
*/ | |||||
@Service | |||||
public class GpuResourceServiceImpl implements GpuResourceService { | |||||
@Autowired | |||||
private GpuResourceMapper gpuResourceMapper; | |||||
@Autowired | |||||
private UserContextService userContextService; | |||||
@Autowired | |||||
private UserService userService; | |||||
/** | |||||
* 查询GPU资源 | |||||
* @param gpuResourceQueryDTO 查询GPU资源请求实体 | |||||
* @return List<GpuResource> gpuResourceSpecs GPU资源列表 | |||||
*/ | |||||
@Override | |||||
public Map<String, Object> getGpuResource(GpuResourceQueryDTO gpuResourceQueryDTO) { | |||||
Page page = gpuResourceQueryDTO.toPage(); | |||||
//排序字段 | |||||
String sort = null == gpuResourceQueryDTO.getSort() ? StringConstant.ID : gpuResourceQueryDTO.getSort(); | |||||
QueryWrapper<GpuResource> queryResourceWrapper = new QueryWrapper<>(); | |||||
queryResourceWrapper.eq(gpuResourceQueryDTO.getGpuType() != null, "gpu_type", gpuResourceQueryDTO.getGpuType()); | |||||
if (StringConstant.SORT_ASC.equals(gpuResourceQueryDTO.getOrder())) { | |||||
queryResourceWrapper.orderByAsc(StringUtils.humpToLine(sort)); | |||||
} else { | |||||
queryResourceWrapper.orderByDesc(StringUtils.humpToLine(sort)); | |||||
} | |||||
Page<GpuResource> pageGpuResourceResult = gpuResourceMapper.selectPage(page, queryResourceWrapper); | |||||
//结果集处理 | |||||
//查询结果数 | |||||
page.setTotal(pageGpuResourceResult.getTotal()); | |||||
List<GpuResource> gpuResource = pageGpuResourceResult.getRecords(); | |||||
List<GpuResourceQueryVO> gpuResourceQueryVOS = new ArrayList<>(); | |||||
if (CollectionUtils.isNotEmpty(gpuResource)) { | |||||
gpuResourceQueryVOS = gpuResource.stream().map(x -> { | |||||
GpuResourceQueryVO gpuResourceQueryVO = new GpuResourceQueryVO(); | |||||
BeanUtils.copyProperties(x, gpuResourceQueryVO); | |||||
return gpuResourceQueryVO; | |||||
}).collect(Collectors.toList()); | |||||
} | |||||
return PageUtil.toPage(page, gpuResourceQueryVOS); | |||||
} | |||||
/** | |||||
* 新增GPU资源 | |||||
* @param gpuResourceCreateDTO 新增GPU资源实体 | |||||
* @return List<Long> 新增GPU资源id | |||||
*/ | |||||
@Override | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public List<Long> create(GpuResourceCreateDTO gpuResourceCreateDTO) { | |||||
UserContext curUser = userContextService.getCurUser(); | |||||
//GPU资源校验 | |||||
QueryWrapper<GpuResource> resourceWrapper = new QueryWrapper<>(); | |||||
resourceWrapper.eq("gpu_type", gpuResourceCreateDTO.getGpuType()) | |||||
.eq("gpu_model", gpuResourceCreateDTO.getGpuModel()); | |||||
if (gpuResourceMapper.selectCount(resourceWrapper) > 0) { | |||||
throw new BusinessException("GPU资源已存在"); | |||||
} | |||||
GpuResource gpuResource = new GpuResource(); | |||||
BeanUtils.copyProperties(gpuResourceCreateDTO, gpuResource); | |||||
try { | |||||
gpuResourceMapper.insert(gpuResource); | |||||
} catch (Exception e) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "The user: {} saved the GpuResource parameters GpuResourceCreateDTO: {} was not successful. Failure reason: {}", curUser.getUsername(), gpuResourceCreateDTO, e); | |||||
throw new BusinessException("内部错误"); | |||||
} | |||||
return Collections.singletonList(gpuResource.getId()); | |||||
} | |||||
/** | |||||
* 修改GPU资源 | |||||
* @param gpuResourceUpdateDTO 修改GPU资源实体 | |||||
* @return List<Long> 修改GPU资源id | |||||
*/ | |||||
@Override | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public List<Long> update(GpuResourceUpdateDTO gpuResourceUpdateDTO) { | |||||
UserContext curUser = userContextService.getCurUser(); | |||||
GpuResource gpuResource = new GpuResource(); | |||||
gpuResource.setId(gpuResourceUpdateDTO.getId()); | |||||
//规格名称校验 | |||||
QueryWrapper<GpuResource> resourceWrapper = new QueryWrapper<>(); | |||||
resourceWrapper.eq("gpu_type", gpuResourceUpdateDTO.getGpuType()) | |||||
.eq("gpu_model", gpuResourceUpdateDTO.getGpuModel()).ne("id", gpuResourceUpdateDTO.getId()); | |||||
if (gpuResourceMapper.selectCount(resourceWrapper) > 0) { | |||||
throw new BusinessException("GPU资源已存在"); | |||||
} | |||||
gpuResource.setGpuType(gpuResourceUpdateDTO.getGpuType()).setGpuModel(gpuResourceUpdateDTO.getGpuModel()).setK8sLabelKey(gpuResourceUpdateDTO.getK8sLabelKey()); | |||||
try { | |||||
gpuResourceMapper.updateById(gpuResource); | |||||
} catch (Exception e) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "The user: {} updated the GpuResource parameters gpuResourceUpdateDTO: {} was not successful. Failure reason :{}", curUser.getUsername(), gpuResourceUpdateDTO, e); | |||||
throw new BusinessException("内部错误"); | |||||
} | |||||
return Collections.singletonList(gpuResource.getId()); | |||||
} | |||||
/** | |||||
* GPU资源删除 | |||||
* @param gpuResourceDeleteDTO GPU资源删除id集合 | |||||
*/ | |||||
@Override | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void delete(GpuResourceDeleteDTO gpuResourceDeleteDTO) { | |||||
UserContext curUser = userContextService.getCurUser(); | |||||
Set<Long> idList = gpuResourceDeleteDTO.getIds(); | |||||
try { | |||||
gpuResourceMapper.deleteBatchIds(idList); | |||||
} catch (Exception e) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "The user: {} Deleted the ResourceSpecs parameters resourceSpecsDeleteDTO: {} was not successful. Failure reason :{}", curUser.getUsername(), gpuResourceDeleteDTO, e); | |||||
throw new BusinessException("内部错误"); | |||||
} | |||||
} | |||||
/** | |||||
* 查询GPU类型 | |||||
* @return List<string> GPU类型列表 | |||||
*/ | |||||
@Override | |||||
public List<String> getGpuType() { | |||||
//查询GPU类型 | |||||
QueryWrapper<GpuResource> queryGpuModelWrapper = new QueryWrapper<>(); | |||||
queryGpuModelWrapper.orderByDesc("id"); | |||||
List<GpuResource> gpuResources = gpuResourceMapper.selectList(queryGpuModelWrapper); | |||||
List<String> gpuTypes = new ArrayList<>(); | |||||
if (CollectionUtils.isNotEmpty(gpuResources)) { | |||||
gpuTypes = gpuResources.stream().map(GpuResource::getGpuType).distinct().collect(Collectors.toList()); | |||||
} | |||||
return gpuTypes; | |||||
} | |||||
/** | |||||
* 查询用户GPU类型 | |||||
* @return List<string> GPU类型列表 | |||||
*/ | |||||
@Override | |||||
public Set<String> getUserGpuType() { | |||||
UserContext curUser = userContextService.getCurUser(); | |||||
UserConfigVO userConfig = userService.findUserConfig(curUser.getId()); | |||||
Set<String> userGpuTypes = new HashSet<>(); | |||||
if (CollectionUtils.isNotEmpty(userConfig.getGpuResources())) { | |||||
for (UserGpuConfigVO userGpuConfig : userConfig.getGpuResources()) { | |||||
if (userGpuConfig.getGpuLimit() > 0) { | |||||
userGpuTypes.add(userGpuConfig.getGpuType()); | |||||
} | |||||
} | |||||
} | |||||
return userGpuTypes; | |||||
} | |||||
/** | |||||
* 根据用户GPU类型查询用户GPU资源 | |||||
* @return List<GpuResource> 用户GPU资源列表 | |||||
*/ | |||||
@Override | |||||
public List<GpuResource> getUserGpuResource(UserGpuResourceQueryDTO userGpuResourceQueryDTO) { | |||||
UserContext curUser = userContextService.getCurUser(); | |||||
UserConfigVO userConfig = userService.findUserConfig(curUser.getId()); | |||||
Set<String> userGpuModels = new HashSet<>(); | |||||
if (CollectionUtils.isNotEmpty(userConfig.getGpuResources())) { | |||||
for (UserGpuConfigVO userGpuConfig : userConfig.getGpuResources()) { | |||||
if (userGpuConfig.getGpuLimit() > 0 && userGpuResourceQueryDTO.getGpuType().equals(userGpuConfig.getGpuType())) { | |||||
userGpuModels.add(userGpuConfig.getGpuModel()); | |||||
} | |||||
} | |||||
} | |||||
QueryWrapper<GpuResource> queryGpuModelWrapper = new QueryWrapper<>(); | |||||
queryGpuModelWrapper.orderByDesc("id").eq("gpu_type", userGpuResourceQueryDTO.getGpuType()).in("gpu_model", userGpuModels); | |||||
return gpuResourceMapper.selectList(queryGpuModelWrapper); | |||||
} | |||||
} |
@@ -15,7 +15,6 @@ | |||||
*/ | */ | ||||
package org.dubhe.admin.service.impl; | package org.dubhe.admin.service.impl; | ||||
import cn.hutool.core.util.ObjectUtil; | |||||
import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||
import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
@@ -27,7 +26,6 @@ import org.dubhe.admin.domain.dto.MenuQueryDTO; | |||||
import org.dubhe.admin.domain.dto.MenuUpdateDTO; | import org.dubhe.admin.domain.dto.MenuUpdateDTO; | ||||
import org.dubhe.admin.domain.dto.RoleSmallDTO; | import org.dubhe.admin.domain.dto.RoleSmallDTO; | ||||
import org.dubhe.admin.domain.entity.Menu; | import org.dubhe.admin.domain.entity.Menu; | ||||
import org.dubhe.admin.domain.vo.MenuMetaVo; | |||||
import org.dubhe.admin.domain.vo.MenuVo; | import org.dubhe.admin.domain.vo.MenuVo; | ||||
import org.dubhe.admin.enums.MenuTypeEnum; | import org.dubhe.admin.enums.MenuTypeEnum; | ||||
import org.dubhe.admin.service.MenuService; | import org.dubhe.admin.service.MenuService; | ||||
@@ -44,6 +42,7 @@ import org.dubhe.biz.log.utils.LogUtil; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import org.springframework.util.CollectionUtils; | |||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
@@ -150,13 +149,13 @@ public class MenuServiceImpl implements MenuService { | |||||
.sort(resources.getSort()) | .sort(resources.getSort()) | ||||
.type(resources.getType()) | .type(resources.getType()) | ||||
.build(); | .build(); | ||||
if(MenuTypeEnum.PAGE_TYPE.getValue().equals(resources.getType())){ | |||||
if (MenuTypeEnum.PAGE_TYPE.getValue().equals(resources.getType()) || MenuTypeEnum.DIR_TYPE.getValue().equals(resources.getType())) { | |||||
menu.setBackTo(resources.getBackTo()); | menu.setBackTo(resources.getBackTo()); | ||||
menu.setExtConfig(resources.getExtConfig()); | menu.setExtConfig(resources.getExtConfig()); | ||||
} | } | ||||
menuMapper.insert(menu); | menuMapper.insert(menu); | ||||
//管理员新增默认权限 | //管理员新增默认权限 | ||||
roleService.tiedRoleMenu(PermissionConstant.ADMIN_ROLE_ID,menu.getId()); | |||||
roleService.tiedRoleMenu(PermissionConstant.ADMIN_ROLE_ID, menu.getId()); | |||||
return menuConvert.toDto(menu); | return menuConvert.toDto(menu); | ||||
} | } | ||||
@@ -202,9 +201,9 @@ public class MenuServiceImpl implements MenuService { | |||||
menu.setHidden(resources.getHidden()); | menu.setHidden(resources.getHidden()); | ||||
menu.setComponentName(resources.getComponentName()); | menu.setComponentName(resources.getComponentName()); | ||||
menu.setPermission(resources.getPermission()); | menu.setPermission(resources.getPermission()); | ||||
if(MenuTypeEnum.PAGE_TYPE.getValue().equals(resources.getType())){ | |||||
if (MenuTypeEnum.PAGE_TYPE.getValue().equals(resources.getType()) || MenuTypeEnum.DIR_TYPE.getValue().equals(resources.getType())) { | |||||
ExtConfigDTO extConfigDTO = analyzeBackToValue(resources.getExtConfig()); | ExtConfigDTO extConfigDTO = analyzeBackToValue(resources.getExtConfig()); | ||||
menu.setBackTo(Objects.isNull(extConfigDTO)?null:extConfigDTO.getBackTo()); | |||||
menu.setBackTo(Objects.isNull(extConfigDTO) ? null : extConfigDTO.getBackTo()); | |||||
menu.setExtConfig(resources.getExtConfig()); | menu.setExtConfig(resources.getExtConfig()); | ||||
} | } | ||||
menuMapper.updateById(menu); | menuMapper.updateById(menu); | ||||
@@ -215,16 +214,16 @@ public class MenuServiceImpl implements MenuService { | |||||
* 解析扩展配置中 backTO 属性值 | * 解析扩展配置中 backTO 属性值 | ||||
* | * | ||||
* @param extConfig 扩展配置 | * @param extConfig 扩展配置 | ||||
* @return ExtConfigDTO扩展配置 | |||||
* @return ExtConfigDTO扩展配置 | |||||
*/ | */ | ||||
private ExtConfigDTO analyzeBackToValue(String extConfig){ | |||||
private ExtConfigDTO analyzeBackToValue(String extConfig) { | |||||
ExtConfigDTO dto = ExtConfigDTO.builder().build(); | ExtConfigDTO dto = ExtConfigDTO.builder().build(); | ||||
try { | try { | ||||
if(!Objects.isNull(extConfig)){ | |||||
if (!Objects.isNull(extConfig)) { | |||||
dto = JSONObject.parseObject(extConfig, ExtConfigDTO.class); | dto = JSONObject.parseObject(extConfig, ExtConfigDTO.class); | ||||
} | } | ||||
}catch (Exception e){ | |||||
LogUtil.error(LogEnum.SYS_ERR,"analyzeBackToValue error, params:{} , error:{}",JSONObject.toJSONString(extConfig),e); | |||||
} catch (Exception e) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "analyzeBackToValue error, params:{} , error:{}", JSONObject.toJSONString(extConfig), e); | |||||
} | } | ||||
return dto; | return dto; | ||||
} | } | ||||
@@ -358,7 +357,7 @@ public class MenuServiceImpl implements MenuService { | |||||
if (menuDTO != null) { | if (menuDTO != null) { | ||||
List<MenuDTO> menuDtoList = menuDTO.getChildren(); | List<MenuDTO> menuDtoList = menuDTO.getChildren(); | ||||
MenuVo menuVo = new MenuVo(); | MenuVo menuVo = new MenuVo(); | ||||
menuVo.setName(ObjectUtil.isNotEmpty(menuDTO.getComponentName()) ? menuDTO.getComponentName() : menuDTO.getName()); | |||||
menuVo.setName(menuDTO.getComponentName()); | |||||
// 一级目录需要加斜杠,不然会报警告 | // 一级目录需要加斜杠,不然会报警告 | ||||
menuVo.setPath(menuDTO.getPid() == 0 ? "/" + menuDTO.getPath() : menuDTO.getPath()); | menuVo.setPath(menuDTO.getPid() == 0 ? "/" + menuDTO.getPath() : menuDTO.getPath()); | ||||
menuVo.setHidden(menuDTO.getHidden()); | menuVo.setHidden(menuDTO.getHidden()); | ||||
@@ -370,7 +369,20 @@ public class MenuServiceImpl implements MenuService { | |||||
menuVo.setComponent(menuDTO.getComponent()); | menuVo.setComponent(menuDTO.getComponent()); | ||||
} | } | ||||
} | } | ||||
menuVo.setMeta(new MenuMetaVo(menuDTO.getName(), menuDTO.getIcon(), menuDTO.getLayout(), !menuDTO.getCache())); | |||||
Map<String, Object> metaMap = new HashMap<>(); | |||||
metaMap.put("title", menuDTO.getName()); | |||||
metaMap.put("icon", menuDTO.getIcon()); | |||||
metaMap.put("layout", menuDTO.getLayout()); | |||||
metaMap.put("noCache", !menuDTO.getCache()); | |||||
if (menuDTO.getExtConfig() != null) { | |||||
Map json = (Map) JSONObject.parse(menuDTO.getExtConfig()); | |||||
if(!CollectionUtils.isEmpty(json)){ | |||||
for (Object key : json.keySet()){ | |||||
metaMap.put(key.toString(),json.get(key)); | |||||
} | |||||
} | |||||
} | |||||
menuVo.setMeta(metaMap); | |||||
if (menuDtoList != null && menuDtoList.size() != 0) { | if (menuDtoList != null && menuDtoList.size() != 0) { | ||||
menuVo.setChildren(buildMenus(menuDtoList)); | menuVo.setChildren(buildMenus(menuDtoList)); | ||||
// 处理是一级菜单并且没有子菜单的情况 | // 处理是一级菜单并且没有子菜单的情况 | ||||
@@ -134,7 +134,7 @@ public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permiss | |||||
Map<String, Object> map = new HashMap<>(2); | Map<String, Object> map = new HashMap<>(2); | ||||
if (trees.size() == 0) { | if (trees.size() == 0) { | ||||
permissions.stream().filter(x -> !ids.contains(x.getId())).collect(Collectors.toList()); | |||||
trees = permissions.stream().filter(x -> !ids.contains(x.getId())).collect(Collectors.toList()); | |||||
} | } | ||||
Map<String, Object> page = new HashMap<>(3); | Map<String, Object> page = new HashMap<>(3); | ||||
@@ -329,7 +329,7 @@ public class RecycleTaskServiceImpl implements RecycleTaskService { | |||||
} | } | ||||
String emptyDir = recycleFileTmpPath + randomPath + File.separator; | String emptyDir = recycleFileTmpPath + randomPath + File.separator; | ||||
LogUtil.debug(LogEnum.GARBAGE_RECYCLE, "recycle task sourcePath:{},emptyDir:{}", sourcePath, emptyDir); | LogUtil.debug(LogEnum.GARBAGE_RECYCLE, "recycle task sourcePath:{},emptyDir:{}", sourcePath, emptyDir); | ||||
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", String.format(ShellFileStoreApiImpl.DEL_COMMAND, userName, ip, emptyDir, emptyDir, sourcePath, emptyDir, sourcePath)}); | |||||
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", String.format(ShellFileStoreApiImpl.DEL_COMMAND, emptyDir, emptyDir, sourcePath, emptyDir, sourcePath)}); | |||||
return processRecycle(process); | return processRecycle(process); | ||||
} else { | } else { | ||||
LogUtil.error(LogEnum.GARBAGE_RECYCLE, "file recycle is failed! sourcePath:{}", sourcePath); | LogUtil.error(LogEnum.GARBAGE_RECYCLE, "file recycle is failed! sourcePath:{}", sourcePath); | ||||
@@ -460,7 +460,7 @@ public class RecycleTaskServiceImpl implements RecycleTaskService { | |||||
String delRealPath = fileStoreApi.formatPath(sourcePath + File.separator + fileName + File.separator + directoryName); | String delRealPath = fileStoreApi.formatPath(sourcePath + File.separator + fileName + File.separator + directoryName); | ||||
delRealPath = delRealPath.endsWith(File.separator) ? delRealPath : delRealPath + File.separator; | delRealPath = delRealPath.endsWith(File.separator) ? delRealPath : delRealPath + File.separator; | ||||
String emptyDir = invalidFileTmpPath + directoryName + File.separator; | String emptyDir = invalidFileTmpPath + directoryName + File.separator; | ||||
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", String.format(ShellFileStoreApiImpl.DEL_COMMAND, userName, ip, emptyDir, emptyDir, delRealPath, emptyDir, delRealPath)}); | |||||
Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", String.format(ShellFileStoreApiImpl.DEL_COMMAND, emptyDir, emptyDir, delRealPath, emptyDir, delRealPath)}); | |||||
Integer deleteStatus = process.waitFor(); | Integer deleteStatus = process.waitFor(); | ||||
LogUtil.info(LogEnum.GARBAGE_RECYCLE, "recycle resources path:{},recycle status:{}", delRealPath, deleteStatus); | LogUtil.info(LogEnum.GARBAGE_RECYCLE, "recycle resources path:{},recycle status:{}", delRealPath, deleteStatus); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
@@ -19,21 +19,27 @@ package org.dubhe.admin.service.impl; | |||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import org.apache.commons.collections4.CollectionUtils; | import org.apache.commons.collections4.CollectionUtils; | ||||
import org.dubhe.admin.client.SystemNodeClient; | |||||
import org.dubhe.admin.dao.ResourceSpecsMapper; | import org.dubhe.admin.dao.ResourceSpecsMapper; | ||||
import org.dubhe.admin.domain.dto.ResourceSpecsCreateDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsDeleteDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsQueryDTO; | |||||
import org.dubhe.admin.domain.dto.ResourceSpecsUpdateDTO; | |||||
import org.dubhe.admin.dao.UserGpuConfigMapper; | |||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.domain.entity.ResourceSpecs; | import org.dubhe.admin.domain.entity.ResourceSpecs; | ||||
import org.dubhe.admin.domain.entity.UserGpuConfig; | |||||
import org.dubhe.admin.domain.vo.ResourceSpecsQueryVO; | import org.dubhe.admin.domain.vo.ResourceSpecsQueryVO; | ||||
import org.dubhe.admin.service.ResourceSpecsService; | import org.dubhe.admin.service.ResourceSpecsService; | ||||
import org.dubhe.admin.service.UserService; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | import org.dubhe.biz.base.constant.StringConstant; | ||||
import org.dubhe.biz.base.context.UserContext; | import org.dubhe.biz.base.context.UserContext; | ||||
import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | import org.dubhe.biz.base.dto.QueryResourceSpecsDTO; | ||||
import org.dubhe.biz.base.dto.QueryUserK8sResourceDTO; | |||||
import org.dubhe.biz.base.exception.BusinessException; | import org.dubhe.biz.base.exception.BusinessException; | ||||
import org.dubhe.biz.base.service.UserContextService; | import org.dubhe.biz.base.service.UserContextService; | ||||
import org.dubhe.biz.base.utils.StringUtils; | import org.dubhe.biz.base.utils.StringUtils; | ||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | import org.dubhe.biz.base.vo.QueryResourceSpecsVO; | ||||
import org.dubhe.biz.base.vo.QueryUserResourceSpecsVO; | |||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.dubhe.biz.db.utils.PageUtil; | import org.dubhe.biz.db.utils.PageUtil; | ||||
import org.dubhe.biz.log.enums.LogEnum; | import org.dubhe.biz.log.enums.LogEnum; | ||||
import org.dubhe.biz.log.utils.LogUtil; | import org.dubhe.biz.log.utils.LogUtil; | ||||
@@ -58,6 +64,15 @@ public class ResourceSpecsServiceImpl implements ResourceSpecsService { | |||||
@Autowired | @Autowired | ||||
private UserContextService userContextService; | private UserContextService userContextService; | ||||
@Autowired | |||||
private UserService userService; | |||||
@Autowired | |||||
private SystemNodeClient systemNodeClient; | |||||
@Autowired | |||||
private UserGpuConfigMapper userGpuConfigMapper; | |||||
/** | /** | ||||
* 查询资源规格 | * 查询资源规格 | ||||
* @param resourceSpecsQueryDTO 查询资源规格请求实体 | * @param resourceSpecsQueryDTO 查询资源规格请求实体 | ||||
@@ -72,6 +87,13 @@ public class ResourceSpecsServiceImpl implements ResourceSpecsService { | |||||
queryResourceSpecsWrapper.like(resourceSpecsQueryDTO.getSpecsName() != null, "specs_name", resourceSpecsQueryDTO.getSpecsName()) | queryResourceSpecsWrapper.like(resourceSpecsQueryDTO.getSpecsName() != null, "specs_name", resourceSpecsQueryDTO.getSpecsName()) | ||||
.eq(resourceSpecsQueryDTO.getResourcesPoolType() != null, "resources_pool_type", resourceSpecsQueryDTO.getResourcesPoolType()) | .eq(resourceSpecsQueryDTO.getResourcesPoolType() != null, "resources_pool_type", resourceSpecsQueryDTO.getResourcesPoolType()) | ||||
.eq(resourceSpecsQueryDTO.getModule() != null, "module", resourceSpecsQueryDTO.getModule()); | .eq(resourceSpecsQueryDTO.getModule() != null, "module", resourceSpecsQueryDTO.getModule()); | ||||
if (resourceSpecsQueryDTO.getMultiGpu() != null) { | |||||
if (resourceSpecsQueryDTO.getMultiGpu()) { | |||||
queryResourceSpecsWrapper.gt("gpu_num", MagicNumConstant.ONE); | |||||
} else { | |||||
queryResourceSpecsWrapper.eq("gpu_num", MagicNumConstant.ONE); | |||||
} | |||||
} | |||||
if (StringConstant.SORT_ASC.equals(resourceSpecsQueryDTO.getOrder())) { | if (StringConstant.SORT_ASC.equals(resourceSpecsQueryDTO.getOrder())) { | ||||
queryResourceSpecsWrapper.orderByAsc(StringUtils.humpToLine(sort)); | queryResourceSpecsWrapper.orderByAsc(StringUtils.humpToLine(sort)); | ||||
} else { | } else { | ||||
@@ -206,4 +228,100 @@ public class ResourceSpecsServiceImpl implements ResourceSpecsService { | |||||
BeanUtils.copyProperties(resourceSpecs, queryResourceSpecsVO); | BeanUtils.copyProperties(resourceSpecs, queryResourceSpecsVO); | ||||
return queryResourceSpecsVO; | return queryResourceSpecsVO; | ||||
} | } | ||||
/** | |||||
* 查询用户资源规格 | |||||
* @param queryUserResourceSpecsDTO 查询用户资源规格请求实体 | |||||
* @return List<QueryUserResourceSpecsVO> 用户资源规格返回结果实体类集合 | |||||
*/ | |||||
@Override | |||||
public List<QueryUserResourceSpecsVO> getUserResourceSpecs(QueryUserResourceSpecsDTO queryUserResourceSpecsDTO) { | |||||
Long userId; | |||||
if (queryUserResourceSpecsDTO.getUserId() == null) { | |||||
userId = userContextService.getCurUser().getId(); | |||||
} else { | |||||
userId = queryUserResourceSpecsDTO.getUserId(); | |||||
} | |||||
UserConfigVO userConfig = userService.findUserConfig(userId); | |||||
if (queryUserResourceSpecsDTO.getResourcesPoolNode() == null) { | |||||
queryUserResourceSpecsDTO.setResourcesPoolNode(MagicNumConstant.ONE); | |||||
} | |||||
QueryWrapper<ResourceSpecs> queryResourceSpecsWrapper = new QueryWrapper<>(); | |||||
queryResourceSpecsWrapper.eq("module", queryUserResourceSpecsDTO.getModule()).eq("resources_pool_type", queryUserResourceSpecsDTO.getResourcesPoolType()) | |||||
.le("cpu_num", userConfig.getCpuLimit()).le("mem_num", userConfig.getMemoryLimit() * MagicNumConstant.ONE_THOUSAND_TWENTY_FOUR); | |||||
if (queryUserResourceSpecsDTO.getResourcesPoolType()) { | |||||
if (queryUserResourceSpecsDTO.getGpuModel() == null || queryUserResourceSpecsDTO.getK8sLabelKey() == null) { | |||||
throw new BusinessException("传参错误"); | |||||
} | |||||
UserGpuConfig userGpuConfig = userGpuConfigMapper.selectOne(new QueryWrapper<>(new UserGpuConfig().setUserId(userId).setGpuModel(queryUserResourceSpecsDTO.getGpuModel()) | |||||
.setK8sLabelKey(queryUserResourceSpecsDTO.getK8sLabelKey())).last(" limit 1 ")); | |||||
Integer gpuLimit = null; | |||||
if (userGpuConfig != null) { | |||||
gpuLimit = userGpuConfig.getGpuLimit(); | |||||
} | |||||
// 如果老用户未初始化GPU配置,则设置默认配置 | |||||
if (userGpuConfig == null && userGpuConfigMapper.selectCountByUserId(userId) == 0) { | |||||
UserGpuConfig preUserGpuConfig = userGpuConfigMapper.selectOne(new QueryWrapper<>(new UserGpuConfig().setUserId(0L).setGpuModel(queryUserResourceSpecsDTO.getGpuModel()).setK8sLabelKey(queryUserResourceSpecsDTO.getK8sLabelKey()))); | |||||
if (preUserGpuConfig != null) { | |||||
gpuLimit = preUserGpuConfig.getGpuLimit(); | |||||
} | |||||
} | |||||
if (gpuLimit != null) { | |||||
queryResourceSpecsWrapper.le("gpu_num", gpuLimit); | |||||
} | |||||
} | |||||
if (queryUserResourceSpecsDTO.getMultiGpu() != null) { | |||||
if (queryUserResourceSpecsDTO.getMultiGpu()) { | |||||
queryResourceSpecsWrapper.gt("gpu_num", MagicNumConstant.ONE); | |||||
} else { | |||||
queryResourceSpecsWrapper.eq("gpu_num", MagicNumConstant.ONE); | |||||
} | |||||
} | |||||
queryResourceSpecsWrapper.orderByAsc("cpu_num"); | |||||
List<ResourceSpecs> resourceSpecs = resourceSpecsMapper.selectList(queryResourceSpecsWrapper); | |||||
List<QueryUserResourceSpecsVO> queryUserResourceSpecsVOS = new ArrayList<>(); | |||||
List<QueryUserK8sResourceDTO> QueryUserK8sResources = new ArrayList<>(); | |||||
if (CollectionUtils.isNotEmpty(resourceSpecs)) { | |||||
QueryUserK8sResources = resourceSpecs.stream().map(x -> { | |||||
QueryUserK8sResourceDTO queryUserK8sResourceDTO = new QueryUserK8sResourceDTO(); | |||||
BeanUtils.copyProperties(x, queryUserK8sResourceDTO); | |||||
queryUserK8sResourceDTO.setUserId(userId).setResourcesPoolNode(queryUserResourceSpecsDTO.getResourcesPoolNode()); | |||||
if (queryUserResourceSpecsDTO.getResourcesPoolType()) { | |||||
queryUserK8sResourceDTO.setGpuModel(queryUserResourceSpecsDTO.getGpuModel()).setK8sLabelKey(queryUserResourceSpecsDTO.getK8sLabelKey()); | |||||
} | |||||
return queryUserK8sResourceDTO; | |||||
}).collect(Collectors.toList()); | |||||
} | |||||
//过滤k8s集群资源 | |||||
if (CollectionUtils.isNotEmpty(QueryUserK8sResources)) { | |||||
DataResponseBody<List<QueryUserResourceSpecsVO>> dataResponseBody = systemNodeClient.queryUserK8sResource(QueryUserK8sResources); | |||||
if (!dataResponseBody.succeed()) { | |||||
throw new BusinessException("dubhe-k8s服务调用异常,查询集群资源是否可用失败"); | |||||
} | |||||
return dataResponseBody.getData(); | |||||
} | |||||
return queryUserResourceSpecsVOS; | |||||
} | |||||
/** | |||||
* 查询资源规格 | |||||
* @param id 资源规格id | |||||
* @return QueryResourceSpecsVO 资源规格返回结果实体类 | |||||
*/ | |||||
@Override | |||||
public QueryResourceSpecsVO queryTadlResourceSpecs(Long id) { | |||||
LogUtil.info(LogEnum.BIZ_SYS,"Query resource specification information with resource id:{}",id); | |||||
ResourceSpecs resourceSpecs = resourceSpecsMapper.selectById(id); | |||||
LogUtil.info(LogEnum.BIZ_SYS,"Obtain resource specification information:{} ",resourceSpecs); | |||||
if (resourceSpecs == null) { | |||||
throw new BusinessException("资源规格不存在或已被删除"); | |||||
} | |||||
QueryResourceSpecsVO queryResourceSpecsVO = new QueryResourceSpecsVO(); | |||||
BeanUtils.copyProperties(resourceSpecs, queryResourceSpecsVO); | |||||
LogUtil.info(LogEnum.BIZ_SYS,"Return resource specification information :{} ",queryResourceSpecsVO); | |||||
return queryResourceSpecsVO; | |||||
} | |||||
} | } |
@@ -22,6 +22,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||||
import com.baomidou.mybatisplus.core.metadata.IPage; | import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import org.dubhe.admin.dao.UserGroupMapper; | import org.dubhe.admin.dao.UserGroupMapper; | ||||
import org.dubhe.admin.dao.UserMapper; | |||||
import org.dubhe.admin.dao.UserRoleMapper; | import org.dubhe.admin.dao.UserRoleMapper; | ||||
import org.dubhe.admin.domain.dto.*; | import org.dubhe.admin.domain.dto.*; | ||||
import org.dubhe.admin.domain.entity.Group; | import org.dubhe.admin.domain.entity.Group; | ||||
@@ -32,6 +33,7 @@ import org.dubhe.admin.service.UserGroupService; | |||||
import org.dubhe.admin.service.UserService; | import org.dubhe.admin.service.UserService; | ||||
import org.dubhe.biz.base.constant.StringConstant; | import org.dubhe.biz.base.constant.StringConstant; | ||||
import org.dubhe.biz.base.context.UserContext; | import org.dubhe.biz.base.context.UserContext; | ||||
import org.dubhe.biz.base.dto.UserConfigSaveDTO; | |||||
import org.dubhe.biz.base.exception.BusinessException; | import org.dubhe.biz.base.exception.BusinessException; | ||||
import org.dubhe.biz.base.service.UserContextService; | import org.dubhe.biz.base.service.UserContextService; | ||||
import org.dubhe.biz.base.utils.ReflectionUtils; | import org.dubhe.biz.base.utils.ReflectionUtils; | ||||
@@ -39,9 +41,12 @@ import org.dubhe.biz.base.utils.StringUtils; | |||||
import org.dubhe.biz.db.utils.PageUtil; | import org.dubhe.biz.db.utils.PageUtil; | ||||
import org.dubhe.biz.log.enums.LogEnum; | import org.dubhe.biz.log.enums.LogEnum; | ||||
import org.dubhe.biz.log.utils.LogUtil; | import org.dubhe.biz.log.utils.LogUtil; | ||||
import org.dubhe.cloud.authconfig.factory.PasswordEncoderFactory; | |||||
import org.springframework.beans.BeanUtils; | import org.springframework.beans.BeanUtils; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.dao.DuplicateKeyException; | import org.springframework.dao.DuplicateKeyException; | ||||
import org.springframework.security.crypto.password.PasswordEncoder; | |||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
@@ -55,9 +60,15 @@ import java.util.stream.Collectors; | |||||
@Service | @Service | ||||
public class UserGroupServiceImpl implements UserGroupService { | public class UserGroupServiceImpl implements UserGroupService { | ||||
@Value("${initial_password}") | |||||
private String initialPassword; | |||||
@Autowired | @Autowired | ||||
private UserGroupMapper userGroupMapper; | private UserGroupMapper userGroupMapper; | ||||
@Autowired | |||||
private UserMapper userMapper; | |||||
@Autowired | @Autowired | ||||
private UserContextService userContextService; | private UserContextService userContextService; | ||||
@@ -248,7 +259,7 @@ public class UserGroupServiceImpl implements UserGroupService { | |||||
* @param userGroupUpdDTO 批量删除用户组用户DTO | * @param userGroupUpdDTO 批量删除用户组用户DTO | ||||
*/ | */ | ||||
@Override | @Override | ||||
public void delUser(UserGroupUpdDTO userGroupUpdDTO) { | |||||
public void delUser(UserGroupUpdDTO userGroupUpdDTO, String accessToken) { | |||||
//获取用户组的成员id | //获取用户组的成员id | ||||
List<User> userList = userGroupMapper.queryUserByGroupId(userGroupUpdDTO.getGroupId()); | List<User> userList = userGroupMapper.queryUserByGroupId(userGroupUpdDTO.getGroupId()); | ||||
userGroupMapper.delUserByGroupId(userGroupUpdDTO.getGroupId()); | userGroupMapper.delUserByGroupId(userGroupUpdDTO.getGroupId()); | ||||
@@ -258,7 +269,7 @@ public class UserGroupServiceImpl implements UserGroupService { | |||||
ids.add(user.getId()); | ids.add(user.getId()); | ||||
} | } | ||||
} | } | ||||
userService.delete(ids); | |||||
userService.delete(ids, accessToken); | |||||
} | } | ||||
/** | /** | ||||
@@ -289,4 +300,45 @@ public class UserGroupServiceImpl implements UserGroupService { | |||||
//添加用户的新角色 | //添加用户的新角色 | ||||
userRoleMapper.insertBatchs(userRoleList); | userRoleMapper.insertBatchs(userRoleList); | ||||
} | } | ||||
/** | |||||
* 批量重置用户组用户的密码 | |||||
* | |||||
* @param groupId | |||||
*/ | |||||
@Override | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void resetUserPassword(Long groupId) { | |||||
//获取用户组的成员id | |||||
List<User> userList = userGroupMapper.queryUserByGroupId(groupId); | |||||
Set<Long> ids = new HashSet<>(); | |||||
if (CollUtil.isNotEmpty(userList)) { | |||||
for (User user : userList) { | |||||
ids.add(user.getId()); | |||||
} | |||||
} | |||||
PasswordEncoder passwordEncoder = PasswordEncoderFactory.getPasswordEncoder(); | |||||
//重置为默认密码123456,加密密码 | |||||
String encode = passwordEncoder.encode(initialPassword); | |||||
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>(); | |||||
updateWrapper.in(User::getId, ids); | |||||
updateWrapper.set(User::getPassword,encode); | |||||
updateWrapper.set(User::getLastPasswordResetTime,new Date()); | |||||
userService.update(updateWrapper); | |||||
} | |||||
@Override | |||||
public void saveUserConfig(UserGroupConfigSaveDTO userGroupConfigSaveDTO) { | |||||
UserConfigSaveDTO userConfigSaveDTO = new UserConfigSaveDTO(); | |||||
BeanUtils.copyProperties(userGroupConfigSaveDTO,userConfigSaveDTO); | |||||
List<User> users = userGroupMapper.queryUserByGroupId(userGroupConfigSaveDTO.getGroupId()); | |||||
if(CollUtil.isNotEmpty(users)) { | |||||
users.forEach(user -> { | |||||
userConfigSaveDTO.setUserId(user.getId()); | |||||
userService.saveUserConfig(userConfigSaveDTO,null); | |||||
}); | |||||
} | |||||
} | |||||
} | } |
@@ -0,0 +1,314 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.admin.service.impl; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||||
import com.google.common.collect.Maps; | |||||
import org.dubhe.admin.client.ResourceNamespaceClient; | |||||
import org.dubhe.admin.dao.UserConfigMapper; | |||||
import org.dubhe.admin.dao.UserGpuConfigMapper; | |||||
import org.dubhe.admin.dao.UserMapper; | |||||
import org.dubhe.admin.domain.dto.UserResourceListDTO; | |||||
import org.dubhe.admin.domain.dto.UserResourceQueryDTO; | |||||
import org.dubhe.admin.domain.entity.UserConfig; | |||||
import org.dubhe.admin.domain.entity.UserGpuConfig; | |||||
import org.dubhe.admin.domain.vo.UserLimitConfigVO; | |||||
import org.dubhe.admin.domain.vo.UserResourceResVO; | |||||
import org.dubhe.admin.enums.ResourceTypeEnum; | |||||
import org.dubhe.admin.enums.StatTypeEnum; | |||||
import org.dubhe.admin.service.UserResourceService; | |||||
import org.dubhe.biz.base.constant.NumberConstant; | |||||
import org.dubhe.biz.base.constant.StringConstant; | |||||
import org.dubhe.biz.base.constant.SymbolConstant; | |||||
import org.dubhe.biz.base.constant.UserConstant; | |||||
import org.dubhe.biz.base.exception.BusinessException; | |||||
import org.dubhe.biz.base.utils.MathUtils; | |||||
import org.dubhe.biz.base.vo.DataResponseBody; | |||||
import org.dubhe.biz.base.vo.GpuAllotVO; | |||||
import org.dubhe.biz.base.vo.UserAllotVO; | |||||
import org.dubhe.biz.db.utils.PageUtil; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Service; | |||||
import java.util.ArrayList; | |||||
import java.util.EnumSet; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* @description 用户资源统计实现层 | |||||
* @date 2021-11-23 | |||||
*/ | |||||
@Service | |||||
public class UserResourceServiceImpl implements UserResourceService { | |||||
@Autowired | |||||
private UserConfigMapper userConfigMapper; | |||||
@Autowired | |||||
private UserGpuConfigMapper userGpuConfigMapper; | |||||
@Autowired | |||||
private ResourceNamespaceClient resourceNamespaceClient; | |||||
@Autowired | |||||
private UserMapper userMapper; | |||||
private Map<String, Map<Long, String>> gpuMap = Maps.newHashMap(); | |||||
private Map<String, Map<Long, String>> cpuMap = Maps.newHashMap(); | |||||
private Map<String, Map<Long, String>> memMap = Maps.newHashMap(); | |||||
private Map<Long, UserAllotVO> gpuAllotMap = Maps.newHashMap(); | |||||
private final static List<String> SUMDAYS = new ArrayList(); | |||||
static { | |||||
SUMDAYS.add(UserConstant.UNIT_7D); | |||||
SUMDAYS.add(UserConstant.UNIT_15D); | |||||
} | |||||
/** | |||||
* 用户资源Top10统计 | |||||
* | |||||
* @param resourceQueryDTO 请求DTO实体 | |||||
* @return List<UserAllotVO> 用户Top10资源列表 | |||||
*/ | |||||
@Override | |||||
public List<UserAllotVO> getResourceTotal(UserResourceQueryDTO resourceQueryDTO) { | |||||
List<UserAllotVO> userAllotList; | |||||
//获取资源配额 | |||||
if (resourceQueryDTO.getStatType().equals(StatTypeEnum.ALLOT_TYPE.getCode())) { | |||||
userAllotList = toResourceAllot(resourceQueryDTO); | |||||
} else { | |||||
userAllotList = toResourceUsage(resourceQueryDTO); | |||||
} | |||||
return userAllotList; | |||||
} | |||||
/** | |||||
* 用户资源统计 | |||||
* | |||||
* @return List<UserResourceResVO> 用户资源统计列表VO | |||||
*/ | |||||
@Override | |||||
public Map<String, Object> getResourceList(UserResourceListDTO resourceListDTO) { | |||||
List<UserResourceResVO> userResourceResList = new ArrayList<>(); | |||||
Page page = resourceListDTO.toPage(); | |||||
String sort = StrUtil.isEmpty(resourceListDTO.getSort()) ? ResourceTypeEnum.GPU_TYPE.getDesc() : resourceListDTO.getSort(); | |||||
String order = StrUtil.isEmpty(resourceListDTO.getOrder()) ? StringConstant.SORT_DESC : resourceListDTO.getOrder(); | |||||
List<UserLimitConfigVO> userLimitConfigs = userConfigMapper.selectLimitSum(page, sort, order); | |||||
List<Long> userIds = userLimitConfigs.stream().map(UserLimitConfigVO::getUserId).collect(Collectors.toList()); | |||||
String namespaces = userIds.stream().map(id -> UserConstant.NAMESPACE_PREFIX + id).collect(Collectors.joining("|")); | |||||
//查询gpu具体型号的配额 | |||||
toGpuAllotMap(userIds); | |||||
//查询不同条件下的资源使用峰值 | |||||
SUMDAYS.stream().forEach(day -> { | |||||
EnumSet.allOf(ResourceTypeEnum.class).forEach(code -> { | |||||
toResourceUsageMap(code.getCode(), day, namespaces); | |||||
}); | |||||
}); | |||||
for (UserLimitConfigVO userLimitConfig : userLimitConfigs) { | |||||
UserResourceResVO userResourceRes = new UserResourceResVO(); | |||||
userResourceRes.setId(userLimitConfig.getUserId()) | |||||
.setUserName(userLimitConfig.getUserName()) | |||||
.setNickName(userLimitConfig.getNickName()) | |||||
.setGpu(userLimitConfig.getGpu()) | |||||
.setCpu(userLimitConfig.getCpu()) | |||||
.setMem(userLimitConfig.getMem()); | |||||
if (gpuAllotMap.containsKey(userLimitConfig.getUserId())) { | |||||
userResourceRes.setGpuModelAllots(new ArrayList<>()); | |||||
} else { | |||||
userResourceRes.setGpuModelAllots(gpuAllotMap.get(userLimitConfig.getUserId()).getGpuAllotList()); | |||||
} | |||||
userResourceRes.setGpu7unit(gpuMap.get(UserConstant.UNIT_7D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO)); | |||||
userResourceRes.setGpu15unit(gpuMap.get(UserConstant.UNIT_15D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO)); | |||||
userResourceRes.setGpu7(MathUtils.floatDivision(userResourceRes.getGpu7unit(), userResourceRes.getGpu(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setGpu15(MathUtils.floatDivision(userResourceRes.getGpu15unit(), userResourceRes.getGpu(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setCpu7unit(MathUtils.floatDivision(cpuMap.get(UserConstant.UNIT_7D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO), SymbolConstant.ONE, NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setCpu15unit(MathUtils.floatDivision(cpuMap.get(UserConstant.UNIT_15D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO), SymbolConstant.ONE, NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setCpu7(MathUtils.floatDivision(userResourceRes.getCpu7unit(), userResourceRes.getCpu(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setCpu15(MathUtils.floatDivision(userResourceRes.getCpu15unit(), userResourceRes.getCpu(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setMem7unit(MathUtils.floatDivision(memMap.get(UserConstant.UNIT_7D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO), StringConstant.MEM_UNIT, NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setMem15unit(MathUtils.floatDivision(memMap.get(UserConstant.UNIT_15D).getOrDefault(userLimitConfig.getUserId(), SymbolConstant.ZERO), StringConstant.MEM_UNIT, NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setMem7(MathUtils.floatDivision(userResourceRes.getMem7unit(), userResourceRes.getMem(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceRes.setMem15(MathUtils.floatDivision(userResourceRes.getMem15unit(), userResourceRes.getMem(), NumberConstant.NUMBER_2).toString()); | |||||
userResourceResList.add(userResourceRes); | |||||
} | |||||
return PageUtil.toPage(page, userResourceResList); | |||||
} | |||||
/** | |||||
* 根据namespace-userId批量查询资源用量峰值 | |||||
* | |||||
* @param resourceType 资源类型 | |||||
* @param sumDay 查询周期 | |||||
* @param namespaces 拼接的namespace字符串,例:namespace-1 | namespace-2 | namespace-3 | |||||
*/ | |||||
private void toResourceUsageMap(Integer resourceType, String sumDay, String namespaces) { | |||||
DataResponseBody<Map<Long, String>> result = resourceNamespaceClient.getResourceUsageByUser(resourceType, sumDay, namespaces); | |||||
if (!result.succeed()) { | |||||
throw new BusinessException("查询某用户用量峰值远程调用失败"); | |||||
} | |||||
if (resourceType.equals(ResourceTypeEnum.GPU_TYPE.getCode())) { | |||||
gpuMap.put(sumDay, result.getData()); | |||||
} else if (resourceType.equals(ResourceTypeEnum.CPU_TYPE.getCode())) { | |||||
cpuMap.put(sumDay, result.getData()); | |||||
} else if (resourceType.equals(ResourceTypeEnum.MEMORY_TYPE.getCode())) { | |||||
memMap.put(sumDay, result.getData()); | |||||
} | |||||
} | |||||
/** | |||||
* 统计用户GPU具体型号的配额 | |||||
* | |||||
* @param userIds 用户id集合 | |||||
*/ | |||||
private void toGpuAllotMap(List<Long> userIds) { | |||||
//按型号获取gpu分配总量 | |||||
List<UserGpuConfig> userGpuConfigs = userGpuConfigMapper.selectList(new LambdaQueryWrapper<UserGpuConfig>().in(UserGpuConfig::getUserId, userIds)); | |||||
for (Long userId : userIds) { | |||||
UserAllotVO userAllotVO = new UserAllotVO(); | |||||
List<GpuAllotVO> gpuAllots = new ArrayList<>(); | |||||
for (UserGpuConfig gpuConfig : userGpuConfigs) { | |||||
if (userId.equals(gpuConfig.getUserId())) { | |||||
GpuAllotVO gpuAllotVO = new GpuAllotVO(); | |||||
gpuAllotVO.setGpuModel(gpuConfig.getGpuModel()); | |||||
gpuAllotVO.setAllotTotal(gpuConfig.getGpuLimit()); | |||||
gpuAllots.add(gpuAllotVO); | |||||
userAllotVO.setAllotTotal(MathUtils.add(userAllotVO.getAllotTotal(), gpuConfig.getGpuLimit().toString())); | |||||
userAllotVO.setUserId(gpuConfig.getUserId()); | |||||
userAllotVO.setGpuAllotList(gpuAllots); | |||||
} | |||||
} | |||||
gpuAllotMap.put(userId, userAllotVO); | |||||
} | |||||
} | |||||
/** | |||||
* 远程调用prometheus统计用户资源使用峰值 | |||||
* | |||||
* @param resourceQueryDTO 查询DTO实体 | |||||
* @return List<UserAllotVO> GPU型号资源配额列表 | |||||
*/ | |||||
private List<UserAllotVO> toResourceUsage(UserResourceQueryDTO resourceQueryDTO) { | |||||
List<UserAllotVO> userAllotList = new ArrayList<>(); | |||||
DataResponseBody<List<UserAllotVO>> result = resourceNamespaceClient.getResourceNamespace(resourceQueryDTO.getResourceType(), resourceQueryDTO.getSumDay()); | |||||
if (!result.succeed()) { | |||||
throw new BusinessException("查询用户用量峰值远程调用失败"); | |||||
} | |||||
if (CollUtil.isNotEmpty(result.getData())) { | |||||
userAllotList = result.getData().stream().map(userAllotVO -> { | |||||
Long userId = Long.valueOf(userAllotVO.getUserName().replaceAll(UserConstant.NAMESPACE_PREFIX, StrUtil.EMPTY)); | |||||
userAllotVO.setUserName(userMapper.findUserNameById(userId)); | |||||
userAllotVO.setUserId(userId); | |||||
if (!resourceQueryDTO.getResourceType().equals(ResourceTypeEnum.GPU_TYPE.getCode())) { | |||||
userAllotVO.setAllotTotal(MathUtils.floatDivision(userAllotVO.getAllotTotal(), StringConstant.MEM_UNIT, 2).toString()); | |||||
} else { | |||||
userAllotVO.setAllotTotal(userAllotVO.getAllotTotal()); | |||||
} | |||||
return userAllotVO; | |||||
}).collect(Collectors.toList()); | |||||
} | |||||
if (resourceQueryDTO.getStatType().equals(StatTypeEnum.USAGE_RATE_TYPE.getCode())) { | |||||
userAllotList = toUserAllotById(resourceQueryDTO.getResourceType(), userAllotList); | |||||
} | |||||
return userAllotList; | |||||
} | |||||
/** | |||||
* TOP10资源统计配额 | |||||
* | |||||
* @param resourceQueryDTO 用户资源统计DTO | |||||
* @return List<UserAllotVO> 用户Top10资源列表 | |||||
*/ | |||||
private List<UserAllotVO> toResourceAllot(UserResourceQueryDTO resourceQueryDTO) { | |||||
List<UserAllotVO> userAllotList = new ArrayList<>(); | |||||
switch (resourceQueryDTO.getResourceType()) { | |||||
case 2: | |||||
userAllotList = userConfigMapper.selectCpuAllotTotal(); | |||||
break; | |||||
case 3: | |||||
userAllotList = userConfigMapper.selectMemoryAllotTotal(); | |||||
break; | |||||
case 1: | |||||
List<UserGpuConfig> gpuConfigList = userGpuConfigMapper.selectAllotTotal(); | |||||
for (UserGpuConfig gpuConfig : gpuConfigList) { | |||||
UserAllotVO userAllotVO = new UserAllotVO(); | |||||
userAllotVO.setUserName(gpuConfig.getUserName()); | |||||
userAllotVO.setAllotTotal(gpuConfig.getGpuLimit().toString()); | |||||
userAllotVO.setGpuAllotList(userGpuConfigMapper.selectGpuModelTotal(gpuConfig.getUserId())); | |||||
userAllotList.add(userAllotVO); | |||||
} | |||||
default: | |||||
break; | |||||
} | |||||
return userAllotList; | |||||
} | |||||
/** | |||||
* 用户资源配额统计 | |||||
* | |||||
* @param resourceType 资源类型 | |||||
* @param userAllotList 用户Top10资源列表 | |||||
* @return List<UserAllotVO> 用户Top10资源列表 | |||||
*/ | |||||
private List<UserAllotVO> toUserAllotById(Integer resourceType, List<UserAllotVO> userAllotList) { | |||||
switch (resourceType) { | |||||
//GPU配额总量 | |||||
case 1: | |||||
userAllotList = userAllotList.stream().map(userAllotVO -> { | |||||
int gpuSum = userGpuConfigMapper.selectGpuLimitSum(userAllotVO.getUserId()); | |||||
userAllotVO.setAllotTotal(MathUtils.floatDivision(userAllotVO.getAllotTotal(), String.valueOf(gpuSum), NumberConstant.NUMBER_2).toString()); | |||||
return userAllotVO; | |||||
}).collect(Collectors.toList()); | |||||
break; | |||||
//CPU配额总量 | |||||
case 2: | |||||
userAllotList = userAllotList.stream().map(userAllotVO -> { | |||||
UserConfig userConfig = userConfigMapper.selectLimitSumByUser(userAllotVO.getUserId()); | |||||
if (userConfig != null) { | |||||
userAllotVO.setAllotTotal(MathUtils.floatDivision(userAllotVO.getAllotTotal(), String.valueOf(userConfig.getCpuLimit()), 2).toString()); | |||||
} | |||||
return userAllotVO; | |||||
}).collect(Collectors.toList()); | |||||
break; | |||||
//内存配额总量 | |||||
case 3: | |||||
userAllotList = userAllotList.stream().map(userAllotVO -> { | |||||
UserConfig userConfig = userConfigMapper.selectLimitSumByUser(userAllotVO.getUserId()); | |||||
if (userConfig != null) { | |||||
userAllotVO.setAllotTotal(MathUtils.floatDivision(userAllotVO.getAllotTotal(), String.valueOf(userConfig.getMemoryLimit()), NumberConstant.NUMBER_2).toString()); | |||||
} | |||||
return userAllotVO; | |||||
}).collect(Collectors.toList()); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return userAllotList; | |||||
} | |||||
} |
@@ -16,6 +16,7 @@ | |||||
*/ | */ | ||||
package org.dubhe.admin.service.impl; | package org.dubhe.admin.service.impl; | ||||
import cn.hutool.core.collection.CollectionUtil; | |||||
import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||
import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||
import cn.hutool.crypto.asymmetric.KeyType; | import cn.hutool.crypto.asymmetric.KeyType; | ||||
@@ -26,18 +27,39 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
import com.baomidou.mybatisplus.core.metadata.IPage; | import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | ||||
import org.dubhe.admin.async.CleanupUserResourcesAsync; | |||||
import org.dubhe.admin.client.AuthServiceClient; | import org.dubhe.admin.client.AuthServiceClient; | ||||
import org.dubhe.admin.client.GpuConfigClient; | |||||
import org.dubhe.admin.client.ResourceQuotaClient; | import org.dubhe.admin.client.ResourceQuotaClient; | ||||
import org.dubhe.admin.dao.*; | |||||
import org.dubhe.admin.domain.dto.*; | |||||
import org.dubhe.admin.client.template.GpuConfigTemplateClient; | |||||
import org.dubhe.admin.client.template.ObtainAccessToken; | |||||
import org.dubhe.admin.client.template.ResourceQuotaTemplateClient; | |||||
import org.dubhe.admin.dao.MenuMapper; | |||||
import org.dubhe.admin.dao.PermissionMapper; | |||||
import org.dubhe.admin.dao.RoleMapper; | |||||
import org.dubhe.admin.dao.TeamMapper; | |||||
import org.dubhe.admin.dao.UserAvatarMapper; | |||||
import org.dubhe.admin.dao.UserConfigMapper; | |||||
import org.dubhe.admin.dao.UserGpuConfigMapper; | |||||
import org.dubhe.admin.dao.UserMapper; | |||||
import org.dubhe.admin.dao.UserRoleMapper; | |||||
import org.dubhe.admin.domain.dto.AuthUserDTO; | |||||
import org.dubhe.admin.domain.dto.EmailDTO; | |||||
import org.dubhe.admin.domain.dto.UserCenterUpdateDTO; | |||||
import org.dubhe.admin.domain.dto.UserCreateDTO; | |||||
import org.dubhe.admin.domain.dto.UserEmailUpdateDTO; | |||||
import org.dubhe.admin.domain.dto.UserQueryDTO; | |||||
import org.dubhe.admin.domain.dto.UserRegisterDTO; | |||||
import org.dubhe.admin.domain.dto.UserRegisterMailDTO; | |||||
import org.dubhe.admin.domain.dto.UserResetPasswordDTO; | |||||
import org.dubhe.admin.domain.dto.UserUpdateDTO; | |||||
import org.dubhe.admin.domain.entity.Role; | import org.dubhe.admin.domain.entity.Role; | ||||
import org.dubhe.admin.domain.entity.User; | import org.dubhe.admin.domain.entity.User; | ||||
import org.dubhe.admin.domain.entity.UserAvatar; | import org.dubhe.admin.domain.entity.UserAvatar; | ||||
import org.dubhe.admin.domain.entity.UserConfig; | import org.dubhe.admin.domain.entity.UserConfig; | ||||
import org.dubhe.admin.domain.entity.UserGpuConfig; | |||||
import org.dubhe.admin.domain.entity.UserRole; | import org.dubhe.admin.domain.entity.UserRole; | ||||
import org.dubhe.admin.domain.vo.EmailVo; | import org.dubhe.admin.domain.vo.EmailVo; | ||||
import org.dubhe.admin.domain.vo.UserConfigCreateVO; | |||||
import org.dubhe.admin.domain.vo.UserConfigVO; | |||||
import org.dubhe.admin.domain.vo.UserVO; | import org.dubhe.admin.domain.vo.UserVO; | ||||
import org.dubhe.admin.enums.UserMailCodeEnum; | import org.dubhe.admin.enums.UserMailCodeEnum; | ||||
import org.dubhe.admin.event.EmailEventPublisher; | import org.dubhe.admin.event.EmailEventPublisher; | ||||
@@ -48,16 +70,29 @@ import org.dubhe.biz.base.constant.AuthConst; | |||||
import org.dubhe.biz.base.constant.ResponseCode; | import org.dubhe.biz.base.constant.ResponseCode; | ||||
import org.dubhe.biz.base.constant.UserConstant; | import org.dubhe.biz.base.constant.UserConstant; | ||||
import org.dubhe.biz.base.context.UserContext; | import org.dubhe.biz.base.context.UserContext; | ||||
import org.dubhe.biz.base.dto.*; | |||||
import org.dubhe.biz.base.dto.GpuConfigDTO; | |||||
import org.dubhe.biz.base.dto.Oauth2TokenDTO; | |||||
import org.dubhe.biz.base.dto.ResourceQuotaDTO; | |||||
import org.dubhe.biz.base.dto.SysPermissionDTO; | |||||
import org.dubhe.biz.base.dto.SysRoleDTO; | |||||
import org.dubhe.biz.base.dto.SysUserConfigDTO; | |||||
import org.dubhe.biz.base.dto.SysUserGpuConfigDTO; | |||||
import org.dubhe.biz.base.dto.TeamDTO; | |||||
import org.dubhe.biz.base.dto.UserConfigSaveDTO; | |||||
import org.dubhe.biz.base.dto.UserDTO; | |||||
import org.dubhe.biz.base.dto.UserGpuConfigDTO; | |||||
import org.dubhe.biz.base.enums.BaseErrorCodeEnum; | import org.dubhe.biz.base.enums.BaseErrorCodeEnum; | ||||
import org.dubhe.biz.base.enums.SwitchEnum; | import org.dubhe.biz.base.enums.SwitchEnum; | ||||
import org.dubhe.biz.base.exception.BusinessException; | import org.dubhe.biz.base.exception.BusinessException; | ||||
import org.dubhe.biz.base.exception.CaptchaException; | import org.dubhe.biz.base.exception.CaptchaException; | ||||
import org.dubhe.biz.base.utils.DateUtil; | |||||
import org.dubhe.biz.base.utils.Md5Util; | import org.dubhe.biz.base.utils.Md5Util; | ||||
import org.dubhe.biz.base.utils.RandomUtil; | import org.dubhe.biz.base.utils.RandomUtil; | ||||
import org.dubhe.biz.base.utils.RsaEncrypt; | import org.dubhe.biz.base.utils.RsaEncrypt; | ||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.base.vo.GpuAllotVO; | |||||
import org.dubhe.biz.base.vo.UserAllotResourceVO; | |||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.dubhe.biz.base.vo.UserGpuConfigVO; | |||||
import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | import org.dubhe.biz.dataresponse.factory.DataResponseFactory; | ||||
import org.dubhe.biz.db.utils.PageUtil; | import org.dubhe.biz.db.utils.PageUtil; | ||||
import org.dubhe.biz.db.utils.WrapperHelp; | import org.dubhe.biz.db.utils.WrapperHelp; | ||||
@@ -65,6 +100,7 @@ import org.dubhe.biz.file.utils.DubheFileUtil; | |||||
import org.dubhe.biz.log.enums.LogEnum; | import org.dubhe.biz.log.enums.LogEnum; | ||||
import org.dubhe.biz.log.utils.LogUtil; | import org.dubhe.biz.log.utils.LogUtil; | ||||
import org.dubhe.biz.permission.annotation.DataPermissionMethod; | import org.dubhe.biz.permission.annotation.DataPermissionMethod; | ||||
import org.dubhe.biz.permission.aspect.PermissionAspect; | |||||
import org.dubhe.biz.redis.utils.RedisUtils; | import org.dubhe.biz.redis.utils.RedisUtils; | ||||
import org.dubhe.cloud.authconfig.dto.JwtUserDTO; | import org.dubhe.cloud.authconfig.dto.JwtUserDTO; | ||||
import org.dubhe.cloud.authconfig.factory.PasswordEncoderFactory; | import org.dubhe.cloud.authconfig.factory.PasswordEncoderFactory; | ||||
@@ -73,15 +109,28 @@ import org.springframework.beans.BeanUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
import org.springframework.cglib.beans.BeanMap; | import org.springframework.cglib.beans.BeanMap; | ||||
import org.springframework.cloud.context.config.annotation.RefreshScope; | |||||
import org.springframework.security.crypto.password.PasswordEncoder; | import org.springframework.security.crypto.password.PasswordEncoder; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
import org.springframework.transaction.support.TransactionSynchronizationAdapter; | |||||
import org.springframework.transaction.support.TransactionSynchronizationManager; | |||||
import org.springframework.util.CollectionUtils; | import org.springframework.util.CollectionUtils; | ||||
import javax.annotation.Resource; | import javax.annotation.Resource; | ||||
import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.*; | |||||
import java.time.Duration; | |||||
import java.time.LocalDate; | |||||
import java.time.LocalDateTime; | |||||
import java.util.ArrayList; | |||||
import java.util.Date; | |||||
import java.util.HashMap; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import java.util.Objects; | |||||
import java.util.Set; | |||||
import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||
/** | /** | ||||
@@ -89,6 +138,7 @@ import java.util.stream.Collectors; | |||||
* @date 2020-11-26 | * @date 2020-11-26 | ||||
*/ | */ | ||||
@Service | @Service | ||||
@RefreshScope | |||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { | public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { | ||||
@Value("${rsa.private_key}") | @Value("${rsa.private_key}") | ||||
@@ -98,7 +148,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
private String initialPassword; | private String initialPassword; | ||||
@Value("${user.config.notebook-delay-delete-time}") | @Value("${user.config.notebook-delay-delete-time}") | ||||
private Integer defaultNotebookDelayDeleteTime; | |||||
private Integer userConfigNotebookDelayDeleteTime; | |||||
@Value("${user.config.cpu-limit}") | @Value("${user.config.cpu-limit}") | ||||
private Integer cpuLimit; | private Integer cpuLimit; | ||||
@@ -106,8 +156,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
@Value("${user.config.memory-limit}") | @Value("${user.config.memory-limit}") | ||||
private Integer memoryLimit; | private Integer memoryLimit; | ||||
@Value("${user.config.gpu-limit}") | |||||
private Integer gpuLimit; | |||||
@Value("${user.config.gpu-limit.gpu-type}") | |||||
private String gpuType; | |||||
@Value("${user.config.gpu-limit.gpu-model}") | |||||
private String gpuModel; | |||||
@Value("${user.config.gpu-limit.k8s-label-key}") | |||||
private String k8sLabelKey; | |||||
@Value("${user.config.gpu-limit.gpu-num-limit}") | |||||
private Integer gpuNumLimit; | |||||
@Autowired | @Autowired | ||||
private UserMapper userMapper; | private UserMapper userMapper; | ||||
@@ -131,7 +190,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
@Autowired | @Autowired | ||||
private UserAvatarMapper userAvatarMapper; | private UserAvatarMapper userAvatarMapper; | ||||
@Autowired | @Autowired | ||||
private RedisUtils redisUtils; | private RedisUtils redisUtils; | ||||
@@ -150,16 +208,35 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
@Autowired | @Autowired | ||||
private UserConfigMapper userConfigMapper; | private UserConfigMapper userConfigMapper; | ||||
@Autowired | |||||
private UserGpuConfigMapper userGpuConfigMapper; | |||||
@Autowired | @Autowired | ||||
ResourceQuotaClient resourceQuotaClient; | ResourceQuotaClient resourceQuotaClient; | ||||
@Autowired | |||||
ResourceQuotaTemplateClient resourceQuotaTemplateClient; | |||||
@Autowired | |||||
GpuConfigTemplateClient gpuConfigTemplateClient; | |||||
@Autowired | |||||
private GpuConfigClient gpuConfigClient; | |||||
@Autowired | |||||
private CleanupUserResourcesAsync cleanupUserResourcesAsync; | |||||
@Autowired | |||||
private ObtainAccessToken obtainAccessToken; | |||||
/** | /** | ||||
* 测试标识 true:允许debug false:拒绝debug | * 测试标识 true:允许debug false:拒绝debug | ||||
*/ | */ | ||||
@Value("${debug.flag}") | @Value("${debug.flag}") | ||||
private Boolean debugFlag; | private Boolean debugFlag; | ||||
@Value("${email.send-limit}") | |||||
private Integer emailSendLimit; | |||||
private final String LOCK_SEND_CODE = "LOCK_SEND_CODE"; | private final String LOCK_SEND_CODE = "LOCK_SEND_CODE"; | ||||
/** | /** | ||||
@@ -173,10 +250,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
public Object queryAll(UserQueryDTO criteria, Page page) { | public Object queryAll(UserQueryDTO criteria, Page page) { | ||||
if (criteria.getRoleId() == null) { | if (criteria.getRoleId() == null) { | ||||
IPage<User> users = userMapper.selectCollPage(page, WrapperHelp.getWrapper(criteria)); | IPage<User> users = userMapper.selectCollPage(page, WrapperHelp.getWrapper(criteria)); | ||||
return PageUtil.toPage(users, userConvert::toDto); | |||||
List<UserDTO> userDTOList = convertToUserDTO(users); | |||||
return PageUtil.toPage(users, userDTOList); | |||||
} else { | } else { | ||||
IPage<User> users = userMapper.selectCollPageByRoleId(page, WrapperHelp.getWrapper(criteria), criteria.getRoleId()); | IPage<User> users = userMapper.selectCollPageByRoleId(page, WrapperHelp.getWrapper(criteria), criteria.getRoleId()); | ||||
return PageUtil.toPage(users, userConvert::toDto); | |||||
List<UserDTO> userDTOList = convertToUserDTO(users); | |||||
return PageUtil.toPage(users, userDTOList); | |||||
} | } | ||||
} | } | ||||
@@ -189,7 +268,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
@Override | @Override | ||||
public List<UserDTO> queryAll(UserQueryDTO criteria) { | public List<UserDTO> queryAll(UserQueryDTO criteria) { | ||||
List<User> users = userMapper.selectCollList(WrapperHelp.getWrapper(criteria)); | List<User> users = userMapper.selectCollList(WrapperHelp.getWrapper(criteria)); | ||||
return userConvert.toDto(users); | |||||
List<UserDTO> userDTOList = null; | |||||
if (CollectionUtil.isEmpty(users)) { | |||||
return userDTOList; | |||||
} | |||||
userDTOList = userConvert.toDto(users); | |||||
for (UserDTO userDTO : userDTOList) { | |||||
String userGroupName = userMapper.queryUserGroupNameByUserId(userDTO.getId()); | |||||
userDTO.setUserGroupName(userGroupName); | |||||
} | |||||
return userDTOList; | |||||
} | } | ||||
/** | /** | ||||
@@ -248,15 +337,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
for (Role role : resources.getRoles()) { | for (Role role : resources.getRoles()) { | ||||
roleMapper.tiedUserRole(user.getId(), role.getId()); | roleMapper.tiedUserRole(user.getId(), role.getId()); | ||||
} | } | ||||
UserConfigDTO userConfigDTO = new UserConfigDTO(); | |||||
userConfigDTO.setUserId(user.getId()); | |||||
userConfigDTO.setCpuLimit(cpuLimit); | |||||
userConfigDTO.setMemoryLimit(memoryLimit); | |||||
userConfigDTO.setGpuLimit(gpuLimit); | |||||
DataResponseBody dataResponseBody = resourceQuotaClient.updateResourceQuota(userConfigDTO); | |||||
if (!dataResponseBody.succeed()){ | |||||
throw new BusinessException("用户配置更新失败"); | |||||
} | |||||
//初始化用户配置 | |||||
UserConfigSaveDTO userConfigDTO = new UserConfigSaveDTO(); | |||||
userConfigDTO.setUserId(user.getId()).setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setNotebookDelayDeleteTime(userConfigNotebookDelayDeleteTime); | |||||
List<UserGpuConfigDTO> userGpuConfigs = new ArrayList<>(); | |||||
userGpuConfigs.add(new UserGpuConfigDTO().setGpuType(gpuType).setGpuModel(gpuModel).setK8sLabelKey(k8sLabelKey).setGpuLimit(gpuNumLimit)); | |||||
userConfigDTO.setGpuResources(userGpuConfigs); | |||||
saveUserConfig(userConfigDTO, null); | |||||
return userConvert.toDto(user); | return userConvert.toDto(user); | ||||
} | } | ||||
@@ -307,19 +395,15 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
*/ | */ | ||||
@Override | @Override | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public void delete(Set<Long> ids) { | |||||
public void delete(Set<Long> ids, String accessToken) { | |||||
if (!CollectionUtils.isEmpty(ids)) { | if (!CollectionUtils.isEmpty(ids)) { | ||||
Long adminId = Long.valueOf(UserConstant.ADMIN_USER_ID); | Long adminId = Long.valueOf(UserConstant.ADMIN_USER_ID); | ||||
if (ids.contains(adminId)) { | if (ids.contains(adminId)) { | ||||
throw new BusinessException(BaseErrorCodeEnum.SYSTEM_USER_CANNOT_DELETE); | throw new BusinessException(BaseErrorCodeEnum.SYSTEM_USER_CANNOT_DELETE); | ||||
} | } | ||||
ids.forEach(id -> { | |||||
userMapper.updateById( | |||||
User.builder() | |||||
.id(id) | |||||
.deleted(SwitchEnum.getBooleanValue(SwitchEnum.ON.getValue())) | |||||
.build()); | |||||
}); | |||||
userMapper.deleteBatchIds(ids); | |||||
//异步清理用户资源 | |||||
cleanupUserResourcesAsync.cleanUserResource(ids, accessToken); | |||||
} | } | ||||
} | } | ||||
@@ -339,6 +423,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
} | } | ||||
UserDTO dto = new UserDTO(); | UserDTO dto = new UserDTO(); | ||||
BeanUtils.copyProperties(user, dto); | BeanUtils.copyProperties(user, dto); | ||||
if (user.getUserAvatar() != null && StrUtil.isNotBlank(user.getUserAvatar().getPath())) { | |||||
dto.setUserAvatarPath(user.getUserAvatar().getPath()); | |||||
} | |||||
List<Role> roles = roleMapper.findRolesByUserId(user.getId()); | List<Role> roles = roleMapper.findRolesByUserId(user.getId()); | ||||
if (!CollectionUtils.isEmpty(roles)) { | if (!CollectionUtils.isEmpty(roles)) { | ||||
dto.setRoles(roles.stream().map(a -> { | dto.setRoles(roles.stream().map(a -> { | ||||
@@ -357,12 +444,36 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
private SysUserConfigDTO getUserConfig(Long userId) { | private SysUserConfigDTO getUserConfig(Long userId) { | ||||
UserConfig userConfig = userConfigMapper.selectOne(new QueryWrapper<>(new UserConfig().setUserId(userId))); | UserConfig userConfig = userConfigMapper.selectOne(new QueryWrapper<>(new UserConfig().setUserId(userId))); | ||||
SysUserConfigDTO sysUserConfigDTO= new SysUserConfigDTO(); | |||||
if (userConfig == null){ | |||||
return sysUserConfigDTO.setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setGpuLimit(gpuLimit).setNotebookDelayDeleteTime(defaultNotebookDelayDeleteTime); | |||||
SysUserConfigDTO sysUserConfigDTO = new SysUserConfigDTO(); | |||||
// 如果用户配置为空,则返回默认配置 | |||||
if (userConfig == null) { | |||||
sysUserConfigDTO.setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setNotebookDelayDeleteTime(userConfigNotebookDelayDeleteTime); | |||||
} else { | |||||
BeanUtils.copyProperties(userConfig, sysUserConfigDTO); | |||||
} | |||||
// 查询用户GPU配置 | |||||
List<UserGpuConfig> userGpuConfigs = userGpuConfigMapper.selectList(new QueryWrapper<>(new UserGpuConfig().setUserId(userId))); | |||||
// 如果老用户未初始化GPU配置,则返回默认配置 | |||||
if (CollectionUtils.isEmpty(userGpuConfigs) && userGpuConfigMapper.selectCountByUserId(userId) == 0) { | |||||
List<UserGpuConfig> preUserGpuConfigs = userGpuConfigMapper.selectList(new QueryWrapper<>(new UserGpuConfig().setUserId(0L))); | |||||
if (CollectionUtil.isNotEmpty(preUserGpuConfigs)) { | |||||
userGpuConfigs.addAll(preUserGpuConfigs); | |||||
} | |||||
} | |||||
List<SysUserGpuConfigDTO> sysUserGpuConfigDTOs = userGpuConfigs.stream().map(x -> { | |||||
SysUserGpuConfigDTO sysUserGpuConfigDTO = new SysUserGpuConfigDTO(); | |||||
BeanUtils.copyProperties(x, sysUserGpuConfigDTO); | |||||
return sysUserGpuConfigDTO; | |||||
}).collect(Collectors.toList()); | |||||
sysUserConfigDTO.setGpuResources(sysUserGpuConfigDTOs); | |||||
//如果当前用户如果没有默认镜像,就使用管理员的 | |||||
if (userConfig == null || userConfig.getDefaultImageId() == null) { | |||||
LambdaQueryWrapper<UserConfig> queryWrapper = new LambdaQueryWrapper<>(); | |||||
queryWrapper.eq(UserConfig::getUserId, PermissionAspect.PUBLIC_DATA_USER_ID); | |||||
UserConfig adminConfig = userConfigMapper.selectOne(queryWrapper); | |||||
sysUserConfigDTO.setDefaultImageId(adminConfig.getDefaultImageId()); | |||||
} | } | ||||
BeanUtils.copyProperties(userConfig, sysUserConfigDTO); | |||||
return sysUserConfigDTO; | return sysUserConfigDTO; | ||||
} | } | ||||
@@ -491,6 +602,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
//用户信息校验 | //用户信息校验 | ||||
checkoutUserInfo(userRegisterDTO); | checkoutUserInfo(userRegisterDTO); | ||||
String encode = passwordEncoder.encode(RsaEncrypt.decrypt(userRegisterDTO.getPassword(), privateKey)); | String encode = passwordEncoder.encode(RsaEncrypt.decrypt(userRegisterDTO.getPassword(), privateKey)); | ||||
Long userId; | |||||
try { | try { | ||||
User newUser = User.builder() | User newUser = User.builder() | ||||
.email(userRegisterDTO.getEmail()) | .email(userRegisterDTO.getEmail()) | ||||
@@ -503,18 +615,42 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
//新增用户注册信息 | //新增用户注册信息 | ||||
userMapper.insert(newUser); | userMapper.insert(newUser); | ||||
userId = newUser.getId(); | |||||
//绑定用户默认权限 | //绑定用户默认权限 | ||||
userRoleMapper.insert(UserRole.builder().roleId((long) UserConstant.REGISTER_ROLE_ID).userId(newUser.getId()).build()); | |||||
userRoleMapper.insert(UserRole.builder().roleId((long) UserConstant.REGISTER_ROLE_ID).userId(userId).build()); | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
LogUtil.error(LogEnum.SYS_ERR, "UserServiceImpl userRegister error , param:{} error:{}", JSONObject.toJSONString(userRegisterDTO), e); | LogUtil.error(LogEnum.SYS_ERR, "UserServiceImpl userRegister error , param:{} error:{}", JSONObject.toJSONString(userRegisterDTO), e); | ||||
throw new BusinessException(BaseErrorCodeEnum.ERROR_SYSTEM.getCode(), BaseErrorCodeEnum.ERROR_SYSTEM.getMsg()); | throw new BusinessException(BaseErrorCodeEnum.ERROR_SYSTEM.getCode(), BaseErrorCodeEnum.ERROR_SYSTEM.getMsg()); | ||||
} | } | ||||
//初始化用户配置 | |||||
execute(userId, userRegisterDTO.getUsername(), userRegisterDTO.getPassword()); | |||||
return new DataResponseBody(); | return new DataResponseBody(); | ||||
} | } | ||||
/** | |||||
* 同步初始化用户配置 | |||||
* @param userId 用户id | |||||
* @param username 用户名 | |||||
* @param password 用户密码 | |||||
*/ | |||||
public void execute(Long userId, String username, String password) { | |||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { | |||||
@Override | |||||
public void afterCommit() { | |||||
//为注册用户生成token | |||||
String token = obtainAccessToken.generateToken(username, password); | |||||
//初始化用户配置 | |||||
UserConfigSaveDTO userConfigDTO = new UserConfigSaveDTO(); | |||||
userConfigDTO.setUserId(userId).setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setNotebookDelayDeleteTime(userConfigNotebookDelayDeleteTime); | |||||
List<UserGpuConfigDTO> userGpuConfigs = new ArrayList<>(); | |||||
userGpuConfigs.add(new UserGpuConfigDTO().setGpuType(gpuType).setGpuModel(gpuModel).setK8sLabelKey(k8sLabelKey).setGpuLimit(gpuNumLimit)); | |||||
userConfigDTO.setGpuResources(userGpuConfigs); | |||||
saveUserConfig(userConfigDTO, token); | |||||
} | |||||
}); | |||||
} | |||||
/** | /** | ||||
* 获取code通过发送邮件 | * 获取code通过发送邮件 | ||||
@@ -565,6 +701,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
} catch (Exception e) { | } catch (Exception e) { | ||||
redisUtils.hdel(UserConstant.USER_EMAIL_REGISTER.concat(email), email); | redisUtils.hdel(UserConstant.USER_EMAIL_REGISTER.concat(email), email); | ||||
redisUtils.hdel(UserConstant.USER_EMAIL_LIMIT_COUNT.concat(email), email); | |||||
LogUtil.error(LogEnum.SYS_ERR, "UserServiceImpl getCodeBySentEmail error , param:{} error:{}", email, e); | LogUtil.error(LogEnum.SYS_ERR, "UserServiceImpl getCodeBySentEmail error , param:{} error:{}", email, e); | ||||
throw new BusinessException(BaseErrorCodeEnum.ERROR_SYSTEM.getCode(), BaseErrorCodeEnum.ERROR_SYSTEM.getMsg()); | throw new BusinessException(BaseErrorCodeEnum.ERROR_SYSTEM.getCode(), BaseErrorCodeEnum.ERROR_SYSTEM.getMsg()); | ||||
} | } | ||||
@@ -623,7 +760,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
.email(curUser.getUser().getEmail()) | .email(curUser.getUser().getEmail()) | ||||
.password(Md5Util.createMd5(Md5Util.createMd5(curUser.getUsername()).concat(initialPassword))) | .password(Md5Util.createMd5(Md5Util.createMd5(curUser.getUsername()).concat(initialPassword))) | ||||
.username(curUser.getUsername()) | .username(curUser.getUsername()) | ||||
.is_staff(!CollectionUtils.isEmpty(userRoles) ? true : false).build(); | |||||
.is_staff(!CollectionUtils.isEmpty(userRoles)).build(); | |||||
return BeanMap.create(vo); | return BeanMap.create(vo); | ||||
} | } | ||||
@@ -752,43 +889,112 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
// 查询用户配置 | // 查询用户配置 | ||||
UserConfig userConfig = userConfigMapper.selectOne(new QueryWrapper<>(new UserConfig().setUserId(userId))); | UserConfig userConfig = userConfigMapper.selectOne(new QueryWrapper<>(new UserConfig().setUserId(userId))); | ||||
UserConfigVO userConfigVO = new UserConfigVO(); | UserConfigVO userConfigVO = new UserConfigVO(); | ||||
// 如果用户配置为空,则返回 | |||||
if (userConfig == null){ | |||||
return userConfigVO.setUserId(userId).setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setGpuLimit(gpuLimit).setNotebookDelayDeleteTime(defaultNotebookDelayDeleteTime); | |||||
// 如果用户配置为空,则返回默认配置 | |||||
if (userConfig == null) { | |||||
userConfigVO.setUserId(userId).setCpuLimit(cpuLimit).setMemoryLimit(memoryLimit) | |||||
.setNotebookDelayDeleteTime(userConfigNotebookDelayDeleteTime); | |||||
} else { | |||||
BeanUtils.copyProperties(userConfig, userConfigVO); | |||||
} | } | ||||
// 封装用户配置 VO | |||||
BeanUtils.copyProperties(userConfig, userConfigVO); | |||||
// 查询用户GPU配置 | |||||
List<UserGpuConfig> userGpuConfigs = userGpuConfigMapper.selectList(new QueryWrapper<>(new UserGpuConfig().setUserId(userId))); | |||||
List<UserGpuConfigVO> userGpuConfigVOList = new ArrayList<>(); | |||||
// 如果老用户未初始化GPU配置,则返回默认配置 | |||||
if (CollectionUtils.isEmpty(userGpuConfigs) && userGpuConfigMapper.selectCountByUserId(userId) == 0) { | |||||
List<UserGpuConfig> preUserGpuConfigs = userGpuConfigMapper.selectList(new QueryWrapper<>(new UserGpuConfig().setUserId(PermissionAspect.PUBLIC_DATA_USER_ID))); | |||||
userGpuConfigs = preUserGpuConfigs; | |||||
} | |||||
userGpuConfigs.forEach(userGpuConfig -> { | |||||
UserGpuConfigVO userGpuConfigVO = new UserGpuConfigVO(); | |||||
BeanUtils.copyProperties(userGpuConfig, userGpuConfigVO); | |||||
userGpuConfigVOList.add(userGpuConfigVO); | |||||
}); | |||||
userConfigVO.setGpuResources(userGpuConfigVOList); | |||||
return userConfigVO; | return userConfigVO; | ||||
} | } | ||||
/** | /** | ||||
* 创建或更新用户配置 | * 创建或更新用户配置 | ||||
* | * | ||||
* @param userConfigDTO 用户配置 | |||||
* @return org.dubhe.admin.domain.vo.UserConfigCreateVO 用户配置 VO | |||||
* @param userConfigSaveDTO 用户配置 | |||||
*/ | */ | ||||
@Override | @Override | ||||
@Transactional(rollbackFor = Exception.class) | @Transactional(rollbackFor = Exception.class) | ||||
public UserConfigCreateVO createOrUpdateUserConfig(UserConfigDTO userConfigDTO) { | |||||
DataResponseBody dataResponseBody = resourceQuotaClient.updateResourceQuota(userConfigDTO); | |||||
if (!dataResponseBody.succeed()){ | |||||
throw new BusinessException("用户配置更新失败"); | |||||
public void saveUserConfig(UserConfigSaveDTO userConfigSaveDTO, String token) { | |||||
//设置k8s quota (k8s quota设置只支持以厂商为单位的配置) | |||||
ResourceQuotaDTO resourceQuotaDTO = new ResourceQuotaDTO(); | |||||
BeanUtils.copyProperties(userConfigSaveDTO, resourceQuotaDTO); | |||||
//目前只有nvidia和suiyuan,map初始化空间设置为2 | |||||
Map<String, Integer> map = new HashMap<>(2); | |||||
if (!CollectionUtils.isEmpty(userConfigSaveDTO.getGpuResources())) { | |||||
for (UserGpuConfigDTO userGpuConfigDTO : userConfigSaveDTO.getGpuResources()) { | |||||
Integer gpuNumLimit = userGpuConfigDTO.getGpuLimit(); | |||||
if (map.containsKey(userGpuConfigDTO.getK8sLabelKey())) { | |||||
gpuNumLimit = map.get(userGpuConfigDTO.getK8sLabelKey()) + userGpuConfigDTO.getGpuLimit(); | |||||
} | |||||
map.put(userGpuConfigDTO.getK8sLabelKey(), gpuNumLimit); | |||||
} | |||||
} | |||||
resourceQuotaDTO.setGpuLimit(map); | |||||
//设置k8s GPU型号配置 | |||||
GpuConfigDTO gpuConfigDTO = new GpuConfigDTO(); | |||||
gpuConfigDTO.setUserId(userConfigSaveDTO.getUserId()); | |||||
if (!CollectionUtils.isEmpty(userConfigSaveDTO.getGpuResources())) { | |||||
List<SysUserGpuConfigDTO> sysUserGpuConfigs = userConfigSaveDTO.getGpuResources().stream().map(x -> { | |||||
SysUserGpuConfigDTO sysUserGpuConfigDTO = new SysUserGpuConfigDTO(); | |||||
BeanUtils.copyProperties(x, sysUserGpuConfigDTO); | |||||
return sysUserGpuConfigDTO; | |||||
}).collect(Collectors.toList()); | |||||
gpuConfigDTO.setGpuResources(sysUserGpuConfigs); | |||||
} | } | ||||
DataResponseBody gpuConfigDataResponse; | |||||
if (token == null) { | |||||
gpuConfigDataResponse = gpuConfigClient.updateGpuConfig(gpuConfigDTO); | |||||
} else { | |||||
gpuConfigDataResponse = gpuConfigTemplateClient.updateGpuConfig(gpuConfigDTO, AuthConst.ACCESS_TOKEN_PREFIX + token); | |||||
} | |||||
if (gpuConfigDataResponse == null || !gpuConfigDataResponse.succeed()) { | |||||
throw new BusinessException("k8s GPU型号配置更新失败"); | |||||
} | |||||
//创建或更新用户配置 | |||||
UserConfig userConfig = new UserConfig(); | UserConfig userConfig = new UserConfig(); | ||||
BeanUtils.copyProperties(userConfigDTO, userConfig); | |||||
BeanUtils.copyProperties(userConfigSaveDTO, userConfig); | |||||
userConfigMapper.insertOrUpdate(userConfig); | userConfigMapper.insertOrUpdate(userConfig); | ||||
// 封装用户配置 VO | |||||
UserConfigCreateVO userConfigCreateVO = new UserConfigCreateVO().setId(userConfig.getId()); | |||||
return userConfigCreateVO; | |||||
} | |||||
//创建或更新用户GPU配置 | |||||
//删除原有记录 | |||||
if (userGpuConfigMapper.selectCount(new QueryWrapper<>(new UserGpuConfig().setUserId(userConfigSaveDTO.getUserId()))) > 0) { | |||||
userGpuConfigMapper.delete(new QueryWrapper<>(new UserGpuConfig().setUserId(userConfigSaveDTO.getUserId()))); | |||||
} | |||||
if (!CollectionUtils.isEmpty(userConfigSaveDTO.getGpuResources())) { | |||||
List<UserGpuConfig> userGpuConfigs = userConfigSaveDTO.getGpuResources().stream().map(x -> | |||||
{ | |||||
UserGpuConfig userGpuConfig = new UserGpuConfig(); | |||||
BeanUtils.copyProperties(x, userGpuConfig); | |||||
userGpuConfig.setUserId(userConfigSaveDTO.getUserId()); | |||||
return userGpuConfig; | |||||
}).collect(Collectors.toList()); | |||||
userGpuConfigMapper.insertBatchs(userGpuConfigs); | |||||
} | |||||
//更新quota中GPU的配额 | |||||
DataResponseBody dataResponseBody; | |||||
if (token == null) { | |||||
dataResponseBody = resourceQuotaClient.updateResourceQuota(resourceQuotaDTO); | |||||
} else { | |||||
dataResponseBody = resourceQuotaTemplateClient.updateResourceQuota(resourceQuotaDTO, AuthConst.ACCESS_TOKEN_PREFIX + token); | |||||
} | |||||
if (dataResponseBody == null || !dataResponseBody.succeed()) { | |||||
throw new BusinessException("k8s quota用户配置更新失败"); | |||||
} | |||||
} | |||||
/** | /** | ||||
* 校验验证码 | * 校验验证码 | ||||
* | * | ||||
* @param loginCaptcha 验证码参数 | |||||
* @param uuid 验证码redis-key | |||||
* @param loginCaptcha 验证码参数 | |||||
* @param uuid 验证码redis-key | |||||
*/ | */ | ||||
private void validateCode(String loginCaptcha, String uuid) { | private void validateCode(String loginCaptcha, String uuid) { | ||||
// 验证码未输入 | // 验证码未输入 | ||||
@@ -853,17 +1059,15 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
*/ | */ | ||||
private void limitSendEmail(final String receiverMailAddress) { | private void limitSendEmail(final String receiverMailAddress) { | ||||
double count = redisUtils.hincr(UserConstant.USER_EMAIL_LIMIT_COUNT.concat(receiverMailAddress), receiverMailAddress, 1); | double count = redisUtils.hincr(UserConstant.USER_EMAIL_LIMIT_COUNT.concat(receiverMailAddress), receiverMailAddress, 1); | ||||
if (count > UserConstant.COUNT_SENT_EMAIL) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "Email verification code cannot exceed three times , error:{}", UserConstant.COUNT_SENT_EMAIL); | |||||
if (count > emailSendLimit) { | |||||
LogUtil.error(LogEnum.SYS_ERR, "Email verification code cannot exceed three times , error:{}", emailSendLimit); | |||||
throw new BusinessException(BaseErrorCodeEnum.SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES.getCode(), | throw new BusinessException(BaseErrorCodeEnum.SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES.getCode(), | ||||
BaseErrorCodeEnum.SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES.getMsg()); | BaseErrorCodeEnum.SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES.getMsg()); | ||||
} else { | } else { | ||||
// 验证码次数凌晨清除 | // 验证码次数凌晨清除 | ||||
String concat = UserConstant.USER_EMAIL_LIMIT_COUNT.concat(receiverMailAddress); | String concat = UserConstant.USER_EMAIL_LIMIT_COUNT.concat(receiverMailAddress); | ||||
Long secondsNextEarlyMorning = DateUtil.getSecondTime(); | |||||
redisUtils.expire(concat, secondsNextEarlyMorning); | |||||
Duration duration = Duration.between(LocalDateTime.now(), LocalDate.now().plusDays(1).atTime(0, 0, 0)); | |||||
redisUtils.expire(concat, duration.getSeconds()); | |||||
} | } | ||||
} | } | ||||
@@ -889,8 +1093,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
/** | /** | ||||
* 校验 邮箱地址 和 验证码 | * 校验 邮箱地址 和 验证码 | ||||
* | * | ||||
* @param code 验证码 | |||||
* @param email 邮箱 | |||||
* @param code 验证码 | |||||
* @param email 邮箱 | |||||
* @param codeRedisKey redis-key | * @param codeRedisKey redis-key | ||||
*/ | */ | ||||
private void checkoutEmailAndCode(String code, String email, String codeRedisKey) { | private void checkoutEmailAndCode(String code, String email, String codeRedisKey) { | ||||
@@ -993,4 +1197,58 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us | |||||
dto.setUserConfig(sysUserConfigDTO); | dto.setUserConfig(sysUserConfigDTO); | ||||
return DataResponseFactory.success(dto); | return DataResponseFactory.success(dto); | ||||
} | } | ||||
/** | |||||
* 重置密码 | |||||
* | |||||
* @return 重置密码结果集 | |||||
*/ | |||||
@Transactional(rollbackFor = Exception.class) | |||||
@Override | |||||
public DataResponseBody resetPassword(Long userId) { | |||||
PasswordEncoder passwordEncoder = PasswordEncoderFactory.getPasswordEncoder(); | |||||
//重置为默认密码123456,加密密码 | |||||
String encode = passwordEncoder.encode(initialPassword); | |||||
userMapper.updateById(User.builder().id(userId).password(encode).lastPasswordResetTime(new Date()).build()); | |||||
return new DataResponseBody(); | |||||
} | |||||
/** | |||||
* 获取用户分配的资源总量 | |||||
* | |||||
* @return 资源配额总量统计 | |||||
*/ | |||||
@Override | |||||
public DataResponseBody getAllotResources() { | |||||
//获取内存、cpu分配总量 | |||||
UserAllotResourceVO userAllotResourceVO = userConfigMapper.selectResourceSum(); | |||||
//按型号获取gpu分配总量 | |||||
List<GpuAllotVO> gpuAllotVOList = userGpuConfigMapper.selectGpuAllotSum(); | |||||
List<Integer> gpuAllotTotal = gpuAllotVOList.stream().map(allot -> Integer.valueOf(allot.getAllotTotal())).collect(Collectors.toList()); | |||||
userAllotResourceVO.setGpuAllotTotal(gpuAllotTotal.stream().reduce(Integer::sum).get()); | |||||
userAllotResourceVO.setGpuAllotList(gpuAllotVOList); | |||||
return new DataResponseBody(userAllotResourceVO); | |||||
} | |||||
/** | |||||
* 将user转换为userDTO,并且设置对应的用户组名 | |||||
* | |||||
* @return userDTO list | |||||
*/ | |||||
private List<UserDTO> convertToUserDTO(IPage<User> users) { | |||||
List<UserDTO> userDTOList = new ArrayList<>(); | |||||
if (CollectionUtil.isEmpty(users.getRecords())) { | |||||
return userDTOList; | |||||
} | |||||
userDTOList = userConvert.toDto(users.getRecords()); | |||||
for (UserDTO userDTO : userDTOList) { | |||||
String userGroupName = userMapper.queryUserGroupNameByUserId(userDTO.getId()); | |||||
userDTO.setUserGroupName(userGroupName); | |||||
} | |||||
return userDTOList; | |||||
} | |||||
} | } |
@@ -10,8 +10,8 @@ spring: | |||||
nacos: | nacos: | ||||
config: | config: | ||||
enabled: true | enabled: true | ||||
server-addr: 127.0.0.1:8848 | |||||
namespace: dubhe-server-cloud-prod | |||||
server-addr: 10.105.1.133:8848 | |||||
namespace: dubhe-server-cloud-dev | |||||
shared-configs[0]: | shared-configs[0]: | ||||
data-id: common-biz.yaml | data-id: common-biz.yaml | ||||
group: dubhe | group: dubhe | ||||
@@ -33,5 +33,5 @@ spring: | |||||
enabled: true | enabled: true | ||||
namespace: dubhe-server-cloud-dev | namespace: dubhe-server-cloud-dev | ||||
group: dubhe | group: dubhe | ||||
server-addr: 127.0.0.1:8848 | |||||
server-addr: 10.105.1.133:8848 | |||||
@@ -21,9 +21,6 @@ | |||||
<if test="memoryLimit != null"> | <if test="memoryLimit != null"> | ||||
memory_limit, | memory_limit, | ||||
</if> | </if> | ||||
<if test="gpuLimit != null"> | |||||
gpu_limit, | |||||
</if> | |||||
<if test="createUserId != null"> | <if test="createUserId != null"> | ||||
create_user_id, | create_user_id, | ||||
</if> | </if> | ||||
@@ -33,6 +30,9 @@ | |||||
<if test="updateUserId != null"> | <if test="updateUserId != null"> | ||||
update_user_id, | update_user_id, | ||||
</if> | </if> | ||||
<if test="defaultImageId != null"> | |||||
default_image_id, | |||||
</if> | |||||
<if test="deleted != null"> | <if test="deleted != null"> | ||||
deleted, | deleted, | ||||
</if> | </if> | ||||
@@ -50,9 +50,6 @@ | |||||
<if test="memoryLimit != null"> | <if test="memoryLimit != null"> | ||||
#{memoryLimit}, | #{memoryLimit}, | ||||
</if> | </if> | ||||
<if test="gpuLimit != null"> | |||||
#{gpuLimit}, | |||||
</if> | |||||
<if test="createUserId != null"> | <if test="createUserId != null"> | ||||
#{createUserId}, | #{createUserId}, | ||||
</if> | </if> | ||||
@@ -62,6 +59,9 @@ | |||||
<if test="updateUserId != null"> | <if test="updateUserId != null"> | ||||
#{updateUserId}, | #{updateUserId}, | ||||
</if> | </if> | ||||
<if test="defaultImageId != null"> | |||||
#{defaultImageId}, | |||||
</if> | |||||
<if test="deleted != null"> | <if test="deleted != null"> | ||||
#{deleted}, | #{deleted}, | ||||
</if> | </if> | ||||
@@ -77,9 +77,6 @@ | |||||
<if test="memoryLimit != null"> | <if test="memoryLimit != null"> | ||||
memory_limit = #{memoryLimit}, | memory_limit = #{memoryLimit}, | ||||
</if> | </if> | ||||
<if test="gpuLimit != null"> | |||||
gpu_limit = #{gpuLimit}, | |||||
</if> | |||||
<if test="createTime != null"> | <if test="createTime != null"> | ||||
create_time = #{createTime}, | create_time = #{createTime}, | ||||
</if> | </if> | ||||
@@ -92,9 +89,26 @@ | |||||
<if test="updateUserId != null"> | <if test="updateUserId != null"> | ||||
update_user_id = #{updateUserId}, | update_user_id = #{updateUserId}, | ||||
</if> | </if> | ||||
<if test="defaultImageId != null"> | |||||
default_image_id = #{defaultImageId}, | |||||
</if> | |||||
<if test="deleted != null"> | <if test="deleted != null"> | ||||
deleted = #{deleted}, | deleted = #{deleted}, | ||||
</if> | </if> | ||||
</trim> | </trim> | ||||
</insert> | </insert> | ||||
</mapper> | |||||
<select id="selectLimitSum" resultType="org.dubhe.admin.domain.vo.UserLimitConfigVO"> | |||||
select | |||||
u.id userId, | |||||
u.username userName, | |||||
u.nick_name nickName, | |||||
uc.cpu_limit cpu, | |||||
uc.memory_limit mem, | |||||
sum(ugc.gpu_limit) gpu | |||||
from user u | |||||
left join user_config uc on u.id=uc.user_id | |||||
left join user_gpu_config ugc on uc.user_id=ugc.user_id | |||||
where uc.deleted=0 and ugc.deleted=0 group by userId order by ${sort} ${order} | |||||
</select> | |||||
</mapper> |
@@ -0,0 +1,12 @@ | |||||
<?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="org.dubhe.admin.dao.UserGpuConfigMapper"> | |||||
<insert id="insertBatchs" parameterType="java.util.List"> | |||||
insert into user_gpu_config (user_id,gpu_type,gpu_model,k8s_label_key,gpu_limit) values | |||||
<foreach collection="list" item="item" separator=","> | |||||
(#{item.userId}, #{item.gpuType}, #{item.gpuModel}, #{item.k8sLabelKey}, #{item.gpuLimit}) | |||||
</foreach> | |||||
</insert> | |||||
</mapper> |
@@ -13,4 +13,9 @@ | |||||
left join users_roles ur on ra.role_id = ur.role_id | left join users_roles ur on ra.role_id = ur.role_id | ||||
where ur.user_id = #{userId} and p.deleted=0; | where ur.user_id = #{userId} and p.deleted=0; | ||||
</select> | </select> | ||||
<select id="queryUserGroupNameByUserId" parameterType="Long" resultType="java.lang.String"> | |||||
select g.name from pt_group g, user u, user_group ug | |||||
where u.id = #{userId} and u.id = ug.user_id and ug.group_id = g.id and g.deleted = 0 and u.deleted = 0 | |||||
</select> | |||||
</mapper> | </mapper> |
@@ -1,5 +1,6 @@ | |||||
package org.dubhe.admin; | package org.dubhe.admin; | ||||
import com.alibaba.fastjson.JSON; | |||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
import org.dubhe.admin.domain.dto.DictCreateDTO; | import org.dubhe.admin.domain.dto.DictCreateDTO; | ||||
import org.dubhe.admin.domain.dto.DictDetailDTO; | import org.dubhe.admin.domain.dto.DictDetailDTO; | ||||
@@ -7,8 +8,10 @@ import org.dubhe.admin.domain.dto.DictDetailQueryDTO; | |||||
import org.dubhe.admin.domain.entity.DictDetail; | import org.dubhe.admin.domain.entity.DictDetail; | ||||
import org.dubhe.admin.rest.DictController; | import org.dubhe.admin.rest.DictController; | ||||
import org.dubhe.admin.service.DictDetailService; | import org.dubhe.admin.service.DictDetailService; | ||||
import org.dubhe.admin.service.UserService; | |||||
import org.dubhe.biz.base.utils.DateUtil; | import org.dubhe.biz.base.utils.DateUtil; | ||||
import org.dubhe.biz.base.vo.DataResponseBody; | import org.dubhe.biz.base.vo.DataResponseBody; | ||||
import org.dubhe.biz.base.vo.UserConfigVO; | |||||
import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import org.springframework.boot.test.context.SpringBootTest; | import org.springframework.boot.test.context.SpringBootTest; | ||||
@@ -28,6 +31,9 @@ public class AdminApplicationTests { | |||||
@Autowired | @Autowired | ||||
private DictDetailService dictDetailService; | private DictDetailService dictDetailService; | ||||
@Autowired | |||||
private UserService userService; | |||||
/** | /** | ||||
* 字典分页查询 | * 字典分页查询 | ||||
*/ | */ | ||||
@@ -67,4 +73,10 @@ public class AdminApplicationTests { | |||||
} | } | ||||
@Test | |||||
public void findUserConfig() { | |||||
UserConfigVO userConfig = userService.findUserConfig(1l); | |||||
System.out.println(JSON.toJSONString(userConfig)); | |||||
} | |||||
} | } |
@@ -11,8 +11,8 @@ spring: | |||||
nacos: | nacos: | ||||
config: | config: | ||||
enabled: true | enabled: true | ||||
server-addr: 127.0.0.1:8848 | |||||
namespace: dubhe-server-cloud-prod | |||||
server-addr: 10.105.1.133:8848 | |||||
namespace: dubhe-server-cloud-dev | |||||
shared-configs[0]: | shared-configs[0]: | ||||
data-id: common-biz.yaml | data-id: common-biz.yaml | ||||
group: dubhe | group: dubhe | ||||
@@ -25,5 +25,5 @@ spring: | |||||
enabled: true | enabled: true | ||||
namespace: dubhe-server-cloud-dev | namespace: dubhe-server-cloud-dev | ||||
group: dubhe | group: dubhe | ||||
server-addr: 127.0.0.1:8848 | |||||
server-addr: 10.105.1.133:8848 | |||||
@@ -81,6 +81,10 @@ public class ApplicationNameConst { | |||||
*/ | */ | ||||
public final static String SERVER_DATA_DCM = "dubhe-data-dcm"; | public final static String SERVER_DATA_DCM = "dubhe-data-dcm"; | ||||
/** | |||||
* TADL | |||||
*/ | |||||
public final static String SERVER_TADL = "dubhe-tadl"; | |||||
/** | /** | ||||
* k8s | * k8s | ||||
*/ | */ | ||||
@@ -54,10 +54,10 @@ public class AuthConst { | |||||
* 默认匿名访问路径 | * 默认匿名访问路径 | ||||
*/ | */ | ||||
public final static String[] DEFAULT_PERMIT_PATHS = {"/swagger**/**", "/webjars/**", "/v2/api-docs/**", "/doc.html/**", | public final static String[] DEFAULT_PERMIT_PATHS = {"/swagger**/**", "/webjars/**", "/v2/api-docs/**", "/doc.html/**", | ||||
"/users/findUserByUsername", "/auth/login", "/auth/code", | |||||
"/datasets/files/annotations/auto","/datasets/versions/**/convert/finish", "/datasets/enhance/finish", | |||||
"/auth/getCodeBySentEmail","/auth/userRegister","/ws/**", | |||||
StringConstant.RECYCLE_CALL_URI+"**" | |||||
"/users/findUserByUsername", "/auth/login", "/auth/code", "/auth/resetPassword", | |||||
"/datasets/files/annotations/auto", "/datasets/versions/**/convert/finish", "/datasets/enhance/finish", | |||||
"/auth/getCodeBySentEmail", "/auth/userRegister", "/ws/**", | |||||
StringConstant.RECYCLE_CALL_URI + "**" | |||||
}; | }; | ||||
/** | /** | ||||
@@ -68,6 +68,7 @@ public final class MagicNumConstant { | |||||
public static final int TWO_THOUSAND_TWENTY_EIGHT = 2048; | public static final int TWO_THOUSAND_TWENTY_EIGHT = 2048; | ||||
public static final int THREE_THOUSAND = 3000; | public static final int THREE_THOUSAND = 3000; | ||||
public static final int FOUR_THOUSAND = 4000; | public static final int FOUR_THOUSAND = 4000; | ||||
public static final int EIGHT_THOUSAND_ONE_HUNDRED_NINETY_TWO = 8192; | |||||
public static final int NINE_THOUSAND = 9000; | public static final int NINE_THOUSAND = 9000; | ||||
public static final int NINE_THOUSAND_NINE_HUNDRED_NINTY_NINE = 9999; | public static final int NINE_THOUSAND_NINE_HUNDRED_NINTY_NINE = 9999; | ||||
public static final int TEN_THOUSAND = 10000; | public static final int TEN_THOUSAND = 10000; | ||||
@@ -32,6 +32,8 @@ public class NumberConstant { | |||||
public final static int NUMBER_6 = 6; | public final static int NUMBER_6 = 6; | ||||
public final static int NUMBER_8 = 8; | public final static int NUMBER_8 = 8; | ||||
public final static int NUMBER_10 = 10; | public final static int NUMBER_10 = 10; | ||||
public final static int NUMBER_12 = 12; | |||||
public final static int NUMBER_24 = 24; | |||||
public final static int NUMBER_30 = 30; | public final static int NUMBER_30 = 30; | ||||
public final static int NUMBER_32 = 32; | public final static int NUMBER_32 = 32; | ||||
public final static int NUMBER_50 = 50; | public final static int NUMBER_50 = 50; | ||||
@@ -132,6 +132,9 @@ public final class Permissions { | |||||
public static final String USER_GROUP_EDIT_USER_ROLE = "hasAuthority('ROLE_system:userGroup:editUserRole')"; | public static final String USER_GROUP_EDIT_USER_ROLE = "hasAuthority('ROLE_system:userGroup:editUserRole')"; | ||||
public static final String USER_GROUP_EDIT_USER_STATE = "hasAuthority('ROLE_system:userGroup:editUserState')"; | public static final String USER_GROUP_EDIT_USER_STATE = "hasAuthority('ROLE_system:userGroup:editUserState')"; | ||||
public static final String USER_GROUP_DELETE_USER = "hasAuthority('ROLE_system:userGroup:deleteUser')"; | public static final String USER_GROUP_DELETE_USER = "hasAuthority('ROLE_system:userGroup:deleteUser')"; | ||||
public static final String USER_GROUP_RESET_USER_PASSWORD ="hasAuthority('ROLE_system:userGroup:resetUserPassword')" ; | |||||
public static final String USER_GROUP_CONFIG_EDIT ="hasAuthority('ROLE_system:userGroup:editUserConfig')" ; | |||||
/** | /** | ||||
* 控制台:用户管理 | * 控制台:用户管理 | ||||
@@ -142,6 +145,7 @@ public final class Permissions { | |||||
public static final String USER_DOWNLOAD = "hasAuthority('ROLE_system:user:download')"; | public static final String USER_DOWNLOAD = "hasAuthority('ROLE_system:user:download')"; | ||||
public static final String USER_CONFIG_EDIT = "hasAuthority('ROLE_system:user:configEdit')"; | public static final String USER_CONFIG_EDIT = "hasAuthority('ROLE_system:user:configEdit')"; | ||||
public static final String USER_RESOURCE_INFO = "hasAuthority('ROLE_system:user:resourceInfo')"; | public static final String USER_RESOURCE_INFO = "hasAuthority('ROLE_system:user:resourceInfo')"; | ||||
public static final String USER_RESET_PASSWORD = "hasAuthority('ROLE_system:user:resetPassword')"; | |||||
/** | /** | ||||
* 控制台:角色管理 | * 控制台:角色管理 | ||||
@@ -202,6 +206,13 @@ public final class Permissions { | |||||
public static final String SPECS_EDIT = "hasAuthority('ROLE_system:specs:edit')"; | public static final String SPECS_EDIT = "hasAuthority('ROLE_system:specs:edit')"; | ||||
public static final String SPECS_DELETE = "hasAuthority('ROLE_system:specs:delete')"; | public static final String SPECS_DELETE = "hasAuthority('ROLE_system:specs:delete')"; | ||||
/** | |||||
* 控制台:GPU资源管理 | |||||
*/ | |||||
public static final String GPU_CREATE = "hasAuthority('ROLE_system:gpu:create')"; | |||||
public static final String GPU_EDIT = "hasAuthority('ROLE_system:gpu:edit')"; | |||||
public static final String GPU_DELETE = "hasAuthority('ROLE_system:gpu:delete')"; | |||||
/** | /** | ||||
* 专业版:终端 | * 专业版:终端 | ||||
*/ | */ | ||||
@@ -211,6 +222,8 @@ public final class Permissions { | |||||
public static final String TERMINAL_DELETE = "hasAuthority('ROLE_terminal:specs:delete')"; | public static final String TERMINAL_DELETE = "hasAuthority('ROLE_terminal:specs:delete')"; | ||||
public static final String TERMINAL_DETAIL = "hasAuthority('ROLE_terminal:specs:detail')"; | public static final String TERMINAL_DETAIL = "hasAuthority('ROLE_terminal:specs:detail')"; | ||||
public static final String TERMINAL_LIST = "hasAuthority('ROLE_terminal:specs:list')"; | public static final String TERMINAL_LIST = "hasAuthority('ROLE_terminal:specs:list')"; | ||||
public static final String TERMINAL_UPDATE = "hasAuthority('ROLE_terminal:specs:update')"; | |||||
private Permissions() { | private Permissions() { | ||||
} | } | ||||
@@ -30,7 +30,7 @@ public final class StringConstant { | |||||
public static final String REQUEST_METHOD_GET = "GET"; | public static final String REQUEST_METHOD_GET = "GET"; | ||||
/** | /** | ||||
* 字母、数字、英文横杠和下划线匹配 | |||||
* 字母、数字、汉字、英文横杠和下划线匹配 | |||||
*/ | */ | ||||
public static final String REGEXP_NAME = "^[a-zA-Z0-9\\-\\_\\u4e00-\\u9fa5]+$"; | public static final String REGEXP_NAME = "^[a-zA-Z0-9\\-\\_\\u4e00-\\u9fa5]+$"; | ||||
@@ -49,10 +49,43 @@ public final class StringConstant { | |||||
*/ | */ | ||||
public static final String REGEXP_SPECS = "^[a-zA-Z0-9\\-\\_\\s\\u4e00-\\u9fa5]+$"; | public static final String REGEXP_SPECS = "^[a-zA-Z0-9\\-\\_\\s\\u4e00-\\u9fa5]+$"; | ||||
/** | |||||
* GPU类型支持字母、数字、汉字、英文横杠、英文.号、空白字符和英文斜杠 | |||||
*/ | |||||
public static final String REGEXP_GPU_TYPE = "^[a-zA-Z0-9\\-\\.\\s\\/\\u4e00-\\u9fa5]+$"; | |||||
/** | |||||
* GPU型号支持小写字母、数字、英文横杠、英文.号和英文斜杠 | |||||
*/ | |||||
public static final String REGEXP_GPU_MODEL = "^[a-z0-9\\-\\.\\/]+$"; | |||||
/** | |||||
* k8s GPU资源名称支持小写字母、数字、英文横杠、英文.号和英文斜杠 | |||||
*/ | |||||
public static final String REGEXP_K8S = "^[a-z0-9\\-\\.\\/]+$"; | |||||
/** | /** | ||||
* 整数匹配 | * 整数匹配 | ||||
*/ | */ | ||||
public static final Pattern PATTERN_NUM = Pattern.compile("^[-\\+]?[\\d]*$"); | public static final Pattern PATTERN_NUM = Pattern.compile("^[-\\+]?[\\d]*$"); | ||||
/** | |||||
* 数字匹配 | |||||
*/ | |||||
public static final String NUMBER ="(\\d+)"; | |||||
/** | |||||
* 整数匹配 | |||||
*/ | |||||
public static final Pattern PATTERN_NUMBER = Pattern.compile("(\\d+)"); | |||||
/** | |||||
* 小数匹配 | |||||
*/ | |||||
public static final Pattern PATTERN_DECIMAL = Pattern.compile("(\\d+\\.\\d+)"); | |||||
/** | |||||
* 描述内容支持字母、数字、汉字、英文横杠和下划线 | |||||
*/ | |||||
public static final String REGEXP_DESCRIPTION = "^[a-zA-Z0-9\\-\\_\\u4e00-\\u9fa5]+$"; | |||||
/** | /** | ||||
@@ -80,7 +113,7 @@ public final class StringConstant { | |||||
public static final String K8S_CALLBACK_PATH_DEPLOYMENT = "/api/k8s/callback/deployment"; | public static final String K8S_CALLBACK_PATH_DEPLOYMENT = "/api/k8s/callback/deployment"; | ||||
public static final String MULTIPART = "multipart/form-data"; | public static final String MULTIPART = "multipart/form-data"; | ||||
public static final String PIP_SITE_PACKAGE ="pip-site-package"; | |||||
public static final String PIP_SITE_PACKAGE = "pip-site-package"; | |||||
/** | /** | ||||
* 分页内容 | * 分页内容 | ||||
@@ -106,12 +139,20 @@ public final class StringConstant { | |||||
public static final String START_LOW = "start"; | public static final String START_LOW = "start"; | ||||
public static final String END_LOW = "end"; | public static final String END_LOW = "end"; | ||||
public static final String STEP_LOW = "step"; | public static final String STEP_LOW = "step"; | ||||
//1024*1024*1024 | |||||
public static final String MEM_UNIT = "1073741824"; | |||||
/** | /** | ||||
* 任务缓存 | * 任务缓存 | ||||
*/ | */ | ||||
public static final String CACHE_TASK_ID ="task_id"; | |||||
public static final String CACHE_TASK_NAME ="task_name"; | |||||
public static final String CACHE_TASK_ID = "task_id"; | |||||
public static final String CACHE_TASK_NAME = "task_name"; | |||||
/** | |||||
* python命令行参数格式 | |||||
*/ | |||||
public static final String PYTHON_COMMAND_PATTERN = " --%s=%s"; | |||||
private StringConstant() { | private StringConstant() { | ||||
@@ -27,8 +27,10 @@ public class SymbolConstant { | |||||
public static final String COLON = ":"; | public static final String COLON = ":"; | ||||
public static final String LINEBREAK = "\n"; | public static final String LINEBREAK = "\n"; | ||||
public static final String BLANK = ""; | public static final String BLANK = ""; | ||||
public static final String SPACE = " "; | |||||
public static final String QUESTION = "?"; | public static final String QUESTION = "?"; | ||||
public static final String ZERO = "0"; | public static final String ZERO = "0"; | ||||
public static final String ONE = "1"; | |||||
public static final String DOT = "."; | public static final String DOT = "."; | ||||
public static final String TOKEN = "token"; | public static final String TOKEN = "token"; | ||||
public static final String GET = "get"; | public static final String GET = "get"; | ||||
@@ -101,4 +101,19 @@ public class UserConstant { | |||||
*/ | */ | ||||
public final static Long DEFAULT_CREATE_USER_ID = 0L; | public final static Long DEFAULT_CREATE_USER_ID = 0L; | ||||
/** | |||||
* namespace前缀 | |||||
*/ | |||||
public final static String NAMESPACE_PREFIX = "namespace-"; | |||||
/** | |||||
* 查询7d内的用户资源用量 | |||||
*/ | |||||
public final static String UNIT_7D = "7d"; | |||||
/** | |||||
* 查询15d内的用户资源用量 | |||||
*/ | |||||
public final static String UNIT_15D = "15d"; | |||||
} | } |
@@ -0,0 +1,38 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Getter; | |||||
import lombok.Setter; | |||||
import java.io.Serializable; | |||||
import java.util.Set; | |||||
/** | |||||
* @description 删除用数据包 | |||||
* @date 2020-03-15 | |||||
*/ | |||||
@Getter | |||||
@Setter | |||||
public class DeleteDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
private Set<Long> ids; | |||||
} |
@@ -0,0 +1,45 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户配置DTO | |||||
* @date 2021-09-06 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class GpuConfigDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
/** | |||||
* 用户 ID | |||||
*/ | |||||
@NotNull(message = "用户 ID 不能为空") | |||||
private Long userId; | |||||
/** | |||||
* GPU 资源限制 | |||||
*/ | |||||
private List<SysUserGpuConfigDTO> gpuResources; | |||||
} |
@@ -18,6 +18,7 @@ package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import org.dubhe.biz.base.constant.NumberConstant; | import org.dubhe.biz.base.constant.NumberConstant; | ||||
import org.dubhe.biz.base.constant.StringConstant; | import org.dubhe.biz.base.constant.StringConstant; | ||||
import org.hibernate.validator.constraints.Length; | import org.hibernate.validator.constraints.Length; | ||||
@@ -42,7 +43,7 @@ public class ModelOptAlgorithmCreateDTO implements Serializable { | |||||
private String name; | private String name; | ||||
@NotBlank(message = "代码目录不能为空") | @NotBlank(message = "代码目录不能为空") | ||||
@Length(max = NumberConstant.NUMBER_64, message = "代码目录-输入长度不能超过128个字符") | |||||
@Length(max = MagicNumConstant.ONE_HUNDRED_TWENTY_EIGHT, message = "代码目录-输入长度不能超过128个字符") | |||||
private String path; | private String path; | ||||
} | } |
@@ -0,0 +1,38 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import javax.validation.constraints.NotEmpty; | |||||
import java.io.Serializable; | |||||
import java.util.Set; | |||||
/** | |||||
* @description 命名空间删除DTO | |||||
* @date 2021-11-29 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class NamespaceDeleteDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@NotEmpty(message = "id不能为空") | |||||
Set<Long> ids; | |||||
} |
@@ -37,4 +37,6 @@ public class PtImageQueryUrlDTO { | |||||
private Integer projectType; | private Integer projectType; | ||||
private Long id; | |||||
} | } |
@@ -45,10 +45,10 @@ public class QueryResourceSpecsDTO implements Serializable { | |||||
private String specsName; | private String specsName; | ||||
/** | /** | ||||
* 所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving) | |||||
* 所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving,4:dubhe-tadl,5:dubhe-optimize) | |||||
*/ | */ | ||||
@NotNull(message = "所属业务场景不能为空") | @NotNull(message = "所属业务场景不能为空") | ||||
@Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | @Min(value = MagicNumConstant.ZERO, message = "所属业务场景错误") | ||||
@Max(value = MagicNumConstant.THREE, message = "所属业务场景错误") | |||||
@Max(value = MagicNumConstant.FIVE, message = "所属业务场景错误") | |||||
private Integer module; | private Integer module; | ||||
} | } |
@@ -0,0 +1,121 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import org.dubhe.biz.base.constant.MagicNumConstant; | |||||
import javax.validation.constraints.Min; | |||||
import javax.validation.constraints.NotEmpty; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
import java.sql.Timestamp; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户k8s可用资源查询实体类 | |||||
* @date 2021-09-10 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class QueryUserK8sResourceDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@NotNull(message = "用户 ID 不能为空") | |||||
private Long userId; | |||||
@NotNull(message = "节点个数") | |||||
private Integer resourcesPoolNode; | |||||
/** | |||||
* GPU型号(例如:v100) | |||||
*/ | |||||
private String gpuModel; | |||||
/** | |||||
*k8s GPU资源标签key值(例如:nvidia.com/gpu) | |||||
*/ | |||||
private String k8sLabelKey; | |||||
/** | |||||
* 主键ID | |||||
*/ | |||||
@NotNull(message = "主键ID") | |||||
private Long id; | |||||
/** | |||||
*规格名称 | |||||
*/ | |||||
private String specsName; | |||||
/** | |||||
*规格类型(0为CPU, 1为GPU) | |||||
*/ | |||||
@NotNull(message = "规格类型(0为CPU, 1为GPU)") | |||||
private Boolean resourcesPoolType; | |||||
/** | |||||
*所属业务场景(0:通用,1:dubhe-notebook,2:dubhe-train,3:dubhe-serving,4:dubhe-tadl) | |||||
*/ | |||||
private Integer module; | |||||
/** | |||||
*CPU数量,单位:核 | |||||
*/ | |||||
@NotNull(message = "CPU数量,单位:核") | |||||
private Integer cpuNum; | |||||
/** | |||||
*GPU数量,单位:核 | |||||
*/ | |||||
@NotNull(message = "GPU数量,单位:核") | |||||
private Integer gpuNum; | |||||
/** | |||||
*内存大小,单位:M | |||||
*/ | |||||
@NotNull(message = "内存大小,单位:M") | |||||
private Integer memNum; | |||||
/** | |||||
*工作空间的存储配额,单位:M | |||||
*/ | |||||
private Integer workspaceRequest; | |||||
/** | |||||
*创建人 | |||||
*/ | |||||
private Long createUserId; | |||||
/** | |||||
*创建时间 | |||||
*/ | |||||
private Timestamp createTime; | |||||
/** | |||||
*更新人 | |||||
*/ | |||||
private Long updateUserId; | |||||
/** | |||||
*更新时间 | |||||
*/ | |||||
private Timestamp updateTime; | |||||
} |
@@ -0,0 +1,43 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.util.Map; | |||||
/** | |||||
* @description k8s节点资源隔离DTO | |||||
* @date 2021-07-21 | |||||
*/ | |||||
@Data | |||||
public class ResourceQuotaDTO { | |||||
@NotNull(message = "用户 ID 不能为空") | |||||
private Long userId; | |||||
@NotNull(message = "CPU 资源限制配置不能为空") | |||||
private Integer cpuLimit; | |||||
@NotNull(message = "内存资源限制配置不能为空") | |||||
private Integer memoryLimit; | |||||
@NotNull(message = "GPU 资源限制配置不能为空") | |||||
private Map<String, Integer> gpuLimit; | |||||
} |
@@ -18,7 +18,9 @@ package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | import lombok.Data; | ||||
import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
import java.util.List; | |||||
/** | /** | ||||
* @description 系统用户配置 DTO | * @description 系统用户配置 DTO | ||||
@@ -26,7 +28,7 @@ import java.io.Serializable; | |||||
*/ | */ | ||||
@Data | @Data | ||||
@Accessors(chain = true) | @Accessors(chain = true) | ||||
public class SysUserConfigDTO implements Serializable{ | |||||
public class SysUserConfigDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | private static final long serialVersionUID = 1L; | ||||
@@ -46,8 +48,12 @@ public class SysUserConfigDTO implements Serializable{ | |||||
private Integer memoryLimit; | private Integer memoryLimit; | ||||
/** | /** | ||||
* GPU 资源限制配置 | |||||
* GPU 资源限制 | |||||
*/ | */ | ||||
private Integer gpuLimit; | |||||
private List<SysUserGpuConfigDTO> gpuResources; | |||||
/** | |||||
* 用户默认镜像 | |||||
*/ | |||||
private Long defaultImageId; | |||||
} | } |
@@ -0,0 +1,52 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description 系统用户GPU配置 DTO | |||||
* @date 2021-09-03 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class SysUserGpuConfigDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
/** | |||||
* GPU类型(例如:NVIDIA) | |||||
*/ | |||||
private String gpuType; | |||||
/** | |||||
* GPU型号(例如:v100) | |||||
*/ | |||||
private String gpuModel; | |||||
/** | |||||
* k8s GPU资源标签key值(例如:nvidia.com/gpu) | |||||
*/ | |||||
private String k8sLabelKey; | |||||
/** | |||||
* GPU 资源限制配置不能为空 | |||||
*/ | |||||
private Integer gpuLimit; | |||||
} |
@@ -0,0 +1,50 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
import java.util.List; | |||||
/** | |||||
* @description 用户配置DTO | |||||
* @date 2021-7-1 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class UserConfigSaveDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@NotNull(message = "用户 ID 不能为空") | |||||
private Long userId; | |||||
@NotNull(message = "Notebook 延迟删除时间配置不能为空") | |||||
private Integer notebookDelayDeleteTime; | |||||
@NotNull(message = "CPU 资源限制配置不能为空") | |||||
private Integer cpuLimit; | |||||
@NotNull(message = "内存资源限制配置不能为空") | |||||
private Integer memoryLimit; | |||||
private Long defaultImageId; | |||||
private List<UserGpuConfigDTO> gpuResources; | |||||
} |
@@ -45,6 +45,8 @@ public class UserDTO implements Serializable { | |||||
private String remark; | private String remark; | ||||
private String userGroupName; | |||||
private Date lastPasswordResetTime; | private Date lastPasswordResetTime; | ||||
private Timestamp createTime; | private Timestamp createTime; | ||||
@@ -0,0 +1,46 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.dto; | |||||
import lombok.Data; | |||||
import lombok.experimental.Accessors; | |||||
import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | |||||
import java.io.Serializable; | |||||
/** | |||||
* @description 用户GPU配置DTO | |||||
* @date 2021-7-1 | |||||
*/ | |||||
@Data | |||||
@Accessors(chain = true) | |||||
public class UserGpuConfigDTO implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@NotBlank(message = "GPU类型") | |||||
private String gpuType; | |||||
@NotBlank(message = "GPU型号") | |||||
private String gpuModel; | |||||
@NotBlank(message = "k8s GPU资源标签key值") | |||||
private String k8sLabelKey; | |||||
@NotNull(message = "GPU 资源限制配置不能为空") | |||||
private Integer gpuLimit; | |||||
} |
@@ -43,7 +43,7 @@ public enum BaseErrorCodeEnum implements ErrorCode { | |||||
SYSTEM_USER_ALREADY_REGISTER(20003, "账号已注册!"), | SYSTEM_USER_ALREADY_REGISTER(20003, "账号已注册!"), | ||||
SYSTEM_USER_REGISTER_EMAIL_INFO_EXPIRED(20004, "邮箱验证码已过期!"), | SYSTEM_USER_REGISTER_EMAIL_INFO_EXPIRED(20004, "邮箱验证码已过期!"), | ||||
SYSTEM_USER_EMAIL_ALREADY_EXISTS(20004, "该邮箱已被注册!"), | SYSTEM_USER_EMAIL_ALREADY_EXISTS(20004, "该邮箱已被注册!"), | ||||
SYSTEM_USER_EMAIL_PASSWORD_ERROR(20005, "邮件密码错误!"), | |||||
SYSTEM_USER_EMAIL_PASSWORD_ERROR(20005, "密码错误!"), | |||||
SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES(20006, "邮件发送不能超过三次!"), | SYSTEM_USER_EMAIL_CODE_CANNOT_EXCEED_TIMES(20006, "邮件发送不能超过三次!"), | ||||
SYSTEM_USER_EMAIL_OR_CODE_ERROR(20007, "邮箱地址或验证码错误、请重新输入!"), | SYSTEM_USER_EMAIL_OR_CODE_ERROR(20007, "邮箱地址或验证码错误、请重新输入!"), | ||||
SYSTEM_USER_IS_LOCKED(20008, "用户已锁定!"), | SYSTEM_USER_IS_LOCKED(20008, "用户已锁定!"), | ||||
@@ -61,7 +61,10 @@ public enum BizEnum { | |||||
* 专业版终端 | * 专业版终端 | ||||
*/ | */ | ||||
TERMINAL("专业版终端", "terminal", 7), | TERMINAL("专业版终端", "terminal", 7), | ||||
; | |||||
/** | |||||
* TADL | |||||
*/ | |||||
TADL("TADL服务", "tadl", 8); | |||||
/** | /** | ||||
* 业务模块名称 | * 业务模块名称 | ||||
@@ -35,8 +35,9 @@ public class AesUtil { | |||||
private static final String AES = "AES"; | private static final String AES = "AES"; | ||||
public static final String RESOURCE_KYE = "123456"; | |||||
private AesUtil(){ | |||||
private AesUtil() { | |||||
} | } | ||||
@@ -50,7 +51,7 @@ public class AesUtil { | |||||
* @throws NoSuchPaddingException | * @throws NoSuchPaddingException | ||||
* @throws InvalidKeyException | * @throws InvalidKeyException | ||||
*/ | */ | ||||
private static Cipher getCipher(int mode,String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { | |||||
private static Cipher getCipher(int mode, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { | |||||
MessageDigest md5Digest = MessageDigest.getInstance("MD5"); | MessageDigest md5Digest = MessageDigest.getInstance("MD5"); | ||||
SecretKeySpec secretKeySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(StandardCharsets.UTF_8)), AES); | SecretKeySpec secretKeySpec = new SecretKeySpec(md5Digest.digest(key.getBytes(StandardCharsets.UTF_8)), AES); | ||||
Cipher cipher = Cipher.getInstance(AES); | Cipher cipher = Cipher.getInstance(AES); | ||||
@@ -67,7 +68,7 @@ public class AesUtil { | |||||
*/ | */ | ||||
public static String encrypt(String data, String key) { | public static String encrypt(String data, String key) { | ||||
try { | try { | ||||
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE,key); | |||||
Cipher cipher = getCipher(Cipher.ENCRYPT_MODE, key); | |||||
byte[] content = data.getBytes(StandardCharsets.UTF_8); | byte[] content = data.getBytes(StandardCharsets.UTF_8); | ||||
return new String(HexUtil.encodeHex(cipher.doFinal(content), false)); | return new String(HexUtil.encodeHex(cipher.doFinal(content), false)); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
@@ -79,11 +80,11 @@ public class AesUtil { | |||||
* 解密 | * 解密 | ||||
* @param hexData 十六进制密文 | * @param hexData 十六进制密文 | ||||
* @param key 秘钥 | * @param key 秘钥 | ||||
* @return String 密文 | |||||
* @return String 密文 | |||||
*/ | */ | ||||
public static String decrypt(String hexData, String key) { | public static String decrypt(String hexData, String key) { | ||||
try { | try { | ||||
Cipher cipher = getCipher(Cipher.DECRYPT_MODE,key); | |||||
Cipher cipher = getCipher(Cipher.DECRYPT_MODE, key); | |||||
byte[] content = HexUtil.decodeHex(hexData); | byte[] content = HexUtil.decodeHex(hexData); | ||||
return new String(cipher.doFinal(content), StandardCharsets.UTF_8); | return new String(cipher.doFinal(content), StandardCharsets.UTF_8); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
@@ -0,0 +1,44 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.utils; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import static org.dubhe.biz.base.constant.StringConstant.PYTHON_COMMAND_PATTERN; | |||||
/** | |||||
* @description 命令行工具类 | |||||
* @date 2021-09-22 | |||||
*/ | |||||
public class CommandUtil { | |||||
/** | |||||
* 构造python运行命令 | |||||
* | |||||
* @param runCommand | |||||
* @param runParams | |||||
* @return | |||||
*/ | |||||
public static String buildPythonCommand(String runCommand, JSONObject runParams) { | |||||
StringBuilder sb = new StringBuilder(); | |||||
sb.append(runCommand); | |||||
if (null != runParams && !runParams.isEmpty()) { | |||||
runParams.forEach((k, v) -> sb.append(String.format(PYTHON_COMMAND_PATTERN, k, v))); | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
} |
@@ -19,6 +19,7 @@ package org.dubhe.biz.base.utils; | |||||
import java.sql.Timestamp; | import java.sql.Timestamp; | ||||
import java.text.DateFormat; | import java.text.DateFormat; | ||||
import java.text.ParseException; | |||||
import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||
import java.time.Instant; | import java.time.Instant; | ||||
import java.time.LocalDate; | import java.time.LocalDate; | ||||
@@ -125,4 +126,24 @@ public class DateUtil { | |||||
return Timestamp.valueOf(sdf.format(calendar.getTime())); | return Timestamp.valueOf(sdf.format(calendar.getTime())); | ||||
} | } | ||||
/** | |||||
* CST时间转换成UTC Date String | |||||
* 输入:2021-11-17T08:50:23Z | |||||
* 返回:2021-11-17 16:50:23 | |||||
* | |||||
* @param time | |||||
* @return | |||||
* @throws ParseException | |||||
*/ | |||||
public static String convertCST2UTCDate(String time) throws ParseException { | |||||
SimpleDateFormat parseFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); | |||||
Date dateTime = parseFormat.parse(time); | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.setTime(dateTime); | |||||
calendar.set(Calendar.HOUR,calendar.get(Calendar.HOUR) + 8); | |||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
return simpleDateFormat.format(calendar.getTime()); | |||||
} | |||||
} | } |
@@ -0,0 +1,39 @@ | |||||
/** | |||||
* Copyright 2020 Tianshu AI Platform. All Rights Reserved. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||||
* you may not use this file except in compliance with the License. | |||||
* You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* ============================================================= | |||||
*/ | |||||
package org.dubhe.biz.base.utils; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* @description Map工具类 | |||||
* @date 2021-09-22 | |||||
*/ | |||||
public class MapUtil { | |||||
public static Map<String, String> convertJsonObject(JSONObject object) { | |||||
if (object == null) { | |||||
return new HashMap<>(); | |||||
} | |||||
return JSONObject.parseObject(object.toJSONString(), | |||||
new TypeReference<Map<String, String>>(){}); | |||||
} | |||||
} |
@@ -72,4 +72,5 @@ public class MathUtils { | |||||
return Float.valueOf(num1) / Float.valueOf(num2); | return Float.valueOf(num1) / Float.valueOf(num2); | ||||
} | } | ||||
} | } | ||||
} | } |