Browse Source

[Improvement-3369][api] Introduce tenant service interface for clear code (#3420)

* [Improvement][api] Introduce tenant service interface for clear code

* Checkstyle

* Checkstyle
pull/3/MERGE
Yichao Yang 4 years ago committed by GitHub
parent
commit
c003cd133d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 62
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java
  2. 379
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TenantService.java
  3. 331
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TenantServiceImpl.java
  4. 133
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TenantServiceTest.java

62
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/TenantController.java

@ -14,8 +14,15 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.api.controller; package org.apache.dolphinscheduler.api.controller;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_TENANT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_TENANT_BY_ID_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_TENANT_LIST_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_TENANT_LIST_PAGING_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_TENANT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.VERIFY_TENANT_CODE_ERROR;
import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ApiException; import org.apache.dolphinscheduler.api.exceptions.ApiException;
@ -24,20 +31,26 @@ import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.utils.ParameterUtils; import org.apache.dolphinscheduler.common.utils.ParameterUtils;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import java.util.Map;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import springfox.documentation.annotations.ApiIgnore; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import java.util.Map; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import static org.apache.dolphinscheduler.api.enums.Status.*; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;
/** /**
@ -57,10 +70,10 @@ public class TenantController extends BaseController {
/** /**
* create tenant * create tenant
* *
* @param loginUser login user * @param loginUser login user
* @param tenantCode tenant code * @param tenantCode tenant code
* @param tenantName tenant name * @param tenantName tenant name
* @param queueId queue id * @param queueId queue id
* @param description description * @param description description
* @return create result code * @return create result code
*/ */
@ -92,8 +105,8 @@ public class TenantController extends BaseController {
* *
* @param loginUser login user * @param loginUser login user
* @param searchVal search value * @param searchVal search value
* @param pageNo page number * @param pageNo page number
* @param pageSize page size * @param pageSize page size
* @return tenant list page * @return tenant list page
*/ */
@ApiOperation(value = "queryTenantlistPaging", notes = "QUERY_TENANT_LIST_PAGING_NOTES") @ApiOperation(value = "queryTenantlistPaging", notes = "QUERY_TENANT_LIST_PAGING_NOTES")
@ -141,11 +154,11 @@ public class TenantController extends BaseController {
/** /**
* udpate tenant * udpate tenant
* *
* @param loginUser login user * @param loginUser login user
* @param id tennat id * @param id tennat id
* @param tenantCode tennat code * @param tenantCode tennat code
* @param tenantName tennat name * @param tenantName tennat name
* @param queueId queue id * @param queueId queue id
* @param description description * @param description description
* @return update result code * @return update result code
*/ */
@ -177,7 +190,7 @@ public class TenantController extends BaseController {
* delete tenant by id * delete tenant by id
* *
* @param loginUser login user * @param loginUser login user
* @param id tenant id * @param id tenant id
* @return delete result code * @return delete result code
*/ */
@ApiOperation(value = "deleteTenantById", notes = "DELETE_TENANT_NOTES") @ApiOperation(value = "deleteTenantById", notes = "DELETE_TENANT_NOTES")
@ -195,11 +208,10 @@ public class TenantController extends BaseController {
return returnDataList(result); return returnDataList(result);
} }
/** /**
* verify tenant code * verify tenant code
* *
* @param loginUser login user * @param loginUser login user
* @param tenantCode tenant code * @param tenantCode tenant code
* @return true if tenant code can user, otherwise return false * @return true if tenant code can user, otherwise return false
*/ */
@ -211,12 +223,10 @@ public class TenantController extends BaseController {
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@ApiException(VERIFY_TENANT_CODE_ERROR) @ApiException(VERIFY_TENANT_CODE_ERROR)
public Result verifyTenantCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser, public Result verifyTenantCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "tenantCode") String tenantCode @RequestParam(value = "tenantCode") String tenantCode) {
) {
logger.info("login user {}, verfiy tenant code: {}", logger.info("login user {}, verfiy tenant code: {}",
loginUser.getUserName(), tenantCode); loginUser.getUserName(), tenantCode);
return tenantService.verifyTenantCode(tenantCode); return tenantService.verifyTenantCode(tenantCode);
} }
} }

