diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.http b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.http new file mode 100644 index 00000000..8d41545b --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.http @@ -0,0 +1,64 @@ +### 创建主机 +POST {{baseUrl}}/asset/host/create +Content-Type: application/json +Authorization: {{token}} + +{ + "name": "", + "code": "", + "address": "" +} + + +### 通过 id 更新主机 +PUT {{baseUrl}}/asset/host/update +Content-Type: application/json +Authorization: {{token}} + +{ + "id": "", + "name": "", + "code": "", + "address": "" +} + + +### 通过 id 查询主机 +GET {{baseUrl}}/asset/host/get?id=1&extra=true&config=true +Authorization: {{token}} + + +### 查询主机 +POST {{baseUrl}}/asset/host/list-all +Content-Type: application/json +Authorization: {{token}} + +{ + "id": "", + "name": "", + "code": "", + "address": "" +} + + +### 分页查询主机 +POST {{baseUrl}}/asset/host/query +Content-Type: application/json +Authorization: {{token}} + +{ + "page": 1, + "limit": 10, + "id": "", + "name": "", + "code": "", + "address": "" +} + + +### 通过 id 删除主机 +DELETE {{baseUrl}}/asset/host/delete?id=1 +Authorization: {{token}} + + +### diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.java new file mode 100644 index 00000000..8161936f --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/controller/HostController.java @@ -0,0 +1,100 @@ +package com.orion.ops.module.asset.controller; + +import com.orion.lang.define.wrapper.DataGrid; +import com.orion.ops.framework.common.annotation.IgnoreLog; +import com.orion.ops.framework.common.annotation.RestWrapper; +import com.orion.ops.framework.common.constant.IgnoreLogMode; +import com.orion.ops.framework.common.valid.group.Id; +import com.orion.ops.framework.common.valid.group.Page; +import com.orion.ops.module.asset.entity.request.host.HostCreateRequest; +import com.orion.ops.module.asset.entity.request.host.HostQueryRequest; +import com.orion.ops.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.ops.module.asset.entity.vo.HostVO; +import com.orion.ops.module.asset.service.HostService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 主机 api + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Tag(name = "asset - 主机服务") +@Slf4j +@Validated +@RestWrapper +@RestController +@RequestMapping("/asset/host") +@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"}) +public class HostController { + + @Resource + private HostService hostService; + + @PostMapping("/create") + @Operation(summary = "创建主机") + @PreAuthorize("@ss.hasPermission('asset:host:create')") + public Long createHost(@Validated @RequestBody HostCreateRequest request) { + return hostService.createHost(request); + } + + @PutMapping("/update") + @Operation(summary = "通过 id 更新主机") + @PreAuthorize("@ss.hasPermission('asset:host:update')") + public Integer updateHost(@Validated(Id.class) @RequestBody HostUpdateRequest request) { + return hostService.updateHostById(request); + } + + @IgnoreLog(IgnoreLogMode.RET) + @GetMapping("/get") + @Operation(summary = "通过 id 查询主机") + @Parameter(name = "id", description = "id", required = true) + @Parameter(name = "extra", description = "是否查询额外信息") + @Parameter(name = "config", description = "是否查询配置信息") + @PreAuthorize("@ss.hasPermission('asset:host:query')") + public HostVO getHost(@RequestParam("id") Long id, + @RequestParam(name = "extra", required = false) boolean extra, + @RequestParam(name = "config", required = false) boolean config) { + HostQueryRequest request = new HostQueryRequest(); + request.setId(id); + request.setExtra(extra); + request.setConfig(config); + return hostService.getHostById(request); + } + + @IgnoreLog(IgnoreLogMode.RET) + @PostMapping("/list-all") + @Operation(summary = "查询主机") + @PreAuthorize("@ss.hasPermission('asset:host:query')") + public List getHostListAll(@Validated @RequestBody HostQueryRequest request) { + return hostService.getHostList(request); + } + + @IgnoreLog(IgnoreLogMode.RET) + @PostMapping("/query") + @Operation(summary = "分页查询主机") + @PreAuthorize("@ss.hasPermission('asset:host:query')") + public DataGrid getHostPage(@Validated(Page.class) @RequestBody HostQueryRequest request) { + return hostService.getHostPage(request); + } + + @DeleteMapping("/delete") + @Operation(summary = "通过 id 删除主机") + @Parameter(name = "id", description = "id", required = true) + @PreAuthorize("@ss.hasPermission('asset:host:delete')") + public Integer deleteHost(@RequestParam("id") Long id) { + return hostService.deleteHostById(id); + } + +} + diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConfigConvert.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConfigConvert.java new file mode 100644 index 00000000..25a5117e --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConfigConvert.java @@ -0,0 +1,22 @@ +package com.orion.ops.module.asset.convert; + +import com.orion.ops.module.asset.entity.domain.HostConfigDO; +import com.orion.ops.module.asset.entity.vo.HostConfigVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 主机配置 内部对象转换器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Mapper +public interface HostConfigConvert { + + HostConfigConvert MAPPER = Mappers.getMapper(HostConfigConvert.class); + + HostConfigVO to(HostConfigDO domain); + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConvert.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConvert.java new file mode 100644 index 00000000..c2b2c4a5 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/HostConvert.java @@ -0,0 +1,35 @@ +package com.orion.ops.module.asset.convert; + +import com.orion.ops.module.asset.entity.domain.HostDO; +import com.orion.ops.module.asset.entity.request.host.HostCreateRequest; +import com.orion.ops.module.asset.entity.request.host.HostQueryRequest; +import com.orion.ops.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.ops.module.asset.entity.vo.HostVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 主机 内部对象转换器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Mapper +public interface HostConvert { + + HostConvert MAPPER = Mappers.getMapper(HostConvert.class); + + HostDO to(HostCreateRequest request); + + HostDO to(HostUpdateRequest request); + + HostDO to(HostQueryRequest request); + + HostVO to(HostDO domain); + + List to(List list); + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostConfigDAO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostConfigDAO.java new file mode 100644 index 00000000..0cd59ecf --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostConfigDAO.java @@ -0,0 +1,92 @@ +package com.orion.ops.module.asset.dao; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.ops.framework.mybatis.core.mapper.IMapper; +import com.orion.ops.module.asset.entity.domain.HostConfigDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 主机配置 Mapper 接口 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Mapper +public interface HostConfigDAO extends IMapper { + + /** + * 通过 hostId 查询主机配置 + * + * @param hostId hostId + * @param type type + * @return row + */ + default HostConfigDO getHostConfigByHostId(Long hostId, String type) { + // 条件 + LambdaQueryWrapper wrapper = this.lambda() + .eq(HostConfigDO::getHostId, hostId) + .eq(HostConfigDO::getType, type); + // 查询 + return this.of(wrapper).getOne(); + } + + /** + * 通过 hostId 查询主机配置 + * + * @param hostId hostId + * @return rows + */ + default List getHostConfigByHostId(Long hostId) { + // 条件 + LambdaQueryWrapper wrapper = this.lambda() + .eq(HostConfigDO::getHostId, hostId); + // 查询 + return this.of(wrapper).list(); + } + + /** + * 通过 hostId 批量查询主机配置 + * + * @param hostIdList hostIdList + * @return rows + */ + default List getHostConfigByHostIdList(List hostIdList) { + // 条件 + LambdaQueryWrapper wrapper = this.lambda() + .in(HostConfigDO::getHostId, hostIdList); + // 查询 + return this.of(wrapper).list(); + } + + /** + * 通过 hostId 删除主机配置 + * + * @param hostId hostId + * @return effect + */ + default Integer deleteByHostId(Long hostId) { + // 条件 + LambdaQueryWrapper wrapper = this.lambda() + .eq(HostConfigDO::getHostId, hostId); + // 删除 + return this.delete(wrapper); + } + + /** + * 通过 hostId 批量删除主机配置 + * + * @param hostIdList hostIdList + * @return effect + */ + default Integer deleteByHostIdList(List hostIdList) { + // 条件 + LambdaQueryWrapper wrapper = this.lambda() + .in(HostConfigDO::getHostId, hostIdList); + // 删除 + return this.delete(wrapper); + } + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostDAO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostDAO.java new file mode 100644 index 00000000..30969e1a --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/HostDAO.java @@ -0,0 +1,32 @@ +package com.orion.ops.module.asset.dao; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.ops.framework.mybatis.core.mapper.IMapper; +import com.orion.ops.module.asset.entity.domain.HostDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 主机 Mapper 接口 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Mapper +public interface HostDAO extends IMapper { + + /** + * 获取查询条件 + * + * @param entity entity + * @return 查询条件 + */ + default LambdaQueryWrapper queryCondition(HostDO entity) { + return this.wrapper() + .eq(HostDO::getId, entity.getId()) + .eq(HostDO::getName, entity.getName()) + .eq(HostDO::getCode, entity.getCode()) + .eq(HostDO::getAddress, entity.getAddress()); + } + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostConfigDO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostConfigDO.java new file mode 100644 index 00000000..013369eb --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostConfigDO.java @@ -0,0 +1,49 @@ +package com.orion.ops.module.asset.entity.domain; + +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 com.orion.ops.framework.mybatis.core.domain.BaseDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +/** + * 主机配置 实体对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName(value = "host_config", autoResultMap = true) +@Schema(name = "HostConfigDO", description = "主机配置 实体对象") +public class HostConfigDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "主机id") + @TableField("host_id") + private Long hostId; + + @Schema(description = "连接类型") + @TableField("type") + private String type; + + @Schema(description = "配置详情") + @TableField("config") + private String config; + + @Schema(description = "配置版本号") + @TableField("version") + private String version; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostDO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostDO.java new file mode 100644 index 00000000..1331961d --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/HostDO.java @@ -0,0 +1,45 @@ +package com.orion.ops.module.asset.entity.domain; + +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 com.orion.ops.framework.mybatis.core.domain.BaseDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +/** + * 主机 实体对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName(value = "host", autoResultMap = true) +@Schema(name = "HostDO", description = "主机 实体对象") +public class HostDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "主机名称") + @TableField("name") + private String name; + + @Schema(description = "主机编码") + @TableField("code") + private String code; + + @Schema(description = "主机地址") + @TableField("address") + private String address; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostCreateRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostCreateRequest.java new file mode 100644 index 00000000..ed07706c --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostCreateRequest.java @@ -0,0 +1,46 @@ +package com.orion.ops.module.asset.entity.request.host; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.List; + +/** + * 主机 创建请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostCreateRequest", description = "主机 创建请求对象") +public class HostCreateRequest implements Serializable { + + @NotBlank + @Size(max = 64) + @Schema(description = "主机名称") + private String name; + + @NotBlank + @Size(max = 64) + @Schema(description = "主机编码") + private String code; + + @NotBlank + @Size(max = 128) + @Schema(description = "主机地址") + private String address; + + @Schema(description = "tags") + private List tags; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostQueryRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostQueryRequest.java new file mode 100644 index 00000000..5426ab5e --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostQueryRequest.java @@ -0,0 +1,52 @@ +package com.orion.ops.module.asset.entity.request.host; + +import com.orion.ops.framework.common.entity.PageRequest; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import javax.validation.constraints.Size; +import java.util.List; + +/** + * 主机 查询请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "HostQueryRequest", description = "主机 查询请求对象") +public class HostQueryRequest extends PageRequest { + + @Schema(description = "id") + private Long id; + + @Size(max = 64) + @Schema(description = "主机名称") + private String name; + + @Size(max = 64) + @Schema(description = "主机编码") + private String code; + + @Size(max = 128) + @Schema(description = "主机地址") + private String address; + + @Schema(description = "是否为收藏") + private Boolean favorite; + + @Schema(description = "tag") + private List tags; + + @Schema(description = "是否查询额外信息") + private Boolean extra; + + @Schema(description = "是否查询配置信息") + private Boolean config; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostUpdateRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostUpdateRequest.java new file mode 100644 index 00000000..5b9f06f9 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/request/host/HostUpdateRequest.java @@ -0,0 +1,51 @@ +package com.orion.ops.module.asset.entity.request.host; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.List; + +/** + * 主机 更新请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostUpdateRequest", description = "主机 更新请求对象") +public class HostUpdateRequest implements Serializable { + + @NotNull + @Schema(description = "id") + private Long id; + + @NotBlank + @Size(max = 64) + @Schema(description = "主机名称") + private String name; + + @NotBlank + @Size(max = 64) + @Schema(description = "主机编码") + private String code; + + @NotBlank + @Size(max = 128) + @Schema(description = "主机地址") + private String address; + + @Schema(description = "tags") + private List tags; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostConfigVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostConfigVO.java new file mode 100644 index 00000000..3425e595 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostConfigVO.java @@ -0,0 +1,34 @@ +package com.orion.ops.module.asset.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * 主机配置 视图响应对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/9/11 17:58 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostConfigVO", description = "主机配置 视图响应对象") +public class HostConfigVO { + + @Schema(description = "id") + private Long id; + + @Schema(description = "version") + private String version; + + @Schema(description = "config") + private Map config; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostVO.java new file mode 100644 index 00000000..86744c2d --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/HostVO.java @@ -0,0 +1,62 @@ +package com.orion.ops.module.asset.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; +import java.util.Map; + +/** + * 主机 视图响应对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostVO", description = "主机 视图响应对象") +public class HostVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + private Long id; + + @Schema(description = "主机名称") + private String name; + + @Schema(description = "主机编码") + private String code; + + @Schema(description = "主机地址") + private String address; + + @Schema(description = "创建时间") + private Date createTime; + + @Schema(description = "修改时间") + private Date updateTime; + + @Schema(description = "创建人") + private String creator; + + @Schema(description = "修改人") + private String updater; + + @Schema(description = "是否收藏") + private Boolean favorite; + + @Schema(description = "tags") + private Map tags; + + @Schema(description = "configs") + private Map configs; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/HostConfigTypeEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/HostConfigTypeEnum.java new file mode 100644 index 00000000..e6b93b68 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/enums/HostConfigTypeEnum.java @@ -0,0 +1,37 @@ +package com.orion.ops.module.asset.enums; + +/** + * 主机配置类型枚举 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/9/11 14:37 + */ +public enum HostConfigTypeEnum { + + /** + * ssh 配置 + */ + SSH, + + /** + * sftp 配置 + */ + SFTP, + + /** + * rdp 配置 + */ + RDP, + + /** + * 环境变量 + */ + ENV, + + /** + * 普通配置 + */ + CONFIG, + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConfigService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConfigService.java new file mode 100644 index 00000000..8f72af54 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostConfigService.java @@ -0,0 +1,12 @@ +package com.orion.ops.module.asset.service; + +/** + * 主机配置 服务类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +public interface HostConfigService { + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostService.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostService.java new file mode 100644 index 00000000..b30d517a --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/HostService.java @@ -0,0 +1,68 @@ +package com.orion.ops.module.asset.service; + +import com.orion.lang.define.wrapper.DataGrid; +import com.orion.ops.module.asset.entity.request.host.HostCreateRequest; +import com.orion.ops.module.asset.entity.request.host.HostQueryRequest; +import com.orion.ops.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.ops.module.asset.entity.vo.HostVO; + +import java.util.List; + +/** + * 主机 服务类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +public interface HostService { + + /** + * 创建主机 + * + * @param request request + * @return id + */ + Long createHost(HostCreateRequest request); + + /** + * 通过 id 更新主机 + * + * @param request request + * @return effect + */ + Integer updateHostById(HostUpdateRequest request); + + /** + * 通过 id 查询主机 + * + * @param request request + * @return row + */ + HostVO getHostById(HostQueryRequest request); + + /** + * 查询主机 + * + * @param request request + * @return rows + */ + List getHostList(HostQueryRequest request); + + /** + * 分页查询主机 + * + * @param request request + * @return rows + */ + DataGrid getHostPage(HostQueryRequest request); + + /** + * 通过 id 删除主机 + * + * @param id id + * @return effect + */ + Integer deleteHostById(Long id); + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConfigServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConfigServiceImpl.java new file mode 100644 index 00000000..87a4aed8 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostConfigServiceImpl.java @@ -0,0 +1,24 @@ +package com.orion.ops.module.asset.service.impl; + +import com.orion.ops.module.asset.dao.HostConfigDAO; +import com.orion.ops.module.asset.service.HostConfigService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 主机配置 服务实现类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Slf4j +@Service +public class HostConfigServiceImpl implements HostConfigService { + + @Resource + private HostConfigDAO hostConfigDAO; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostServiceImpl.java new file mode 100644 index 00000000..ab53ed67 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/HostServiceImpl.java @@ -0,0 +1,332 @@ +package com.orion.ops.module.asset.service.impl; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.lang.define.wrapper.DataGrid; +import com.orion.lang.utils.Booleans; +import com.orion.lang.utils.collect.Lists; +import com.orion.ops.framework.common.constant.ErrorMessage; +import com.orion.ops.framework.common.utils.Valid; +import com.orion.ops.framework.security.core.utils.SecurityUtils; +import com.orion.ops.module.asset.convert.HostConfigConvert; +import com.orion.ops.module.asset.convert.HostConvert; +import com.orion.ops.module.asset.dao.HostConfigDAO; +import com.orion.ops.module.asset.dao.HostDAO; +import com.orion.ops.module.asset.entity.domain.HostConfigDO; +import com.orion.ops.module.asset.entity.domain.HostDO; +import com.orion.ops.module.asset.entity.request.host.HostCreateRequest; +import com.orion.ops.module.asset.entity.request.host.HostQueryRequest; +import com.orion.ops.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.ops.module.asset.entity.vo.HostConfigVO; +import com.orion.ops.module.asset.entity.vo.HostVO; +import com.orion.ops.module.asset.service.HostService; +import com.orion.ops.module.infra.api.FavoriteApi; +import com.orion.ops.module.infra.api.TagRelApi; +import com.orion.ops.module.infra.entity.dto.tag.TagDTO; +import com.orion.ops.module.infra.enums.FavoriteTypeEnum; +import com.orion.ops.module.infra.enums.TagTypeEnum; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; +import java.util.stream.Collectors; + +/** + * 主机 服务实现类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Slf4j +@Service +public class HostServiceImpl implements HostService { + + private static final ThreadLocal> FAVORITE_HOLDER = new ThreadLocal<>(); + + @Resource + private HostDAO hostDAO; + + @Resource + private HostConfigDAO hostConfigDAO; + + @Resource + private TagRelApi tagRelApi; + + @Resource + private FavoriteApi favoriteApi; + + @Override + public Long createHost(HostCreateRequest request) { + log.info("HostService-createHost request: {}", JSON.toJSONString(request)); + // 转换 + HostDO record = HostConvert.MAPPER.to(request); + // 查询数据是否冲突 + this.checkHostNamePresent(record); + this.checkHostCodePresent(record); + // 插入主机 + int effect = hostDAO.insert(record); + log.info("HostService-createHost effect: {}", effect); + Long id = record.getId(); + // 插入 tag + List tags = request.getTags(); + if (!Lists.isEmpty(tags)) { + tagRelApi.addTagRel(TagTypeEnum.HOST, id, tags); + } + return id; + } + + @Override + public Integer updateHostById(HostUpdateRequest request) { + log.info("HostService-updateHostById request: {}", JSON.toJSONString(request)); + // 查询 + Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING); + HostDO record = hostDAO.selectById(id); + Valid.notNull(record, ErrorMessage.DATA_ABSENT); + // 转换 + HostDO updateRecord = HostConvert.MAPPER.to(request); + // 查询数据是否冲突 + this.checkHostNamePresent(updateRecord); + this.checkHostCodePresent(updateRecord); + // 更新 + int effect = hostDAO.updateById(updateRecord); + log.info("HostService-updateHostById effect: {}", effect); + // 更新 tag + tagRelApi.setTagRel(TagTypeEnum.HOST, id, request.getTags()); + return effect; + } + + @Override + public HostVO getHostById(HostQueryRequest request) { + // 查询 + HostDO record = hostDAO.selectById(request.getId()); + Valid.notNull(record, ErrorMessage.DATA_ABSENT); + // 转换 + HostVO vo = HostConvert.MAPPER.to(record); + // 查询拓展信息 + this.setExtraInfo(request, Lists.singleton(vo)); + return vo; + } + + @Override + public List getHostList(HostQueryRequest request) { + try { + // 条件 + LambdaQueryWrapper wrapper = this.buildQueryWrapper(request); + if (wrapper == null) { + return Lists.empty(); + } + // 查询 + List hosts = hostDAO.of(wrapper).list(HostConvert.MAPPER::to); + // 查询拓展信息 + this.setExtraInfo(request, hosts); + return hosts; + } finally { + FAVORITE_HOLDER.remove(); + } + } + + @Override + public DataGrid getHostPage(HostQueryRequest request) { + try { + // 条件 + LambdaQueryWrapper wrapper = this.buildQueryWrapper(request); + if (wrapper == null) { + return DataGrid.of(Lists.empty()); + } + // 查询 + DataGrid hosts = hostDAO.of(wrapper) + .page(request) + .dataGrid(HostConvert.MAPPER::to); + // 查询拓展信息 + this.setExtraInfo(request, hosts.getRows()); + return hosts; + } finally { + FAVORITE_HOLDER.remove(); + } + } + + @Override + public Integer deleteHostById(Long id) { + log.info("HostService-deleteHostById id: {}", id); + int effect = hostDAO.deleteById(id); + log.info("HostService-deleteHostById effect: {}", effect); + // 删除配置 + hostConfigDAO.deleteByHostId(id); + // 删除 tag 引用 + tagRelApi.deleteRelId(TagTypeEnum.HOST, id); + // 删除收藏引用 + favoriteApi.deleteByRelId(FavoriteTypeEnum.HOST, id); + return effect; + } + + /** + * 检测 name 是否存在 + * + * @param domain domain + */ + private void checkHostNamePresent(HostDO domain) { + // 构造条件 + LambdaQueryWrapper wrapper = hostDAO.wrapper() + // 更新时忽略当前记录 + .ne(HostDO::getId, domain.getId()) + .eq(HostDO::getName, domain.getName()); + // 检查是否存在 + boolean present = hostDAO.of(wrapper).present(); + Valid.isFalse(present, ErrorMessage.NAME_PRESENT); + } + + /** + * 检测 code 是否存在 + * + * @param domain domain + */ + private void checkHostCodePresent(HostDO domain) { + // 构造条件 + LambdaQueryWrapper wrapper = hostDAO.wrapper() + // 更新时忽略当前记录 + .ne(HostDO::getId, domain.getId()) + .eq(HostDO::getCode, domain.getCode()); + // 检查是否存在 + boolean present = hostDAO.of(wrapper).present(); + Valid.isFalse(present, ErrorMessage.CODE_PRESENT); + } + + /** + * 构建查询 wrapper + * + * @param request request + * @return wrapper + */ + @SneakyThrows + private LambdaQueryWrapper buildQueryWrapper(HostQueryRequest request) { + boolean setIdList = Booleans.isTrue(request.getFavorite()) || Lists.isNotEmpty(request.getTags()); + List> idListGrouping = new ArrayList<>(); + // 查询收藏 + Future> favoriteFuture = null; + if (Booleans.isTrue(request.getFavorite())) { + favoriteFuture = favoriteApi.getFavoriteRelIdList(FavoriteTypeEnum.HOST, SecurityUtils.getLoginUserId()); + } + // tag 条件 + if (Lists.isNotEmpty(request.getTags())) { + List tagRelIdList = tagRelApi.getRelIdByTagId(request.getTags()); + if (tagRelIdList.isEmpty()) { + return null; + } + idListGrouping.add(tagRelIdList); + } + // 获取收藏结果 + if (favoriteFuture != null) { + List favorites = favoriteFuture.get(); + // 无收藏 + if (Lists.isEmpty(favorites)) { + return null; + } + idListGrouping.add(favorites); + } + // flat + List idList = null; + if (setIdList && !idListGrouping.isEmpty()) { + idList = idListGrouping.get(0); + // 交集 + for (int i = 1; i < idListGrouping.size(); i++) { + idList.retainAll(idListGrouping.get(i)); + } + if (idList.isEmpty()) { + return null; + } + } + // 基础条件 + LambdaQueryWrapper wrapper = hostDAO.wrapper() + .eq(HostDO::getId, request.getId()) + .like(HostDO::getName, request.getName()) + .like(HostDO::getCode, request.getCode()) + .like(HostDO::getAddress, request.getAddress()); + if (setIdList) { + wrapper.in(HostDO::getId, idList); + } + return wrapper; + } + + /** + * 设置额外信息 + * + * @param request request + * @param hosts hosts + */ + @SneakyThrows + private void setExtraInfo(HostQueryRequest request, List hosts) { + if (hosts.isEmpty()) { + return; + } + List idList = hosts.stream().map(HostVO::getId).collect(Collectors.toList()); + // 查询额外信息 + Future>> tagsFuture = null; + Future> favoriteFuture = null; + if (Booleans.isTrue(request.getExtra())) { + // tag + tagsFuture = tagRelApi.getRelTags(TagTypeEnum.HOST, idList); + // 从缓存中读取 收藏 + List favorites = FAVORITE_HOLDER.get(); + if (favorites != null) { + favoriteFuture = CompletableFuture.completedFuture(favorites); + } else { + favoriteFuture = favoriteApi.getFavoriteRelIdList(FavoriteTypeEnum.HOST, SecurityUtils.getLoginUserId()); + } + } + // 查询配置 + if (Booleans.isTrue(request.getConfig())) { + // 配置分组 + Map> hostConfigGrouping = hostConfigDAO.getHostConfigByHostIdList(idList) + .stream() + .collect(Collectors.groupingBy(HostConfigDO::getHostId)); + // 设置配置 + hosts.forEach(s -> { + List configs = hostConfigGrouping.get(s.getId()); + if (Lists.isEmpty(configs)) { + return; + } + Map configMap = configs.stream() + .collect(Collectors.toMap( + HostConfigDO::getType, + HostConfigConvert.MAPPER::to, + (v1, v2) -> v2 + )); + s.setConfigs(configMap); + }); + } + // 设置 tag 信息 + List> tagList = null; + if (tagsFuture != null && (tagList = tagsFuture.get()) != null) { + for (int i = 0; i < hosts.size(); i++) { + List tags = tagList.get(i); + if (Lists.isEmpty(tags)) { + continue; + } + Map tagMap = tags.stream() + .collect(Collectors.toMap( + TagDTO::getId, + TagDTO::getName, + (v1, v2) -> v2, + LinkedHashMap::new + )); + hosts.get(i).setTags(tagMap); + } + } + // 设置收藏信息 + List favoriteIdList = null; + if (favoriteFuture != null && (favoriteIdList = favoriteFuture.get()) != null) { + for (HostVO host : hosts) { + host.setFavorite(favoriteIdList.contains(host.getId())); + } + } + } + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml new file mode 100644 index 00000000..6d4fe0d8 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + id, host_id, type, config, version, create_time, update_time, creator, updater, deleted + + + diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostMapper.xml b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostMapper.xml new file mode 100644 index 00000000..7a42934e --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/HostMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + id, name, code, address, create_time, update_time, creator, updater, deleted + + +