calvin
10 months ago
committed by
GitHub
64 changed files with 1178 additions and 56 deletions
@ -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 org.apache.dolphinscheduler.api.controller; |
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR; |
||||
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException; |
||||
import org.apache.dolphinscheduler.api.service.ProjectWorkerGroupRelationService; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PathVariable; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestAttribute; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.ResponseStatus; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import io.swagger.v3.oas.annotations.Operation; |
||||
import io.swagger.v3.oas.annotations.Parameter; |
||||
import io.swagger.v3.oas.annotations.Parameters; |
||||
import io.swagger.v3.oas.annotations.media.Schema; |
||||
import io.swagger.v3.oas.annotations.tags.Tag; |
||||
|
||||
/** |
||||
* project and worker group controller |
||||
*/ |
||||
@Tag(name = "PROJECT_WORKER_GROUP_TAG") |
||||
@RestController |
||||
@RequestMapping("projects/{projectCode}/worker-group") |
||||
@Slf4j |
||||
public class ProjectWorkerGroupController extends BaseController { |
||||
|
||||
@Autowired |
||||
private ProjectWorkerGroupRelationService projectWorkerGroupRelationService; |
||||
|
||||
/** |
||||
* assign worker groups to the project |
||||
* |
||||
* @param loginUser login user |
||||
* @param projectCode project code |
||||
@ @RequestParam(value = "workerGroups", required = false) String workerGroups |
||||
* @return create result code |
||||
*/ |
||||
@Operation(summary = "assignWorkerGroups", description = "CREATE_PROCESS_DEFINITION_NOTES") |
||||
@Parameters({ |
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", schema = @Schema(implementation = long.class, example = "123456")), |
||||
@Parameter(name = "workerGroups", description = "WORKER_GROUP_LIST", schema = @Schema(implementation = List.class)) |
||||
}) |
||||
@PostMapping() |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
@ApiException(ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR) |
||||
public Result assignWorkerGroups(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode, |
||||
@Parameter(name = "workerGroups") String[] workerGroups) { |
||||
|
||||
List<String> workerGroupList = Arrays.stream(workerGroups).collect(Collectors.toList()); |
||||
return projectWorkerGroupRelationService.assignWorkerGroupsToProject(loginUser, projectCode, workerGroupList); |
||||
} |
||||
|
||||
/** |
||||
* query worker groups that assigned to the project |
||||
* |
||||
* @param projectCode project code |
||||
* @return worker group list |
||||
*/ |
||||
@Operation(summary = "queryWorkerGroups", description = "QUERY_WORKER_GROUP_LIST") |
||||
@Parameters({ |
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", schema = @Schema(implementation = long.class, example = "123456")) |
||||
}) |
||||
@GetMapping() |
||||
@ResponseStatus(HttpStatus.OK) |
||||
public Map<String, Object> queryWorkerGroups(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser, |
||||
@Parameter(name = "projectCode", description = "PROJECT_CODE", required = true) @PathVariable long projectCode) { |
||||
return projectWorkerGroupRelationService.queryWorkerGroupsByProject(loginUser, projectCode); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,48 @@
|
||||
/* |
||||
* 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.utils.Result; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
|
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* the service of project and worker group |
||||
*/ |
||||
public interface ProjectWorkerGroupRelationService { |
||||
|
||||
/** |
||||
* assign worker groups to a project |
||||
* |
||||
* @param loginUser the login user |
||||
* @param projectCode the project code |
||||
* @param workerGroups assigned worker group names |
||||
*/ |
||||
Result assignWorkerGroupsToProject(User loginUser, Long projectCode, List<String> workerGroups); |
||||
|
||||
/** |
||||
* query worker groups that assigned to the project |
||||
* |
||||
* @param loginUser the login user |
||||
* @param projectCode project code |
||||
*/ |
||||
Map<String, Object> queryWorkerGroupsByProject(User loginUser, Long projectCode); |
||||
|
||||
} |
@ -0,0 +1,233 @@
|
||||
/* |
||||
* 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.impl; |
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status; |
||||
import org.apache.dolphinscheduler.api.exceptions.ServiceException; |
||||
import org.apache.dolphinscheduler.api.service.ProjectService; |
||||
import org.apache.dolphinscheduler.api.service.ProjectWorkerGroupRelationService; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.dao.entity.Project; |
||||
import org.apache.dolphinscheduler.dao.entity.ProjectWorkerGroup; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectWorkerGroupMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.WorkerGroupMapper; |
||||
|
||||
import org.apache.commons.collections.CollectionUtils; |
||||
import org.apache.commons.collections4.SetUtils; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.util.Date; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Objects; |
||||
import java.util.Set; |
||||
import java.util.TreeSet; |
||||
import java.util.stream.Collectors; |
||||
|
||||
import lombok.extern.slf4j.Slf4j; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
||||
/** |
||||
* task definition service impl |
||||
*/ |
||||
@Service |
||||
@Slf4j |
||||
public class ProjectWorkerGroupRelationServiceImpl extends BaseServiceImpl |
||||
implements |
||||
ProjectWorkerGroupRelationService { |
||||
|
||||
@Autowired |
||||
private ProjectWorkerGroupMapper projectWorkerGroupMapper; |
||||
|
||||
@Autowired |
||||
private ProjectMapper projectMapper; |
||||
|
||||
@Autowired |
||||
private WorkerGroupMapper workerGroupMapper; |
||||
|
||||
@Autowired |
||||
private TaskDefinitionMapper taskDefinitionMapper; |
||||
|
||||
@Autowired |
||||
private ScheduleMapper scheduleMapper; |
||||
|
||||
@Autowired |
||||
private ProjectService projectService; |
||||
|
||||
/** |
||||
* assign worker groups to a project |
||||
* |
||||
* @param loginUser the login user |
||||
* @param projectCode the project code |
||||
* @param workerGroups assigned worker group names |
||||
*/ |
||||
@Override |
||||
public Result assignWorkerGroupsToProject(User loginUser, Long projectCode, List<String> workerGroups) { |
||||
|
||||
Result result = new Result(); |
||||
|
||||
if (!isAdmin(loginUser)) { |
||||
putMsg(result, Status.USER_NO_OPERATION_PERM); |
||||
return result; |
||||
} |
||||
|
||||
if (Objects.isNull(projectCode)) { |
||||
putMsg(result, Status.PROJECT_NOT_EXIST); |
||||
return result; |
||||
} |
||||
|
||||
if (CollectionUtils.isEmpty(workerGroups)) { |
||||
putMsg(result, Status.WORKER_GROUP_TO_PROJECT_IS_EMPTY); |
||||
return result; |
||||
} |
||||
|
||||
Project project = projectMapper.queryByCode(projectCode); |
||||
if (Objects.isNull(project)) { |
||||
putMsg(result, Status.PROJECT_NOT_EXIST); |
||||
return result; |
||||
} |
||||
|
||||
Set<String> workerGroupNames = |
||||
workerGroupMapper.queryAllWorkerGroup().stream().map(item -> item.getName()).collect( |
||||
Collectors.toSet()); |
||||
|
||||
workerGroupNames.add(Constants.DEFAULT_WORKER_GROUP); |
||||
|
||||
Set<String> assignedWorkerGroupNames = workerGroups.stream().collect(Collectors.toSet()); |
||||
|
||||
Set<String> difference = SetUtils.difference(assignedWorkerGroupNames, workerGroupNames); |
||||
|
||||
if (difference.size() > 0) { |
||||
putMsg(result, Status.WORKER_GROUP_NOT_EXIST, difference.toString()); |
||||
return result; |
||||
} |
||||
|
||||
Set<String> projectWorkerGroupNames = projectWorkerGroupMapper.selectList(new QueryWrapper<ProjectWorkerGroup>() |
||||
.lambda() |
||||
.eq(ProjectWorkerGroup::getProjectCode, projectCode)).stream().map(item -> item.getWorkerGroup()) |
||||
.collect(Collectors.toSet()); |
||||
|
||||
difference = SetUtils.difference(projectWorkerGroupNames, assignedWorkerGroupNames); |
||||
|
||||
if (CollectionUtils.isNotEmpty(difference)) { |
||||
Set<String> usedWorkerGroups = getAllUsedWorkerGroups(project); |
||||
|
||||
if (CollectionUtils.isNotEmpty(usedWorkerGroups) && usedWorkerGroups.containsAll(difference)) { |
||||
throw new ServiceException(Status.USED_WORKER_GROUP_EXISTS, |
||||
SetUtils.intersection(usedWorkerGroups, difference).toSet()); |
||||
} |
||||
|
||||
int deleted = projectWorkerGroupMapper.delete( |
||||
new QueryWrapper<ProjectWorkerGroup>().lambda().eq(ProjectWorkerGroup::getProjectCode, projectCode) |
||||
.in(ProjectWorkerGroup::getWorkerGroup, difference)); |
||||
if (deleted > 0) { |
||||
log.info("Success to delete worker groups [{}] for the project [{}] .", difference, project.getName()); |
||||
} else { |
||||
log.error("Failed to delete worker groups [{}] for the project [{}].", difference, project.getName()); |
||||
throw new ServiceException(Status.ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR); |
||||
} |
||||
} |
||||
|
||||
difference = SetUtils.difference(assignedWorkerGroupNames, projectWorkerGroupNames); |
||||
Date now = new Date(); |
||||
if (CollectionUtils.isNotEmpty(difference)) { |
||||
difference.stream().forEach(workerGroupName -> { |
||||
ProjectWorkerGroup projectWorkerGroup = new ProjectWorkerGroup(); |
||||
projectWorkerGroup.setProjectCode(projectCode); |
||||
projectWorkerGroup.setWorkerGroup(workerGroupName); |
||||
projectWorkerGroup.setCreateTime(now); |
||||
projectWorkerGroup.setUpdateTime(now); |
||||
int create = projectWorkerGroupMapper.insert(projectWorkerGroup); |
||||
if (create > 0) { |
||||
log.info("Success to add worker group [{}] for the project [{}] .", workerGroupName, |
||||
project.getName()); |
||||
} else { |
||||
log.error("Failed to add worker group [{}] for the project [{}].", workerGroupName, |
||||
project.getName()); |
||||
throw new ServiceException(Status.ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
putMsg(result, Status.SUCCESS); |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* query worker groups that assigned to the project |
||||
* |
||||
* @param projectCode project code |
||||
*/ |
||||
@Override |
||||
public Map<String, Object> queryWorkerGroupsByProject(User loginUser, Long projectCode) { |
||||
Map<String, Object> result = new HashMap<>(); |
||||
|
||||
Project project = projectMapper.queryByCode(projectCode); |
||||
// check project auth
|
||||
boolean hasProjectAndPerm = projectService.hasProjectAndPerm(loginUser, project, result, null); |
||||
if (!hasProjectAndPerm) { |
||||
return result; |
||||
} |
||||
|
||||
Set<String> assignedWorkerGroups = getAllUsedWorkerGroups(project); |
||||
|
||||
projectWorkerGroupMapper.selectList( |
||||
new QueryWrapper<ProjectWorkerGroup>().lambda().eq(ProjectWorkerGroup::getProjectCode, projectCode)) |
||||
.stream().forEach(projectWorkerGroup -> assignedWorkerGroups.add(projectWorkerGroup.getWorkerGroup())); |
||||
|
||||
List<ProjectWorkerGroup> projectWorkerGroups = assignedWorkerGroups.stream().map(workerGroup -> { |
||||
ProjectWorkerGroup projectWorkerGroup = new ProjectWorkerGroup(); |
||||
projectWorkerGroup.setProjectCode(projectCode); |
||||
projectWorkerGroup.setWorkerGroup(workerGroup); |
||||
return projectWorkerGroup; |
||||
}).collect(Collectors.toList()); |
||||
|
||||
result.put(Constants.DATA_LIST, projectWorkerGroups); |
||||
putMsg(result, Status.SUCCESS); |
||||
return result; |
||||
} |
||||
|
||||
private Set<String> getAllUsedWorkerGroups(Project project) { |
||||
Set<String> usedWorkerGroups = new TreeSet<>(); |
||||
// query all worker groups that tasks depend on
|
||||
taskDefinitionMapper.queryAllDefinitionList(project.getCode()).stream().forEach(taskDefinition -> { |
||||
if (StringUtils.isNotEmpty(taskDefinition.getWorkerGroup())) { |
||||
usedWorkerGroups.add(taskDefinition.getWorkerGroup()); |
||||
} |
||||
}); |
||||
|
||||
// query all worker groups that timings depend on
|
||||
scheduleMapper.querySchedulerListByProjectName(project.getName()) |
||||
.stream() |
||||
.filter(schedule -> StringUtils.isNotEmpty(schedule.getWorkerGroup())) |
||||
.forEach(schedule -> usedWorkerGroups.add(schedule.getWorkerGroup())); |
||||
|
||||
return usedWorkerGroups; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,161 @@
|
||||
/* |
||||
* 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.api.service.impl.ProjectWorkerGroupRelationServiceImpl; |
||||
import org.apache.dolphinscheduler.api.utils.Result; |
||||
import org.apache.dolphinscheduler.common.constants.Constants; |
||||
import org.apache.dolphinscheduler.common.enums.UserType; |
||||
import org.apache.dolphinscheduler.dao.entity.Project; |
||||
import org.apache.dolphinscheduler.dao.entity.ProjectWorkerGroup; |
||||
import org.apache.dolphinscheduler.dao.entity.User; |
||||
import org.apache.dolphinscheduler.dao.entity.WorkerGroup; |
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectWorkerGroupMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper; |
||||
import org.apache.dolphinscheduler.dao.mapper.WorkerGroupMapper; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.junit.jupiter.api.extension.ExtendWith; |
||||
import org.mockito.InjectMocks; |
||||
import org.mockito.Mock; |
||||
import org.mockito.Mockito; |
||||
import org.mockito.junit.jupiter.MockitoExtension; |
||||
import org.mockito.junit.jupiter.MockitoSettings; |
||||
import org.mockito.quality.Strictness; |
||||
|
||||
import com.google.common.collect.Lists; |
||||
|
||||
@ExtendWith(MockitoExtension.class) |
||||
@MockitoSettings(strictness = Strictness.LENIENT) |
||||
public class ProjectWorkerGroupRelationServiceTest { |
||||
|
||||
@InjectMocks |
||||
private ProjectWorkerGroupRelationServiceImpl projectWorkerGroupRelationService; |
||||
|
||||
@Mock |
||||
private ProjectMapper projectMapper; |
||||
|
||||
@Mock |
||||
private ProjectWorkerGroupMapper projectWorkerGroupMapper; |
||||
|
||||
@Mock |
||||
private WorkerGroupMapper workerGroupMapper; |
||||
|
||||
@Mock |
||||
private ProjectService projectService; |
||||
|
||||
@Mock |
||||
private TaskDefinitionMapper taskDefinitionMapper; |
||||
|
||||
@Mock |
||||
private ScheduleMapper scheduleMapper; |
||||
|
||||
protected final static long projectCode = 1L; |
||||
|
||||
@Test |
||||
public void testAssignWorkerGroupsToProject() { |
||||
User loginUser = getAdminUser(); |
||||
|
||||
Mockito.when(projectMapper.queryByCode(projectCode)).thenReturn(null); |
||||
Result result = projectWorkerGroupRelationService.assignWorkerGroupsToProject(loginUser, projectCode, |
||||
getWorkerGroups()); |
||||
Assertions.assertEquals(Status.PROJECT_NOT_EXIST.getCode(), result.getCode()); |
||||
|
||||
WorkerGroup workerGroup = new WorkerGroup(); |
||||
workerGroup.setName("test"); |
||||
Mockito.when(projectMapper.queryByCode(Mockito.anyLong())).thenReturn(getProject()); |
||||
Mockito.when(workerGroupMapper.queryAllWorkerGroup()).thenReturn(Lists.newArrayList(workerGroup)); |
||||
Mockito.when(projectWorkerGroupMapper.insert(Mockito.any())).thenReturn(1); |
||||
|
||||
result = projectWorkerGroupRelationService.assignWorkerGroupsToProject(loginUser, projectCode, |
||||
getWorkerGroups()); |
||||
Assertions.assertEquals(Status.SUCCESS.getCode(), result.getCode()); |
||||
} |
||||
|
||||
@Test |
||||
public void testQueryWorkerGroupsByProject() { |
||||
|
||||
Mockito.when(projectService.hasProjectAndPerm(Mockito.any(), Mockito.any(), Mockito.anyMap(), Mockito.any())) |
||||
.thenReturn(true); |
||||
|
||||
Mockito.when(projectMapper.queryByCode(projectCode)) |
||||
.thenReturn(getProject()); |
||||
|
||||
Mockito.when(projectWorkerGroupMapper.selectList(Mockito.any())) |
||||
.thenReturn(Lists.newArrayList(getProjectWorkerGroup())); |
||||
|
||||
Mockito.when(taskDefinitionMapper.queryAllDefinitionList(Mockito.anyLong())) |
||||
.thenReturn(new ArrayList<>()); |
||||
|
||||
Mockito.when(scheduleMapper.querySchedulerListByProjectName(Mockito.any())) |
||||
.thenReturn(Lists.newArrayList()); |
||||
|
||||
Map<String, Object> result = |
||||
projectWorkerGroupRelationService.queryWorkerGroupsByProject(getGeneralUser(), projectCode); |
||||
|
||||
ProjectWorkerGroup[] actualValue = |
||||
((List<ProjectWorkerGroup>) result.get(Constants.DATA_LIST)).toArray(new ProjectWorkerGroup[0]); |
||||
|
||||
Assertions.assertEquals(actualValue[0].getWorkerGroup(), getProjectWorkerGroup().getWorkerGroup()); |
||||
} |
||||
|
||||
private List<String> getWorkerGroups() { |
||||
return Lists.newArrayList("default"); |
||||
} |
||||
|
||||
private User getGeneralUser() { |
||||
User loginUser = new User(); |
||||
loginUser.setUserType(UserType.GENERAL_USER); |
||||
loginUser.setUserName("userName"); |
||||
loginUser.setId(1); |
||||
return loginUser; |
||||
} |
||||
|
||||
private User getAdminUser() { |
||||
User loginUser = new User(); |
||||
loginUser.setUserType(UserType.ADMIN_USER); |
||||
loginUser.setUserName("userName"); |
||||
loginUser.setId(1); |
||||
return loginUser; |
||||
} |
||||
|
||||
private Project getProject() { |
||||
Project project = new Project(); |
||||
project.setCode(projectCode); |
||||
project.setId(1); |
||||
project.setName("test"); |
||||
project.setUserId(1); |
||||
return project; |
||||
} |
||||
|
||||
private ProjectWorkerGroup getProjectWorkerGroup() { |
||||
ProjectWorkerGroup projectWorkerGroup = new ProjectWorkerGroup(); |
||||
projectWorkerGroup.setId(1); |
||||
projectWorkerGroup.setProjectCode(projectCode); |
||||
projectWorkerGroup.setWorkerGroup("default"); |
||||
return projectWorkerGroup; |
||||
} |
||||
} |
@ -0,0 +1,56 @@
|
||||
/* |
||||
* 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; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType; |
||||
import com.baomidou.mybatisplus.annotation.TableId; |
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
||||
@Data |
||||
@TableName("t_ds_relation_project_worker_group") |
||||
public class ProjectWorkerGroup { |
||||
|
||||
/** |
||||
* id |
||||
*/ |
||||
@TableId(value = "id", type = IdType.AUTO) |
||||
private Integer id; |
||||
|
||||
/** |
||||
* project code |
||||
*/ |
||||
private Long projectCode; |
||||
|
||||
/** |
||||
* worker group |
||||
*/ |
||||
private String workerGroup; |
||||
|
||||
/** |
||||
* create time |
||||
*/ |
||||
private Date createTime; |
||||
|
||||
/** |
||||
* update time |
||||
*/ |
||||
private Date updateTime; |
||||
} |
@ -0,0 +1,26 @@
|
||||
/* |
||||
* 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.ProjectWorkerGroup; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
||||
public interface ProjectWorkerGroupMapper extends BaseMapper<ProjectWorkerGroup> { |
||||
|
||||
} |
@ -0,0 +1,113 @@
|
||||
/* |
||||
* 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.BaseDaoTest; |
||||
import org.apache.dolphinscheduler.dao.entity.ProjectWorkerGroup; |
||||
|
||||
import java.util.Date; |
||||
import java.util.List; |
||||
|
||||
import org.junit.jupiter.api.Assertions; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
||||
public class ProjectWorkerGroupMapperTest extends BaseDaoTest { |
||||
|
||||
@Autowired |
||||
private ProjectWorkerGroupMapper projectWorkerGroupMapper; |
||||
|
||||
/** |
||||
* insert |
||||
* |
||||
* @return ProjectWorkerGroup |
||||
*/ |
||||
private ProjectWorkerGroup insertOne() { |
||||
// insertOne
|
||||
ProjectWorkerGroup projectWorkerGroup = new ProjectWorkerGroup(); |
||||
|
||||
projectWorkerGroup.setProjectCode(1L); |
||||
projectWorkerGroup.setWorkerGroup("WorkerGroup1");; |
||||
projectWorkerGroupMapper.insert(projectWorkerGroup); |
||||
return projectWorkerGroup; |
||||
} |
||||
|
||||
/** |
||||
* test update |
||||
*/ |
||||
@Test |
||||
public void testUpdate() { |
||||
// insertOne
|
||||
ProjectWorkerGroup projectWorkerGroup = insertOne(); |
||||
projectWorkerGroup.setCreateTime(new Date()); |
||||
// update
|
||||
int update = projectWorkerGroupMapper.updateById(projectWorkerGroup); |
||||
Assertions.assertEquals(update, 1); |
||||
} |
||||
|
||||
/** |
||||
* test delete |
||||
*/ |
||||
@Test |
||||
public void testDelete() { |
||||
ProjectWorkerGroup projectWorkerGroup = insertOne(); |
||||
int delete = projectWorkerGroupMapper.deleteById(projectWorkerGroup.getId()); |
||||
Assertions.assertEquals(delete, 1); |
||||
} |
||||
|
||||
/** |
||||
* test query |
||||
*/ |
||||
@Test |
||||
public void testQuery() { |
||||
ProjectWorkerGroup projectWorkerGroup = insertOne(); |
||||
// query
|
||||
List<ProjectWorkerGroup> projectUsers = projectWorkerGroupMapper.selectList(null); |
||||
Assertions.assertNotEquals(0, projectUsers.size()); |
||||
} |
||||
|
||||
/** |
||||
* test delete the relation of project and worker group |
||||
*/ |
||||
@Test |
||||
public void testDeleteProjectWorkerGroupRelation() { |
||||
|
||||
ProjectWorkerGroup projectWorkerGroup = insertOne(); |
||||
int delete = projectWorkerGroupMapper.delete(new QueryWrapper<ProjectWorkerGroup>() |
||||
.lambda() |
||||
.eq(ProjectWorkerGroup::getProjectCode, projectWorkerGroup.getProjectCode()) |
||||
.eq(ProjectWorkerGroup::getWorkerGroup, projectWorkerGroup.getWorkerGroup())); |
||||
|
||||
Assertions.assertTrue(delete >= 1); |
||||
} |
||||
|
||||
/** |
||||
* test query the relation of project and worker group |
||||
*/ |
||||
@Test |
||||
public void testQueryProjectWorkerGroupRelation() { |
||||
ProjectWorkerGroup projectWorkerGroup = insertOne(); |
||||
projectWorkerGroup = projectWorkerGroupMapper.selectOne(new QueryWrapper<ProjectWorkerGroup>() |
||||
.lambda() |
||||
.eq(ProjectWorkerGroup::getProjectCode, projectWorkerGroup.getProjectCode()) |
||||
.eq(ProjectWorkerGroup::getWorkerGroup, projectWorkerGroup.getWorkerGroup())); |
||||
|
||||
Assertions.assertNotEquals(null, projectWorkerGroup); |
||||
} |
||||
} |
@ -0,0 +1,39 @@
|
||||
/* |
||||
* 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 { axios } from '@/service/service' |
||||
import { UpdateProjectWorkerGroupsReq } from "@/service/modules/projects-worker-group/types"; |
||||
|
||||
export function queryWorkerGroupsByProjectCode( |
||||
projectCode: number |
||||
): any { |
||||
return axios({ |
||||
url: `/projects/${projectCode}/worker-group`, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
export function assignWorkerGroups( |
||||
data: UpdateProjectWorkerGroupsReq, |
||||
projectCode: number |
||||
): any { |
||||
return axios({ |
||||
url: `/projects/${projectCode}/worker-group`, |
||||
method: 'post', |
||||
data |
||||
}) |
||||
} |
@ -0,0 +1,34 @@
|
||||
/* |
||||
* 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. |
||||
*/ |
||||
|
||||
interface ProjectWorkerGroup { |
||||
id: number |
||||
projectCode: number |
||||
workerGroup: string |
||||
createTime: string |
||||
updateTime: string |
||||
} |
||||
|
||||
|
||||
interface UpdateProjectWorkerGroupsReq { |
||||
workerGroups: string |
||||
} |
||||
|
||||
export { |
||||
ProjectWorkerGroup, |
||||
UpdateProjectWorkerGroupsReq |
||||
} |
@ -0,0 +1,77 @@
|
||||
/* |
||||
* 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 { useI18n } from 'vue-i18n' |
||||
import { reactive, ref, SetupContext } from 'vue' |
||||
import { useUserStore } from '@/store/user/user' |
||||
import { Option } from "naive-ui/es/transfer/src/interface" |
||||
import { queryAllWorkerGroups } from "@/service/modules/worker-groups" |
||||
import { queryWorkerGroupsByProjectCode, assignWorkerGroups } from "@/service/modules/projects-worker-group" |
||||
import { UpdateProjectWorkerGroupsReq } from "@/service/modules/projects-worker-group/types" |
||||
|
||||
export function useWorkerGroup( |
||||
props: any, |
||||
ctx: SetupContext<('cancelModal' | 'confirmModal')[]> |
||||
) { |
||||
const { t } = useI18n() |
||||
const userStore = useUserStore() |
||||
|
||||
const variables = reactive({ |
||||
model: { |
||||
workerGroupOptions: [] as Option[], |
||||
assignedWorkerGroups: ref([] as any) |
||||
} |
||||
}) |
||||
|
||||
const initOptions = () => { |
||||
variables.model.workerGroupOptions = [] |
||||
queryAllWorkerGroups().then((res: any) => { |
||||
for (const workerGroup of res) { |
||||
variables.model.workerGroupOptions.push({label: workerGroup, value: workerGroup, disabled: workerGroup==='default'}) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
const initAssignedWorkerGroups = (projectCode: number) => { |
||||
variables.model.assignedWorkerGroups = ref([] as any) |
||||
queryWorkerGroupsByProjectCode(projectCode).then((res: any) =>{ |
||||
res.data.forEach((item: any) => { |
||||
variables.model.assignedWorkerGroups.push(item.workerGroup) |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
initOptions() |
||||
|
||||
const handleValidate = () => { |
||||
if (variables.model?.assignedWorkerGroups.length>0) { |
||||
submitModal() |
||||
ctx.emit('confirmModal', props.showModalRef) |
||||
} |
||||
} |
||||
|
||||
const submitModal = async () => { |
||||
if (props.row.code) { |
||||
let data: UpdateProjectWorkerGroupsReq = { |
||||
workerGroups: variables.model.assignedWorkerGroups.length>0? variables.model.assignedWorkerGroups.join(','):'' |
||||
} |
||||
assignWorkerGroups(data, props.row.code) |
||||
} |
||||
} |
||||
|
||||
return { variables, t, handleValidate, initAssignedWorkerGroups } |
||||
} |
@ -0,0 +1,91 @@
|
||||
/* |
||||
* 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 { |
||||
defineComponent, |
||||
getCurrentInstance, |
||||
PropType, |
||||
toRefs, |
||||
watch |
||||
} from 'vue' |
||||
import { NTransfer} from 'naive-ui' |
||||
import Modal from '@/components/modal' |
||||
import styles from "@/views/security/user-manage/index.module.scss"; |
||||
import {useWorkerGroup} from "@/views/projects/list/components/use-worker-group"; |
||||
|
||||
const props = { |
||||
showModalRef: { |
||||
type: Boolean as PropType<boolean>, |
||||
default: false |
||||
}, |
||||
row: { |
||||
type: Object as PropType<any>, |
||||
default: {} |
||||
} |
||||
} |
||||
|
||||
const WorkerGroupModal = defineComponent({ |
||||
name: 'WorkerGroupModal', |
||||
props, |
||||
emits: ['cancelModal', 'confirmModal'], |
||||
setup(props, ctx) { |
||||
const { variables, t, handleValidate, initAssignedWorkerGroups } = useWorkerGroup(props, ctx) |
||||
|
||||
const cancelModal = () => { |
||||
ctx.emit('cancelModal', props.showModalRef) |
||||
} |
||||
|
||||
const trim = getCurrentInstance()?.appContext.config.globalProperties.trim |
||||
|
||||
const confirmModal = () => { |
||||
handleValidate() |
||||
} |
||||
|
||||
watch( |
||||
() => props.showModalRef, |
||||
() => { |
||||
if (props.showModalRef) { |
||||
initAssignedWorkerGroups(props.row.code) |
||||
} |
||||
} |
||||
) |
||||
|
||||
return { ...toRefs(variables), t, cancelModal, confirmModal, trim } |
||||
}, |
||||
render() { |
||||
const { t } = this |
||||
return ( |
||||
<Modal |
||||
title={t('project.list.assign_worker_group')} |
||||
show={this.showModalRef} |
||||
onConfirm={this.confirmModal} |
||||
onCancel={this.cancelModal} |
||||
confirmClassName='btn-submit' |
||||
cancelClassName='btn-cancel' |
||||
> |
||||
<NTransfer |
||||
virtualScroll |
||||
class={styles.transfer} |
||||
options={this.model.workerGroupOptions} |
||||
v-model:value={this.model.assignedWorkerGroups} |
||||
/> |
||||
</Modal> |
||||
) |
||||
} |
||||
}) |
||||
|
||||
export default WorkerGroupModal |
Loading…
Reference in new issue