379
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/TenantService.java

@ -14,338 +14,85 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.api.service; package org.apache.dolphinscheduler.api.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.HadoopUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper;
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* tenant service * tenant service
*/ */
@Service public interface TenantService {
public class TenantService extends BaseService{
private static final Logger logger = LoggerFactory.getLogger(TenantService.class);
@Autowired
private TenantMapper tenantMapper;
@Autowired
private ProcessInstanceMapper processInstanceMapper;
@Autowired
private ProcessDefinitionMapper processDefinitionMapper;
@Autowired
private UserMapper userMapper;
/**
* create tenant
*
*
* @param loginUser login user
* @param tenantCode tenant code
* @param tenantName tenant name
* @param queueId queue id
* @param desc description
* @return create result code
* @throws Exception exception
*/
@Transactional(rollbackFor = Exception.class)
public Map<String,Object> createTenant(User loginUser,
String tenantCode,
String tenantName,
int queueId,
String desc) throws Exception {
Map<String, Object> result = new HashMap<>();
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
if (checkTenantExists(tenantCode)){
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, tenantCode);
return result;
}
Tenant tenant = new Tenant();
Date now = new Date();
if (!tenantCode.matches("^[0-9a-zA-Z_.-]{1,}$") || tenantCode.startsWith("-") || tenantCode.startsWith(".")){
putMsg(result, Status.VERIFY_TENANT_CODE_ERROR);
return result;
}
tenant.setTenantCode(tenantCode);
tenant.setTenantName(tenantName);
tenant.setQueueId(queueId);
tenant.setDescription(desc);
tenant.setCreateTime(now);
tenant.setUpdateTime(now);
// save
tenantMapper.insert(tenant);
// if hdfs startup
if (PropertyUtils.getResUploadStartupState()){
createTenantDirIfNotExists(tenantCode);
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query tenant list paging
*
* @param loginUser login user
* @param searchVal search value
* @param pageNo page number
* @param pageSize page size
* @return tenant list page
*/
public Map<String,Object> queryTenantList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>();
if (checkAdmin(loginUser, result)) {
return result;
}
Page<Tenant> page = new Page(pageNo, pageSize);
IPage<Tenant> tenantIPage = tenantMapper.queryTenantPaging(page, searchVal);
PageInfo<Tenant> pageInfo = new PageInfo<>(pageNo, pageSize);
pageInfo.setTotalCount((int)tenantIPage.getTotal());
pageInfo.setLists(tenantIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* updateProcessInstance tenant
*
* @param loginUser login user
* @param id tennat id
* @param tenantCode tennat code
* @param tenantName tennat name
* @param queueId queue id
* @param desc description
* @return update result code
* @throws Exception exception
*/
public Map<String, Object> updateTenant(User loginUser,int id,String tenantCode, String tenantName, int queueId, String desc) throws Exception {
Map<String, Object> result = new HashMap<>();
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null){
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
// updateProcessInstance tenant
/** /**
* if the tenant code is modified, the original resource needs to be copied to the new tenant. * create tenant
*
* @param loginUser login user
* @param tenantCode tenant code
* @param tenantName tenant name
* @param queueId queue id
* @param desc description
* @return create result code
* @throws Exception exception
*/ */
if (!tenant.getTenantCode().equals(tenantCode)){ Map<String, Object> createTenant(User loginUser,
if (checkTenantExists(tenantCode)){ String tenantCode,
// if hdfs startup String tenantName,
if (PropertyUtils.getResUploadStartupState()){ int queueId,
String resourcePath = HadoopUtils.getHdfsDataBasePath() + "/" + tenantCode + "/resources"; String desc) throws Exception;
String udfsPath = HadoopUtils.getHdfsUdfDir(tenantCode);
//init hdfs resource
HadoopUtils.getInstance().mkdir(resourcePath);
HadoopUtils.getInstance().mkdir(udfsPath);
}
}else {
putMsg(result, Status.TENANT_CODE_HAS_ALREADY_EXISTS);
return result;
}
}
Date now = new Date();
if (StringUtils.isNotEmpty(tenantCode)){
tenant.setTenantCode(tenantCode);
}
if (StringUtils.isNotEmpty(tenantName)){
tenant.setTenantName(tenantName);
}
if (queueId != 0){
tenant.setQueueId(queueId);
}
tenant.setDescription(desc);
tenant.setUpdateTime(now);
tenantMapper.updateById(tenant);
result.put(Constants.STATUS, Status.SUCCESS);
result.put(Constants.MSG, Status.SUCCESS.getMsg());
return result;
}
/**
* delete tenant
*
* @param loginUser login user
* @param id tenant id
* @return delete result code
* @throws Exception exception
*/
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> deleteTenantById(User loginUser, int id) throws Exception {
Map<String, Object> result = new HashMap<>();
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null){
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
List<ProcessInstance> processInstances = getProcessInstancesByTenant(tenant);
if(CollectionUtils.isNotEmpty(processInstances)){
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL, processInstances.size());
return result;
}
List<ProcessDefinition> processDefinitions = processDefinitionMapper.queryDefinitionListByTenant(tenant.getId());
if(CollectionUtils.isNotEmpty(processDefinitions)){
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL_DEFINES, processDefinitions.size());
return result;
}
List<User> userList = userMapper.queryUserListByTenant(tenant.getId());
if(CollectionUtils.isNotEmpty(userList)){
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL_USERS, userList.size());
return result;
}
// if resource upload startup
if (PropertyUtils.getResUploadStartupState()){
String tenantPath = HadoopUtils.getHdfsDataBasePath() + "/" + tenant.getTenantCode();
if (HadoopUtils.getInstance().exists(tenantPath)){
HadoopUtils.getInstance().delete(tenantPath, true);
}
}
tenantMapper.deleteById(id);
processInstanceMapper.updateProcessInstanceByTenantId(id, -1);
putMsg(result, Status.SUCCESS);
return result;
}
private List<ProcessInstance> getProcessInstancesByTenant(Tenant tenant) { /**
return processInstanceMapper.queryByTenantIdAndStatus(tenant.getId(), org.apache.dolphinscheduler.common.Constants.NOT_TERMINATED_STATES); * query tenant list paging
} *
* @param loginUser login user
/** * @param searchVal search value
* query tenant list * @param pageNo page number
* * @param pageSize page size
* @param loginUser login user * @return tenant list page
* @return tenant list */
*/ Map<String, Object> queryTenantList(User loginUser, String searchVal, Integer pageNo, Integer pageSize);
public Map<String, Object> queryTenantList(User loginUser) {
Map<String, Object> result = new HashMap<>();
List<Tenant> resourceList = tenantMapper.selectList(null);
result.put(Constants.DATA_LIST, resourceList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query tenant list via tenant code
* @param tenantCode tenant code
* @return tenant list
*/
public Map<String, Object> queryTenantList(String tenantCode) {
Map<String, Object> result = new HashMap<>();
List<Tenant> resourceList = tenantMapper.queryByTenantCode(tenantCode);
if (CollectionUtils.isNotEmpty(resourceList)) {
result.put(Constants.DATA_LIST, resourceList);
putMsg(result, Status.SUCCESS);
} else {
putMsg(result, Status.TENANT_NOT_EXIST);
}
return result; /**
} * updateProcessInstance tenant
*
* @param loginUser login user
* @param id tennat id
* @param tenantCode tennat code
* @param tenantName tennat name
* @param queueId queue id
* @param desc description
* @return update result code
* @throws Exception exception
*/
Map<String, Object> updateTenant(User loginUser, int id, String tenantCode, String tenantName, int queueId,
String desc) throws Exception;
/** /**
* verify tenant code * delete tenant
* *
* @param tenantCode tenant code * @param loginUser login user
* @return true if tenant code can user, otherwise return false * @param id tenant id
*/ * @return delete result code
public Result verifyTenantCode(String tenantCode) { * @throws Exception exception
Result result = new Result(); */
if (checkTenantExists(tenantCode)) { Map<String, Object> deleteTenantById(User loginUser, int id) throws Exception;
logger.error("tenant {} has exist, can't create again.", tenantCode);
putMsg(result, Status.TENANT_NAME_EXIST, tenantCode);
} else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* query tenant list
*
* @param loginUser login user
* @return tenant list
*/
Map<String, Object> queryTenantList(User loginUser);
/** /**
* check tenant exists * verify tenant code
* *
* @param tenantCode tenant code * @param tenantCode tenant code
* @return ture if the tenant code exists, otherwise return false * @return true if tenant code can user, otherwise return false
*/ */
private boolean checkTenantExists(String tenantCode) { Result verifyTenantCode(String tenantCode);
List<Tenant> tenants = tenantMapper.queryByTenantCode(tenantCode);
return CollectionUtils.isNotEmpty(tenants);
}
} }

331
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TenantServiceImpl.java

@ -0,0 +1,331 @@
/*
* 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.service.BaseService;
import org.apache.dolphinscheduler.api.service.TenantService;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.HadoopUtils;
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper;
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* tenant service
*/
@Service
public class TenantServiceImpl extends BaseService implements TenantService {
private static final Logger logger = LoggerFactory.getLogger(TenantServiceImpl.class);
@Autowired
private TenantMapper tenantMapper;
@Autowired
private ProcessInstanceMapper processInstanceMapper;
@Autowired
private ProcessDefinitionMapper processDefinitionMapper;
@Autowired
private UserMapper userMapper;
/**
* create tenant
*
* @param loginUser login user
* @param tenantCode tenant code
* @param tenantName tenant name
* @param queueId queue id
* @param desc description
* @return create result code
* @throws Exception exception
*/
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> createTenant(User loginUser,
String tenantCode,
String tenantName,
int queueId,
String desc) throws Exception {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
if (checkTenantExists(tenantCode)) {
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, tenantCode);
return result;
}
Tenant tenant = new Tenant();
Date now = new Date();
if (!tenantCode.matches("^[0-9a-zA-Z_.-]{1,}$") || tenantCode.startsWith("-") || tenantCode.startsWith(".")) {
putMsg(result, Status.VERIFY_TENANT_CODE_ERROR);
return result;
}
tenant.setTenantCode(tenantCode);
tenant.setTenantName(tenantName);
tenant.setQueueId(queueId);
tenant.setDescription(desc);
tenant.setCreateTime(now);
tenant.setUpdateTime(now);
// save
tenantMapper.insert(tenant);
// if hdfs startup
if (PropertyUtils.getResUploadStartupState()) {
createTenantDirIfNotExists(tenantCode);
}
putMsg(result, Status.SUCCESS);
return result;
}
/**
* query tenant list paging
*
* @param loginUser login user
* @param searchVal search value
* @param pageNo page number
* @param pageSize page size
* @return tenant list page
*/
public Map<String, Object> queryTenantList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Page<Tenant> page = new Page<>(pageNo, pageSize);
IPage<Tenant> tenantIPage = tenantMapper.queryTenantPaging(page, searchVal);
PageInfo<Tenant> pageInfo = new PageInfo<>(pageNo, pageSize);
pageInfo.setTotalCount((int) tenantIPage.getTotal());
pageInfo.setLists(tenantIPage.getRecords());
result.put(Constants.DATA_LIST, pageInfo);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* updateProcessInstance tenant
*
* @param loginUser login user
* @param id tennat id
* @param tenantCode tennat code
* @param tenantName tennat name
* @param queueId queue id
* @param desc description
* @return update result code
* @throws Exception exception
*/
public Map<String, Object> updateTenant(User loginUser, int id, String tenantCode, String tenantName, int queueId,
String desc) throws Exception {
Map<String, Object> result = new HashMap<>(5);
result.put(Constants.STATUS, false);
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null) {
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
// updateProcessInstance tenant
/**
* if the tenant code is modified, the original resource needs to be copied to the new tenant.
*/
if (!tenant.getTenantCode().equals(tenantCode)) {
if (checkTenantExists(tenantCode)) {
// if hdfs startup
if (PropertyUtils.getResUploadStartupState()) {
String resourcePath = HadoopUtils.getHdfsDataBasePath() + "/" + tenantCode + "/resources";
String udfsPath = HadoopUtils.getHdfsUdfDir(tenantCode);
//init hdfs resource
HadoopUtils.getInstance().mkdir(resourcePath);
HadoopUtils.getInstance().mkdir(udfsPath);
}
} else {
putMsg(result, Status.TENANT_CODE_HAS_ALREADY_EXISTS);
return result;
}
}
Date now = new Date();
if (StringUtils.isNotEmpty(tenantCode)) {
tenant.setTenantCode(tenantCode);
}
if (StringUtils.isNotEmpty(tenantName)) {
tenant.setTenantName(tenantName);
}
if (queueId != 0) {
tenant.setQueueId(queueId);
}
tenant.setDescription(desc);
tenant.setUpdateTime(now);
tenantMapper.updateById(tenant);
result.put(Constants.STATUS, Status.SUCCESS);
result.put(Constants.MSG, Status.SUCCESS.getMsg());
return result;
}
/**
* delete tenant
*
* @param loginUser login user
* @param id tenant id
* @return delete result code
* @throws Exception exception
*/
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> deleteTenantById(User loginUser, int id) throws Exception {
Map<String, Object> result = new HashMap<>(5);
if (checkAdmin(loginUser, result)) {
return result;
}
Tenant tenant = tenantMapper.queryById(id);
if (tenant == null) {
putMsg(result, Status.TENANT_NOT_EXIST);
return result;
}
List<ProcessInstance> processInstances = getProcessInstancesByTenant(tenant);
if (CollectionUtils.isNotEmpty(processInstances)) {
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL, processInstances.size());
return result;
}
List<ProcessDefinition> processDefinitions =
processDefinitionMapper.queryDefinitionListByTenant(tenant.getId());
if (CollectionUtils.isNotEmpty(processDefinitions)) {
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL_DEFINES, processDefinitions.size());
return result;
}
List<User> userList = userMapper.queryUserListByTenant(tenant.getId());
if (CollectionUtils.isNotEmpty(userList)) {
putMsg(result, Status.DELETE_TENANT_BY_ID_FAIL_USERS, userList.size());
return result;
}
// if resource upload startup
if (PropertyUtils.getResUploadStartupState()) {
String tenantPath = HadoopUtils.getHdfsDataBasePath() + "/" + tenant.getTenantCode();
if (HadoopUtils.getInstance().exists(tenantPath)) {
HadoopUtils.getInstance().delete(tenantPath, true);
}
}
tenantMapper.deleteById(id);
processInstanceMapper.updateProcessInstanceByTenantId(id, -1);
putMsg(result, Status.SUCCESS);
return result;
}
private List<ProcessInstance> getProcessInstancesByTenant(Tenant tenant) {
return processInstanceMapper.queryByTenantIdAndStatus(tenant.getId(), Constants.NOT_TERMINATED_STATES);
}
/**
* query tenant list
*
* @param loginUser login user
* @return tenant list
*/
public Map<String, Object> queryTenantList(User loginUser) {
Map<String, Object> result = new HashMap<>(5);
List<Tenant> resourceList = tenantMapper.selectList(null);
result.put(Constants.DATA_LIST, resourceList);
putMsg(result, Status.SUCCESS);
return result;
}
/**
* verify tenant code
*
* @param tenantCode tenant code
* @return true if tenant code can user, otherwise return false
*/
public Result verifyTenantCode(String tenantCode) {
Result result = new Result();
if (checkTenantExists(tenantCode)) {
putMsg(result, Status.TENANT_NAME_EXIST, tenantCode);
} else {
putMsg(result, Status.SUCCESS);
}
return result;
}
/**
* check tenant exists
*
* @param tenantCode tenant code
* @return ture if the tenant code exists, otherwise return false
*/
private boolean checkTenantExists(String tenantCode) {
List<Tenant> tenants = tenantMapper.queryByTenantCode(tenantCode);
return CollectionUtils.isNotEmpty(tenants);
}
}

133
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/TenantServiceTest.java

@ -14,14 +14,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.api.service;
import java.util.ArrayList; package org.apache.dolphinscheduler.api.service;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.dolphinscheduler.api.enums.Status; import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.service.impl.TenantServiceImpl;
import org.apache.dolphinscheduler.api.utils.PageInfo; import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result; import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
@ -35,6 +32,12 @@ import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper; import org.apache.dolphinscheduler.dao.mapper.ProcessInstanceMapper;
import org.apache.dolphinscheduler.dao.mapper.TenantMapper; import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper; import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -54,54 +57,61 @@ public class TenantServiceTest {
private static final Logger logger = LoggerFactory.getLogger(TenantServiceTest.class); private static final Logger logger = LoggerFactory.getLogger(TenantServiceTest.class);
@InjectMocks @InjectMocks
private TenantService tenantService; private TenantServiceImpl tenantService;
@Mock @Mock
private TenantMapper tenantMapper; private TenantMapper tenantMapper;
@Mock @Mock
private ProcessDefinitionMapper processDefinitionMapper; private ProcessDefinitionMapper processDefinitionMapper;
@Mock @Mock
private ProcessInstanceMapper processInstanceMapper; private ProcessInstanceMapper processInstanceMapper;
@Mock @Mock
private UserMapper userMapper; private UserMapper userMapper;
private String tenantCode = "TenantServiceTest"; private static final String tenantCode = "TenantServiceTest";
private String tenantName = "TenantServiceTest";
private static final String tenantName = "TenantServiceTest";
@Test @Test
public void testCreateTenant(){ public void testCreateTenant() {
User loginUser = getLoginUser(); User loginUser = getLoginUser();
Mockito.when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getList()); Mockito.when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getList());
try { try {
//check tenantCode //check tenantCode
Map<String, Object> result = tenantService.createTenant(getLoginUser(), "%!1111", tenantName, 1, "TenantServiceTest"); Map<String, Object> result =
tenantService.createTenant(getLoginUser(), "%!1111", tenantName, 1, "TenantServiceTest");
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.VERIFY_TENANT_CODE_ERROR,result.get(Constants.STATUS)); Assert.assertEquals(Status.VERIFY_TENANT_CODE_ERROR, result.get(Constants.STATUS));
//check exist //check exist
result = tenantService.createTenant(loginUser, tenantCode, tenantName, 1, "TenantServiceTest"); result = tenantService.createTenant(loginUser, tenantCode, tenantName, 1, "TenantServiceTest");
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR,result.get(Constants.STATUS)); Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
// success // success
result = tenantService.createTenant(loginUser, "test", "test", 1, "TenantServiceTest"); result = tenantService.createTenant(loginUser, "test", "test", 1, "TenantServiceTest");
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS,result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
} catch (Exception e) { } catch (Exception e) {
logger.error("create tenant error",e); logger.error("create tenant error", e);
Assert.assertTrue(false); Assert.fail();
} }
} }
@Test @Test
public void testQueryTenantListPage(){ @SuppressWarnings("unchecked")
public void testQueryTenantListPage() {
IPage<Tenant> page = new Page<>(1,10); IPage<Tenant> page = new Page<>(1, 10);
page.setRecords(getList()); page.setRecords(getList());
page.setTotal(1L); page.setTotal(1L);
Mockito.when(tenantMapper.queryTenantPaging(Mockito.any(Page.class), Mockito.eq("TenantServiceTest"))).thenReturn(page); Mockito.when(tenantMapper.queryTenantPaging(Mockito.any(Page.class), Mockito.eq("TenantServiceTest")))
.thenReturn(page);
Map<String, Object> result = tenantService.queryTenantList(getLoginUser(), "TenantServiceTest", 1, 10); Map<String, Object> result = tenantService.queryTenantList(getLoginUser(), "TenantServiceTest", 1, 10);
logger.info(result.toString()); logger.info(result.toString());
PageInfo<Tenant> pageInfo = (PageInfo<Tenant>) result.get(Constants.DATA_LIST); PageInfo<Tenant> pageInfo = (PageInfo<Tenant>) result.get(Constants.DATA_LIST);
@ -110,87 +120,71 @@ public class TenantServiceTest {
} }
@Test @Test
public void testUpdateTenant(){ public void testUpdateTenant() {
Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant()); Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant());
try { try {
// id not exist // id not exist
Map<String, Object> result = tenantService.updateTenant(getLoginUser(), 912222, tenantCode, tenantName, 1, "desc"); Map<String, Object> result =
tenantService.updateTenant(getLoginUser(), 912222, tenantCode, tenantName, 1, "desc");
logger.info(result.toString()); logger.info(result.toString());
// success // success
Assert.assertEquals(Status.TENANT_NOT_EXIST,result.get(Constants.STATUS)); Assert.assertEquals(Status.TENANT_NOT_EXIST, result.get(Constants.STATUS));
result = tenantService.updateTenant(getLoginUser(), 1, tenantCode, "TenantServiceTest001", 1, "desc"); result = tenantService.updateTenant(getLoginUser(), 1, tenantCode, "TenantServiceTest001", 1, "desc");
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS,result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
} catch (Exception e) { } catch (Exception e) {
logger.error("update tenant error",e); logger.error("update tenant error", e);
Assert.assertTrue(false); Assert.fail();
} }
} }
@Test @Test
public void testDeleteTenantById(){ public void testDeleteTenantById() {
Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant()); Mockito.when(tenantMapper.queryById(1)).thenReturn(getTenant());
Mockito.when(processInstanceMapper.queryByTenantIdAndStatus(1, Constants.NOT_TERMINATED_STATES)).thenReturn(getInstanceList()); Mockito.when(processInstanceMapper.queryByTenantIdAndStatus(1, Constants.NOT_TERMINATED_STATES))
.thenReturn(getInstanceList());
Mockito.when(processDefinitionMapper.queryDefinitionListByTenant(2)).thenReturn(getDefinitionsList()); Mockito.when(processDefinitionMapper.queryDefinitionListByTenant(2)).thenReturn(getDefinitionsList());
Mockito.when( userMapper.queryUserListByTenant(3)).thenReturn(getUserList()); Mockito.when(userMapper.queryUserListByTenant(3)).thenReturn(getUserList());
try { try {
//TENANT_NOT_EXIST //TENANT_NOT_EXIST
Map<String, Object> result = tenantService.deleteTenantById(getLoginUser(),12); Map<String, Object> result = tenantService.deleteTenantById(getLoginUser(), 12);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.TENANT_NOT_EXIST,result.get(Constants.STATUS)); Assert.assertEquals(Status.TENANT_NOT_EXIST, result.get(Constants.STATUS));
//DELETE_TENANT_BY_ID_FAIL //DELETE_TENANT_BY_ID_FAIL
result = tenantService.deleteTenantById(getLoginUser(),1); result = tenantService.deleteTenantById(getLoginUser(), 1);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL,result.get(Constants.STATUS)); Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL, result.get(Constants.STATUS));
//DELETE_TENANT_BY_ID_FAIL_DEFINES //DELETE_TENANT_BY_ID_FAIL_DEFINES
Mockito.when(tenantMapper.queryById(2)).thenReturn(getTenant(2)); Mockito.when(tenantMapper.queryById(2)).thenReturn(getTenant(2));
result = tenantService.deleteTenantById(getLoginUser(),2); result = tenantService.deleteTenantById(getLoginUser(), 2);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL_DEFINES,result.get(Constants.STATUS)); Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL_DEFINES, result.get(Constants.STATUS));
//DELETE_TENANT_BY_ID_FAIL_USERS //DELETE_TENANT_BY_ID_FAIL_USERS
Mockito.when(tenantMapper.queryById(3)).thenReturn(getTenant(3)); Mockito.when(tenantMapper.queryById(3)).thenReturn(getTenant(3));
result = tenantService.deleteTenantById(getLoginUser(),3); result = tenantService.deleteTenantById(getLoginUser(), 3);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL_USERS,result.get(Constants.STATUS)); Assert.assertEquals(Status.DELETE_TENANT_BY_ID_FAIL_USERS, result.get(Constants.STATUS));
// success // success
Mockito.when(tenantMapper.queryById(4)).thenReturn(getTenant(4)); Mockito.when(tenantMapper.queryById(4)).thenReturn(getTenant(4));
result = tenantService.deleteTenantById(getLoginUser(),4); result = tenantService.deleteTenantById(getLoginUser(), 4);
logger.info(result.toString()); logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS,result.get(Constants.STATUS)); Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
} catch (Exception e) { } catch (Exception e) {
logger.error("delete tenant error",e); logger.error("delete tenant error", e);
Assert.assertTrue(false); Assert.fail();
} }
} }
@Test @Test
public void testQueryTenantList(){ public void testVerifyTenantCode() {
Mockito.when( tenantMapper.selectList(null)).thenReturn(getList());
Map<String, Object> result = tenantService.queryTenantList(getLoginUser());
logger.info(result.toString());
List<Tenant> tenantList = (List<Tenant>) result.get(Constants.DATA_LIST);
Assert.assertTrue(CollectionUtils.isNotEmpty(tenantList));
Mockito.when( tenantMapper.queryByTenantCode("1")).thenReturn(getList());
Map<String, Object> successRes = tenantService.queryTenantList("1");
Assert.assertEquals(Status.SUCCESS,successRes.get(Constants.STATUS));
Mockito.when( tenantMapper.queryByTenantCode("1")).thenReturn(null);
Map<String, Object> tenantNotExistRes = tenantService.queryTenantList("1");
Assert.assertEquals(Status.TENANT_NOT_EXIST,tenantNotExistRes.get(Constants.STATUS));
}
@Test
public void testVerifyTenantCode(){
Mockito.when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getList()); Mockito.when(tenantMapper.queryByTenantCode(tenantCode)).thenReturn(getList());
// tenantCode not exist // tenantCode not exist
@ -209,12 +203,10 @@ public class TenantServiceTest {
Assert.assertEquals(resultString, result.getMsg()); Assert.assertEquals(resultString, result.getMsg());
} }
/** /**
* get user * get user
* @return
*/ */
private User getLoginUser(){ private User getLoginUser() {
User loginUser = new User(); User loginUser = new User();
loginUser.setUserType(UserType.ADMIN_USER); loginUser.setUserType(UserType.ADMIN_USER);
@ -223,9 +215,8 @@ public class TenantServiceTest {
/** /**
* get list * get list
* @return
*/ */
private List<Tenant> getList(){ private List<Tenant> getList() {
List<Tenant> tenantList = new ArrayList<>(); List<Tenant> tenantList = new ArrayList<>();
tenantList.add(getTenant()); tenantList.add(getTenant());
return tenantList; return tenantList;
@ -233,16 +224,15 @@ public class TenantServiceTest {
/** /**
* get tenant * get tenant
* @return
*/ */
private Tenant getTenant(){ private Tenant getTenant() {
return getTenant(1); return getTenant(1);
} }
/** /**
* get tenant * get tenant
* @return
*/ */
private Tenant getTenant(int id){ private Tenant getTenant(int id) {
Tenant tenant = new Tenant(); Tenant tenant = new Tenant();
tenant.setId(id); tenant.setId(id);
tenant.setTenantCode(tenantCode); tenant.setTenantCode(tenantCode);
@ -250,25 +240,24 @@ public class TenantServiceTest {
return tenant; return tenant;
} }
private List<User> getUserList(){ private List<User> getUserList() {
List<User> userList = new ArrayList<>(); List<User> userList = new ArrayList<>();
userList.add(getLoginUser()); userList.add(getLoginUser());
return userList; return userList;
} }
private List<ProcessInstance> getInstanceList(){ private List<ProcessInstance> getInstanceList() {
List<ProcessInstance> processInstances = new ArrayList<>(); List<ProcessInstance> processInstances = new ArrayList<>();
ProcessInstance processInstance = new ProcessInstance(); ProcessInstance processInstance = new ProcessInstance();
processInstances.add(processInstance); processInstances.add(processInstance);
return processInstances; return processInstances;
} }
private List<ProcessDefinition> getDefinitionsList(){ private List<ProcessDefinition> getDefinitionsList() {
List<ProcessDefinition> processDefinitions = new ArrayList<>(); List<ProcessDefinition> processDefinitions = new ArrayList<>();
ProcessDefinition processDefinition = new ProcessDefinition(); ProcessDefinition processDefinition = new ProcessDefinition();
processDefinitions.add(processDefinition); processDefinitions.add(processDefinition);
return processDefinitions; return processDefinitions;
} }
} }

Loading…
Cancel
Save