From f27c62a5dbee2c0f3f51b7975cbc2cd2e792b313 Mon Sep 17 00:00:00 2001 From: LiemLin Date: Thu, 30 Jul 2020 13:32:29 +0800 Subject: [PATCH] workflow lineage (#2421) * workflow lineage * workflow lineage unit test * stash * add apache license * Update .env * code optimize * add unit test * add apache license * add apache license * optimized code * add postgresql support and optimized code * Update pom.xml * Update en_US.js * Update zh_CN.js * remove mock code * inport i18n * Update pom.xml * Delete .env * add env file Co-authored-by: linhaiqiang Co-authored-by: dailidong Co-authored-by: becarchal --- .../controller/WorkFlowLineageController.java | 81 +++++++++ .../dolphinscheduler/api/enums/Status.java | 14 +- .../api/service/WorkFlowLineageService.java | 97 ++++++++++ .../WorkFlowLineageControllerTest.java | 69 +++++++ .../service/WorkFlowLineageServiceTest.java | 88 +++++++++ .../datasource/SpringConnectionFactory.java | 14 ++ .../dao/entity/WorkFlowLineage.java | 94 ++++++++++ .../dao/entity/WorkFlowRelation.java | 38 ++++ .../dao/mapper/WorkFlowLineageMapper.java | 32 ++++ .../dao/mapper/WorkFlowLineageMapper.xml | 103 +++++++++++ .../dao/mapper/WorkFlowLineageMapperTest.java | 62 +++++++ dolphinscheduler-ui/build/config.js | 1 - .../src/js/conf/home/pages/projects/index.vue | 4 +- .../pages/kinship/_source/graphGrid.vue | 63 +++++++ .../pages/kinship/_source/graphGridOption.js | 145 +++++++++++++++ .../pages/kinship/_source/img/dag_bg.png | Bin 0 -> 5101 bytes .../pages/projects/pages/kinship/index.vue | 169 ++++++++++++++++++ .../src/js/conf/home/router/index.js | 8 + .../src/js/conf/home/store/index.js | 2 + .../src/js/conf/home/store/kinship/actions.js | 89 +++++++++ .../src/js/conf/home/store/kinship/getters.js | 19 ++ .../src/js/conf/home/store/kinship/index.js | 30 ++++ .../js/conf/home/store/kinship/mutations.js | 17 ++ .../src/js/conf/home/store/kinship/state.js | 23 +++ .../components/secondaryMenu/_source/menu.js | 11 +- .../src/js/module/i18n/locale/en_US.js | 11 +- .../src/js/module/i18n/locale/zh_CN.js | 7 + pom.xml | 3 + .../dolphinscheduler-ui/.gitignore | 6 + 29 files changed, 1288 insertions(+), 12 deletions(-) create mode 100644 dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageController.java create mode 100644 dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageService.java create mode 100644 dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageControllerTest.java create mode 100644 dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageServiceTest.java create mode 100644 dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowLineage.java create mode 100644 dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowRelation.java create mode 100644 dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.java create mode 100644 dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.xml create mode 100644 dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapperTest.java create mode 100644 dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/graphGrid.vue create mode 100644 dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/graphGridOption.js create mode 100644 dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/img/dag_bg.png create mode 100644 dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/index.vue create mode 100644 dolphinscheduler-ui/src/js/conf/home/store/kinship/actions.js create mode 100644 dolphinscheduler-ui/src/js/conf/home/store/kinship/getters.js create mode 100644 dolphinscheduler-ui/src/js/conf/home/store/kinship/index.js create mode 100644 dolphinscheduler-ui/src/js/conf/home/store/kinship/mutations.js create mode 100644 dolphinscheduler-ui/src/js/conf/home/store/kinship/state.js create mode 100644 repository/dolphinscheduler/dolphinscheduler-ui/.gitignore diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageController.java new file mode 100644 index 0000000000..895d2cd8da --- /dev/null +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageController.java @@ -0,0 +1,81 @@ +/* + * 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 org.apache.dolphinscheduler.api.controller; + +import org.apache.dolphinscheduler.api.service.WorkFlowLineageService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.utils.ParameterUtils; +import io.swagger.annotations.ApiParam; +import org.apache.dolphinscheduler.dao.entity.WorkFlowLineage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; +import springfox.documentation.annotations.ApiIgnore; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.apache.dolphinscheduler.api.enums.Status.QUERY_WORKFLOW_LINEAGE_ERROR; + +@RestController +@RequestMapping("lineages/{projectId}") +public class WorkFlowLineageController extends BaseController { + private static final Logger logger = LoggerFactory.getLogger(WorkFlowLineageController.class); + + @Autowired + private WorkFlowLineageService workFlowLineageService; + + @GetMapping(value="/list-name") + @ResponseStatus(HttpStatus.OK) + public Result> queryWorkFlowLineageByName(@ApiIgnore @RequestParam(value = "searchVal", required = false) String searchVal, @ApiParam(name = "projectId", value = "PROJECT_ID", required = true) @PathVariable int projectId) { + try { + searchVal = ParameterUtils.handleEscapes(searchVal); + Map result = workFlowLineageService.queryWorkFlowLineageByName(searchVal,projectId); + return returnDataList(result); + } catch (Exception e){ + logger.error(QUERY_WORKFLOW_LINEAGE_ERROR.getMsg(),e); + return error(QUERY_WORKFLOW_LINEAGE_ERROR.getCode(), QUERY_WORKFLOW_LINEAGE_ERROR.getMsg()); + } + } + + @GetMapping(value="/list-ids") + @ResponseStatus(HttpStatus.OK) + public Result> queryWorkFlowLineageByIds(@ApiIgnore @RequestParam(value = "ids", required = false) String ids,@ApiParam(name = "projectId", value = "PROJECT_ID", required = true) @PathVariable int projectId) { + + try { + ids = ParameterUtils.handleEscapes(ids); + Set idsSet = new HashSet<>(); + if(ids != null) { + String[] idsStr = ids.split(","); + for (String id : idsStr) + { + idsSet.add(Integer.parseInt(id)); + } + } + + Map result = workFlowLineageService.queryWorkFlowLineageByIds(idsSet, projectId); + return returnDataList(result); + } catch (Exception e){ + logger.error(QUERY_WORKFLOW_LINEAGE_ERROR.getMsg(),e); + return error(QUERY_WORKFLOW_LINEAGE_ERROR.getCode(), QUERY_WORKFLOW_LINEAGE_ERROR.getMsg()); + } + } +} diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java index ec0b8f0a76..caa390ed8e 100644 --- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java @@ -168,15 +168,15 @@ public enum Status { PREVIEW_SCHEDULE_ERROR(10139,"preview schedule error", "预览调度配置错误"), PARSE_TO_CRON_EXPRESSION_ERROR(10140,"parse cron to cron expression error", "解析调度表达式错误"), SCHEDULE_START_TIME_END_TIME_SAME(10141,"The start time must not be the same as the end", "开始时间不能和结束时间一样"), - DELETE_TENANT_BY_ID_FAIL(10142,"delete tenant by id fail, for there are {0} process instances in executing using it", "删除租户失败,有[{0}]个运行中的工作流实例正在使用"), - DELETE_TENANT_BY_ID_FAIL_DEFINES(10143,"delete tenant by id fail, for there are {0} process definitions using it", "删除租户失败,有[{0}]个工作流定义正在使用"), - DELETE_TENANT_BY_ID_FAIL_USERS(10144,"delete tenant by id fail, for there are {0} users using it", "删除租户失败,有[{0}]个用户正在使用"), - DELETE_WORKER_GROUP_BY_ID_FAIL(10145,"delete worker group by id fail, for there are {0} process instances in executing using it", "删除Worker分组失败,有[{0}]个运行中的工作流实例正在使用"), - QUERY_WORKER_GROUP_FAIL(10146,"query worker group fail ", "查询worker分组失败"), - DELETE_WORKER_GROUP_FAIL(10147,"delete worker group fail ", "删除worker分组失败"), + DELETE_TENANT_BY_ID_FAIL(100142,"delete tenant by id fail, for there are {0} process instances in executing using it", "删除租户失败,有[{0}]个运行中的工作流实例正在使用"), + DELETE_TENANT_BY_ID_FAIL_DEFINES(100143,"delete tenant by id fail, for there are {0} process definitions using it", "删除租户失败,有[{0}]个工作流定义正在使用"), + DELETE_TENANT_BY_ID_FAIL_USERS(100144,"delete tenant by id fail, for there are {0} users using it", "删除租户失败,有[{0}]个用户正在使用"), + DELETE_WORKER_GROUP_BY_ID_FAIL(100145,"delete worker group by id fail, for there are {0} process instances in executing using it", "删除Worker分组失败,有[{0}]个运行中的工作流实例正在使用"), + QUERY_WORKER_GROUP_FAIL(100146,"query worker group fail ", "查询worker分组失败"), + DELETE_WORKER_GROUP_FAIL(100147,"delete worker group fail ", "删除worker分组失败"), + QUERY_WORKFLOW_LINEAGE_ERROR(10143,"query workflow lineage error", "查询血缘失败"), COPY_PROCESS_DEFINITION_ERROR(10148,"copy process definition error", "复制工作流错误"), USER_DISABLED(10149,"The current user is disabled", "当前用户已停用"), - UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"), UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"), RESOURCE_NOT_EXIST(20004, "resource not exist", "资源不存在"), diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageService.java new file mode 100644 index 0000000000..29fd99c0f7 --- /dev/null +++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageService.java @@ -0,0 +1,97 @@ +/* + * 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 org.apache.dolphinscheduler.api.service; + +import org.apache.dolphinscheduler.api.enums.Status; +import org.apache.dolphinscheduler.common.Constants; +import org.apache.dolphinscheduler.dao.mapper.WorkFlowLineageMapper; +import org.apache.dolphinscheduler.dao.entity.WorkFlowLineage; +import org.apache.dolphinscheduler.dao.entity.WorkFlowRelation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Service +public class WorkFlowLineageService extends BaseService { + + @Autowired + private WorkFlowLineageMapper workFlowLineageMapper; + + public Map queryWorkFlowLineageByName(String workFlowName, int projectId) { + Map result = new HashMap<>(5); + List workFlowLineageList = workFlowLineageMapper.queryByName(workFlowName, projectId); + result.put(Constants.DATA_LIST, workFlowLineageList); + putMsg(result, Status.SUCCESS); + return result; + } + + private List getWorkFlowRelationRecursion(Set ids, List workFlowRelations,Set sourceIds) { + for(int id : ids) { + sourceIds.addAll(ids); + List workFlowRelationsTmp = workFlowLineageMapper.querySourceTarget(id); + if(workFlowRelationsTmp != null && !workFlowRelationsTmp.isEmpty()) { + Set idsTmp = new HashSet<>(); + for(WorkFlowRelation workFlowRelation:workFlowRelationsTmp) { + if(!sourceIds.contains(workFlowRelation.getTargetWorkFlowId())){ + idsTmp.add(workFlowRelation.getTargetWorkFlowId()); + } + } + workFlowRelations.addAll(workFlowRelationsTmp); + getWorkFlowRelationRecursion(idsTmp, workFlowRelations,sourceIds); + } + } + return workFlowRelations; + } + + public Map queryWorkFlowLineageByIds(Set ids,int projectId) { + Map result = new HashMap<>(5); + List workFlowLineageList = workFlowLineageMapper.queryByIds(ids, projectId); + Map workFlowLists = new HashMap<>(5); + Set idsV = new HashSet<>(); + if(ids == null || ids.isEmpty()){ + for(WorkFlowLineage workFlowLineage:workFlowLineageList) { + idsV.add(workFlowLineage.getWorkFlowId()); + } + } else { + idsV = ids; + } + List workFlowRelations = new ArrayList<>(); + Set sourceIds = new HashSet<>(); + getWorkFlowRelationRecursion(idsV, workFlowRelations, sourceIds); + + Set idSet = new HashSet<>(); + //If the incoming parameter is not empty, you need to add downstream workflow detail attributes + if(ids != null && !ids.isEmpty()) { + for(WorkFlowRelation workFlowRelation : workFlowRelations) { + idSet.add(workFlowRelation.getTargetWorkFlowId()); + } + for(int id : ids){ + idSet.remove(id); + } + if(!idSet.isEmpty()) { + workFlowLineageList.addAll(workFlowLineageMapper.queryByIds(idSet, projectId)); + } + } + + workFlowLists.put("workFlowList",workFlowLineageList); + workFlowLists.put("workFlowRelationList",workFlowRelations); + result.put(Constants.DATA_LIST, workFlowLists); + putMsg(result, Status.SUCCESS); + return result; + } +} diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageControllerTest.java new file mode 100644 index 0000000000..7dea15d537 --- /dev/null +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/WorkFlowLineageControllerTest.java @@ -0,0 +1,69 @@ +/* + * 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 org.apache.dolphinscheduler.api.controller; + +import org.apache.dolphinscheduler.api.enums.Status; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.utils.JSONUtils; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class WorkFlowLineageControllerTest extends AbstractControllerTest { + private static Logger logger = LoggerFactory.getLogger(WorkFlowLineageControllerTest.class); + + @Test + public void testQueryWorkFlowLineageByName() throws Exception { + MultiValueMap paramsMap = new LinkedMultiValueMap<>(); + paramsMap.add("searchVal","test"); + MvcResult mvcResult = mockMvc.perform(get("/lineages/1/list-name") + .header("sessionId", sessionId) + .params(paramsMap)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andReturn(); + Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class); + Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue()); + logger.info(mvcResult.getResponse().getContentAsString()); + + } + + @Test + public void testQueryWorkFlowLineageByIds() throws Exception { + MultiValueMap paramsMap = new LinkedMultiValueMap<>(); + paramsMap.add("ids","1"); + MvcResult mvcResult = mockMvc.perform(get("/lineages/1/list-ids") + .header("sessionId", sessionId) + .params(paramsMap)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andReturn(); + Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class); + Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue()); + logger.info(mvcResult.getResponse().getContentAsString()); + } + +} diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageServiceTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageServiceTest.java new file mode 100644 index 0000000000..999e079bf5 --- /dev/null +++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/WorkFlowLineageServiceTest.java @@ -0,0 +1,88 @@ +/* + * 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 org.apache.dolphinscheduler.api.service; + +import org.apache.dolphinscheduler.common.Constants; +import org.apache.dolphinscheduler.common.utils.EncryptionUtils; +import org.apache.dolphinscheduler.dao.entity.WorkFlowLineage; +import org.apache.dolphinscheduler.dao.entity.WorkFlowRelation; +import org.apache.dolphinscheduler.dao.mapper.WorkFlowLineageMapper; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.*; + +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class WorkFlowLineageServiceTest { + + @InjectMocks + private WorkFlowLineageService workFlowLineageService; + + @Mock + private WorkFlowLineageMapper workFlowLineageMapper; + + @Test + public void testQueryWorkFlowLineageByName() { + String searchVal = "test"; + when(workFlowLineageMapper.queryByName(searchVal, 1)).thenReturn(getWorkFlowLineages()); + Map result = workFlowLineageService.queryWorkFlowLineageByName(searchVal,1); + List workFlowLineageList = (List)result.get(Constants.DATA_LIST); + Assert.assertTrue(workFlowLineageList.size()>0); + } + + @Test + public void testQueryWorkFlowLineageByIds() { + + Set ids = new HashSet<>(); + ids.add(1); + ids.add(2); + + when(workFlowLineageMapper.queryByIds(ids, 1)).thenReturn(getWorkFlowLineages()); + when(workFlowLineageMapper.querySourceTarget(1)).thenReturn(getWorkFlowRelation()); + Map result = workFlowLineageService.queryWorkFlowLineageByIds(ids,1); + Map workFlowLists = (Map)result.get(Constants.DATA_LIST); + List workFlowLineages = (List)workFlowLists.get("workFlowList"); + List workFlowRelations = (List)workFlowLists.get("workFlowRelationList"); + Assert.assertTrue(workFlowLineages.size()>0); + Assert.assertTrue(workFlowRelations.size()>0); + } + + private List getWorkFlowLineages() { + List workFlowLineages = new ArrayList<>(); + WorkFlowLineage workFlowLineage = new WorkFlowLineage(); + workFlowLineage.setWorkFlowId(1); + workFlowLineage.setWorkFlowName("testdag"); + workFlowLineages.add(workFlowLineage); + return workFlowLineages; + } + + private List getWorkFlowRelation(){ + List workFlowRelations = new ArrayList<>(); + WorkFlowRelation workFlowRelation = new WorkFlowRelation(); + workFlowRelation.setSourceWorkFlowId(1); + workFlowRelation.setTargetWorkFlowId(2); + workFlowRelations.add(workFlowRelation); + return workFlowRelations; + } + +} diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/SpringConnectionFactory.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/SpringConnectionFactory.java index 9e27d949aa..5dcdc75ab5 100644 --- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/SpringConnectionFactory.java +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/datasource/SpringConnectionFactory.java @@ -26,6 +26,8 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.dao.utils.PropertyUtils; +import org.apache.ibatis.mapping.DatabaseIdProvider; +import org.apache.ibatis.mapping.VendorDatabaseIdProvider; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.JdbcType; @@ -39,6 +41,8 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import java.util.Properties; + /** * data source connection factory @@ -129,6 +133,7 @@ public class SpringConnectionFactory { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(resolver.getResources("org/apache/dolphinscheduler/dao/mapper/*Mapper.xml")); sqlSessionFactoryBean.setTypeEnumsPackage("org.apache.dolphinscheduler.*.enums"); + sqlSessionFactoryBean.setDatabaseIdProvider(databaseIdProvider()); return sqlSessionFactoryBean.getObject(); } @@ -142,4 +147,13 @@ public class SpringConnectionFactory { return new SqlSessionTemplate(sqlSessionFactory()); } + @Bean + public DatabaseIdProvider databaseIdProvider(){ + DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider(); + Properties properties = new Properties(); + properties.setProperty("MySQL", "mysql"); + properties.setProperty("PostgreSQL", "pg"); + databaseIdProvider.setProperties(properties); + return databaseIdProvider; + } } diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowLineage.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowLineage.java new file mode 100644 index 0000000000..6c2d9c3168 --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowLineage.java @@ -0,0 +1,94 @@ +/* + * 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 org.apache.dolphinscheduler.dao.entity; + +import java.util.Date; + +public class WorkFlowLineage { + private int workFlowId; + private String workFlowName; + private String workFlowPublishStatus; + private Date scheduleStartTime; + private Date scheduleEndTime; + private String crontab; + private int schedulePublishStatus; + private String sourceWorkFlowId; + + public String getSourceWorkFlowId() { + return sourceWorkFlowId; + } + + public void setSourceWorkFlowId(String sourceWorkFlowId) { + this.sourceWorkFlowId = sourceWorkFlowId; + } + + public int getWorkFlowId() { + return workFlowId; + } + + public void setWorkFlowId(int workFlowId) { + this.workFlowId = workFlowId; + } + + public String getWorkFlowName() { + return workFlowName; + } + + public void setWorkFlowName(String workFlowName) { + this.workFlowName = workFlowName; + } + + public String getWorkFlowPublishStatus() { + return workFlowPublishStatus; + } + + public void setWorkFlowPublishStatus(String workFlowPublishStatus) { + this.workFlowPublishStatus = workFlowPublishStatus; + } + + public Date getScheduleStartTime() { + return scheduleStartTime; + } + + public void setScheduleStartTime(Date scheduleStartTime) { + this.scheduleStartTime = scheduleStartTime; + } + + public Date getScheduleEndTime() { + return scheduleEndTime; + } + + public void setScheduleEndTime(Date scheduleEndTime) { + this.scheduleEndTime = scheduleEndTime; + } + + public String getCrontab() { + return crontab; + } + + public void setCrontab(String crontab) { + this.crontab = crontab; + } + + public int getSchedulePublishStatus() { + return schedulePublishStatus; + } + + public void setSchedulePublishStatus(int schedulePublishStatus) { + this.schedulePublishStatus = schedulePublishStatus; + } +} diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowRelation.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowRelation.java new file mode 100644 index 0000000000..c03c68eb0d --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/WorkFlowRelation.java @@ -0,0 +1,38 @@ +/* + * 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 org.apache.dolphinscheduler.dao.entity; + +public class WorkFlowRelation { + private int sourceWorkFlowId; + private int targetWorkFlowId; + + public int getSourceWorkFlowId() { + return sourceWorkFlowId; + } + + public void setSourceWorkFlowId(int sourceWorkFlowId) { + this.sourceWorkFlowId = sourceWorkFlowId; + } + + public int getTargetWorkFlowId() { + return targetWorkFlowId; + } + + public void setTargetWorkFlowId(int targetWorkFlowId) { + this.targetWorkFlowId = targetWorkFlowId; + } +} diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.java new file mode 100644 index 0000000000..3abba3b7d3 --- /dev/null +++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.java @@ -0,0 +1,32 @@ +/* + * 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 org.apache.dolphinscheduler.dao.mapper; + +import org.apache.dolphinscheduler.dao.entity.WorkFlowLineage; +import org.apache.dolphinscheduler.dao.entity.WorkFlowRelation; +import org.apache.ibatis.annotations.Param; +import java.util.List; +import java.util.Set; + +public interface WorkFlowLineageMapper { + + public List queryByName(@Param("searchVal") String searchVal, @Param("projectId") int projectId); + + public List queryByIds(@Param("ids") Set ids, @Param("projectId") int projectId); + + public List querySourceTarget(@Param("id") int id); +} diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.xml new file mode 100644 index 0000000000..823ea0f774 --- /dev/null +++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapper.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapperTest.java b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapperTest.java new file mode 100644 index 0000000000..5645e1cf75 --- /dev/null +++ b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/WorkFlowLineageMapperTest.java @@ -0,0 +1,62 @@ +/* + * 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 org.apache.dolphinscheduler.dao.mapper; + +import org.apache.dolphinscheduler.dao.entity.WorkFlowLineage; +import org.apache.dolphinscheduler.dao.entity.WorkFlowRelation; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@RunWith(SpringRunner.class) +@SpringBootTest +@Transactional +@Rollback(true) +public class WorkFlowLineageMapperTest { + @Autowired + private WorkFlowLineageMapper workFlowLineageMapper; + + @Test + public void testQueryByName() { + List workFlowLineages = workFlowLineageMapper.queryByName("test",1); + Assert.assertNotEquals(workFlowLineages.size(), 0); + } + + + @Test + public void testQueryByIds() { + Set ids = new HashSet<>(); + ids.add(1); + List workFlowLineages = workFlowLineageMapper.queryByIds(ids,1); + Assert.assertNotEquals(workFlowLineages.size(), 0); + } + + @Test + public void testQuerySourceTarget() { + List workFlowRelations = workFlowLineageMapper.querySourceTarget(1); + Assert.assertNotEquals(workFlowRelations.size(), 0); + } +} diff --git a/dolphinscheduler-ui/build/config.js b/dolphinscheduler-ui/build/config.js index 53a421d9a0..2800115d80 100644 --- a/dolphinscheduler-ui/build/config.js +++ b/dolphinscheduler-ui/build/config.js @@ -116,7 +116,6 @@ const pages = glob.sync(['*/!(_*).html'], { cwd: viewDir }).map(p => { minify: minifierConfig }) }) - const baseConfig = { entry: jsEntry, output: { diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/index.vue index 13aa0536f5..cbf4a728e6 100644 --- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/index.vue +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/index.vue @@ -17,7 +17,9 @@ + + diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/graphGridOption.js b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/graphGridOption.js new file mode 100644 index 0000000000..117a177651 --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/graphGridOption.js @@ -0,0 +1,145 @@ +/* + * 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. + */ +import _ from 'lodash'; +import i18n from '@/module/i18n/index.js' + +const getCategory = (categoryDic, { workFlowPublishStatus, schedulePublishStatus, id }, sourceWorkFlowId) => { + if (id === sourceWorkFlowId) return categoryDic['active'] + switch (true) { + case workFlowPublishStatus === '0': + return categoryDic['0']; + case workFlowPublishStatus === '1' && schedulePublishStatus === '0': + return categoryDic['10']; + case workFlowPublishStatus === '1' && schedulePublishStatus === '1': + default: + return categoryDic['1']; + } +} + +export default function (locations, links, sourceWorkFlowId, isShowLabel) { + + const categoryDic = { + 'active': { color: '#2D8DF0', category: i18n.$t('KinshipStateActive')}, + '1': { color: '#00C800', category: i18n.$t('KinshipState1')}, + '0': { color: '#999999', category: i18n.$t('KinshipState0')}, + '10': { color: '#FF8F05', category: i18n.$t('KinshipState10')}, + } + const newData = _.map(locations, (item) => { + const { color, category } = getCategory(categoryDic, item, sourceWorkFlowId) + return { + ...item, + emphasis: { + itemStyle: { + color + }, + }, + category + } + }); + + const categories = [ + { name: categoryDic.active.category}, + { name: categoryDic['1'].category}, + { name: categoryDic['0'].category}, + { name: categoryDic['10'].category}, + ] + let option = { + tooltip: { + trigger: 'item', + triggerOn: 'mousemove', + backgroundColor: '#2D303A', + padding: [8, 12], + formatter: (params) => { + if (!params.data.name) return ''; + const { name, scheduleStartTime, scheduleEndTime, crontab, workFlowPublishStatus, schedulePublishStatus } = params.data; + const str = ` + 工作流名字:${name}
+ 调度开始时间:${scheduleStartTime}
+ 调度结束时间:${scheduleEndTime}
+ crontab表达式:${crontab}
+ 工作流发布状态:${workFlowPublishStatus}
+ 调度发布状态:${schedulePublishStatus}
+ ` + return str; + }, + color: '#2D303A', + textStyle: { + rich: { + a: { + fontSize: 12, + color: '#2D303A', + lineHeight: 12, + align: 'left', + padding: [4, 4, 4, 4] + }, + } + }, + }, + color: [categoryDic.active.color, categoryDic['1'].color, categoryDic['0'].color, categoryDic['10'].color], + legend: [{ + orient: 'horizontal', + top: 6, + left: 6, + data: categories, + }], + series: [{ + type: 'graph', + layout: 'force', + nodeScaleRatio: 1.2, + draggable: true, + animation: false, + data: newData, + roam: true, + symbol: 'roundRect', + symbolSize: 70, + categories, + label: { + show: isShowLabel, + position: 'inside', + formatter: (params) => { + if (!params.data.name) return ''; + const str = params.data.name.split('_').map(item => `{a|${item}\n}`).join('') + return str; + }, + color: '#222222', + textStyle: { + rich: { + a: { + fontSize: 12, + color: '#222222', + lineHeight: 12, + align: 'left', + padding: [4, 4, 4, 4] + }, + } + } + }, + edgeSymbol: ['circle', 'arrow'], + edgeSymbolSize: [4, 12], + force: { + repulsion: 1000, + edgeLength: 300 + }, + links: links, + lineStyle: { + color: '#999999' + } + }] + }; + + return option +} diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/img/dag_bg.png b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/_source/img/dag_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..d9fa09817ed92ea7e85bd3f3d0004f687d289b12 GIT binary patch literal 5101 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 Usj!pQ&hM_tQ44f|;n_?710Ng3UjP6A literal 0 HcmV?d00001 diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/index.vue new file mode 100644 index 0000000000..2472a69786 --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/kinship/index.vue @@ -0,0 +1,169 @@ +/* + * 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. + */ + + + diff --git a/dolphinscheduler-ui/src/js/conf/home/router/index.js b/dolphinscheduler-ui/src/js/conf/home/router/index.js index b4236f3685..b65586c433 100644 --- a/dolphinscheduler-ui/src/js/conf/home/router/index.js +++ b/dolphinscheduler-ui/src/js/conf/home/router/index.js @@ -57,6 +57,14 @@ const router = new Router({ title: `${i18n.$t('Project Home')}` } }, + { + path: '/projects/kinship', + name: 'projects-kinship', + component: resolve => require(['../pages/projects/pages/kinship/index'], resolve), + meta: { + title: `${i18n.$t('Kinship')}` + } + }, { path: '/projects/list', name: 'projects-list', diff --git a/dolphinscheduler-ui/src/js/conf/home/store/index.js b/dolphinscheduler-ui/src/js/conf/home/store/index.js index 5ca2187479..a7e5824ff0 100644 --- a/dolphinscheduler-ui/src/js/conf/home/store/index.js +++ b/dolphinscheduler-ui/src/js/conf/home/store/index.js @@ -17,6 +17,7 @@ import Vue from 'vue' import Vuex from 'vuex' import dag from './dag' +import kinship from './kinship' import projects from './projects' import resource from './resource' import security from './security' @@ -28,6 +29,7 @@ export default new Vuex.Store({ modules: { dag, projects, + kinship, resource, security, datasource, diff --git a/dolphinscheduler-ui/src/js/conf/home/store/kinship/actions.js b/dolphinscheduler-ui/src/js/conf/home/store/kinship/actions.js new file mode 100644 index 0000000000..f87a57d17f --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/store/kinship/actions.js @@ -0,0 +1,89 @@ +/* + * 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. + */ + +import _ from 'lodash' +import io from '@/module/io' +import localStore from '@/module/util/localStorage' + +export default { + /** + * Get workFlow DAG + */ + getWorkFlowList ({ state }, payload) { + const projectId = localStore.getItem('projectId'); + return new Promise((resolve, reject) => { + const url = `lineages/${projectId}/list-name`; + io.get(url, { + searchVal: payload, + }, res => { + const workList = []; + if (res.data) { + _.map(res.data, (item) => { + workList.push({ + id: `${item.workFlowId}`, + name: item.workFlowName, + }) + }) + } + state.workList = workList /* JSON.parse(connects) */ + resolve(res.data) + }).catch(res => { + reject(res) + }) + }) + }, + /** + * Get workFlow DAG + */ + getWorkFlowDAG ({ state }, payload) { + const projectId = localStore.getItem('projectId'); + return new Promise((resolve, reject) => { + const url = `lineages/${projectId}/list-ids`; + io.get(url, { + ids: payload, + }, res => { + let locations = []; + let connects = []; + if (res.data.workFlowList) { + locations = _.uniqBy(res.data.workFlowList, 'workFlowId').map((item) => ({ + id: `${item.workFlowId}`, + name: item.workFlowName, + workFlowPublishStatus: item.workFlowPublishStatus, + scheduleStartTime: item.scheduleStartTime, + scheduleEndTime: item.scheduleEndTime, + crontab: item.crontab, + schedulePublishStatus: item.schedulePublishStatus + })) + } + if (res.data.workFlowRelationList) { + connects = _.map(res.data.workFlowRelationList, (item) => ({ + source: `${item.sourceWorkFlowId}`, // should be string, or connects will not show by echarts + target: `${item.targetWorkFlowId}`, // should be string, or connects will not show by echarts + })) + } + state.sourceWorkFlowId = payload || ''; + // locations + state.locations = locations /* JSON.parse(locations) */ + // connects + state.connects = connects /* JSON.parse(connects) */ + resolve(res.data) + }).catch(res => { + reject(res) + }) + }) + }, +} diff --git a/dolphinscheduler-ui/src/js/conf/home/store/kinship/getters.js b/dolphinscheduler-ui/src/js/conf/home/store/kinship/getters.js new file mode 100644 index 0000000000..e84c864c3c --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/store/kinship/getters.js @@ -0,0 +1,19 @@ +/* + * 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. + */ + +export default { +} diff --git a/dolphinscheduler-ui/src/js/conf/home/store/kinship/index.js b/dolphinscheduler-ui/src/js/conf/home/store/kinship/index.js new file mode 100644 index 0000000000..24abd1ccaa --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/store/kinship/index.js @@ -0,0 +1,30 @@ +/* + * 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. + */ + +import actions from './actions' +import getters from './getters' +import mutations from './mutations' +import state from './state' + +export default { + strict: true, + namespaced: true, + state, + getters, + mutations, + actions +} diff --git a/dolphinscheduler-ui/src/js/conf/home/store/kinship/mutations.js b/dolphinscheduler-ui/src/js/conf/home/store/kinship/mutations.js new file mode 100644 index 0000000000..2d71cd834f --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/store/kinship/mutations.js @@ -0,0 +1,17 @@ +/* + * 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. + */ +export default {} diff --git a/dolphinscheduler-ui/src/js/conf/home/store/kinship/state.js b/dolphinscheduler-ui/src/js/conf/home/store/kinship/state.js new file mode 100644 index 0000000000..6f22b86477 --- /dev/null +++ b/dolphinscheduler-ui/src/js/conf/home/store/kinship/state.js @@ -0,0 +1,23 @@ +/* + * 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. + */ + +export default { + sourceWorkFlowId: '', + workList: [], + locations: [], + connects: [] +} diff --git a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js index 6487c2faef..56834a294e 100644 --- a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js +++ b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js @@ -31,8 +31,17 @@ const menu = { children: [] }, { - name: `${i18n.$t('Process')}`, + name: `${i18n.$t('Kinship')}`, id: 1, + path: 'projects-kinship', + isOpen: true, + disabled: true, + icon: 'ans-icon-node', + children: [] + }, + { + name: `${i18n.$t('Process')}`, + id: 2, path: '', isOpen: true, disabled: true, diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js index eaca45d150..8afa0edd68 100755 --- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js +++ b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js @@ -545,8 +545,8 @@ export default { '0 means unlimited by count': '0 means unlimited', 'Modify User': 'Modify User', 'Whether directory': 'Whether directory', - Yes: 'Yes', - No: 'No', + 'Yes': 'Yes', + 'No': 'No', 'Hadoop Custom Params': 'Hadoop Params', 'Sqoop Advanced Parameters': 'Sqoop Params', 'Sqoop Job Name': 'Job Name', @@ -605,6 +605,13 @@ export default { 'Successful branch flow and failed branch flow are required': 'conditions node Successful and failed branch flow are required', 'Unauthorized or deleted resources': 'Unauthorized or deleted resources', 'Please delete all non-existent resources': 'Please delete all non-existent resources', + 'Kinship': 'Workflow relationship', + 'Reset': 'Reset', + 'KinshipStateActive': 'Active', + 'KinshipState1': 'Online', + 'KinshipState0': 'Workflow is not online', + 'KinshipState10': 'Scheduling is not online', + 'Dag label display control': 'Dag label display control', 'Enable': 'Enable', 'Timeout Settings': 'Timeout Settings', 'Connect Timeout':'Connect Timeout', diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js index 8d6ecd7025..cda0d4a36c 100755 --- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js +++ b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js @@ -605,6 +605,13 @@ export default { 'Successful branch flow and failed branch flow are required': 'conditions节点成功和失败分支流转必填', 'Unauthorized or deleted resources': '未授权或已删除资源', 'Please delete all non-existent resources': '请删除所有未授权或已删除资源', + 'Kinship': '工作流关系', + 'Reset': '重置', + 'KinshipStateActive': '当前选择', + 'KinshipState1': '已上线', + 'KinshipState0': '工作流未上线', + 'KinshipState10': '调度未上线', + 'Dag label display control': 'Dag节点名称显隐', 'Enable': '启用', 'Disable': '停用', 'The Worker group no longer exists, please select the correct Worker group!': '该Worker分组已经不存在,请选择正确的Worker分组!', diff --git a/pom.xml b/pom.xml index 196e95a917..b469f38c1d 100644 --- a/pom.xml +++ b/pom.xml @@ -552,6 +552,7 @@ apache-dolphinscheduler-incubating-${project.version} + @@ -733,7 +734,9 @@ **/api/service/UserAlertGroupServiceTest.java **/api/service/UsersServiceTest.java **/api/service/WorkerGroupServiceTest.java + **/api/service/WorkFlowLineageServiceTest.java **/api/controller/ProcessDefinitionControllerTest.java + **/api/controller/WorkFlowLineageControllerTest.java **/api/utils/exportprocess/DataSourceParamTest.java **/api/utils/exportprocess/DependentParamTest.java **/api/utils/CheckUtilsTest.java diff --git a/repository/dolphinscheduler/dolphinscheduler-ui/.gitignore b/repository/dolphinscheduler/dolphinscheduler-ui/.gitignore new file mode 100644 index 0000000000..27c1333c66 --- /dev/null +++ b/repository/dolphinscheduler/dolphinscheduler-ui/.gitignore @@ -0,0 +1,6 @@ +.idea +.settings +package-lock.json +.classpath +.project +node_modules \ No newline at end of file