From 7828459e9e496232aa130a37b90ca18e8a16e46e Mon Sep 17 00:00:00 2001 From: mabofu Date: Tue, 27 Dec 2022 16:33:09 +0800 Subject: [PATCH] Add add osd and remove feature --- .../node/controller/NodeController.java | 23 +++- .../dsms/modules/node/model/vo/NodeAddVO.java | 43 ++++++ .../vo/{NodeVO.java => NodeQueryVO.java} | 4 +- .../modules/node/model/vo/NodeRemoveVO.java | 39 ++++++ .../node/service/impl/NodeServiceImpl.java | 124 +++++++++++++++++- .../common/constant/DeviceStatusEnum.java | 2 +- .../com/dsms/common/constant/ResultCode.java | 3 + .../dsms/common/constant/TaskTypeEnum.java | 41 ++++++ .../dfsbroker/node/service/INodeService.java | 18 +++ sql/dsms-engine_init.sql | 2 +- 10 files changed, 285 insertions(+), 14 deletions(-) create mode 100644 dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeAddVO.java rename dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/{NodeVO.java => NodeQueryVO.java} (91%) create mode 100644 dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeRemoveVO.java create mode 100644 dsms-engine-common/src/main/java/com/dsms/common/constant/TaskTypeEnum.java diff --git a/dsms-engine-application/src/main/java/com/dsms/modules/node/controller/NodeController.java b/dsms-engine-application/src/main/java/com/dsms/modules/node/controller/NodeController.java index 87c6cded..a029dd99 100644 --- a/dsms-engine-application/src/main/java/com/dsms/modules/node/controller/NodeController.java +++ b/dsms-engine-application/src/main/java/com/dsms/modules/node/controller/NodeController.java @@ -16,25 +16,22 @@ package com.dsms.modules.node.controller; -import cn.hutool.core.lang.Validator; import com.dsms.common.model.Result; import com.dsms.dfsbroker.node.model.Node; import com.dsms.dfsbroker.node.service.INodeService; -import com.dsms.modules.cluster.model.vo.ClusterVO; -import com.dsms.modules.node.model.vo.NodeVO; +import com.dsms.modules.node.model.vo.NodeAddVO; +import com.dsms.modules.node.model.vo.NodeQueryVO; +import com.dsms.modules.node.model.vo.NodeRemoveVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.apache.commons.lang3.Validate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; -import java.util.Map; @RestController @@ -55,8 +52,20 @@ public class NodeController { @ApiOperation("节点池模块-获取节点详细信息") @PostMapping("/get") - public Result info(@Validated @RequestBody NodeVO nodeVO) { + public Result info(@Validated @RequestBody NodeQueryVO nodeVO) { return Result.OK(nodeService.getNodeInfo(nodeVO.getNodeName())); } + @ApiOperation("节点池模块-节点管理磁盘") + @PostMapping("/add_osd") + public Result addOsd(@Validated @RequestBody NodeAddVO nodeAddVO) { + return Result.OK(nodeService.addOsd(nodeAddVO.getNodeName(), nodeAddVO.getDevicePath())); + } + + @ApiOperation("节点池模块-节点移除磁盘") + @PostMapping("/remove_osd") + public Result removeOsd(@RequestBody NodeRemoveVO nodeRemoveVO) { + return Result.OK(nodeService.removeOsd(nodeRemoveVO.getOsdId())); + } + } diff --git a/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeAddVO.java b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeAddVO.java new file mode 100644 index 00000000..f3d162e0 --- /dev/null +++ b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeAddVO.java @@ -0,0 +1,43 @@ +/* + * Copyright 2022 The DSMS Authors. + * + * 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 com.dsms.modules.node.model.vo; + +import com.dsms.common.validator.Ip; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +@ApiModel(value = "节点池模块 Request VO", description = "节点新增磁盘") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class NodeAddVO { + + @ApiModelProperty(value = "节点名称", required = true, example = "node1") + @NotBlank(message = "节点名称不能为空") + private String nodeName; + @ApiModelProperty(value = "磁盘路径", required = true, example = "/dev/sda") + @NotBlank(message = "磁盘路径不能为空") + private String devicePath; + + +} diff --git a/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeVO.java b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeQueryVO.java similarity index 91% rename from dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeVO.java rename to dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeQueryVO.java index 7ab55c6c..2071ada9 100644 --- a/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeVO.java +++ b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeQueryVO.java @@ -24,12 +24,12 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; -@ApiModel(value = "节点详情 Request VO", description = "节点详情") +@ApiModel(value = "节点池模块 Request VO", description = "节点详情") @Data @NoArgsConstructor @AllArgsConstructor @Builder -public class NodeVO { +public class NodeQueryVO { @ApiModelProperty(value = "节点名称", required = true, example = "node1") diff --git a/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeRemoveVO.java b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeRemoveVO.java new file mode 100644 index 00000000..df99b59b --- /dev/null +++ b/dsms-engine-application/src/main/java/com/dsms/modules/node/model/vo/NodeRemoveVO.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 The DSMS Authors. + * + * 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 com.dsms.modules.node.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +@ApiModel(value = "节点池模块 Request VO", description = "节点移除磁盘") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class NodeRemoveVO { + + @ApiModelProperty(value = "osdId", required = true, example = "0") + @NotNull(message = "osdId 不能为空") + private Integer osdId; + + +} diff --git a/dsms-engine-application/src/main/java/com/dsms/modules/node/service/impl/NodeServiceImpl.java b/dsms-engine-application/src/main/java/com/dsms/modules/node/service/impl/NodeServiceImpl.java index 42ef0b64..e2adcbe9 100644 --- a/dsms-engine-application/src/main/java/com/dsms/modules/node/service/impl/NodeServiceImpl.java +++ b/dsms-engine-application/src/main/java/com/dsms/modules/node/service/impl/NodeServiceImpl.java @@ -16,9 +16,13 @@ package com.dsms.modules.node.service.impl; -import com.dsms.common.constant.NodeStatusEnum; -import com.dsms.common.constant.ResultCode; +import com.dsms.common.constant.*; import com.dsms.common.exception.DsmsEngineException; +import com.dsms.common.remotecall.model.RemoteResponse; +import com.dsms.common.taskmanager.TaskException; +import com.dsms.common.taskmanager.model.AsyncTask; +import com.dsms.common.taskmanager.model.Task; +import com.dsms.common.taskmanager.service.ITaskService; import com.dsms.dfsbroker.node.api.NodeApi; import com.dsms.dfsbroker.node.model.Device; import com.dsms.dfsbroker.node.model.Node; @@ -32,7 +36,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; -import java.io.IOException; import java.net.Socket; import java.util.ArrayList; import java.util.List; @@ -44,6 +47,9 @@ public class NodeServiceImpl implements INodeService { @Autowired private NodeApi nodeApi; + @Autowired + private ITaskService taskService; + @Override public List list() { @@ -84,6 +90,7 @@ public class NodeServiceImpl implements INodeService { long count = devices.stream().filter(device -> device.getOsdId() != null).count(); node.setNodeUsedDevice((int) count); node.setNodeAllDevice(devices.size()); + node.setDevices(devices); } catch (Throwable e) { log.warn("get device count from dsms-storage fail", e); } @@ -126,4 +133,115 @@ public class NodeServiceImpl implements INodeService { return node; } + + @Override + public boolean addOsd(String nodeName, String devicePath) { + //1.校验 node 和磁盘 + if (!validateNode(nodeName)) { + throw new DsmsEngineException(ResultCode.NODE_NOT_EXIST); + } + if (!validateDeviceAvailable(nodeName, devicePath)) { + throw new DsmsEngineException(ResultCode.NODE_DEVICE_NOT_AVAILABLE); + } + + //2.构建任务 + RemoteResponse response; + try { + response = nodeApi.addOsd(RemoteCallUtil.generateRemoteRequest(), nodeName, devicePath); + if (ObjectUtils.isEmpty(response.getId())) { + throw new TaskException("add osd schedule create fail"); + } + } catch (Throwable e) { + throw new DsmsEngineException(e, ResultCode.NODE_ADDOSD_TASKERROR); + } + + Task task = new AsyncTask(); + task.setTaskName(TaskTypeEnum.ADD_OSD.getName()); + task.setTaskType(TaskTypeEnum.ADD_OSD.getType()); + task.setTaskParam(response.getId()); + task.setTaskMessage("节点管理磁盘,节点:" + nodeName + ", 磁盘路径:" + devicePath); + task.setTaskStatus(TaskStatusEnum.QUEUE.getStatus()); + + return taskService.save(task); + } + + @Override + public boolean removeOsd(Integer osdId) { + //1.校验osdId + if (!validateOsdId(osdId)) { + throw new DsmsEngineException(ResultCode.NODE_OSD_NOT_EXIST); + } + + try { + boolean rmOsdSchedule = nodeApi.rmOsdSchedule(RemoteCallUtil.generateRemoteRequest(), new String[]{osdId.toString()}); + if (!rmOsdSchedule) { + throw new TaskException("rm osd schedule create fail"); + } + } catch (Throwable e) { + throw new DsmsEngineException(e, ResultCode.NODE_REMOVEOSD_TASKERROR); + } + + Task task = new AsyncTask(); + task.setTaskName(TaskTypeEnum.REMOVE_OSD.getName()); + task.setTaskType(TaskTypeEnum.REMOVE_OSD.getType()); + task.setTaskParam(String.valueOf(osdId)); + task.setTaskMessage("节点移除磁盘,osdId:" + osdId); + task.setTaskStatus(TaskStatusEnum.QUEUE.getStatus()); + + return taskService.save(task); + } + + @Override + public boolean validateNode(String nodeName) { + List nodeList = list(); + boolean nodeExist = false; + for (Node node : nodeList) { + if (node.getNodeName().equals(nodeName)) { + nodeExist = true; + break; + } + } + + return nodeExist; + } + + + @Override + public boolean validateDeviceAvailable(String nodeName, String devicePath) { + List nodeList = list(); + boolean nodeExist = false; + boolean deviceAvailable = false; + for (Node node : nodeList) { + if (node.getNodeName().equals(nodeName)) { + nodeExist = true; + for (Device device : node.getDevices()) { + if (device.getDevicePath().equals(devicePath) && DeviceStatusEnum.AVAILABLE.getStatus().equals(device.getDeviceStatus())) { + deviceAvailable = true; + break; + } + } + } + } + + return nodeExist && deviceAvailable; + } + + @Override + public boolean validateOsdId(Integer osdId) { + boolean osdExist = false; + try { + OsdDfResult osdDf = nodeApi.getOsdDf(RemoteCallUtil.generateRemoteRequest()); + List osdDfDevice = Device.osdDfResultParseDevice(osdDf); + for (Device deviceDf : osdDfDevice) { + if (deviceDf.getOsdId().equals(osdId)) { + osdExist = true; + break; + } + } + } catch (Throwable e) { + return false; + } + + return osdExist; + } } diff --git a/dsms-engine-common/src/main/java/com/dsms/common/constant/DeviceStatusEnum.java b/dsms-engine-common/src/main/java/com/dsms/common/constant/DeviceStatusEnum.java index 917a7710..2e5f27b3 100644 --- a/dsms-engine-common/src/main/java/com/dsms/common/constant/DeviceStatusEnum.java +++ b/dsms-engine-common/src/main/java/com/dsms/common/constant/DeviceStatusEnum.java @@ -33,7 +33,7 @@ public enum DeviceStatusEnum { */ AVAILABLE(1, "可用"); - private final int status; + private final Integer status; private final String message; } diff --git a/dsms-engine-common/src/main/java/com/dsms/common/constant/ResultCode.java b/dsms-engine-common/src/main/java/com/dsms/common/constant/ResultCode.java index 08a27f1b..29c8b13a 100644 --- a/dsms-engine-common/src/main/java/com/dsms/common/constant/ResultCode.java +++ b/dsms-engine-common/src/main/java/com/dsms/common/constant/ResultCode.java @@ -52,6 +52,9 @@ public enum ResultCode { NODE_POOLEXIST(1201, "磁盘已占用,请先移除占用"), NODE_REMOVEOSD_TASKERROR(1202, "节点删除磁盘任务创建失败"), NODE_LISTNODE_ERROR(1203, "获取节点池信息失败"), + NODE_NOT_EXIST(1204, "节点不存在"), + NODE_DEVICE_NOT_AVAILABLE(1205, "磁盘不可用"), + NODE_OSD_NOT_EXIST(1206, "osd不存在"), ; /** diff --git a/dsms-engine-common/src/main/java/com/dsms/common/constant/TaskTypeEnum.java b/dsms-engine-common/src/main/java/com/dsms/common/constant/TaskTypeEnum.java new file mode 100644 index 00000000..daba4c40 --- /dev/null +++ b/dsms-engine-common/src/main/java/com/dsms/common/constant/TaskTypeEnum.java @@ -0,0 +1,41 @@ +/* + * Copyright 2022 The DSMS Authors. + * + * 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 com.dsms.common.constant; + +import lombok.AllArgsConstructor; +import lombok.Getter; + + +/** + * 任务类型枚举 + */ +@Getter +@AllArgsConstructor +public enum TaskTypeEnum { + /** + * 管理磁盘 + */ + ADD_OSD("add_osd", "节点管理磁盘"), + /** + * 移除磁盘 + */ + REMOVE_OSD("remove_osd", "节点移除磁盘"); + + private final String type; + private final String name; + +} diff --git a/dsms-engine-dfsbroker/src/main/java/com/dsms/dfsbroker/node/service/INodeService.java b/dsms-engine-dfsbroker/src/main/java/com/dsms/dfsbroker/node/service/INodeService.java index 64cc384d..70120139 100644 --- a/dsms-engine-dfsbroker/src/main/java/com/dsms/dfsbroker/node/service/INodeService.java +++ b/dsms-engine-dfsbroker/src/main/java/com/dsms/dfsbroker/node/service/INodeService.java @@ -34,4 +34,22 @@ public interface INodeService { * @return 包含磁盘信息的node对象 */ Node getNodeInfo(String nodeName); + + /** + * 节点新增磁盘 + * @param nodeName 节点名称 + * @param devicePath 节点路径 + */ + boolean addOsd(String nodeName, String devicePath); + /** + * 节点移除磁盘 + * @param osdId osdId + */ + boolean removeOsd(Integer osdId); + + boolean validateNode(String nodeName); + + boolean validateDeviceAvailable(String nodeName, String devicePath); + + boolean validateOsdId(Integer osdId); } diff --git a/sql/dsms-engine_init.sql b/sql/dsms-engine_init.sql index 8e3fb742..c7be7951 100644 --- a/sql/dsms-engine_init.sql +++ b/sql/dsms-engine_init.sql @@ -76,6 +76,6 @@ CREATE TABLE `task` ( `task_message` varchar(32) NOT NULL DEFAULT '' COMMENT '任务信息', `task_param` varchar(32) NOT NULL DEFAULT '' COMMENT '任务参数', `task_start_time` datetime NOT NULL DEFAULT current_timestamp() COMMENT '任务开始时间', - `task_end_time` datetime NOT NULL COMMENT '任务结束时间', + `task_end_time` datetime COMMENT '任务结束时间', PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '任务信息表'; \ No newline at end of file -- Gitee