diff --git a/escheduler-api/src/main/java/cn/escheduler/api/controller/ProcessDefinitionController.java b/escheduler-api/src/main/java/cn/escheduler/api/controller/ProcessDefinitionController.java index 4678425e308fa4407ad936dfe5da3cf598a85dd1..0ca71da70d7a553255311d9bfc60d9ccd796ac3d 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/controller/ProcessDefinitionController.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/controller/ProcessDefinitionController.java @@ -325,4 +325,29 @@ public class ProcessDefinitionController extends BaseController{ } } + /** + * delete process definition by id + * + * @param loginUser + * @param projectName + * @param processDefinitionId + * @return + */ + @GetMapping(value="/delete") + @ResponseStatus(HttpStatus.OK) + public Result deleteProcessDefinitionById(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @PathVariable String projectName, + @RequestParam("processDefinitionId") Integer processDefinitionId + ){ + try{ + logger.info("delete process definition by id, login user:{}, project name:{}, process definition id:{}", + loginUser.getUserName(), projectName, processDefinitionId); + Map result = processDefinitionService.deleteProcessDefinitionById(loginUser, projectName, processDefinitionId); + return returnDataList(result); + }catch (Exception e){ + logger.error(DELETE_PROCESS_DEFINE_BY_ID_ERROR.getMsg(),e); + return error(Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR.getCode(), Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR.getMsg()); + } + } + } diff --git a/escheduler-api/src/main/java/cn/escheduler/api/controller/UsersController.java b/escheduler-api/src/main/java/cn/escheduler/api/controller/UsersController.java index 524ac73faa38fac8e2f01fe2d0b25f96dc0c2c94..41a6a63bb1e4501cf5bd434eccd07f84ce6ba777 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/controller/UsersController.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/controller/UsersController.java @@ -137,7 +137,7 @@ public class UsersController extends BaseController{ logger.info("login user {}, updateProcessInstance user, userName: {}, email: {}, tenantId: {}, userPassword: {}, phone: {}, user queue: {}", loginUser.getUserName(), userName, email, tenantId, Constants.PASSWORD_DEFAULT, phone,queue); try { - Map result = usersService.updateUser(id,userName,userPassword,email,tenantId,phone,queue); + Map result = usersService.updateUser(id, userName, userPassword, email, tenantId, phone, queue); return returnDataList(result); }catch (Exception e){ logger.error(UPDATE_USER_ERROR.getMsg(),e); @@ -285,6 +285,26 @@ public class UsersController extends BaseController{ @GetMapping(value="/list") @ResponseStatus(HttpStatus.OK) public Result listUser(@RequestAttribute(value = Constants.SESSION_USER) User loginUser){ + logger.info("login user {}, user list"); + try{ + Map result = usersService.queryAllGeneralUsers(loginUser); + return returnDataList(result); + }catch (Exception e){ + logger.error(USER_LIST_ERROR.getMsg(),e); + return error(Status.USER_LIST_ERROR.getCode(), Status.USER_LIST_ERROR.getMsg()); + } + } + + + /** + * user list no paging + * + * @param loginUser + * @return + */ + @GetMapping(value="/list-all") + @ResponseStatus(HttpStatus.OK) + public Result listAll(@RequestAttribute(value = Constants.SESSION_USER) User loginUser){ logger.info("login user {}, user list"); try{ Map result = usersService.queryUserList(loginUser); @@ -295,6 +315,7 @@ public class UsersController extends BaseController{ } } + /** * verify username * diff --git a/escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java b/escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java index 6d57da211662ca3af204a9cd209cba7ceb3f4983..d90cf12858899fb5b891f5ab0ebccc464f595680 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/enums/Status.java @@ -201,6 +201,9 @@ public enum Status { DATA_IS_NULL(50018,"data %s is null"), PROCESS_NODE_HAS_CYCLE(50019,"process node has cycle"), PROCESS_NODE_S_PARAMETER_INVALID(50020,"process node %s parameter invalid"), + PROCESS_DEFINE_STATE_ONLINE(50021, "process definition {0} is already on line"), + DELETE_PROCESS_DEFINE_BY_ID_ERROR(50022,"delete process definition by id error"), + SCHEDULE_CRON_STATE_ONLINE(50023,"the status of schedule {0} is already on line"), HDFS_NOT_STARTUP(60001,"hdfs not startup"), diff --git a/escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java b/escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java index bb7133817c3c7830ee79d05a134988f5f669d9c7..cfa38146160c88bb7690edbebaa472870592bcdd 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java @@ -336,6 +336,65 @@ public class ProcessDefinitionService extends BaseDAGService { return result; } + /** + * delete process definition by id + * + * @param loginUser + * @param projectName + * @param processDefinitionId + * @return + */ + @Transactional(value = "TransactionManager", rollbackFor = Exception.class) + public Map deleteProcessDefinitionById(User loginUser, String projectName, Integer processDefinitionId) { + + Map result = new HashMap<>(5); + Project project = projectMapper.queryByName(projectName); + + Map checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName); + Status resultEnum = (Status) checkResult.get(Constants.STATUS); + if (resultEnum != Status.SUCCESS) { + return checkResult; + } + + + ProcessDefinition processDefinition = processDefineMapper.queryByDefineId(processDefinitionId); + + if (processDefinition == null) { + putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, processDefinitionId); + return result; + } + // check process definition is already online + if (processDefinition.getReleaseState() == ReleaseState.ONLINE) { + putMsg(result, Status.PROCESS_DEFINE_STATE_ONLINE,processDefinitionId); + return result; + } + + // get the timing according to the process definition + List schedules = scheduleMapper.selectAllByProcessDefineArray(new int[processDefinitionId]); + if (!schedules.isEmpty() && schedules.size() > 1) { + logger.warn("scheduler num is {},Greater than 1",schedules.size()); + putMsg(result, Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR); + return result; + }else if(schedules.size() == 1){ + Schedule schedule = schedules.get(0); + if(schedule.getReleaseState() == ReleaseState.OFFLINE){ + scheduleMapper.delete(schedule.getId()); + }else if(schedule.getReleaseState() == ReleaseState.ONLINE){ + putMsg(result, Status.SCHEDULE_CRON_STATE_ONLINE,schedule.getId()); + return result; + } + } + + int delete = processDefineMapper.delete(processDefinitionId); + + if (delete > 0) { + putMsg(result, Status.SUCCESS); + } else { + putMsg(result, Status.DELETE_PROCESS_DEFINE_BY_ID_ERROR); + } + return result; + } + /** * release process definition: online / offline * diff --git a/escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java b/escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java index 33cd50bac0261c20709a9e885b4295f6153a3e1b..16766a98cf2afac09dd87fcb49cc673cdec704ba 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java @@ -518,6 +518,27 @@ public class UsersService extends BaseService { return result; } + /** + * query user list + * + * @param loginUser + * @return + */ + public Map queryAllGeneralUsers(User loginUser) { + Map result = new HashMap<>(5); + //only admin can operate + if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM, Constants.STATUS)) { + return result; + } + + List userList = userMapper.queryAllGeneralUsers(); + result.put(Constants.DATA_LIST, userList); + putMsg(result, Status.SUCCESS); + + return result; + } + + /** * query user list * diff --git a/escheduler-api/src/test/java/cn/escheduler/api/service/ProcessDefinitionServiceTest.java b/escheduler-api/src/test/java/cn/escheduler/api/service/ProcessDefinitionServiceTest.java index 7a6b069f59bd355d40bd7e4a4aaa315ad10ad8a2..48dcd043fac16a3e6c97dd983a47ba28b05af0fc 100644 --- a/escheduler-api/src/test/java/cn/escheduler/api/service/ProcessDefinitionServiceTest.java +++ b/escheduler-api/src/test/java/cn/escheduler/api/service/ProcessDefinitionServiceTest.java @@ -63,4 +63,16 @@ public class ProcessDefinitionServiceTest { Assert.assertEquals(Status.SUCCESS, map.get(Constants.STATUS)); logger.info(JSON.toJSONString(map)); } + + @Test + public void deleteProcessDefinitionByIdTest() throws Exception { + + User loginUser = new User(); + loginUser.setId(2); + loginUser.setUserType(UserType.GENERAL_USER); + Map map = processDefinitionService.deleteProcessDefinitionById(loginUser, "li_sql_test", 6); + + Assert.assertEquals(Status.SUCCESS, map.get(Constants.STATUS)); + logger.info(JSON.toJSONString(map)); + } } \ No newline at end of file diff --git a/escheduler-common/pom.xml b/escheduler-common/pom.xml index dc95fc7f9c0425a602e80f221e84b9f09648339d..4f76b55cac96e07d4f4fbc450a112edbe5b44b9b 100644 --- a/escheduler-common/pom.xml +++ b/escheduler-common/pom.xml @@ -230,6 +230,29 @@ + + org.apache.hadoop + hadoop-aws + + + org.apache.hadoop + hadoop-common + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + + org.apache.commons commons-lang3 diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/HadoopUtils.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/HadoopUtils.java index f114b112a5a383dd4ba20c2bdaf8cd6e548347f4..b76d6347dadba629ed2eb8af8b320dc7b04f7b38 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/utils/HadoopUtils.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/HadoopUtils.java @@ -34,12 +34,14 @@ import org.slf4j.LoggerFactory; import java.io.*; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import static cn.escheduler.common.Constants.*; import static cn.escheduler.common.utils.PropertyUtils.getInt; import static cn.escheduler.common.utils.PropertyUtils.getString; +import static cn.escheduler.common.utils.PropertyUtils.getPrefixedProperties; /** * hadoop utils @@ -76,7 +78,9 @@ public class HadoopUtils implements Closeable { if(defaultFS.startsWith("file")){ String defaultFSProp = getString(FS_DEFAULTFS); if(StringUtils.isNotBlank(defaultFSProp)){ + Map fsRelatedProps = getPrefixedProperties("fs."); configuration.set(FS_DEFAULTFS,defaultFSProp); + fsRelatedProps.entrySet().stream().forEach(entry -> configuration.set(entry.getKey(), entry.getValue())); }else{ logger.error("property:{} can not to be empty, please set!"); throw new RuntimeException("property:{} can not to be empty, please set!"); @@ -316,7 +320,13 @@ public class HadoopUtils implements Closeable { * @return data hdfs path */ public static String getHdfsDataBasePath() { - return getString(DATA_STORE_2_HDFS_BASEPATH); + String basePath = getString(DATA_STORE_2_HDFS_BASEPATH); + if ("/".equals(basePath)) { + // if basepath is configured to /, the generated url may be //default/resources (with extra leading /) + return ""; + } else { + return basePath; + } } /** @@ -365,7 +375,7 @@ public class HadoopUtils implements Closeable { * @return file directory of tenants on hdfs */ private static String getHdfsTenantDir(String tenantCode) { - return String.format("%s/%s", getString(DATA_STORE_2_HDFS_BASEPATH), tenantCode); + return String.format("%s/%s", getHdfsDataBasePath(), tenantCode); } diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/PropertyUtils.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/PropertyUtils.java index 363bb417a8ad599e3a54643adf98e041b3a5578e..f5dab1261818aad5f59eace256aeac11c9be45bc 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/utils/PropertyUtils.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/PropertyUtils.java @@ -22,6 +22,8 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.Properties; import static cn.escheduler.common.Constants.COMMON_PROPERTIES_PATH; @@ -189,4 +191,19 @@ public class PropertyUtils { String val = getString(key); return val == null ? defaultValue : Enum.valueOf(type, val); } + + /** + * get all properties with specified prefix, like: fs. + * @param prefix prefix to search + * @return + */ + public static Map getPrefixedProperties(String prefix) { + Map matchedProperties = new HashMap<>(); + for (String propName : properties.stringPropertyNames()) { + if (propName.startsWith(prefix)) { + matchedProperties.put(propName, properties.getProperty(propName)); + } + } + return matchedProperties; + } } diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapper.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapper.java index f1a48bde94d3ce9a4ff7cf4e04c1a10741d3331a..4806979b821646ac7bcd48f6c4dc877484dad367 100644 --- a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapper.java +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapper.java @@ -173,6 +173,12 @@ public interface ScheduleMapper { @SelectProvider(type = ScheduleMapperProvider.class, method = "selectAllByProcessDefineArray") List selectAllByProcessDefineArray(@Param("processDefineIds") int[] processDefineIds); - + /** + * delete schedule by id + * @param scheduleId + * @return + */ + @DeleteProvider(type = ScheduleMapperProvider.class, method = "delete") + int delete(@Param("scheduleId") int scheduleId); } diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapperProvider.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapperProvider.java index 5674675a25e6bd6f93c22819c4cfba1286d3c058..bdfeb409e201e0ad634666ddc542f0bd7485b3e8 100644 --- a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapperProvider.java +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ScheduleMapperProvider.java @@ -180,4 +180,21 @@ public class ScheduleMapperProvider { WHERE("release_state = 1"); }}.toString(); } + + /** + * delete schedule by id + * + * @param parameter + * @return + */ + public String delete(Map parameter) { + return new SQL() { + { + DELETE_FROM(DB_NAME); + + WHERE("`id`=#{scheduleId}"); + } + }.toString(); + } + } diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java index 21415c758ee4e66cb59bc924a26e48c94be5e7b7..9c814543b139b22d081d724f98777257dc8c5a89 100644 --- a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapper.java @@ -76,6 +76,25 @@ public interface UserMapper { @SelectProvider(type = UserMapperProvider.class, method = "queryById") User queryById(@Param("userId") int userId); + /** + * query all general user list + * @return + */ + @Results(value = { + @Result(property = "id", column = "id", id = true, javaType = Integer.class, jdbcType = JdbcType.INTEGER), + @Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "userPassword", column = "user_password", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "email", column = "email", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "phone", column = "phone", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "userType", column = "user_type", typeHandler = EnumOrdinalTypeHandler.class, javaType = UserType.class, jdbcType = JdbcType.TINYINT), + @Result(property = "tenantId", column = "tenant_id", javaType = Integer.class, jdbcType = JdbcType.INTEGER), + @Result(property = "createTime", column = "create_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE), + @Result(property = "updateTime", column = "update_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE) + }) + @SelectProvider(type = UserMapperProvider.class, method = "queryAllGeneralUsers") + List queryAllGeneralUsers(); + + /** * query all user list * @return diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java index d060f46dd23755dca515fc6124c6fdd036c8e371..2fe0af9f20ba20c954e3e7d05fa5c64c35dd14d0 100644 --- a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java @@ -118,7 +118,7 @@ public class UserMapperProvider { * * @return */ - public String queryAllUsers() { + public String queryAllGeneralUsers() { return new SQL() { { SELECT("*"); @@ -130,6 +130,22 @@ public class UserMapperProvider { }.toString(); } + /** + * query all user list + * + * @return + */ + public String queryAllUsers() { + return new SQL() { + { + SELECT("*"); + FROM(TABLE_NAME); + } + }.toString(); + } + + + /** * check user name and password * @@ -188,13 +204,17 @@ public class UserMapperProvider { return new SQL() { { SELECT("u.*,t.tenant_name as tenantName,q.queue_name as queueName"); - FROM(TABLE_NAME +" u,t_escheduler_tenant t,t_escheduler_queue q"); - WHERE("u.user_type = 1 AND u.tenant_id = t.id and t.queue_id = q.id"); + FROM(TABLE_NAME + " u "); + LEFT_OUTER_JOIN("t_escheduler_tenant t on u.tenant_id = t.id"); + LEFT_OUTER_JOIN("t_escheduler_queue q on t.queue_id = q.id"); + WHERE("u.user_type = 1"); Object searchVal = parameter.get("searchVal"); if(searchVal != null && StringUtils.isNotEmpty(searchVal.toString())){ WHERE( " u.user_name like concat('%', #{searchVal}, '%') "); } ORDER_BY(" u.update_time desc limit #{offset},#{pageSize} "); + + } }.toString(); diff --git a/escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue b/escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue index 348379ef62dfc5bf71d3c501bc88defb019cb554..1b0b22bb44368856dc50fe08cccf36eb363d8c42 100644 --- a/escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue +++ b/escheduler-ui/src/js/conf/home/pages/user/pages/token/_source/createToken.vue @@ -140,7 +140,7 @@ } } if (this.auth) { - this.store.dispatch(`security/getUsersList`).then(res => { + this.store.dispatch(`security/getUsersAll`).then(res => { this.userIdList = _.map(res, v => _.pick(v, ['id', 'userName'])) d(this.userIdList[0].id) }) @@ -158,4 +158,4 @@ .create-token-model { width: 640px; } - \ No newline at end of file + diff --git a/escheduler-ui/src/js/conf/home/store/security/actions.js b/escheduler-ui/src/js/conf/home/store/security/actions.js index 67ed62f57bf407ff87af70243f92fea7e7b6475d..9fda7663ab597699bb0af2d26d94da5a05721a73 100644 --- a/escheduler-ui/src/js/conf/home/store/security/actions.js +++ b/escheduler-ui/src/js/conf/home/store/security/actions.js @@ -100,7 +100,7 @@ export default { }) }, /** - * Paging query user list + * user list expect admin */ getUsersList ({ state }, payload) { return new Promise((resolve, reject) => { @@ -111,6 +111,18 @@ export default { }) }) }, + /** + * user all list + */ + getUsersAll ({ state }, payload) { + return new Promise((resolve, reject) => { + io.get(`users/list-all`, payload, res => { + resolve(res.data) + }).catch(e => { + reject(e) + }) + }) + }, /** * Update user * @param "id":int, diff --git a/pom.xml b/pom.xml index 3e5ff0d79d978eb66b9f68c992c3233cfbc2f6d2..15849c8382241f076234e75318269b93bbcb0521 100644 --- a/pom.xml +++ b/pom.xml @@ -323,6 +323,11 @@ hadoop-yarn-common ${hadoop.version} + + org.apache.hadoop + hadoop-aws + ${hadoop.version} + javax.servlet