From 3bf44c5e1224847d9afe622071819b9145f6af60 Mon Sep 17 00:00:00 2001 From: kalencaya <1942460489@qq.com> Date: Wed, 29 Nov 2023 09:51:37 +0800 Subject: [PATCH] [Feature][scaleph-engine-doris] add doris instance service (#651) * feature: add doris instance service * feature: add doris instance controller * feature: add doris instance controller * feature: add doris instance web * feature: add doris instance steps * feature: add doris instance steps * feature: add doris instance steps * fix: system nav bar error --- .../ws/WsDorisInstanceController.java | 104 ++++++++++ .../dao/entity/master/ws/WsDorisInstance.java | 83 ++++++++ .../master/ws/WsDorisInstanceMapper.java | 31 +++ .../master/ws/WsDorisInstanceMapper.xml | 57 ++++++ .../operator/status/ComponentStatus.java | 2 +- .../doris/service/WsDorisInstanceService.java | 47 +++++ .../convert/WsDorisInstanceConvert.java | 105 ++++++++++ .../doris/service/dto/WsDorisInstanceDTO.java | 80 ++++++++ .../impl/WsDorisInstanceServiceImpl.java | 138 +++++++++++++ .../param/WsDorisInstanceAddParam.java | 66 +++++++ .../param/WsDorisInstanceListParam.java | 36 ++++ .../param/WsDorisInstanceUpdateParam.java | 70 +++++++ .../generator/MybatisPlusGenerator.java | 2 +- scaleph-ui-react/config/routes.ts | 15 ++ scaleph-ui-react/src/locales/zh-CN/menu.ts | 1 + .../src/locales/zh-CN/pages/project.ts | 7 + .../doris/instance/dorisInstanceSteps.ts | 62 ++++++ .../doris/template/dorisTemplateSteps.ts | 2 +- .../Doris/Instance/Steps/BaseStepForm.tsx | 68 +++++++ .../Workspace/Doris/Instance/Steps/index.tsx | 74 +++++++ .../Workspace/Doris/Instance/index.tsx | 182 ++++++++++++++++++ .../Doris/Template/Steps/BaseStepForm.tsx | 2 - .../Workspace/Doris/Template/index.tsx | 2 +- .../project/WsDorisInstanceService.ts | 57 ++++++ .../src/services/project/typings.d.ts | 54 ++++++ .../mysql/init.d/scaleph-security-mysql.sql | 35 +++- .../docker/mysql/init.d/scaleph-ws-mysql.sql | 32 ++- 27 files changed, 1401 insertions(+), 13 deletions(-) create mode 100644 scaleph-api/src/main/java/cn/sliew/scaleph/api/controller/ws/WsDorisInstanceController.java create mode 100644 scaleph-dao/src/main/java/cn/sliew/scaleph/dao/entity/master/ws/WsDorisInstance.java create mode 100644 scaleph-dao/src/main/java/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.java create mode 100644 scaleph-dao/src/main/resources/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.xml create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/WsDorisInstanceService.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/convert/WsDorisInstanceConvert.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/dto/WsDorisInstanceDTO.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/impl/WsDorisInstanceServiceImpl.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceAddParam.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceListParam.java create mode 100644 scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceUpdateParam.java create mode 100644 scaleph-ui-react/src/models/project/workspace/doris/instance/dorisInstanceSteps.ts create mode 100644 scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/BaseStepForm.tsx create mode 100644 scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/index.tsx create mode 100644 scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/index.tsx create mode 100644 scaleph-ui-react/src/services/project/WsDorisInstanceService.ts diff --git a/scaleph-api/src/main/java/cn/sliew/scaleph/api/controller/ws/WsDorisInstanceController.java b/scaleph-api/src/main/java/cn/sliew/scaleph/api/controller/ws/WsDorisInstanceController.java new file mode 100644 index 000000000..cb75387b6 --- /dev/null +++ b/scaleph-api/src/main/java/cn/sliew/scaleph/api/controller/ws/WsDorisInstanceController.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.api.controller.ws; + +import cn.sliew.scaleph.api.annotation.Logging; +import cn.sliew.scaleph.engine.doris.operator.DorisCluster; +import cn.sliew.scaleph.engine.doris.service.WsDorisInstanceService; +import cn.sliew.scaleph.engine.doris.service.dto.WsDorisInstanceDTO; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceAddParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceListParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceUpdateParam; +import cn.sliew.scaleph.system.model.ResponseVO; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +@Tag(name = "Doris管理-实例管理") +@RestController +@RequestMapping(path = "/api/doris/instance") +public class WsDorisInstanceController { + + @Autowired + private WsDorisInstanceService wsDorisInstanceService; + + @Logging + @GetMapping + @Operation(summary = "查询实例列表", description = "分页查询实例列表") + public ResponseEntity> list(@Valid WsDorisInstanceListParam param) { + Page page = wsDorisInstanceService.list(param); + return new ResponseEntity<>(page, HttpStatus.OK); + } + + @Logging + @GetMapping("/{id}") + @Operation(summary = "查询实例信息", description = "查询实例信息") + public ResponseEntity> selectOne(@PathVariable("id") Long id) { + WsDorisInstanceDTO dto = wsDorisInstanceService.selectOne(id); + return new ResponseEntity(ResponseVO.success(dto), HttpStatus.OK); + } + + @Logging + @PostMapping("asYaml") + @Operation(summary = "转换实例信息", description = "转换实例信息") + public ResponseEntity> asYaml(@RequestBody WsDorisInstanceDTO dto) { + DorisCluster cluster = wsDorisInstanceService.asYaml(dto); + return new ResponseEntity(ResponseVO.success(cluster), HttpStatus.OK); + } + + @Logging + @PutMapping + @Operation(summary = "新增实例", description = "新增实例") + public ResponseEntity insert(@Valid @RequestBody WsDorisInstanceAddParam param) { + wsDorisInstanceService.insert(param); + return new ResponseEntity<>(ResponseVO.success(), HttpStatus.OK); + } + + @Logging + @PostMapping + @Operation(summary = "修改实例", description = "修改实例") + public ResponseEntity update(@Valid @RequestBody WsDorisInstanceUpdateParam param) { + wsDorisInstanceService.update(param); + return new ResponseEntity<>(ResponseVO.success(), HttpStatus.OK); + } + + @Logging + @DeleteMapping("/{id}") + @Operation(summary = "删除实例", description = "删除实例") + public ResponseEntity delete(@PathVariable("id") Long id) { + wsDorisInstanceService.deleteById(id); + return new ResponseEntity<>(ResponseVO.success(), HttpStatus.OK); + } + + @Logging + @DeleteMapping("/batch") + @Operation(summary = "批量删除实例", description = "批量删除实例") + public ResponseEntity deleteBatch(@RequestBody List ids) { + wsDorisInstanceService.deleteBatch(ids); + return new ResponseEntity<>(ResponseVO.success(), HttpStatus.OK); + } + +} diff --git a/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/entity/master/ws/WsDorisInstance.java b/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/entity/master/ws/WsDorisInstance.java new file mode 100644 index 000000000..452c5e6a3 --- /dev/null +++ b/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/entity/master/ws/WsDorisInstance.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.dao.entity.master.ws; + +import cn.sliew.scaleph.common.dict.common.YesOrNo; +import cn.sliew.scaleph.dao.entity.BaseDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * doris instance + */ +@Data +@TableName("ws_doris_instance") +public class WsDorisInstance extends BaseDO { + + private static final long serialVersionUID = 1L; + + @TableField("project_id") + private Long projectId; + + @TableField("cluster_credential_id") + private Long clusterCredentialId; + + @TableField("`name`") + private String name; + + @TableField("instance_id") + private String instanceId; + + @TableField("namespace") + private String namespace; + + @TableField("`admin`") + private String admin; + + @TableField("fe_spec") + private String feSpec; + + @TableField("be_spec") + private String beSpec; + + @TableField("cn_spec") + private String cnSpec; + + @TableField("broker_spec") + private String brokerSpec; + + @TableField("deployed") + private YesOrNo deployed; + + @TableField("fe_status") + private String feStatus; + + @TableField("be_status") + private String beStatus; + + @TableField("cn_status") + private String cnStatus; + + @TableField("broker_status") + private String brokerStatus; + + @TableField("remark") + private String remark; +} diff --git a/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.java b/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.java new file mode 100644 index 000000000..693e0521b --- /dev/null +++ b/scaleph-dao/src/main/java/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.dao.mapper.master.ws; + +import cn.sliew.scaleph.dao.entity.master.ws.WsDorisInstance; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springframework.stereotype.Repository; + +/** + * doris instance Mapper 接口 + */ +@Repository +public interface WsDorisInstanceMapper extends BaseMapper { + +} diff --git a/scaleph-dao/src/main/resources/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.xml b/scaleph-dao/src/main/resources/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.xml new file mode 100644 index 000000000..d3b8a6a9c --- /dev/null +++ b/scaleph-dao/src/main/resources/cn/sliew/scaleph/dao/mapper/master/ws/WsDorisInstanceMapper.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + creator, + create_time, + editor, + update_time, + project_id, cluster_credential_id, `name`, instance_id, namespace, `admin`, fe_spec, be_spec, cn_spec, broker_spec, deployed, fe_status, be_status, cn_status, broker_status, remark + + + diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/operator/status/ComponentStatus.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/operator/status/ComponentStatus.java index 28d794091..5c3c2c317 100644 --- a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/operator/status/ComponentStatus.java +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/operator/status/ComponentStatus.java @@ -48,5 +48,5 @@ public class ComponentStatus { /** * */ - private Object componentCondition; + private ComponentCondition componentCondition; } diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/WsDorisInstanceService.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/WsDorisInstanceService.java new file mode 100644 index 000000000..3ed8b41ea --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/WsDorisInstanceService.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service; + +import cn.sliew.scaleph.engine.doris.operator.DorisCluster; +import cn.sliew.scaleph.engine.doris.service.dto.WsDorisInstanceDTO; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceAddParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceListParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceUpdateParam; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.List; + +public interface WsDorisInstanceService { + + Page list(WsDorisInstanceListParam param); + + WsDorisInstanceDTO selectOne(Long id); + + WsDorisInstanceDTO fromTemplate(Long templateId); + + DorisCluster asYaml(WsDorisInstanceDTO dto); + + int insert(WsDorisInstanceAddParam param); + + int update(WsDorisInstanceUpdateParam param); + + int deleteById(Long id); + + int deleteBatch(List ids); +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/convert/WsDorisInstanceConvert.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/convert/WsDorisInstanceConvert.java new file mode 100644 index 000000000..ffa9bda2a --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/convert/WsDorisInstanceConvert.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.convert; + +import cn.sliew.milky.common.util.JacksonUtil; +import cn.sliew.scaleph.common.convert.BaseConvert; +import cn.sliew.scaleph.dao.entity.master.ws.WsDorisInstance; +import cn.sliew.scaleph.engine.doris.operator.spec.*; +import cn.sliew.scaleph.engine.doris.operator.status.CnStatus; +import cn.sliew.scaleph.engine.doris.operator.status.ComponentStatus; +import cn.sliew.scaleph.engine.doris.service.dto.WsDorisInstanceDTO; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; +import org.springframework.beans.BeanUtils; +import org.springframework.util.StringUtils; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface WsDorisInstanceConvert extends BaseConvert { + WsDorisInstanceConvert INSTANCE = Mappers.getMapper(WsDorisInstanceConvert.class); + + @Override + default WsDorisInstance toDo(WsDorisInstanceDTO dto) { + WsDorisInstance entity = new WsDorisInstance(); + BeanUtils.copyProperties(dto, entity); + if (dto.getAdmin() != null) { + entity.setAdmin(JacksonUtil.toJsonString(dto.getAdmin())); + } + if (dto.getFeSpec() != null) { + entity.setFeSpec(JacksonUtil.toJsonString(dto.getFeSpec())); + } + if (dto.getBeSpec() != null) { + entity.setBeSpec(JacksonUtil.toJsonString(dto.getBeSpec())); + } + if (dto.getCnSpec() != null) { + entity.setCnSpec(JacksonUtil.toJsonString(dto.getCnSpec())); + } + if (dto.getBrokerSpec() != null) { + entity.setBrokerSpec(JacksonUtil.toJsonString(dto.getBrokerSpec())); + } + if (dto.getFeStatus() != null) { + entity.setFeStatus(JacksonUtil.toJsonString(dto.getFeStatus())); + } + if (dto.getBeStatus() != null) { + entity.setBeStatus(JacksonUtil.toJsonString(dto.getBeStatus())); + } + if (dto.getCnStatus() != null) { + entity.setCnStatus(JacksonUtil.toJsonString(dto.getCnStatus())); + } + if (dto.getBrokerStatus() != null) { + entity.setBrokerStatus(JacksonUtil.toJsonString(dto.getBrokerStatus())); + } + return entity; + } + + @Override + default WsDorisInstanceDTO toDto(WsDorisInstance entity) { + WsDorisInstanceDTO dto = new WsDorisInstanceDTO(); + BeanUtils.copyProperties(entity, dto); + if (StringUtils.hasText(entity.getAdmin())) { + dto.setAdmin(JacksonUtil.parseJsonString(entity.getAdmin(), AdminUser.class)); + } + if (StringUtils.hasText(entity.getFeSpec())) { + dto.setFeSpec(JacksonUtil.parseJsonString(entity.getFeSpec(), FeSpec.class)); + } + if (StringUtils.hasText(entity.getBeSpec())) { + dto.setBeSpec(JacksonUtil.parseJsonString(entity.getBeSpec(), BeSpec.class)); + } + if (StringUtils.hasText(entity.getCnSpec())) { + dto.setCnSpec(JacksonUtil.parseJsonString(entity.getCnSpec(), CnSpec.class)); + } + if (StringUtils.hasText(entity.getBrokerSpec())) { + dto.setBrokerSpec(JacksonUtil.parseJsonString(entity.getBrokerSpec(), BrokerSpec.class)); + } + if (StringUtils.hasText(entity.getFeStatus())) { + dto.setFeStatus(JacksonUtil.parseJsonString(entity.getFeStatus(), ComponentStatus.class)); + } + if (StringUtils.hasText(entity.getBeStatus())) { + dto.setBeStatus(JacksonUtil.parseJsonString(entity.getBeStatus(), ComponentStatus.class)); + } + if (StringUtils.hasText(entity.getCnStatus())) { + dto.setCnStatus(JacksonUtil.parseJsonString(entity.getCnStatus(), CnStatus.class)); + } + if (StringUtils.hasText(entity.getBrokerStatus())) { + dto.setBrokerStatus(JacksonUtil.parseJsonString(entity.getBrokerStatus(), ComponentStatus.class)); + } + return dto; + } +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/dto/WsDorisInstanceDTO.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/dto/WsDorisInstanceDTO.java new file mode 100644 index 000000000..623477b9e --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/dto/WsDorisInstanceDTO.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.dto; + +import cn.sliew.scaleph.common.dict.common.YesOrNo; +import cn.sliew.scaleph.engine.doris.operator.spec.*; +import cn.sliew.scaleph.engine.doris.operator.status.CnStatus; +import cn.sliew.scaleph.engine.doris.operator.status.ComponentStatus; +import cn.sliew.scaleph.system.model.BaseDTO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * doris instance + */ +@Data +@Schema(name = "WsDorisInstance对象", description = "doris instance") +public class WsDorisInstanceDTO extends BaseDTO { + + private static final long serialVersionUID = 1L; + + @Schema(description = "项目id") + private Long projectId; + + private Long clusterCredentialId; + + private String name; + + private String instanceId; + + private String namespace; + + @Schema(description = "admin user") + private AdminUser admin; + + @Schema(description = "fe spec") + private FeSpec feSpec; + + @Schema(description = "be spec") + private BeSpec beSpec; + + @Schema(description = "cn spec") + private CnSpec cnSpec; + + @Schema(description = "broker spec") + private BrokerSpec brokerSpec; + + @Schema(description = "是否部署") + private YesOrNo deployed; + + @Schema(description = "fe status") + private ComponentStatus feStatus; + + @Schema(description = "be status") + private ComponentStatus beStatus; + + @Schema(description = "cn status") + private CnStatus cnStatus; + + @Schema(description = "broker status") + private ComponentStatus brokerStatus; + + private String remark; +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/impl/WsDorisInstanceServiceImpl.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/impl/WsDorisInstanceServiceImpl.java new file mode 100644 index 000000000..ef16dac45 --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/impl/WsDorisInstanceServiceImpl.java @@ -0,0 +1,138 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.impl; + +import cn.sliew.milky.common.util.JacksonUtil; +import cn.sliew.scaleph.common.util.UUIDUtil; +import cn.sliew.scaleph.dao.entity.master.ws.WsDorisInstance; +import cn.sliew.scaleph.dao.mapper.master.ws.WsDorisInstanceMapper; +import cn.sliew.scaleph.engine.doris.operator.DorisCluster; +import cn.sliew.scaleph.engine.doris.service.WsDorisInstanceService; +import cn.sliew.scaleph.engine.doris.service.WsDorisTemplateService; +import cn.sliew.scaleph.engine.doris.service.convert.WsDorisInstanceConvert; +import cn.sliew.scaleph.engine.doris.service.dto.WsDorisInstanceDTO; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceAddParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceListParam; +import cn.sliew.scaleph.engine.doris.service.param.WsDorisInstanceUpdateParam; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +import static cn.sliew.milky.common.check.Ensures.checkState; + +@Service +public class WsDorisInstanceServiceImpl implements WsDorisInstanceService { + + @Autowired + private WsDorisInstanceMapper wsDorisInstanceMapper; + @Autowired + private WsDorisTemplateService wsDorisTemplateService; + + @Override + public Page list(WsDorisInstanceListParam param) { + Page page = new Page<>(param.getCurrent(), param.getPageSize()); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(WsDorisInstance.class) + .eq(WsDorisInstance::getProjectId, param.getProjectId()) + .like(StringUtils.hasText(param.getName()), WsDorisInstance::getName, param.getName()) + .orderByAsc(WsDorisInstance::getId); + Page wsDorisInstancePage = wsDorisInstanceMapper.selectPage(page, queryWrapper); + Page result = new Page<>(wsDorisInstancePage.getCurrent(), wsDorisInstancePage.getSize(), wsDorisInstancePage.getTotal()); + List dtoList = WsDorisInstanceConvert.INSTANCE.toDto(page.getRecords()); + result.setRecords(dtoList); + return result; + } + + @Override + public WsDorisInstanceDTO selectOne(Long id) { + WsDorisInstance record = wsDorisInstanceMapper.selectById(id); + checkState(record != null, () -> "doris instance not exist for id = " + id); + return WsDorisInstanceConvert.INSTANCE.toDto(record); + } + + @Override + public WsDorisInstanceDTO fromTemplate(Long templateId) { + return null; + } + + @Override + public DorisCluster asYaml(WsDorisInstanceDTO dto) { + return null; + } + + @Override + public int insert(WsDorisInstanceAddParam param) { + WsDorisInstance record = new WsDorisInstance(); + BeanUtils.copyProperties(param, record); + record.setInstanceId(UUIDUtil.randomUUId()); + if (param.getAdmin() != null) { + record.setAdmin(JacksonUtil.toJsonString(param.getAdmin())); + } + if (param.getFeSpec() != null) { + record.setFeSpec(JacksonUtil.toJsonString(param.getFeSpec())); + } + if (param.getBeSpec() != null) { + record.setBeSpec(JacksonUtil.toJsonString(param.getBeSpec())); + } + if (param.getCnSpec() != null) { + record.setCnSpec(JacksonUtil.toJsonString(param.getCnSpec())); + } + if (param.getBrokerSpec() != null) { + record.setBrokerSpec(JacksonUtil.toJsonString(param.getBrokerSpec())); + } + return wsDorisInstanceMapper.insert(record); + } + + @Override + public int update(WsDorisInstanceUpdateParam param) { + WsDorisInstance record = new WsDorisInstance(); + BeanUtils.copyProperties(param, record); + if (param.getAdmin() != null) { + record.setAdmin(JacksonUtil.toJsonString(param.getAdmin())); + } + if (param.getFeSpec() != null) { + record.setFeSpec(JacksonUtil.toJsonString(param.getFeSpec())); + } + if (param.getBeSpec() != null) { + record.setBeSpec(JacksonUtil.toJsonString(param.getBeSpec())); + } + if (param.getCnSpec() != null) { + record.setCnSpec(JacksonUtil.toJsonString(param.getCnSpec())); + } + if (param.getBrokerSpec() != null) { + record.setBrokerSpec(JacksonUtil.toJsonString(param.getBrokerSpec())); + } + return wsDorisInstanceMapper.updateById(record); + } + + @Override + public int deleteById(Long id) { + return wsDorisInstanceMapper.deleteById(id); + } + + @Override + public int deleteBatch(List ids) { + return wsDorisInstanceMapper.deleteBatchIds(ids); + } +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceAddParam.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceAddParam.java new file mode 100644 index 000000000..384de5254 --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceAddParam.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.param; + +import cn.sliew.scaleph.engine.doris.operator.spec.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class WsDorisInstanceAddParam { + + @NotNull + @Schema(description = "project id") + private Long projectId; + + @NotNull + @Schema(description = "cluster credential id") + private Long clusterCredentialId; + + @NotBlank + @Schema(description = "name") + private String name; + + @NotBlank + @Schema(description = "namespace") + private String namespace; + + @NotNull + @Schema(description = "admin user") + private AdminUser admin; + + @NotNull + @Schema(description = "fe spec") + private FeSpec feSpec; + + @Schema(description = "be spec") + private BeSpec beSpec; + + @Schema(description = "cn spec") + private CnSpec cnSpec; + + @Schema(description = "broker spec") + private BrokerSpec brokerSpec; + + @Schema(description = "remark") + private String remark; +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceListParam.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceListParam.java new file mode 100644 index 000000000..9bc7bdce5 --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceListParam.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.param; + +import cn.sliew.scaleph.system.model.PaginationParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Data +public class WsDorisInstanceListParam extends PaginationParam { + + @NotNull + @Schema(description = "project id") + private Long projectId; + + @Schema(description = "name") + private String name; +} diff --git a/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceUpdateParam.java b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceUpdateParam.java new file mode 100644 index 000000000..e927d27d1 --- /dev/null +++ b/scaleph-engine/scaleph-engine-doris/src/main/java/cn/sliew/scaleph/engine/doris/service/param/WsDorisInstanceUpdateParam.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 cn.sliew.scaleph.engine.doris.service.param; + +import cn.sliew.scaleph.engine.doris.operator.spec.*; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class WsDorisInstanceUpdateParam { + + @NotNull + @Schema(description = "id") + private Long id; + + @NotNull + @Schema(description = "project id") + private Long projectId; + + @NotNull + @Schema(description = "cluster credential id") + private Long clusterCredentialId; + + @NotBlank + @Schema(description = "name") + private String name; + + @NotBlank + @Schema(description = "namespace") + private String namespace; + + @NotNull + @Schema(description = "admin user") + private AdminUser admin; + + @NotNull + @Schema(description = "fe spec") + private FeSpec feSpec; + + @Schema(description = "be spec") + private BeSpec beSpec; + + @Schema(description = "cn spec") + private CnSpec cnSpec; + + @Schema(description = "broker spec") + private BrokerSpec brokerSpec; + + @Schema(description = "remark") + private String remark; +} diff --git a/scaleph-support/scaleph-generator/src/main/java/cn/sliew/scaleph/generator/MybatisPlusGenerator.java b/scaleph-support/scaleph-generator/src/main/java/cn/sliew/scaleph/generator/MybatisPlusGenerator.java index 1a1e9f2ee..a3dca1727 100644 --- a/scaleph-support/scaleph-generator/src/main/java/cn/sliew/scaleph/generator/MybatisPlusGenerator.java +++ b/scaleph-support/scaleph-generator/src/main/java/cn/sliew/scaleph/generator/MybatisPlusGenerator.java @@ -54,7 +54,7 @@ public class MybatisPlusGenerator { /** * just add table names here and run the {@link #main(String[])} method. */ - private static final String[] TABLES = {"ws_doris_template"}; + private static final String[] TABLES = {"ws_doris_instance"}; public static void main(String[] args) { //自动生成配置 diff --git a/scaleph-ui-react/config/routes.ts b/scaleph-ui-react/config/routes.ts index 47eb26af8..0f4d6a829 100644 --- a/scaleph-ui-react/config/routes.ts +++ b/scaleph-ui-react/config/routes.ts @@ -253,6 +253,21 @@ export default [ pCode: PRIVILEGE_CODE.workspaceClusterConfigShow, access: 'normalRouteFilter' }, + { + name: 'instance', + path: '/workspace/doris/instance', + exact: true, + component: './Project/Workspace/Doris/Instance', + pCode: PRIVILEGE_CODE.workspaceClusterConfigShow, + access: 'normalRouteFilter' + }, + { + path: '/workspace/doris/instance/steps', + exact: true, + component: './Project/Workspace/Doris/Instance/Steps', + pCode: PRIVILEGE_CODE.workspaceClusterConfigShow, + access: 'normalRouteFilter' + }, ] }, ] diff --git a/scaleph-ui-react/src/locales/zh-CN/menu.ts b/scaleph-ui-react/src/locales/zh-CN/menu.ts index 4323768e4..2fd892e8b 100644 --- a/scaleph-ui-react/src/locales/zh-CN/menu.ts +++ b/scaleph-ui-react/src/locales/zh-CN/menu.ts @@ -14,6 +14,7 @@ export default { 'menu.project.flink.kubernetes.job': 'Job', 'menu.project.doris': 'Doris', 'menu.project.doris.template': 'Template', + 'menu.project.doris.instance': 'Instance', 'menu.resource': '资源', 'menu.resource.jar': '公共 Jar', diff --git a/scaleph-ui-react/src/locales/zh-CN/pages/project.ts b/scaleph-ui-react/src/locales/zh-CN/pages/project.ts index cff721b09..3d8ce78ec 100644 --- a/scaleph-ui-react/src/locales/zh-CN/pages/project.ts +++ b/scaleph-ui-react/src/locales/zh-CN/pages/project.ts @@ -943,6 +943,13 @@ export default { 'pages.project.doris.template.detail': '模版详情', 'pages.project.doris.template.detail.component': '集群组件', 'pages.project.doris.template.detail.yaml': 'YAML', + 'pages.project.doris.instance': 'Instance', + 'pages.project.doris.instance.name': '名称', + 'pages.project.doris.instance.namespace': '命名空间', + 'pages.project.doris.instance.steps': '创建实例', + 'pages.project.doris.instance.steps.base': '基础信息', + 'pages.project.doris.instance.steps.base.cluster': 'Cluster', + 'pages.project.doris.instance.steps.base.template': 'Template', 'Run': '运行', diff --git a/scaleph-ui-react/src/models/project/workspace/doris/instance/dorisInstanceSteps.ts b/scaleph-ui-react/src/models/project/workspace/doris/instance/dorisInstanceSteps.ts new file mode 100644 index 000000000..9a90b100c --- /dev/null +++ b/scaleph-ui-react/src/models/project/workspace/doris/instance/dorisInstanceSteps.ts @@ -0,0 +1,62 @@ +import {WsDorisInstance, WsDorisTemplate} from "@/services/project/typings"; +import {Effect, Reducer} from "umi"; +import YAML from "yaml"; +import {WsDorisTemplateService} from "@/services/project/WsDorisTemplateService"; + +export interface StateType { + template: WsDorisTemplate, + instance: WsDorisInstance, + instanceYaml: string + instanceYamlWithDefault: string +} + +export interface ModelType { + namespace: string; + + state: StateType; + + effects: { + queryTemplate: Effect; + }; + + reducers: { + updateTemplate: Reducer; + }; +} + +const model: ModelType = { + namespace: "dorisInstanceSteps", + + state: { + template: null, + templateYaml: null, + templateYamlWithDefault: null + }, + + effects: { + *editTemplate({payload}, {call, put}) { + const {data} = yield call(WsDorisTemplateService.asYaml, payload); + const response = yield call(WsDorisTemplateService.asYaml, payload); + yield put({type: 'updateTemplate', + payload: { + template: payload, + templateYaml: YAML.stringify(data), + templateYamlWithDefault: YAML.stringify(response.data) + } + }); + }, + }, + + reducers: { + updateTemplate(state, {payload}) { + return { + ...state, + template: payload.template, + templateYaml: payload.templateYaml, + templateYamlWithDefault: payload.templateYamlWithDefault, + }; + }, + }, +}; + +export default model; diff --git a/scaleph-ui-react/src/models/project/workspace/doris/template/dorisTemplateSteps.ts b/scaleph-ui-react/src/models/project/workspace/doris/template/dorisTemplateSteps.ts index 57cec9362..261bca236 100644 --- a/scaleph-ui-react/src/models/project/workspace/doris/template/dorisTemplateSteps.ts +++ b/scaleph-ui-react/src/models/project/workspace/doris/template/dorisTemplateSteps.ts @@ -33,7 +33,7 @@ const model: ModelType = { }, effects: { - * editTemplate({payload}, {call, put}) { + *editTemplate({payload}, {call, put}) { const {data} = yield call(WsDorisTemplateService.asYaml, payload); const response = yield call(WsDorisTemplateService.asYaml, payload); yield put({type: 'updateTemplate', diff --git a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/BaseStepForm.tsx b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/BaseStepForm.tsx new file mode 100644 index 000000000..591fe55b2 --- /dev/null +++ b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/BaseStepForm.tsx @@ -0,0 +1,68 @@ +import React from "react"; +import {ProCard, ProFormDigit, ProFormSelect, ProFormText} from "@ant-design/pro-components"; +import {useIntl} from "umi"; +import {ClusterCredentialListParam} from "@/services/resource/typings"; +import {ClusterCredentialService} from "@/services/resource/clusterCredential.service"; +import {WsDorisTemplate} from "@/services/project/typings"; +import {WsDorisTemplateService} from "@/services/project/WsDorisTemplateService"; +import {WORKSPACE_CONF} from "@/constant"; + +const DorisInstanceBase: React.FC = () => { + const intl = useIntl(); + const localProjectId = localStorage.getItem(WORKSPACE_CONF.projectId); + + return ( + + + ); +} + +export default DorisInstanceBase; diff --git a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/index.tsx b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/index.tsx new file mode 100644 index 000000000..6fead5b83 --- /dev/null +++ b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/Steps/index.tsx @@ -0,0 +1,74 @@ +import {connect, history, useIntl} from "umi"; +import React, {useRef} from "react"; +import {PageContainer, ProCard, ProFormInstance, StepsForm} from "@ant-design/pro-components"; +import {WORKSPACE_CONF} from "@/constant"; +import {WsDorisInstance, WsDorisTemplate} from "@/services/project/typings"; +import {WsDorisTemplateService} from "@/services/project/WsDorisTemplateService"; +import DorisInstanceBase from "@/pages/Project/Workspace/Doris/Instance/Steps/BaseStepForm"; + +const DorisInstanceSteps: React.FC = (props: any) => { + const intl = useIntl(); + const formRef = useRef(); + const localProjectId = localStorage.getItem(WORKSPACE_CONF.projectId); + + const onBaseStepFinish = (values: Record) => { + const template: WsDorisInstance = { + projectId: localProjectId, + name: values.name, + namespace: values.namespace, + remark: values.remark, + } + editDorisTemplate(template) + return Promise.resolve(true) + } + + const onComponentStepFinish = (values: Record) => { + try { + const template: WsDorisTemplate = WsDorisTemplateService.formatData(props.dorisTemplateSteps.template, values) + editDorisTemplate(template) + } catch (unused) { + } + return Promise.resolve(true) + } + + const editDorisTemplate = (template: WsDorisTemplate) => { + props.dispatch({ + type: 'dorisInstanceSteps/editTemplate', + payload: template + }) + } + + const onAllFinish = (values: Record) => { + return WsDorisTemplateService.add(props.dorisTemplateSteps.template).then((response) => { + if (response.success) { + history.back() + } + }) + } + + return ( + + + + + + + + + + ) +} + +const mapModelToProps = ({dorisInstanceSteps}: any) => ({dorisInstanceSteps}) +export default connect(mapModelToProps)(DorisInstanceSteps); diff --git a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/index.tsx b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/index.tsx new file mode 100644 index 000000000..667c9b776 --- /dev/null +++ b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Instance/index.tsx @@ -0,0 +1,182 @@ +import {history, useAccess, useIntl} from "umi"; +import React, {useRef, useState} from "react"; +import {Button, message, Modal, Space, Tooltip} from "antd"; +import {DeleteOutlined, EditOutlined, NodeIndexOutlined} from "@ant-design/icons"; +import {ActionType, ProColumns, ProFormInstance, ProTable} from "@ant-design/pro-components"; +import {PRIVILEGE_CODE, WORKSPACE_CONF} from "@/constant"; +import {WsDorisInstance, WsDorisTemplate} from "@/services/project/typings"; +import {WsDorisInstanceService} from "@/services/project/WsDorisInstanceService"; + +const DorisInstanceWeb: React.FC = () => { + const intl = useIntl(); + const access = useAccess(); + const actionRef = useRef(); + const formRef = useRef(); + const [selectedRows, setSelectedRows] = useState([]); + const [dorisInstanceFormData, setDorisInstanceFormData] = useState<{ + visiable: WsDorisInstance; + data: WsDorisTemplate; + }>({visiable: false, data: {}}); + const projectId = localStorage.getItem(WORKSPACE_CONF.projectId); + + const tableColumns: ProColumns[] = [ + { + title: intl.formatMessage({id: 'pages.project.doris.template.name'}), + dataIndex: 'name' + }, + { + title: intl.formatMessage({id: 'pages.project.doris.template.namespace'}), + dataIndex: 'namespace', + hideInSearch: true, + }, + { + title: intl.formatMessage({id: 'app.common.data.remark'}), + dataIndex: 'remark', + hideInSearch: true, + }, + { + title: intl.formatMessage({id: 'app.common.data.createTime'}), + dataIndex: 'createTime', + hideInSearch: true, + width: 180, + }, + { + title: intl.formatMessage({id: 'app.common.data.updateTime'}), + dataIndex: 'updateTime', + hideInSearch: true, + width: 180, + }, + { + title: intl.formatMessage({id: 'app.common.operate.label'}), + dataIndex: 'actions', + align: 'center', + width: 120, + fixed: 'right', + valueType: 'option', + render: (_, record) => ( + + {access.canAccess(PRIVILEGE_CODE.datadevProjectEdit) && ( + + + ), + access.canAccess(PRIVILEGE_CODE.datadevResourceDelete) && ( + + ) + ], + }} + pagination={{showQuickJumper: true, showSizeChanger: true, defaultPageSize: 10}} + rowSelection={{ + fixed: true, + onChange(selectedRowKeys, selectedRows, info) { + setSelectedRows(selectedRows); + }, + }} + tableAlertRender={false} + tableAlertOptionRender={false} + /> + ); +} + +export default DorisInstanceWeb; diff --git a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/Steps/BaseStepForm.tsx b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/Steps/BaseStepForm.tsx index c56a2ee41..ce46a3619 100644 --- a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/Steps/BaseStepForm.tsx +++ b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/Steps/BaseStepForm.tsx @@ -1,11 +1,9 @@ import React from "react"; -import {Form} from "antd"; import {ProCard, ProFormDigit, ProFormText} from "@ant-design/pro-components"; import {useIntl} from "umi"; const DorisTemplateBase: React.FC = () => { const intl = useIntl(); - const [form] = Form.useForm() return ( diff --git a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/index.tsx b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/index.tsx index f8f13bafd..a0e092727 100644 --- a/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/index.tsx +++ b/scaleph-ui-react/src/pages/Project/Workspace/Doris/Template/index.tsx @@ -1,6 +1,6 @@ import {history, useAccess, useIntl} from "umi"; import React, {useRef, useState} from "react"; -import {Button, message, Modal, Space, Tag, Tooltip} from "antd"; +import {Button, message, Modal, Space, Tooltip} from "antd"; import {DeleteOutlined, EditOutlined, NodeIndexOutlined} from "@ant-design/icons"; import {ActionType, ProColumns, ProFormInstance, ProTable} from "@ant-design/pro-components"; import {PRIVILEGE_CODE, WORKSPACE_CONF} from "@/constant"; diff --git a/scaleph-ui-react/src/services/project/WsDorisInstanceService.ts b/scaleph-ui-react/src/services/project/WsDorisInstanceService.ts new file mode 100644 index 000000000..be991d2a5 --- /dev/null +++ b/scaleph-ui-react/src/services/project/WsDorisInstanceService.ts @@ -0,0 +1,57 @@ +import {PageResponse, ResponseBody} from '@/app.d'; +import {request} from 'umi'; +import {WsDorisInstance, WsDorisInstanceAddParam, WsDorisInstanceParam, WsDorisInstanceUpdateParam} from './typings'; + +export const WsDorisInstanceService = { + url: '/api/doris/instance', + + list: async (queryParam: WsDorisInstanceParam) => { + return request>(`${WsDorisInstanceService.url}`, { + method: 'GET', + params: queryParam, + }).then((res) => { + const result = { + data: res.records, + total: res.total, + pageSize: res.size, + current: res.current, + }; + return result; + }); + }, + + asYaml: async (param: WsDorisInstance) => { + return request>(`${WsDorisInstanceService.url}/asYaml`, { + method: 'POST', + data: param, + }); + }, + + add: async (param: WsDorisInstanceAddParam) => { + return request>(`${WsDorisInstanceService.url}`, { + method: 'PUT', + data: param, + }); + }, + + update: async (param: WsDorisInstanceUpdateParam) => { + return request>(`${WsDorisInstanceService.url}`, { + method: 'POST', + data: param, + }); + }, + + delete: async (row: WsDorisInstance) => { + return request>(`${WsDorisInstanceService.url}/` + row.id, { + method: 'DELETE', + }); + }, + + deleteBatch: async (rows: WsDorisInstance[]) => { + const params = rows.map((row) => row.id); + return request>(`${WsDorisInstanceService.url}/` + 'batch', { + method: 'DELETE', + data: params, + }); + }, +}; diff --git a/scaleph-ui-react/src/services/project/typings.d.ts b/scaleph-ui-react/src/services/project/typings.d.ts index 24a32088b..50e2b8539 100644 --- a/scaleph-ui-react/src/services/project/typings.d.ts +++ b/scaleph-ui-react/src/services/project/typings.d.ts @@ -432,6 +432,7 @@ export type WsDorisTemplate = { id?: number; projectId: number; name?: string; + templateId?: string; namespace: string; admin?: Record; feSpec?: Record; @@ -471,3 +472,56 @@ export type WsDorisTemplateUpdateParam = { brokerSpec?: Record; remark?: string; }; + +export type WsDorisInstance = { + id?: number; + projectId: number; + clusterCredentialId?: number; + name?: string; + instanceId?: string; + namespace: string; + admin?: Record; + feSpec?: Record; + beSpec?: Record; + cnSpec?: Record; + brokerSpec?: Record; + deployed?: Dict; + feStatus?: Record; + beStatus?: Record; + cnStatus?: Record; + brokerStatus?: Record; + remark?: string; + createTime?: Date; + updateTime?: Date; +}; + +export type WsDorisInstanceParam = QueryParam & { + projectId: number; + name?: string; +}; + +export type WsDorisInstanceAddParam = { + projectId: number; + clusterCredentialId?: number; + name: string; + namespace: string; + admin?: Record; + feSpec?: Record; + beSpec?: Record; + cnSpec?: Record; + brokerSpec?: Record; + remark?: string; +}; + +export type WsDorisInstanceUpdateParam = { + id: number; + clusterCredentialId?: number; + name: string; + namespace: string; + admin?: Record; + feSpec?: Record; + beSpec?: Record; + cnSpec?: Record; + brokerSpec?: Record; + remark?: string; +}; diff --git a/tools/docker/mysql/init.d/scaleph-security-mysql.sql b/tools/docker/mysql/init.d/scaleph-security-mysql.sql index 911deafee..a5194a153 100644 --- a/tools/docker/mysql/init.d/scaleph-security-mysql.sql +++ b/tools/docker/mysql/init.d/scaleph-security-mysql.sql @@ -34,6 +34,23 @@ insert into sec_user (id, type, user_name, nick_name, avatar, email, phone, pass values (1, '0', 'sys_admin', '超级管理员', null, 'test@admin.com', null, '$2a$10$QX2DBrOBGLuhEmboliW66ulvQ5Hiy9GCdhsqqs1HgJVgslYhZEC6q', '0', null, null, 0, '0', null, 'sys', 'sys'); +INSERT INTO `sec_user`(`id`, `type`, `user_name`, `nick_name`, `avatar`, `email`, `phone`, `password`, `gender`, + `address`, `summary`, `order`, `status`, `remark`, `creator`, `editor`) +VALUES (2, '1', 'kalencaya', '王奇', NULL, '1942460489@qq.com', NULL, + '$2a$10$QX2DBrOBGLuhEmboliW66ulvQ5Hiy9GCdhsqqs1HgJVgslYhZEC6q', '1', NULL, NULL, 0, '0', NULL, 'sys', 'sys'); +INSERT INTO `sec_user`(`id`, `type`, `user_name`, `nick_name`, `avatar`, `email`, `phone`, `password`, `gender`, + `address`, `summary`, `order`, `status`, `remark`, `creator`, `editor`) +VALUES (3, '1', 'gleiyu', '耿雷雨', NULL, 'gleiyu@sina.cn', NULL, + '$2a$10$QX2DBrOBGLuhEmboliW66ulvQ5Hiy9GCdhsqqs1HgJVgslYhZEC6q', '1', NULL, NULL, 0, '0', NULL, 'sys', 'sys'); +INSERT INTO `sec_user`(`id`, `type`, `user_name`, `nick_name`, `avatar`, `email`, `phone`, `password`, `gender`, + `address`, `summary`, `order`, `status`, `remark`, `creator`, `editor`) +VALUES (4, '1', 'LiuBodong', 'LiuBodong', NULL, 'liubodong2010@126.com', NULL, + '$2a$10$QX2DBrOBGLuhEmboliW66ulvQ5Hiy9GCdhsqqs1HgJVgslYhZEC6q', '1', NULL, + 'Want to learn everything but do well in nothing.', 0, '0', NULL, 'sys', 'sys'); +INSERT INTO `sec_user`(`id`, `type`, `user_name`, `nick_name`, `avatar`, `email`, `phone`, `password`, `gender`, + `address`, `summary`, `order`, `status`, `remark`, `creator`, `editor`) +VALUES (5, '1', 'bailongsen1027', NULL, NULL, 'test@123.com', NULL, + '$2a$10$QX2DBrOBGLuhEmboliW66ulvQ5Hiy9GCdhsqqs1HgJVgslYhZEC6q', '1', NULL, NULL, 0, '0', NULL, 'sys', 'sys'); /* 角色表 */ drop table if exists sec_role; @@ -305,19 +322,19 @@ create table sec_resource_web INSERT INTO `sec_resource_web`(`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) -VALUES (1, '2', 0, 'index', '/', '/studio/databoard', NULL, NULL, NULL, NULL, 'sys', 'sys'); +VALUES (1, '2', 0, NULL, '/', '/studio/databoard', NULL, NULL, NULL, NULL, 'sys', 'sys'); INSERT INTO `sec_resource_web`(`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) -VALUES (2, '2', 0, '404', '/404', NULL, NULL, NULL, './404', NULL, 'sys', 'sys'); +VALUES (2, '2', 0, NULL, '/404', NULL, NULL, NULL, './404', NULL, 'sys', 'sys'); INSERT INTO `sec_resource_web`(`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) -VALUES (3, '2', 0, 'login', '/login', NULL, 0, NULL, './User/Login', NULL, 'sys', 'sys'); +VALUES (3, '2', 0, NULL, '/login', NULL, 0, NULL, './User/Login', NULL, 'sys', 'sys'); INSERT INTO `sec_resource_web`(`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) -VALUES (4, '2', 0, 'register', '/register', NULL, 0, NULL, './User/Register', NULL, 'sys', 'sys'); +VALUES (4, '2', 0, NULL, '/register', NULL, 0, NULL, './User/Register', NULL, 'sys', 'sys'); INSERT INTO `sec_resource_web`(`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) -VALUES (5, '2', 0, 'user-center', '/user/center', NULL, NULL, NULL, './User', NULL, 'sys', 'sys'); +VALUES (5, '2', 0, NULL, '/user/center', NULL, NULL, NULL, './User', NULL, 'sys', 'sys'); INSERT INTO `sec_resource_web` (`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, `remark`, `creator`, `editor`) VALUES (6, '0', 0, 'studio', '/studio', NULL, NULL, 'CodeSandboxOutlined', NULL, NULL, 'sys', 'sys'); @@ -542,6 +559,14 @@ INSERT INTO `sec_resource_web` (`id`, `type`, `pid`, `name`, `path`, `redirect`, `remark`, `creator`, `editor`) VALUES (68, '2', 64, NULL, '/workspace/doris/template/detail', NULL, NULL, NULL, './Project/Workspace/Doris/Template/Detail', NULL, 'sys', 'sys'); +INSERT INTO `sec_resource_web` (`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, + `remark`, `creator`, `editor`) +VALUES (69, '2', 64, 'instance', '/workspace/doris/instance', NULL, NULL, NULL, './Project/Workspace/Doris/Instance', + NULL, 'sys', 'sys'); +INSERT INTO `sec_resource_web` (`id`, `type`, `pid`, `name`, `path`, `redirect`, `layout`, `icon`, `component`, + `remark`, `creator`, `editor`) +VALUES (70, '2', 64, NULL, '/workspace/doris/instance/steps', NULL, NULL, NULL, + './Project/Workspace/Doris/Instance/Steps', NULL, 'sys', 'sys'); drop table if exists sec_resource_web_role; create table sec_resource_web_role diff --git a/tools/docker/mysql/init.d/scaleph-ws-mysql.sql b/tools/docker/mysql/init.d/scaleph-ws-mysql.sql index 59e38a789..1eba5720e 100644 --- a/tools/docker/mysql/init.d/scaleph-ws-mysql.sql +++ b/tools/docker/mysql/init.d/scaleph-ws-mysql.sql @@ -548,7 +548,7 @@ create table ws_doris_template `name` varchar(64) not null, template_id varchar(64) not null, namespace varchar(255) not null, - admin varchar(255) comment 'session handler', + admin varchar(255) comment 'admin user', `fe_spec` text comment 'fe spec', `be_spec` text comment 'be spec', `cn_spec` text comment 'cn spec', @@ -568,4 +568,32 @@ VALUES (1, 1, 'simple-doriscluster-sample', 'zexbfaf0eba4ce824787a9bed88148eb233 '{"name":"admin","password":"Admin123"}', '{\"replicas\":1,\"image\":\"selectdb/doris.fe-ubuntu:2.0.2\",\"limits\":{\"cpu\":4,\"memory\":\"8Gi\"},\"requests\":{\"cpu\":4,\"memory\":\"8Gi\"}}', '{\"replicas\":1,\"image\":\"selectdb/doris.be-ubuntu:2.0.2\",\"limits\":{\"cpu\":4,\"memory\":\"8Gi\"},\"requests\":{\"cpu\":4,\"memory\":\"8Gi\"}}', - NULL, NULL, NULL, 'sys', 'sys'); \ No newline at end of file + NULL, NULL, NULL, 'sys', 'sys'); + +drop table if exists ws_doris_instance; +create table ws_doris_instance +( + id bigint not null auto_increment comment '自增主键', + project_id bigint not null comment '项目id', + cluster_credential_id bigint not null, + `name` varchar(64) not null, + instance_id varchar(64) not null, + namespace varchar(255) not null, + admin varchar(255) comment 'admin user', + `fe_spec` text comment 'fe spec', + `be_spec` text comment 'be spec', + `cn_spec` text comment 'cn spec', + `broker_spec` text comment 'broker spec', + deployed varchar(8) comment '是否部署', + `fe_status` text comment 'fe status', + `be_status` text comment 'be status', + `cn_status` text comment 'cn status', + `broker_status` text comment 'broker status', + remark varchar(255), + creator varchar(32) comment '创建人', + create_time timestamp default current_timestamp comment '创建时间', + editor varchar(32) comment '修改人', + update_time timestamp default current_timestamp on update current_timestamp comment '修改时间', + primary key (id), + unique key uniq_name (project_id, `name`, cluster_credential_id) +) engine = innodb comment = 'doris instance'; \ No newline at end of file