diff --git a/escheduler-alert/pom.xml b/escheduler-alert/pom.xml index eebf8b8f50..79defd54b8 100644 --- a/escheduler-alert/pom.xml +++ b/escheduler-alert/pom.xml @@ -4,7 +4,7 @@ cn.analysys escheduler - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT escheduler-alert jar diff --git a/escheduler-api/pom.xml b/escheduler-api/pom.xml index e5c5bda8f5..74a97b4784 100644 --- a/escheduler-api/pom.xml +++ b/escheduler-api/pom.xml @@ -3,7 +3,7 @@ cn.analysys escheduler - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT escheduler-api jar diff --git a/escheduler-api/src/main/java/cn/escheduler/api/controller/AccessTokenController.java b/escheduler-api/src/main/java/cn/escheduler/api/controller/AccessTokenController.java new file mode 100644 index 0000000000..27ac1772a0 --- /dev/null +++ b/escheduler-api/src/main/java/cn/escheduler/api/controller/AccessTokenController.java @@ -0,0 +1,169 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.api.controller; + + +import cn.escheduler.api.enums.Status; +import cn.escheduler.api.service.AccessTokenService; +import cn.escheduler.api.service.UsersService; +import cn.escheduler.api.utils.Constants; +import cn.escheduler.api.utils.Result; +import cn.escheduler.dao.model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +import static cn.escheduler.api.enums.Status.*; + + +/** + * user controller + */ +@RestController +@RequestMapping("/access-token") +public class AccessTokenController extends BaseController{ + + + private static final Logger logger = LoggerFactory.getLogger(AccessTokenController.class); + + + @Autowired + private AccessTokenService accessTokenService; + + /** + * create token + * @param loginUser + * @return + */ + @PostMapping(value = "/create") + @ResponseStatus(HttpStatus.CREATED) + public Result createToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "userId") int userId, + @RequestParam(value = "expireTime") String expireTime, + @RequestParam(value = "token") String token){ + logger.info("login user {}, create token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(), + userId,expireTime,token); + + try { + Map result = accessTokenService.createToken(userId, expireTime, token); + return returnDataList(result); + }catch (Exception e){ + logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e); + return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg()); + } + } + + /** + * create token + * @param loginUser + * @return + */ + @PostMapping(value = "/generate") + @ResponseStatus(HttpStatus.CREATED) + public Result generateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "userId") int userId, + @RequestParam(value = "expireTime") String expireTime){ + logger.info("login user {}, generate token , userId : {} , token expire time : {}",loginUser,userId,expireTime); + try { + Map result = accessTokenService.generateToken(userId, expireTime); + return returnDataList(result); + }catch (Exception e){ + logger.error(GENERATE_TOKEN_ERROR.getMsg(),e); + return error(GENERATE_TOKEN_ERROR.getCode(), GENERATE_TOKEN_ERROR.getMsg()); + } + } + + /** + * query access token list paging + * + * @param loginUser + * @param pageNo + * @param searchVal + * @param pageSize + * @return + */ + @GetMapping(value="/list-paging") + @ResponseStatus(HttpStatus.OK) + public Result queryAccessTokenList(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam("pageNo") Integer pageNo, + @RequestParam(value = "searchVal", required = false) String searchVal, + @RequestParam("pageSize") Integer pageSize){ + logger.info("login user {}, list access token paging, pageNo: {}, searchVal: {}, pageSize: {}", + loginUser.getUserName(),pageNo,searchVal,pageSize); + try{ + Map result = checkPageParams(pageNo, pageSize); + if(result.get(Constants.STATUS) != Status.SUCCESS){ + return returnDataListPaging(result); + } + result = accessTokenService.queryAccessTokenList(loginUser, searchVal, pageNo, pageSize); + return returnDataListPaging(result); + }catch (Exception e){ + logger.error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg(),e); + return error(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getCode(),QUERY_ACCESSTOKEN_LIST_PAGING_ERROR.getMsg()); + } + } + + /** + * delete access token by id + * @param loginUser + * @param id + * @return + */ + @PostMapping(value = "/delete") + @ResponseStatus(HttpStatus.OK) + public Result delAccessTokenById(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "id") int id) { + logger.info("login user {}, delete access token, id: {},", loginUser.getUserName(), id); + try { + Map result = accessTokenService.delAccessTokenById(loginUser, id); + return returnDataList(result); + }catch (Exception e){ + logger.error(DELETE_USER_BY_ID_ERROR.getMsg(),e); + return error(Status.DELETE_USER_BY_ID_ERROR.getCode(), Status.DELETE_USER_BY_ID_ERROR.getMsg()); + } + } + + + /** + * update token + * @param loginUser + * @return + */ + @PostMapping(value = "/update") + @ResponseStatus(HttpStatus.CREATED) + public Result updateToken(@RequestAttribute(value = Constants.SESSION_USER) User loginUser, + @RequestParam(value = "id") int id, + @RequestParam(value = "userId") int userId, + @RequestParam(value = "expireTime") String expireTime, + @RequestParam(value = "token") String token){ + logger.info("login user {}, update token , userId : {} , token expire time : {} , token : {}", loginUser.getUserName(), + userId,expireTime,token); + + try { + Map result = accessTokenService.updateToken(id,userId, expireTime, token); + return returnDataList(result); + }catch (Exception e){ + logger.error(CREATE_ACCESS_TOKEN_ERROR.getMsg(),e); + return error(CREATE_ACCESS_TOKEN_ERROR.getCode(), CREATE_ACCESS_TOKEN_ERROR.getMsg()); + } + } + +} diff --git a/escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java b/escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java index 4b1a6a88f1..3ef011d323 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/controller/SchedulerController.java @@ -46,7 +46,6 @@ public class SchedulerController extends BaseController{ private static final Logger logger = LoggerFactory.getLogger(SchedulerController.class); public static final String DEFAULT_WARNING_TYPE = "NONE"; public static final String DEFAULT_NOTIFY_GROUP_ID = "1"; - public static final String DEFAULT_MAX_TRY_TIMES = "0"; public static final String DEFAULT_FAILURE_POLICY = "CONTINUE"; 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 253e8edb52..9f8b7efc14 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 @@ -199,6 +199,12 @@ public enum Status { HDFS_NOT_STARTUP(60001,"hdfs not startup"), + + + CREATE_ACCESS_TOKEN_ERROR(70001,"create access token error"), + GENERATE_TOKEN_ERROR(70002,"generate token error"), + QUERY_ACCESSTOKEN_LIST_PAGING_ERROR(70003,"query access token list paging error"), + ; private int code; diff --git a/escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java b/escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java index 7f287bf725..f3836dc467 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/interceptor/LoginHandlerInterceptor.java @@ -22,6 +22,7 @@ import cn.escheduler.dao.mapper.UserMapper; import cn.escheduler.dao.model.Session; import cn.escheduler.dao.model.User; import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -64,37 +65,31 @@ public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - Session session = sessionService.getSession(request); - - if(logger.isDebugEnabled()){ - logger.debug("session info : " + session); - } - - if (session == null) { - response.setStatus(HttpStatus.SC_UNAUTHORIZED); - logger.info("session info is null "); - return false; - } - - if(logger.isDebugEnabled()){ - logger.debug("session id: {}", session.getId()); + // get token + String token = request.getHeader("token"); + User user = null; + if (StringUtils.isEmpty(token)){ + Session session = sessionService.getSession(request); + + if (session == null) { + response.setStatus(HttpStatus.SC_UNAUTHORIZED); + logger.info("session info is null "); + return false; + } + + //get user object from session + user = userMapper.queryById(session.getUserId()); + }else { + user = userMapper.queryUserByToken(token); } - //get user object from session - User user = userMapper.queryById(session.getUserId()); - - if(logger.isDebugEnabled()){ - logger.info("user info : " + user); - } - - + // if user is null if (user == null) { response.setStatus(HttpStatus.SC_UNAUTHORIZED); + logger.info("user does not exist"); return false; } - request.setAttribute(Constants.SESSION_USER, user); - return true; } diff --git a/escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java b/escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java index 3a6fc1e64d..6fcaf1171d 100644 --- a/escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java +++ b/escheduler-api/src/main/java/cn/escheduler/api/quartz/ProcessScheduleJob.java @@ -125,7 +125,7 @@ public class ProcessScheduleJob implements Job { } Command command = new Command(); - command.setCommandType(CommandType.START_PROCESS); + command.setCommandType(CommandType.SCHEDULER); command.setExecutorId(schedule.getUserId()); command.setFailureStrategy(schedule.getFailureStrategy()); command.setProcessDefinitionId(schedule.getProcessDefinitionId()); diff --git a/escheduler-api/src/main/java/cn/escheduler/api/service/AccessTokenService.java b/escheduler-api/src/main/java/cn/escheduler/api/service/AccessTokenService.java new file mode 100644 index 0000000000..4adde8ad60 --- /dev/null +++ b/escheduler-api/src/main/java/cn/escheduler/api/service/AccessTokenService.java @@ -0,0 +1,184 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.api.service; + +import cn.escheduler.api.enums.Status; +import cn.escheduler.api.utils.CheckUtils; +import cn.escheduler.api.utils.Constants; +import cn.escheduler.api.utils.PageInfo; +import cn.escheduler.api.utils.Result; +import cn.escheduler.common.enums.UserType; +import cn.escheduler.common.utils.*; +import cn.escheduler.dao.mapper.*; +import cn.escheduler.dao.model.*; +import org.apache.commons.lang3.StringUtils; +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.*; + +/** + * user service + */ +@Service +public class AccessTokenService extends BaseService { + + private static final Logger logger = LoggerFactory.getLogger(AccessTokenService.class); + + @Autowired + private AccessTokenMapper accessTokenMapper; + + + /** + * query access token list + * + * @param loginUser + * @param searchVal + * @param pageNo + * @param pageSize + * @return + */ + public Map queryAccessTokenList(User loginUser, String searchVal, Integer pageNo, Integer pageSize) { + Map result = new HashMap<>(5); + + if (check(result, !isAdmin(loginUser), Status.USER_NO_OPERATION_PERM, Constants.STATUS)) { + return result; + } + + Integer count = accessTokenMapper.countAccessTokenPaging(searchVal); + + PageInfo pageInfo = new PageInfo<>(pageNo, pageSize); + + List accessTokenList = accessTokenMapper.queryAccessTokenPaging(searchVal, pageInfo.getStart(), pageSize); + + pageInfo.setTotalCount(count); + pageInfo.setLists(accessTokenList); + result.put(Constants.DATA_LIST, pageInfo); + putMsg(result, Status.SUCCESS); + + return result; + } + + /** + * check + * + * @param result + * @param bool + * @param userNoOperationPerm + * @param status + * @return + */ + private boolean check(Map result, boolean bool, Status userNoOperationPerm, String status) { + //only admin can operate + if (bool) { + result.put(Constants.STATUS, userNoOperationPerm); + result.put(status, userNoOperationPerm.getMsg()); + return true; + } + return false; + } + + + /** + * create token + * + * @param userId + * @param expireTime + * @param token + * @return + */ + public Map createToken(int userId, String expireTime, String token) { + Map result = new HashMap<>(5); + + AccessToken accessToken = new AccessToken(); + accessToken.setUserId(userId); + accessToken.setExpireTime(DateUtils.stringToDate(expireTime)); + accessToken.setToken(token); + accessToken.setCreateTime(new Date()); + accessToken.setUpdateTime(new Date()); + + // insert + int insert = accessTokenMapper.insert(accessToken); + + if (insert > 0) { + putMsg(result, Status.SUCCESS); + } else { + putMsg(result, Status.CREATE_ALERT_GROUP_ERROR); + } + + return result; + } + + /** + * generate token + * @param userId + * @param expireTime + * @return + */ + public Map generateToken(int userId, String expireTime) { + Map result = new HashMap<>(5); + String token = EncryptionUtils.getMd5(userId + expireTime + String.valueOf(System.currentTimeMillis())); + result.put(Constants.DATA_LIST, token); + putMsg(result, Status.SUCCESS); + return result; + } + + /** + * delete access token + * @param loginUser + * @param id + * @return + */ + public Map delAccessTokenById(User loginUser, int id) { + Map result = new HashMap<>(5); + //only admin can operate + if (!isAdmin(loginUser)) { + putMsg(result, Status.USER_NOT_EXIST, id); + return result; + } + + accessTokenMapper.delete(id); + putMsg(result, Status.SUCCESS); + return result; + } + + /** + * update token by id + * @param id + * @param userId + * @param expireTime + * @param token + * @return + */ + public Map updateToken(int id,int userId, String expireTime, String token) { + Map result = new HashMap<>(5); + AccessToken accessToken = new AccessToken(); + accessToken.setId(id); + accessToken.setUserId(userId); + accessToken.setExpireTime(DateUtils.stringToDate(expireTime)); + accessToken.setToken(token); + accessToken.setUpdateTime(new Date()); + + accessTokenMapper.update(accessToken); + + putMsg(result, Status.SUCCESS); + return result; + } +} diff --git a/escheduler-api/src/test/java/cn/escheduler/api/HttpClientTest.java b/escheduler-api/src/test/java/cn/escheduler/api/HttpClientTest.java new file mode 100644 index 0000000000..81a94bc3f0 --- /dev/null +++ b/escheduler-api/src/test/java/cn/escheduler/api/HttpClientTest.java @@ -0,0 +1,162 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.api; + +import java.io.File; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import cn.escheduler.common.utils.EncryptionUtils; +import org.apache.commons.io.FileUtils; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +public class HttpClientTest { + + private static final Logger logger = LoggerFactory.getLogger(HttpClientTest.class); + + public static void main(String[] args) throws Exception { +// doGETParamPathVariableAndChinese(); +// doGETParam(); +// doPOSTParam(); + + String md5 = EncryptionUtils.getMd5(String.valueOf(System.currentTimeMillis()) + "张三"); + System.out.println(md5); + System.out.println(md5.length()); + } + + public static void doPOSTParam()throws Exception{ + // create Httpclient + CloseableHttpClient httpclient = HttpClients.createDefault(); + // 创建http POST请求 + HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/escheduler/projects/create"); + httpPost.setHeader("token", "123"); + // set parameters + List parameters = new ArrayList(); + parameters.add(new BasicNameValuePair("projectName", "qzw")); + parameters.add(new BasicNameValuePair("desc", "qzw")); + + UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters); + httpPost.setEntity(formEntity); + + + CloseableHttpResponse response = null; + try { + // execute + response = httpclient.execute(httpPost); + // eponse status code 200 + if (response.getStatusLine().getStatusCode() == 200) { + String content = EntityUtils.toString(response.getEntity(), "UTF-8"); + System.out.println(content); + } + } finally { + if (response != null) { + response.close(); + } + httpclient.close(); + } + } + + /** + * + * @throws Exception + */ + public static void doGETParamPathVariableAndChinese()throws Exception{ + // create HttpClient + CloseableHttpClient httpclient = HttpClients.createDefault(); + + List parameters = new ArrayList(); +// parameters.add(new BasicNameValuePair("pageSize", "10")); + + // define the parameters of the request + URI uri = new URIBuilder("http://127.0.0.1:12345/escheduler/projects/%E5%85%A8%E9%83%A8%E6%B5%81%E7%A8%8B%E6%B5%8B%E8%AF%95/process/list") + .build(); + + // create http GET request + HttpGet httpGet = new HttpGet(uri); + httpGet.setHeader("token","123"); + //response object + CloseableHttpResponse response = null; + try { + // execute http get request + response = httpclient.execute(httpGet); + // reponse status code 200 + if (response.getStatusLine().getStatusCode() == 200) { + String content = EntityUtils.toString(response.getEntity(), "UTF-8"); + logger.info("start--------------->"); + logger.info(content); + logger.info("end----------------->"); + } + } finally { + if (response != null) { + response.close(); + } + httpclient.close(); + } + } + + /** + * + * @throws Exception + */ + public static void doGETParam()throws Exception{ + // create HttpClient + CloseableHttpClient httpclient = HttpClients.createDefault(); + + List parameters = new ArrayList(); + parameters.add(new BasicNameValuePair("processInstanceId", "41415")); + + // define the parameters of the request + URI uri = new URIBuilder("http://127.0.0.1:12345/escheduler/projects/%E5%85%A8%E9%83%A8%E6%B5%81%E7%A8%8B%E6%B5%8B%E8%AF%95/instance/view-variables") + .setParameters(parameters) + .build(); + + // create http GET request + HttpGet httpGet = new HttpGet(uri); + httpGet.setHeader("token","123"); + //response object + CloseableHttpResponse response = null; + try { + // execute http get request + response = httpclient.execute(httpGet); + // reponse status code 200 + if (response.getStatusLine().getStatusCode() == 200) { + String content = EntityUtils.toString(response.getEntity(), "UTF-8"); + logger.info("start--------------->"); + logger.info(content); + logger.info("end----------------->"); + } + } finally { + if (response != null) { + response.close(); + } + httpclient.close(); + } + } + +} diff --git a/escheduler-common/pom.xml b/escheduler-common/pom.xml index c0daa0bce7..178e969bb3 100644 --- a/escheduler-common/pom.xml +++ b/escheduler-common/pom.xml @@ -4,7 +4,7 @@ escheduler cn.analysys - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT escheduler-common escheduler-common diff --git a/escheduler-common/src/main/java/cn/escheduler/common/Constants.java b/escheduler-common/src/main/java/cn/escheduler/common/Constants.java index 4e9a11c841..e0155e606e 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/Constants.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/Constants.java @@ -70,25 +70,6 @@ public final class Constants { */ public static final String YARN_APPLICATION_STATUS_ADDRESS = "yarn.application.status.address"; - /** - * spring.redis.maxIdle - */ - public static final String SPRING_REDIS_MAXIDLE = "spring.redis.maxIdle"; - - /** - * spring.redis.maxTotal - */ - public static final String SPRING_REDIS_MAXTOTAL = "spring.redis.maxTotal"; - - /** - * spring.redis.host - */ - public static final String SPRING_REDIS_HOST = "spring.redis.host"; - - /** - * spring.redis.port - */ - public static final String SPRING_REDIS_PORT = "spring.redis.port"; /** * hdfs configuration @@ -117,9 +98,14 @@ public final class Constants { public static final String ESCHEDULER_ENV_PATH = "escheduler.env.path"; /** - * escheduler.env.py + * escheduler.env.sh */ - public static final String ESCHEDULER_ENV_PY = "escheduler.env.py"; + public static final String ESCHEDULER_ENV_SH = ".escheduler_env.sh"; + + /** + * python home + */ + public static final String PYTHON_HOME="PYTHON_HOME"; /** * resource.view.suffixs @@ -255,8 +241,6 @@ public final class Constants { public static final String SCHEDULER_QUEUE_IMPL = "escheduler.queue.impl"; - public static final String SCHEDULER_QUEUE_REDIS_IMPL = "redis"; - /** * date format of yyyy-MM-dd HH:mm:ss diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java index 6930d8db35..d0164791d2 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/CommonUtils.java @@ -46,13 +46,6 @@ public class CommonUtils { return envPath; } - /** - * @return get the path of Python system environment variables - */ - public static String getPythonSystemEnvPath() { - return getString(ESCHEDULER_ENV_PY); - } - /** * @return get queue implementation name */ diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/FileUtils.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/FileUtils.java index a07b689871..205f894e04 100644 --- a/escheduler-common/src/main/java/cn/escheduler/common/utils/FileUtils.java +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/FileUtils.java @@ -368,5 +368,61 @@ public class FileUtils { org.apache.commons.io.FileUtils.forceDelete(new File(filename)); } + /** + * Gets all the parent subdirectories of the parentDir directory + * @param parentDir + * @return + */ + public static File[] getAllDir(String parentDir){ + if(parentDir == null || "".equals(parentDir)) { + throw new RuntimeException("parentDir can not be empty"); + } + + File file = new File(parentDir); + if(!file.exists() || !file.isDirectory()) { + throw new RuntimeException("parentDir not exist, or is not a directory:"+parentDir); + } + + File[] schemaDirs = file.listFiles(new FileFilter() { + + @Override + public boolean accept(File pathname) { + if (pathname.isDirectory()) { + return true; + } + else { + return false; + } + } + }); + + return schemaDirs; + } + + /** + * Get Content + * @param inputStream + * @return + * @throws IOException + */ + public static String readFile2Str(InputStream inputStream) throws IOException{ + String all_content=null; + try { + all_content = new String(); + InputStream ins = inputStream; + ByteArrayOutputStream outputstream = new ByteArrayOutputStream(); + byte[] str_b = new byte[1024]; + int i = -1; + while ((i=ins.read(str_b)) > 0) { + outputstream.write(str_b,0,i); + } + all_content = outputstream.toString(); + return all_content; + } catch (Exception e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e); + } + } + } diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/MysqlUtil.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/MysqlUtil.java new file mode 100644 index 0000000000..d2d1ef203d --- /dev/null +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/MysqlUtil.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; + +public class MysqlUtil { + + public static final Logger logger = LoggerFactory.getLogger(MysqlUtil.class); + + private static MysqlUtil instance; + + MysqlUtil() { + } + + public static MysqlUtil getInstance() { + if (null == instance) { + syncInit(); + } + return instance; + } + + private static synchronized void syncInit() { + if (instance == null) { + instance = new MysqlUtil(); + } + } + + public void release(ResultSet rs, Statement stmt, Connection conn) { + try { + if (rs != null) { + rs.close(); + rs = null; + } + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e); + } finally { + try { + if (stmt != null) { + stmt.close(); + stmt = null; + } + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e); + } finally { + try { + if (conn != null) { + conn.close(); + conn = null; + } + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e); + } + } + } + } + + public static void realeaseResource(ResultSet rs, PreparedStatement ps, Connection conn) { + MysqlUtil.getInstance().release(rs,ps,conn); + if (null != rs) { + try { + rs.close(); + } catch (SQLException e) { + logger.error(e.getMessage(),e); + } + } + + if (null != ps) { + try { + ps.close(); + } catch (SQLException e) { + logger.error(e.getMessage(),e); + } + } + + if (null != conn) { + try { + conn.close(); + } catch (SQLException e) { + logger.error(e.getMessage(),e); + } + } + } +} diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/SchemaUtils.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/SchemaUtils.java new file mode 100644 index 0000000000..18f10b1bcd --- /dev/null +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/SchemaUtils.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.common.utils; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Metadata related common classes + * + */ +public class SchemaUtils { + + private static final Logger logger = LoggerFactory.getLogger(SchemaUtils.class); + private static Pattern p = Pattern.compile("\\s*|\t|\r|\n"); + + /** + * 获取所有upgrade目录下的可升级的schema + * Gets upgradable schemas for all upgrade directories + * @return + */ + @SuppressWarnings("unchecked") + public static List getAllSchemaList() { + List schemaDirList = new ArrayList<>(); + File[] schemaDirArr = FileUtils.getAllDir("sql/upgrade"); + if(schemaDirArr == null || schemaDirArr.length == 0) { + return null; + } + + for(File file : schemaDirArr) { + schemaDirList.add(file.getName()); + } + + Collections.sort(schemaDirList , new Comparator() { + @Override + public int compare(Object o1 , Object o2){ + try { + String dir1 = String.valueOf(o1); + String dir2 = String.valueOf(o2); + String version1 = dir1.split("_")[0]; + String version2 = dir2.split("_")[0]; + if(version1.equals(version2)) { + return 0; + } + + if(SchemaUtils.isAGreatVersion(version1, version2)) { + return 1; + } + + return -1; + + } catch (Exception e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e); + } + } + }); + + return schemaDirList; + } + + /** + * 判断schemaVersion是否比version版本高 + * Determine whether schemaVersion is higher than version + * @param schemaVersion + * @param version + * @return + */ + public static boolean isAGreatVersion(String schemaVersion, String version) { + if(StringUtils.isEmpty(schemaVersion) || StringUtils.isEmpty(version)) { + throw new RuntimeException("schemaVersion or version is empty"); + } + + String[] schemaVersionArr = schemaVersion.split("\\."); + String[] versionArr = version.split("\\."); + int arrLength = schemaVersionArr.length < versionArr.length ? schemaVersionArr.length : versionArr.length; + for(int i = 0 ; i < arrLength ; i++) { + if(Integer.valueOf(schemaVersionArr[i]) > Integer.valueOf(versionArr[i])) { + return true; + }else if(Integer.valueOf(schemaVersionArr[i]) < Integer.valueOf(versionArr[i])) { + return false; + } + } + + // 说明直到第arrLength-1个元素,两个版本号都一样,此时谁的arrLength大,谁的版本号就大 + // If the version and schema version is the same from 0 up to the arrlength-1 element,whoever has a larger arrLength has a larger version number + return schemaVersionArr.length > versionArr.length; + } + + /** + * Gets the current software version number of the system + * @return + */ + public static String getSoftVersion() { + String soft_version; + try { + soft_version = FileUtils.readFile2Str(new FileInputStream(new File("sql/soft_version"))); + soft_version = replaceBlank(soft_version); + } catch (FileNotFoundException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException("Failed to get the product version description file. The file could not be found", e); + } catch (IOException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException("Failed to get product version number description file, failed to read the file", e); + } + return soft_version; + } + + /** + * 去掉字符串中的空格回车换行和制表符 + * Strips the string of space carriage returns and tabs + * @param str + * @return + */ + public static String replaceBlank(String str) { + String dest = ""; + if (str!=null) { + + Matcher m = p.matcher(str); + dest = m.replaceAll(""); + } + return dest; + } +} diff --git a/escheduler-common/src/main/java/cn/escheduler/common/utils/ScriptRunner.java b/escheduler-common/src/main/java/cn/escheduler/common/utils/ScriptRunner.java new file mode 100644 index 0000000000..a74d7e268c --- /dev/null +++ b/escheduler-common/src/main/java/cn/escheduler/common/utils/ScriptRunner.java @@ -0,0 +1,317 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.common.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; +import java.sql.*; + +/* + * Slightly modified version of the com.ibatis.common.jdbc.ScriptRunner class + * from the iBATIS Apache project. Only removed dependency on Resource class + * and a constructor + */ +/* + * Copyright 2004 Clinton Begin + * + * Licensed 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. + */ + +/** + * Tool to run database scripts + */ +public class ScriptRunner { + + public static final Logger logger = LoggerFactory.getLogger(ScriptRunner.class); + + private static final String DEFAULT_DELIMITER = ";"; + + private Connection connection; + + private boolean stopOnError; + private boolean autoCommit; + + private String delimiter = DEFAULT_DELIMITER; + private boolean fullLineDelimiter = false; + + /** + * Default constructor + */ + public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) { + this.connection = connection; + this.autoCommit = autoCommit; + this.stopOnError = stopOnError; + } + + public static void main(String[] args) { + String dbName = "db_mmu"; + String appKey = dbName.substring(dbName.lastIndexOf("_")+1, dbName.length()); + System.out.println(appKey); + } + + public void setDelimiter(String delimiter, boolean fullLineDelimiter) { + this.delimiter = delimiter; + this.fullLineDelimiter = fullLineDelimiter; + } + + /** + * Runs an SQL script (read in using the Reader parameter) + * + * @param reader + * - the source of the script + */ + public void runScript(Reader reader) throws IOException, SQLException { + try { + boolean originalAutoCommit = connection.getAutoCommit(); + try { + if (originalAutoCommit != this.autoCommit) { + connection.setAutoCommit(this.autoCommit); + } + runScript(connection, reader); + } finally { + connection.setAutoCommit(originalAutoCommit); + } + } catch (IOException e) { + throw e; + } catch (SQLException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("Error running script. Cause: " + e, e); + } + } + + public void runScript(Reader reader, String dbName) throws IOException, SQLException { + try { + boolean originalAutoCommit = connection.getAutoCommit(); + try { + if (originalAutoCommit != this.autoCommit) { + connection.setAutoCommit(this.autoCommit); + } + runScript(connection, reader, dbName); + } finally { + connection.setAutoCommit(originalAutoCommit); + } + } catch (IOException e) { + throw e; + } catch (SQLException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("Error running script. Cause: " + e, e); + } + } + + /** + * Runs an SQL script (read in using the Reader parameter) using the connection + * passed in + * + * @param conn + * - the connection to use for the script + * @param reader + * - the source of the script + * @throws SQLException + * if any SQL errors occur + * @throws IOException + * if there is an error reading from the Reader + */ + private void runScript(Connection conn, Reader reader) throws IOException, SQLException { + StringBuffer command = null; + try { + LineNumberReader lineReader = new LineNumberReader(reader); + String line = null; + while ((line = lineReader.readLine()) != null) { + if (command == null) { + command = new StringBuffer(); + } + String trimmedLine = line.trim(); + if (trimmedLine.startsWith("--")) { + logger.info(trimmedLine); + } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) { + // Do nothing + } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) { + // Do nothing + + } else if (trimmedLine.startsWith("delimiter")) { + String newDelimiter = trimmedLine.split(" ")[1]; + this.setDelimiter(newDelimiter, fullLineDelimiter); + + } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) + || fullLineDelimiter && trimmedLine.equals(getDelimiter())) { + command.append(line.substring(0, line.lastIndexOf(getDelimiter()))); + command.append(" "); + Statement statement = conn.createStatement(); + + // logger.info(command.toString()); + + boolean hasResults = false; + logger.info("sql:"+command.toString()); + if (stopOnError) { + hasResults = statement.execute(command.toString()); + } else { + try { + statement.execute(command.toString()); + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw e; + } + } + + ResultSet rs = statement.getResultSet(); + if (hasResults && rs != null) { + ResultSetMetaData md = rs.getMetaData(); + int cols = md.getColumnCount(); + for (int i = 0; i < cols; i++) { + String name = md.getColumnLabel(i); + logger.info(name + "\t"); + } + logger.info(""); + while (rs.next()) { + for (int i = 0; i < cols; i++) { + String value = rs.getString(i); + logger.info(value + "\t"); + } + logger.info(""); + } + } + + command = null; + try { + statement.close(); + } catch (Exception e) { + // Ignore to workaround a bug in Jakarta DBCP + } + Thread.yield(); + } else { + command.append(line); + command.append(" "); + } + } + + } catch (SQLException e) { + logger.error("Error executing: " + command.toString()); + throw e; + } catch (IOException e) { + e.fillInStackTrace(); + logger.error("Error executing: " + command.toString()); + throw e; + } + } + + private void runScript(Connection conn, Reader reader , String dbName) throws IOException, SQLException { + StringBuffer command = null; + String sql = ""; + String appKey = dbName.substring(dbName.lastIndexOf("_")+1, dbName.length()); + try { + LineNumberReader lineReader = new LineNumberReader(reader); + String line = null; + while ((line = lineReader.readLine()) != null) { + if (command == null) { + command = new StringBuffer(); + } + String trimmedLine = line.trim(); + if (trimmedLine.startsWith("--")) { + logger.info(trimmedLine); + } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("//")) { + // Do nothing + } else if (trimmedLine.length() < 1 || trimmedLine.startsWith("--")) { + // Do nothing + + } else if (trimmedLine.startsWith("delimiter")) { + String newDelimiter = trimmedLine.split(" ")[1]; + this.setDelimiter(newDelimiter, fullLineDelimiter); + + } else if (!fullLineDelimiter && trimmedLine.endsWith(getDelimiter()) + || fullLineDelimiter && trimmedLine.equals(getDelimiter())) { + command.append(line.substring(0, line.lastIndexOf(getDelimiter()))); + command.append(" "); + Statement statement = conn.createStatement(); + + // logger.info(command.toString()); + + sql = command.toString().replaceAll("\\{\\{APPDB\\}\\}", dbName); + boolean hasResults = false; + logger.info("sql:"+sql); + if (stopOnError) { + hasResults = statement.execute(sql); + } else { + try { + statement.execute(sql); + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw e; + } + } + + ResultSet rs = statement.getResultSet(); + if (hasResults && rs != null) { + ResultSetMetaData md = rs.getMetaData(); + int cols = md.getColumnCount(); + for (int i = 0; i < cols; i++) { + String name = md.getColumnLabel(i); + logger.info(name + "\t"); + } + logger.info(""); + while (rs.next()) { + for (int i = 0; i < cols; i++) { + String value = rs.getString(i); + logger.info(value + "\t"); + } + logger.info(""); + } + } + + command = null; + try { + statement.close(); + } catch (Exception e) { + // Ignore to workaround a bug in Jakarta DBCP + } + Thread.yield(); + } else { + command.append(line); + command.append(" "); + } + } + + } catch (SQLException e) { + logger.error("Error executing: " + sql); + throw e; + } catch (IOException e) { + e.fillInStackTrace(); + logger.error("Error executing: " + sql); + throw e; + } + } + + private String getDelimiter() { + return delimiter; + } + +} \ No newline at end of file diff --git a/escheduler-common/src/main/resources/common/common.properties b/escheduler-common/src/main/resources/common/common.properties index c501ad0d1a..1cb995ba0e 100644 --- a/escheduler-common/src/main/resources/common/common.properties +++ b/escheduler-common/src/main/resources/common/common.properties @@ -18,7 +18,6 @@ hdfs.startup.state=true # system env path. self configuration, please make sure the directory and file exists and have read write execute permissions escheduler.env.path=/opt/.escheduler_env.sh -escheduler.env.py=/opt/escheduler_env.py #resource.view.suffixs resource.view.suffixs=txt,log,sh,conf,cfg,py,java,sql,hql,xml diff --git a/escheduler-dao/pom.xml b/escheduler-dao/pom.xml index 87b5765410..cf0eb1dc1c 100644 --- a/escheduler-dao/pom.xml +++ b/escheduler-dao/pom.xml @@ -4,7 +4,7 @@ cn.analysys escheduler - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT escheduler-dao escheduler-dao diff --git a/escheduler-dao/readme.txt b/escheduler-dao/readme.txt index d3659dc68a..9c8471ad95 100644 --- a/escheduler-dao/readme.txt +++ b/escheduler-dao/readme.txt @@ -1 +1,32 @@ -alter table t_escheduler_user add queue varchar(64); \ No newline at end of file +-- 用户指定队列 +alter table t_escheduler_user add queue varchar(64); + +-- 访问token +CREATE TABLE `t_escheduler_access_token` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) DEFAULT NULL COMMENT '用户id', + `token` varchar(64) DEFAULT NULL COMMENT 'token令牌', + `expire_time` datetime DEFAULT NULL COMMENT 'token有效结束时间', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; + +CREATE TABLE `escheduler`.`t_escheduler_error_command` ( + `id` int(11) NOT NULL COMMENT '主键', + `command_type` tinyint(4) NULL DEFAULT NULL COMMENT '命令类型:0 启动工作流,1 从当前节点开始执行,2 恢复被容错的工作流,3 恢复暂停流程 4 从失败节点开始执行', + `executor_id` int(11) NULL DEFAULT NULL COMMENT '命令执行者', + `process_definition_id` int(11) NULL DEFAULT NULL COMMENT '流程定义id', + `command_param` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '命令的参数(json格式)', + `task_depend_type` tinyint(4) NULL DEFAULT NULL COMMENT '节点依赖类型', + `failure_strategy` tinyint(4) NULL DEFAULT 0 COMMENT '失败策略:0结束,1继续', + `warning_type` tinyint(4) NULL DEFAULT 0 COMMENT '告警类型', + `warning_group_id` int(11) NULL DEFAULT NULL COMMENT '告警组', + `schedule_time` datetime(0) NULL DEFAULT NULL COMMENT '预期运行时间', + `start_time` datetime(0) NULL DEFAULT NULL COMMENT '开始时间', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `dependence` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '依赖字段', + `process_instance_priority` int(11) NULL DEFAULT NULL COMMENT '流程实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest', + `message` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '执行信息', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java b/escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java index e6156a0f4c..ec458f98a9 100644 --- a/escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java @@ -88,6 +88,9 @@ public class ProcessDao extends AbstractBaseDao { @Autowired private ResourceMapper resourceMapper; + @Autowired + private ErrorCommandMapper errorCommandMapper; + /** * task queue impl */ @@ -139,6 +142,7 @@ public class ProcessDao extends AbstractBaseDao { if(processInstance == null){ logger.error("scan command, command parameter is error: %s", command.toString()); delCommandByid(command.getId()); + saveErrorCommand(command, "process instance is null"); return null; }else if(!checkThreadNum(command, validThreadNum)){ logger.info("there is not enough thread for this command: {}",command.toString() ); @@ -153,11 +157,18 @@ public class ProcessDao extends AbstractBaseDao { } }catch (Exception e){ logger.error("scan command error ", e); + saveErrorCommand(command, e.toString()); delCommandByid(command.getId()); } return null; } + private void saveErrorCommand(Command command, String message) { + + ErrorCommand errorCommand = new ErrorCommand(command, message); + this.errorCommandMapper.insert(errorCommand); + } + /** * set process waiting thread * @param command diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapper.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapper.java new file mode 100644 index 0000000000..aa196561b5 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapper.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.mapper; + +import cn.escheduler.common.enums.UserType; +import cn.escheduler.dao.model.AccessToken; +import cn.escheduler.dao.model.User; +import org.apache.ibatis.annotations.*; +import org.apache.ibatis.type.EnumOrdinalTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.Timestamp; +import java.util.List; + +public interface AccessTokenMapper { + + /** + * insert accessToken + * @param accessToken + * @return + */ + @InsertProvider(type = AccessTokenMapperProvider.class, method = "insert") + @Options(useGeneratedKeys = true,keyProperty = "accessToken.id") + @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "accessToken.id", before = false, resultType = int.class) + int insert(@Param("accessToken") AccessToken accessToken); + + + /** + * delete accessToken + * @param accessTokenId + * @return + */ + @DeleteProvider(type = AccessTokenMapperProvider.class, method = "delete") + int delete(@Param("accessTokenId") int accessTokenId); + + + /** + * update accessToken + * + * @param accessToken + * @return + */ + @UpdateProvider(type = AccessTokenMapperProvider.class, method = "update") + int update(@Param("accessToken") AccessToken accessToken); + + + /** + * query access token list paging + * @param searchVal + * @param offset + * @param pageSize + * @return + */ + @Results(value = {@Result(property = "id", column = "id", id = true, javaType = Integer.class, jdbcType = JdbcType.INTEGER), + @Result(property = "userId", column = "user_id", javaType = Integer.class, jdbcType = JdbcType.INTEGER), + @Result(property = "token", column = "token", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR), + @Result(property = "expireTime", column = "expire_time", javaType = Timestamp.class, jdbcType = JdbcType.DATE), + @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 = AccessTokenMapperProvider.class, method = "queryAccessTokenPaging") + List queryAccessTokenPaging(@Param("searchVal") String searchVal, + @Param("offset") Integer offset, + @Param("pageSize") Integer pageSize); + + /** + * count access token by search value + * @param searchVal + * @return + */ + @SelectProvider(type = AccessTokenMapperProvider.class, method = "countAccessTokenPaging") + Integer countAccessTokenPaging(@Param("searchVal") String searchVal); +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapperProvider.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapperProvider.java new file mode 100644 index 0000000000..a2b69d5cc1 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/AccessTokenMapperProvider.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.mapper; + +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.jdbc.SQL; + +import java.util.Map; + +/** + * access token mapper provider + * + */ +public class AccessTokenMapperProvider { + + private static final String TABLE_NAME = "t_escheduler_access_token"; + + /** + * insert accessToken + * + * @param parameter + * @return + */ + public String insert(Map parameter) { + return new SQL() { + { + INSERT_INTO(TABLE_NAME); + VALUES("`user_id`", "#{accessToken.userId}"); + VALUES("`token`", "#{accessToken.token}"); + VALUES("`expire_time`", "#{accessToken.expireTime}");; + VALUES("`create_time`", "#{accessToken.createTime}"); + VALUES("`update_time`", "#{accessToken.updateTime}"); + } + }.toString(); + } + + /** + * delete accessToken + * + * @param parameter + * @return + */ + public String delete(Map parameter) { + return new SQL() { + { + DELETE_FROM(TABLE_NAME); + + WHERE("`id`=#{accessTokenId}"); + } + }.toString(); + } + + /** + * update accessToken + * + * @param parameter + * @return + */ + public String update(Map parameter) { + return new SQL() { + { + UPDATE(TABLE_NAME); + + SET("`user_id`=#{accessToken.userId}"); + SET("`token`=#{accessToken.token}"); + SET("`expire_time`=#{accessToken.expireTime}"); + SET("`update_time`=#{accessToken.updateTime}"); + + WHERE("`id`=#{user.id}"); + } + }.toString(); + } + + + /** + * count user number by search value + * @param parameter + * @return + */ + public String countAccessTokenPaging(Map parameter) { + return new SQL() {{ + SELECT("count(0)"); + FROM(TABLE_NAME + " t,t_escheduler_user u"); + Object searchVal = parameter.get("searchVal"); + WHERE("u.id = t.user_id"); + if(searchVal != null && StringUtils.isNotEmpty(searchVal.toString())){ + WHERE(" u.user_name like concat('%', #{searchVal}, '%')"); + } + }}.toString(); + } + + /** + * query user list paging + * @param parameter + * @return + */ + public String queryAccessTokenPaging(Map parameter) { + return new SQL() { + { + SELECT("t.*,u.user_name"); + FROM(TABLE_NAME + " t,t_escheduler_user u"); + Object searchVal = parameter.get("searchVal"); + WHERE("u.id = t.user_id"); + if(searchVal != null && StringUtils.isNotEmpty(searchVal.toString())){ + WHERE(" u.user_name like concat('%', #{searchVal}, '%') "); + } + ORDER_BY(" t.update_time desc limit #{offset},#{pageSize} "); + } + }.toString(); + + } + + + + +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapper.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapper.java new file mode 100644 index 0000000000..5c702acf79 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapper.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.mapper; + +import cn.escheduler.common.enums.*; +import cn.escheduler.dao.model.Command; +import cn.escheduler.dao.model.ErrorCommand; +import org.apache.ibatis.annotations.*; +import org.apache.ibatis.type.EnumOrdinalTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.Timestamp; +import java.util.List; + +/** + * command mapper + */ +public interface ErrorCommandMapper { + + /** + * inert error command + * @param errorCommand + * @return + */ + @InsertProvider(type = ErrorCommandMapperProvider.class, method = "insert") + @Options(useGeneratedKeys = true,keyProperty = "errorCommand.id") + @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "errorCommand.id", before = false, resultType = int.class) + int insert(@Param("errorCommand") ErrorCommand errorCommand); + + +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapperProvider.java b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapperProvider.java new file mode 100644 index 0000000000..d5c3f992c7 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ErrorCommandMapperProvider.java @@ -0,0 +1,41 @@ +package cn.escheduler.dao.mapper; + +import cn.escheduler.common.enums.*; +import cn.escheduler.common.utils.EnumFieldUtil; +import org.apache.ibatis.jdbc.SQL; + +import java.util.Map; + +public class ErrorCommandMapperProvider { + + + private static final String TABLE_NAME = "t_escheduler_error_command"; + + + /** + * inert command + * + * @param parameter + * @return + */ + public String insert(Map parameter) { + return new SQL() { + { + INSERT_INTO(TABLE_NAME); + VALUES("`command_type`", EnumFieldUtil.genFieldStr("errorCommand.commandType", CommandType.class)); + VALUES("`process_definition_id`", "#{errorCommand.processDefinitionId}"); + VALUES("`executor_id`", "#{errorCommand.executorId}"); + VALUES("`command_param`", "#{errorCommand.commandParam}"); + VALUES("`task_depend_type`", EnumFieldUtil.genFieldStr("errorCommand.taskDependType", TaskDependType.class)); + VALUES("`failure_strategy`", EnumFieldUtil.genFieldStr("errorCommand.failureStrategy", FailureStrategy.class)); + VALUES("`warning_type`", EnumFieldUtil.genFieldStr("errorCommand.warningType", WarningType.class)); + VALUES("`process_instance_priority`", EnumFieldUtil.genFieldStr("errorCommand.processInstancePriority", Priority.class)); + VALUES("`warning_group_id`", "#{errorCommand.warningGroupId}"); + VALUES("`schedule_time`", "#{errorCommand.scheduleTime}"); + VALUES("`update_time`", "#{errorCommand.updateTime}"); + VALUES("`start_time`", "#{errorCommand.startTime}"); + VALUES("`message`", "#{errorCommand.message}"); + } + }.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 cd74aa9970..21415c758e 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 @@ -231,4 +231,24 @@ public interface UserMapper { */ @SelectProvider(type = UserMapperProvider.class, method = "queryQueueByProcessInstanceId") String queryQueueByProcessInstanceId(@Param("processInstanceId") int processInstanceId); + + + /** + * query user by token + * @param token + * @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 = "queryUserByToken") + User queryUserByToken(@Param("token") String token); } 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 d3f3f677bd..8496687c39 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 @@ -265,4 +265,20 @@ public class UserMapperProvider { }.toString(); } + + /** + * query user by id + * @param parameter + * @return + */ + public String queryUserByToken(Map parameter) { + return new SQL() { + { + SELECT("u.*"); + FROM(TABLE_NAME + " u ,t_escheduler_access_token t"); + WHERE(" u.id = t.user_id and token=#{token}"); + } + }.toString(); + } + } diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/model/AccessToken.java b/escheduler-dao/src/main/java/cn/escheduler/dao/model/AccessToken.java new file mode 100644 index 0000000000..559fe45a96 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/model/AccessToken.java @@ -0,0 +1,126 @@ +package cn.escheduler.dao.model; + +import java.util.Date; + +/* + * 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. + */ +public class AccessToken { + + /** + * id + */ + private int id; + + /** + * user id + */ + private int userId; + + /** + * user name + */ + private String userName; + + /** + * user token + */ + private String token; + + /** + * token expire time + */ + private Date expireTime; + + /** + * create time + */ + private Date createTime; + + /** + * update time + */ + private Date updateTime; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Date getExpireTime() { + return expireTime; + } + + public void setExpireTime(Date expireTime) { + this.expireTime = expireTime; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + return "AccessToken{" + + "id=" + id + + ", userId=" + userId + + ", userName='" + userName + '\'' + + ", token='" + token + '\'' + + ", expireTime=" + expireTime + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + '}'; + } +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/model/ErrorCommand.java b/escheduler-dao/src/main/java/cn/escheduler/dao/model/ErrorCommand.java new file mode 100644 index 0000000000..2128455703 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/model/ErrorCommand.java @@ -0,0 +1,275 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.model; + +import cn.escheduler.common.enums.*; + +import java.util.Date; + +/** + * command + */ +public class ErrorCommand { + + /** + * id + */ + private int id; + + /** + * command type + */ + private CommandType commandType; + + /** + * process definition id + */ + private int processDefinitionId; + + /** + * executor id + */ + private int executorId; + + /** + * command parameter, format json + */ + private String commandParam; + + /** + * task depend type + */ + private TaskDependType taskDependType; + + /** + * failure strategy + */ + private FailureStrategy failureStrategy; + + /** + * warning type + */ + private WarningType warningType; + + /** + * warning group id + */ + private Integer warningGroupId; + + /** + * schedule time + */ + private Date scheduleTime; + + /** + * start time + */ + private Date startTime; + + /** + * process instance priority + */ + private Priority processInstancePriority; + + /** + * update time + */ + private Date updateTime; + + /** + * 执行信息 + */ + private String message; + + + public ErrorCommand(Command command, String message){ + this.commandType = command.getCommandType(); + this.executorId = command.getExecutorId(); + this.processDefinitionId = command.getProcessDefinitionId(); + this.commandParam = command.getCommandParam(); + this.warningType = command.getWarningType(); + this.warningGroupId = command.getWarningGroupId(); + this.scheduleTime = command.getScheduleTime(); + this.taskDependType = command.getTaskDependType(); + this.failureStrategy = command.getFailureStrategy(); + this.startTime = command.getStartTime(); + this.updateTime = command.getUpdateTime(); + this.processInstancePriority = command.getProcessInstancePriority(); + this.message = message; + } + + public ErrorCommand( + CommandType commandType, + TaskDependType taskDependType, + FailureStrategy failureStrategy, + int executorId, + int processDefinitionId, + String commandParam, + WarningType warningType, + int warningGroupId, + Date scheduleTime, + Priority processInstancePriority, + String message){ + this.commandType = commandType; + this.executorId = executorId; + this.processDefinitionId = processDefinitionId; + this.commandParam = commandParam; + this.warningType = warningType; + this.warningGroupId = warningGroupId; + this.scheduleTime = scheduleTime; + this.taskDependType = taskDependType; + this.failureStrategy = failureStrategy; + this.startTime = new Date(); + this.updateTime = new Date(); + this.processInstancePriority = processInstancePriority; + this.message = message; + } + + + public TaskDependType getTaskDependType() { + return taskDependType; + } + + public void setTaskDependType(TaskDependType taskDependType) { + this.taskDependType = taskDependType; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public CommandType getCommandType() { + return commandType; + } + + public void setCommandType(CommandType commandType) { + this.commandType = commandType; + } + + public int getProcessDefinitionId() { + return processDefinitionId; + } + + public void setProcessDefinitionId(int processDefinitionId) { + this.processDefinitionId = processDefinitionId; + } + + + public FailureStrategy getFailureStrategy() { + return failureStrategy; + } + + public void setFailureStrategy(FailureStrategy failureStrategy) { + this.failureStrategy = failureStrategy; + } + + public void setCommandParam(String commandParam) { + this.commandParam = commandParam; + } + + public String getCommandParam() { + return commandParam; + } + + public WarningType getWarningType() { + return warningType; + } + + public void setWarningType(WarningType warningType) { + this.warningType = warningType; + } + + public Integer getWarningGroupId() { + return warningGroupId; + } + + public void setWarningGroupId(Integer warningGroupId) { + this.warningGroupId = warningGroupId; + } + + public Date getScheduleTime() { + return scheduleTime; + } + + public void setScheduleTime(Date scheduleTime) { + this.scheduleTime = scheduleTime; + } + + public Date getStartTime() { + return startTime; + } + + public void setStartTime(Date startTime) { + this.startTime = startTime; + } + + public int getExecutorId() { + return executorId; + } + + public void setExecutorId(int executorId) { + this.executorId = executorId; + } + + public Priority getProcessInstancePriority() { + return processInstancePriority; + } + + public void setProcessInstancePriority(Priority processInstancePriority) { + this.processInstancePriority = processInstancePriority; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "Command{" + + "id=" + id + + ", commandType=" + commandType + + ", processDefinitionId=" + processDefinitionId + + ", executorId=" + executorId + + ", commandParam='" + commandParam + '\'' + + ", taskDependType=" + taskDependType + + ", failureStrategy=" + failureStrategy + + ", warningType=" + warningType + + ", warningGroupId=" + warningGroupId + + ", scheduleTime=" + scheduleTime + + ", startTime=" + startTime + + ", processInstancePriority=" + processInstancePriority + + ", updateTime=" + updateTime + + ", message=" + message + + '}'; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/EschedulerManager.java b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/EschedulerManager.java new file mode 100644 index 0000000000..34f07fbb29 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/EschedulerManager.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.upgrade; + +import cn.escheduler.common.utils.SchemaUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * upgrade manager + */ +public class EschedulerManager { + private static final Logger logger = LoggerFactory.getLogger(EschedulerManager.class); + UpgradeDao upgradeDao = UpgradeDao.getInstance(); + + public void initEscheduler() { + this.initEschedulerSchema(); + } + + public void initEschedulerSchema() { + + logger.info("Start initializing the ark manager mysql table structure"); + upgradeDao.initEschedulerSchema(); + } + + + /** + * upgrade escheduler + */ + public void upgradeEscheduler() throws Exception{ + + // Gets a list of all upgrades + List schemaList = SchemaUtils.getAllSchemaList(); + if(schemaList == null || schemaList.size() == 0) { + logger.info("There is no schema to upgrade!"); + }else { + + String version = ""; + // The target version of the upgrade + String schemaVersion = ""; + for(String schemaDir : schemaList) { + // Gets the version of the current system + if (upgradeDao.isExistsTable("t_escheduler_version")) { + version = upgradeDao.getCurrentVersion(); + }else { + version = "1.0.0"; + } + + schemaVersion = schemaDir.split("_")[0]; + if(SchemaUtils.isAGreatVersion(schemaVersion , version)) { + + logger.info("upgrade escheduler metadata version from " + version + " to " + schemaVersion); + + + logger.info("Begin upgrading escheduler's mysql table structure"); + upgradeDao.upgradeEscheduler(schemaDir); + + } + + } + } + + // Assign the value of the version field in the version table to the version of the product + upgradeDao.updateVersion(SchemaUtils.getSoftVersion()); + } +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/UpgradeDao.java b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/UpgradeDao.java new file mode 100644 index 0000000000..f4fb307f05 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/UpgradeDao.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.upgrade; + +import cn.escheduler.common.utils.MysqlUtil; +import cn.escheduler.common.utils.ScriptRunner; +import cn.escheduler.dao.AbstractBaseDao; +import cn.escheduler.dao.datasource.ConnectionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class UpgradeDao extends AbstractBaseDao { + + public static final Logger logger = LoggerFactory.getLogger(UpgradeDao.class); + private static final String T_VERSION_NAME = "t_escheduler_version"; + + @Override + protected void init() { + + } + + private static class UpgradeDaoHolder { + private static final UpgradeDao INSTANCE = new UpgradeDao(); + } + + private UpgradeDao() { + } + + public static final UpgradeDao getInstance() { + return UpgradeDaoHolder.INSTANCE; + } + + + + public void initEschedulerSchema() { + + // Execute the escheduler DDL, it cannot be rolled back + runInitEschedulerDDL(); + + // Execute the escheduler DML, it can be rolled back + runInitEschedulerDML(); + + } + + private void runInitEschedulerDML() { + Connection conn = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + conn.setAutoCommit(false); + // 执行escheduler_dml.sql脚本,导入escheduler相关的数据 + // Execute the ark_manager_dml.sql script to import the data related to escheduler + + ScriptRunner initScriptRunner = new ScriptRunner(conn, false, true); + Reader initSqlReader = new FileReader(new File("sql/create/release-1.0.0_schema/mysql/escheduler_dml.sql")); + initScriptRunner.runScript(initSqlReader); + + conn.commit(); + } catch (IOException e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (Exception e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } finally { + MysqlUtil.realeaseResource(null, null, conn); + + } + + } + + private void runInitEschedulerDDL() { + Connection conn = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + // Execute the escheduler_ddl.sql script to create the table structure of escheduler + ScriptRunner initScriptRunner = new ScriptRunner(conn, true, true); + Reader initSqlReader = new FileReader(new File("sql/create/release-1.0.0_schema/mysql/escheduler_ddl.sql")); + initScriptRunner.runScript(initSqlReader); + + } catch (IOException e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (Exception e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } finally { + MysqlUtil.realeaseResource(null, null, conn); + + } + + } + + + public boolean isExistsTable(String tableName) { + Connection conn = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + ResultSet rs = conn.getMetaData().getTables(null, null, tableName, null); + if (rs.next()) { + return true; + } else { + return false; + } + + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } finally { + MysqlUtil.realeaseResource(null, null, conn); + + } + + } + + + public String getCurrentVersion() { + String sql = String.format("select version from %s",T_VERSION_NAME); + Connection conn = null; + ResultSet rs = null; + PreparedStatement pstmt = null; + String version = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + pstmt = conn.prepareStatement(sql); + rs = pstmt.executeQuery(); + + if (rs.next()) { + version = rs.getString(1); + } + + return version; + + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException("sql: " + sql, e); + } finally { + MysqlUtil.realeaseResource(rs, pstmt, conn); + + } + } + + + public void upgradeEscheduler(String schemaDir) { + + upgradeEschedulerDDL(schemaDir); + + upgradeEschedulerDML(schemaDir); + + } + + private void upgradeEschedulerDML(String schemaDir) { + String schemaVersion = schemaDir.split("_")[0]; + String mysqlSQLFilePath = "sql/upgrade/" + schemaDir + "/mysql/escheduler_dml.sql"; + Connection conn = null; + PreparedStatement pstmt = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + conn.setAutoCommit(false); + // Execute the upgraded escheduler dml + ScriptRunner scriptRunner = new ScriptRunner(conn, false, true); + Reader sqlReader = new FileReader(new File(mysqlSQLFilePath)); + scriptRunner.runScript(sqlReader); + if (isExistsTable(T_VERSION_NAME)) { + // Change version in the version table to the new version + String upgradeSQL = String.format("update %s set version = ?",T_VERSION_NAME); + pstmt = conn.prepareStatement(upgradeSQL); + pstmt.setString(1, schemaVersion); + pstmt.executeUpdate(); + } + conn.commit(); + } catch (FileNotFoundException e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException("sql file not found ", e); + } catch (IOException e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (SQLException e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (Exception e) { + try { + conn.rollback(); + } catch (SQLException e1) { + logger.error(e1.getMessage(),e1); + } + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } finally { + MysqlUtil.realeaseResource(null, pstmt, conn); + } + + } + + private void upgradeEschedulerDDL(String schemaDir) { + String mysqlSQLFilePath = "sql/upgrade/" + schemaDir + "/mysql/escheduler_ddl.sql"; + Connection conn = null; + PreparedStatement pstmt = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + String dbName = conn.getCatalog(); + logger.info(dbName); + conn.setAutoCommit(true); + // Execute the escheduler ddl.sql for the upgrade + ScriptRunner scriptRunner = new ScriptRunner(conn, true, true); + Reader sqlReader = new FileReader(new File(mysqlSQLFilePath)); + scriptRunner.runScript(sqlReader); + + } catch (FileNotFoundException e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException("sql file not found ", e); + } catch (IOException e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (SQLException e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } catch (Exception e) { + + logger.error(e.getMessage(),e); + throw new RuntimeException(e.getMessage(),e); + } finally { + MysqlUtil.realeaseResource(null, pstmt, conn); + } + + } + + + + public void updateVersion(String version) { + // Change version in the version table to the new version + String upgradeSQL = String.format("update %s set version = ?",T_VERSION_NAME); + PreparedStatement pstmt = null; + Connection conn = null; + try { + conn = ConnectionFactory.getDataSource().getConnection(); + pstmt = conn.prepareStatement(upgradeSQL); + pstmt.setString(1, version); + pstmt.executeUpdate(); + + } catch (SQLException e) { + logger.error(e.getMessage(),e); + throw new RuntimeException("sql: " + upgradeSQL, e); + } finally { + MysqlUtil.realeaseResource(null, pstmt, conn); + } + + } + +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/CreateEscheduler.java b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/CreateEscheduler.java new file mode 100644 index 0000000000..012c32bb9a --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/CreateEscheduler.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.upgrade.shell; + +import cn.escheduler.dao.upgrade.EschedulerManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * init escheduler + * + */ +public class CreateEscheduler { + + private static final Logger logger = LoggerFactory.getLogger(CreateEscheduler.class); + + public static void main(String[] args) { + Thread.currentThread().setName("manager-CreateEscheduler"); + EschedulerManager eschedulerManager = new EschedulerManager(); + eschedulerManager.initEscheduler(); + logger.info("init escheduler finished"); + try { + eschedulerManager.upgradeEscheduler(); + logger.info("upgrade escheduler finished"); + } catch (Exception e) { + logger.error("upgrade escheduler failed",e); + } + + } +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/InitEscheduler.java b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/InitEscheduler.java new file mode 100644 index 0000000000..e88bb1e3f1 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/InitEscheduler.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.upgrade.shell; + +import cn.escheduler.dao.upgrade.EschedulerManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * init escheduler + * + */ +public class InitEscheduler { + + private static final Logger logger = LoggerFactory.getLogger(InitEscheduler.class); + + public static void main(String[] args) { + Thread.currentThread().setName("manager-InitEscheduler"); + EschedulerManager eschedulerManager = new EschedulerManager(); + eschedulerManager.initEscheduler(); + logger.info("init escheduler finished"); + + } +} diff --git a/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/UpgradeEscheduler.java b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/UpgradeEscheduler.java new file mode 100644 index 0000000000..e73a1162c2 --- /dev/null +++ b/escheduler-dao/src/main/java/cn/escheduler/dao/upgrade/shell/UpgradeEscheduler.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.upgrade.shell; + +import cn.escheduler.dao.upgrade.EschedulerManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * upgrade escheduler database + */ +public class UpgradeEscheduler { + private static final Logger logger = LoggerFactory.getLogger(UpgradeEscheduler.class); + + public static void main(String[] args) { + Thread.currentThread().setName("manager-UpgradeEscheduler"); + + EschedulerManager eschedulerManager = new EschedulerManager(); + try { + eschedulerManager.upgradeEscheduler(); + logger.info("upgrade escheduler finished"); + } catch (Exception e) { + logger.error(e.getMessage(),e); + logger.info("Upgrade escheduler failed"); + throw new RuntimeException(e); + } + + + } + + + +} diff --git a/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/AccessTokenMapperTest.java b/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/AccessTokenMapperTest.java new file mode 100644 index 0000000000..d5dfdcb1ec --- /dev/null +++ b/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/AccessTokenMapperTest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package cn.escheduler.dao.mapper; + +import cn.escheduler.common.utils.EncryptionUtils; +import cn.escheduler.dao.datasource.ConnectionFactory; +import cn.escheduler.dao.model.AccessToken; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.util.Date; +import java.util.List; + + + +public class AccessTokenMapperTest { + + + AccessTokenMapper accessTokenMapper; + + @Before + public void before(){ + accessTokenMapper = ConnectionFactory.getSqlSession().getMapper(AccessTokenMapper.class); + } + + @Test + public void testInsert(){ + AccessToken accessToken = new AccessToken(); + accessToken.setUserId(10); + accessToken.setExpireTime(new Date()); + accessToken.setToken("ssssssssssssssssssssssssss"); + accessToken.setCreateTime(new Date()); + accessToken.setUpdateTime(new Date()); + accessTokenMapper.insert(accessToken); + } + + @Test + public void testListPaging(){ + Integer count = accessTokenMapper.countAccessTokenPaging(""); + Assert.assertEquals(count, (Integer) 5); + + List accessTokenList = accessTokenMapper.queryAccessTokenPaging("", 0, 2); + Assert.assertEquals(accessTokenList.size(), 5); + } + + +} diff --git a/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java b/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java index c8e5584236..adede0c329 100644 --- a/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java +++ b/escheduler-dao/src/test/java/cn/escheduler/dao/mapper/UserMapperTest.java @@ -66,4 +66,10 @@ public class UserMapperTest { Assert.assertEquals(queue, "ait"); } + @Test + public void testQueryUserByToken(){ + User user = userMapper.queryUserByToken("ad9e8fccfc11bd18bb45aa994568b8ef"); + Assert.assertEquals(user.getUserName(), "qiaozhanwei"); + } + } diff --git a/escheduler-rpc/pom.xml b/escheduler-rpc/pom.xml index e869ca3a8b..5c2b998fdb 100644 --- a/escheduler-rpc/pom.xml +++ b/escheduler-rpc/pom.xml @@ -4,7 +4,7 @@ escheduler cn.analysys - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT 4.0.0 diff --git a/escheduler-server/pom.xml b/escheduler-server/pom.xml index cb93089689..c3b8b6ca15 100644 --- a/escheduler-server/pom.xml +++ b/escheduler-server/pom.xml @@ -3,7 +3,7 @@ escheduler cn.analysys - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT escheduler-server escheduler-server diff --git a/escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java b/escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java index 6a28e1bbdf..64e5b57498 100644 --- a/escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java +++ b/escheduler-server/src/main/java/cn/escheduler/server/worker/runner/FetchTaskThread.java @@ -172,7 +172,7 @@ public class FetchTaskThread implements Runnable{ FileUtils.createWorkDirAndUserIfAbsent(execLocalPath, processInstance.getTenantCode(), logger); - + logger.info("task : {} ready to submit to task scheduler thread",taskId); // submit task workerExecService.submit(new TaskScheduleThread(taskInstance, processDao)); } diff --git a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java index 6e4d015734..94caffe596 100644 --- a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java +++ b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/PythonCommandExecutor.java @@ -16,12 +16,13 @@ */ package cn.escheduler.server.worker.task; +import cn.escheduler.common.Constants; import cn.escheduler.common.utils.FileUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -34,6 +35,8 @@ import java.util.function.Consumer; */ public class PythonCommandExecutor extends AbstractCommandExecutor { + private static final Logger logger = LoggerFactory.getLogger(PythonCommandExecutor.class); + public static final String PYTHON = "python"; @@ -63,27 +66,13 @@ public class PythonCommandExecutor extends AbstractCommandExecutor { */ @Override protected void createCommandFileIfNotExists(String execCommand, String commandFile) throws IOException { - logger.info("proxy user:{}, work dir:{}", tenantCode, taskDir); + logger.info("tenant :{}, work dir:{}", tenantCode, taskDir); if (!Files.exists(Paths.get(commandFile))) { logger.info("generate command file:{}", commandFile); StringBuilder sb = new StringBuilder(200); sb.append("#-*- encoding=utf8 -*-\n"); - sb.append("import os,sys\n"); - sb.append("BASEDIR = os.path.dirname(os.path.realpath(__file__))\n"); - sb.append("os.chdir(BASEDIR)\n"); - - if (StringUtils.isNotEmpty(envFile)) { - String[] envArray = envFile.split("\\."); - if(envArray.length == 2){ - String path = envArray[0]; - logger.info("path:"+path); - int index = path.lastIndexOf("/"); - sb.append(String.format("sys.path.append('%s')\n",path.substring(0,index))); - sb.append(String.format("import %s\n",path.substring(index+1))); - } - } sb.append("\n\n"); sb.append(String.format("import py_%s_node\n",taskAppId)); @@ -96,7 +85,14 @@ public class PythonCommandExecutor extends AbstractCommandExecutor { @Override protected String commandType() { - return PYTHON; + + String envPath = System.getProperty("user.dir") + Constants.SINGLE_SLASH + "conf"+ + Constants.SINGLE_SLASH +"env" + Constants.SINGLE_SLASH + Constants.ESCHEDULER_ENV_SH; + String pythonHome = getPythonHome(envPath); + if (StringUtils.isEmpty(pythonHome)){ + return PYTHON; + } + return pythonHome; } @Override @@ -109,4 +105,45 @@ public class PythonCommandExecutor extends AbstractCommandExecutor { return true; } + + /** + * get python home + * @param envPath + * @return + */ + private static String getPythonHome(String envPath){ + BufferedReader br = null; + String line = null; + StringBuilder sb = new StringBuilder(); + try { + br = new BufferedReader(new InputStreamReader(new FileInputStream(envPath))); + while ((line = br.readLine()) != null){ + if (line.contains(Constants.PYTHON_HOME)){ + sb.append(line); + break; + } + } + String result = sb.toString(); + if (org.apache.commons.lang.StringUtils.isEmpty(result)){ + return null; + } + String[] arrs = result.split("="); + if (arrs.length == 2){ + return arrs[1]; + } + + }catch (IOException e){ + logger.error("read file failed : " + e.getMessage(),e); + }finally { + try { + if (br != null){ + br.close(); + } + } catch (IOException e) { + logger.error(e.getMessage(),e); + } + } + return null; + } + } diff --git a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java index 2b7ae29b96..49d754404a 100644 --- a/escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java +++ b/escheduler-server/src/main/java/cn/escheduler/server/worker/task/python/PythonTask.java @@ -72,7 +72,7 @@ public class PythonTask extends AbstractTask { this.pythonProcessTask = new PythonCommandExecutor(this::logHandle, taskProps.getTaskDir(), taskProps.getTaskAppId(), - taskProps.getTenantCode(), CommonUtils.getPythonSystemEnvPath(), taskProps.getTaskStartTime(), + taskProps.getTenantCode(), null, taskProps.getTaskStartTime(), taskProps.getTaskTimeout(), logger); this.processDao = DaoFactory.getDaoInstance(ProcessDao.class); } diff --git a/escheduler-server/src/test/java/cn/escheduler/server/worker/EnvFileTest.java b/escheduler-server/src/test/java/cn/escheduler/server/worker/EnvFileTest.java new file mode 100644 index 0000000000..06e2b22678 --- /dev/null +++ b/escheduler-server/src/test/java/cn/escheduler/server/worker/EnvFileTest.java @@ -0,0 +1,65 @@ +package cn.escheduler.server.worker; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * Created by qiaozhanwei on 2019/4/15. + */ +public class EnvFileTest { + + private static final Logger logger = LoggerFactory.getLogger(EnvFileTest.class); + + public static void main(String[] args) { + String path = System.getProperty("user.dir")+"\\script\\env\\.escheduler_env.sh"; + String pythonHome = getPythonHome(path); + logger.info(pythonHome); + + } + + /** + * get python home + * @param path + * @return + */ + private static String getPythonHome(String path){ + BufferedReader br = null; + String line = null; + StringBuilder sb = new StringBuilder(); + try { + br = new BufferedReader(new InputStreamReader(new FileInputStream(path))); + while ((line = br.readLine()) != null){ + if (line.contains("PYTHON_HOME")){ + sb.append(line); + break; + } + } + String result = sb.toString(); + if (StringUtils.isEmpty(result)){ + return null; + } + String[] arrs = result.split("="); + if (arrs.length == 2){ + return arrs[1]; + } + + }catch (IOException e){ + logger.error("read file failed : " + e.getMessage(),e); + }finally { + try { + if (br != null){ + br.close(); + } + } catch (IOException e) { + logger.error(e.getMessage(),e); + } + } + return null; + } +} diff --git a/package.xml b/package.xml index d127415050..edba812b9a 100644 --- a/package.xml +++ b/package.xml @@ -37,7 +37,7 @@ sql - **/*.* + **/* ./sql diff --git a/pom.xml b/pom.xml index 83b2032985..56921834d5 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 cn.analysys escheduler - 1.0.0-SNAPSHOT + 1.0.1-SNAPSHOT pom escheduler http://maven.apache.org diff --git a/script/create_escheduler.sh b/script/create_escheduler.sh new file mode 100644 index 0000000000..dea3b07858 --- /dev/null +++ b/script/create_escheduler.sh @@ -0,0 +1,6 @@ +#!/bin/bash +workDir=`dirname $0` +workDir=`cd ${workDir};pwd` +echo "$workDir/lib" + +java -Xmx1G -cp "$workDir/../lib/*" cn.escheduler.dao.upgrade.shell.CreateEscheduler diff --git a/script/env/escheduler_env.py b/script/env/escheduler_env.py deleted file mode 100644 index e1d0afef4a..0000000000 --- a/script/env/escheduler_env.py +++ /dev/null @@ -1,12 +0,0 @@ -import os - -HADOOP_HOME="/opt/soft/hadoop" -SPARK_HOME1="/opt/soft/spark1" -SPARK_HOME2="/opt/soft/spark2" -PYTHON_HOME="/opt/soft/python" -JAVA_HOME="/opt/soft/java" -HIVE_HOME="/opt/soft/hive" -PATH=os.environ['PATH'] -PATH="%s/bin:%s/bin:%s/bin:%s/bin:%s/bin:%s/bin:%s"%(HIVE_HOME,HADOOP_HOME,SPARK_HOME1,SPARK_HOME2,JAVA_HOME,PYTHON_HOME,PATH) - -os.putenv('PATH','%s'%PATH) \ No newline at end of file diff --git a/script/upgrade_escheduler.sh b/script/upgrade_escheduler.sh new file mode 100644 index 0000000000..343dc5f1db --- /dev/null +++ b/script/upgrade_escheduler.sh @@ -0,0 +1,6 @@ +#!/bin/bash +workDir=`dirname $0` +workDir=`cd ${workDir};pwd` +echo "$workDir/lib" + +java -Xmx1G -cp "$workDir/../lib/*" cn.escheduler.dao.upgrade.shell.UpgradeEscheduler diff --git a/sql/create/release-1.0.0_schema/mysql/escheduler_ddl.sql b/sql/create/release-1.0.0_schema/mysql/escheduler_ddl.sql new file mode 100644 index 0000000000..796eed5842 --- /dev/null +++ b/sql/create/release-1.0.0_schema/mysql/escheduler_ddl.sql @@ -0,0 +1,601 @@ +/* +Navicat MySQL Data Transfer + +Source Server : xx.xx +Source Server Version : 50725 +Source Host : 192.168.xx.xx:3306 +Source Database : escheduler + +Target Server Type : MYSQL +Target Server Version : 50725 +File Encoding : 65001 + +Date: 2019-03-23 11:47:30 +*/ + +SET FOREIGN_KEY_CHECKS=0; + +-- ---------------------------- +-- Table structure for t_escheduler_alert +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_alert`; +CREATE TABLE `t_escheduler_alert` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `title` varchar(64) DEFAULT NULL COMMENT '消息标题', + `show_type` tinyint(4) DEFAULT NULL COMMENT '发送格式,0是TABLE,1是TEXT', + `content` text COMMENT '消息内容(可以是邮件,可以是短信。邮件是JSON Map存放,短信是字符串)', + `alert_type` tinyint(4) DEFAULT NULL COMMENT '0是邮件,1是短信', + `alert_status` tinyint(4) DEFAULT '0' COMMENT '0是待执行,1是执行成功,2执行失败', + `log` text COMMENT '执行日志', + `alertgroup_id` int(11) DEFAULT NULL COMMENT '发送组', + `receivers` text COMMENT '收件人', + `receivers_cc` text COMMENT '抄送人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_alertgroup +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_alertgroup`; +CREATE TABLE `t_escheduler_alertgroup` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `group_name` varchar(255) DEFAULT NULL COMMENT '组名称', + `group_type` tinyint(4) DEFAULT NULL COMMENT '组类型(邮件0,短信1...)', + `desc` varchar(255) DEFAULT NULL COMMENT '备注', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_command +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_command`; +CREATE TABLE `t_escheduler_command` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `command_type` tinyint(4) DEFAULT NULL COMMENT '命令类型:0 启动工作流,1 从当前节点开始执行,2 恢复被容错的工作流,3 恢复暂停流程,4 从失败节点开始执行,5 补数,6 调度,7 重跑,8 暂停,9 停止,10 恢复等待线程', + `process_definition_id` int(11) DEFAULT NULL COMMENT '流程定义id', + `command_param` text COMMENT '命令的参数(json格式)', + `task_depend_type` tinyint(4) DEFAULT NULL COMMENT '节点依赖类型:0 当前节点,1 向前执行,2 向后执行', + `failure_strategy` tinyint(4) DEFAULT '0' COMMENT '失败策略:0结束,1继续', + `warning_type` tinyint(4) DEFAULT '0' COMMENT '告警类型:0 不发,1 流程成功发,2 流程失败发,3 成功失败都发', + `warning_group_id` int(11) DEFAULT NULL COMMENT '告警组', + `schedule_time` datetime DEFAULT NULL COMMENT '预期运行时间', + `start_time` datetime DEFAULT NULL COMMENT '开始时间', + `executor_id` int(11) DEFAULT NULL COMMENT '执行用户id', + `dependence` varchar(255) DEFAULT NULL COMMENT '依赖字段', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `process_instance_priority` int(11) DEFAULT NULL COMMENT '流程实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_datasource +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_datasource`; +CREATE TABLE `t_escheduler_datasource` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(64) NOT NULL COMMENT '数据源名称', + `note` varchar(256) DEFAULT NULL COMMENT '描述', + `type` tinyint(4) NOT NULL COMMENT '数据源类型:0 mysql,1 postgresql,2 hive,3 spark', + `user_id` int(11) NOT NULL COMMENT '创建用户id', + `connection_params` text NOT NULL COMMENT '连接参数(json格式)', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_master_server +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_master_server`; +CREATE TABLE `t_escheduler_master_server` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `host` varchar(45) DEFAULT NULL COMMENT 'ip', + `port` int(11) DEFAULT NULL COMMENT '进程号', + `zk_directory` varchar(64) DEFAULT NULL COMMENT 'zk注册目录', + `res_info` varchar(256) DEFAULT NULL COMMENT '集群资源信息:json格式{"cpu":xxx,"memroy":xxx}', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `last_heartbeat_time` datetime DEFAULT NULL COMMENT '最后心跳时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_process_definition +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_process_definition`; +CREATE TABLE `t_escheduler_process_definition` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) DEFAULT NULL COMMENT '流程定义名称', + `version` int(11) DEFAULT NULL COMMENT '流程定义版本', + `release_state` tinyint(4) DEFAULT NULL COMMENT '流程定义的发布状态:0 未上线 1已上线', + `project_id` int(11) DEFAULT NULL COMMENT '项目id', + `user_id` int(11) DEFAULT NULL COMMENT '流程定义所属用户id', + `process_definition_json` longtext COMMENT '流程定义json串', + `desc` text COMMENT '流程定义描述', + `global_params` text COMMENT '全局参数', + `flag` tinyint(4) DEFAULT NULL COMMENT '流程是否可用\r\n:0 不可用\r\n,1 可用', + `locations` text COMMENT '节点坐标信息', + `connects` text COMMENT '节点连线信息', + `receivers` text COMMENT '收件人', + `receivers_cc` text COMMENT '抄送人', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `process_definition_index` (`project_id`,`id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_process_instance +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_process_instance`; +CREATE TABLE `t_escheduler_process_instance` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) DEFAULT NULL COMMENT '流程实例名称', + `process_definition_id` int(11) DEFAULT NULL COMMENT '流程定义id', + `state` tinyint(4) DEFAULT NULL COMMENT '流程实例状态:0 提交成功,1 正在运行,2 准备暂停,3 暂停,4 准备停止,5 停止,6 失败,7 成功,8 需要容错,9 kill,10 等待线程,11 等待依赖完成', + `recovery` tinyint(4) DEFAULT NULL COMMENT '流程实例容错标识:0 正常,1 需要被容错重启', + `start_time` datetime DEFAULT NULL COMMENT '流程实例开始时间', + `end_time` datetime DEFAULT NULL COMMENT '流程实例结束时间', + `run_times` int(11) DEFAULT NULL COMMENT '流程实例运行次数', + `host` varchar(45) DEFAULT NULL COMMENT '流程实例所在的机器', + `command_type` tinyint(4) DEFAULT NULL COMMENT '命令类型:0 启动工作流,1 从当前节点开始执行,2 恢复被容错的工作流,3 恢复暂停流程,4 从失败节点开始执行,5 补数,6 调度,7 重跑,8 暂停,9 停止,10 恢复等待线程', + `command_param` text COMMENT '命令的参数(json格式)', + `task_depend_type` tinyint(4) DEFAULT NULL COMMENT '节点依赖类型:0 当前节点,1 向前执行,2 向后执行', + `max_try_times` tinyint(4) DEFAULT '0' COMMENT '最大重试次数', + `failure_strategy` tinyint(4) DEFAULT '0' COMMENT '失败策略 0 失败后结束,1 失败后继续', + `warning_type` tinyint(4) DEFAULT '0' COMMENT '告警类型:0 不发,1 流程成功发,2 流程失败发,3 成功失败都发', + `warning_group_id` int(11) DEFAULT NULL COMMENT '告警组id', + `schedule_time` datetime DEFAULT NULL COMMENT '预期运行时间', + `command_start_time` datetime DEFAULT NULL COMMENT '开始命令时间', + `global_params` text COMMENT '全局参数(固化流程定义的参数)', + `process_instance_json` longtext COMMENT '流程实例json(copy的流程定义的json)', + `flag` tinyint(4) DEFAULT '1' COMMENT '是否可用,1 可用,0不可用', + `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `is_sub_process` int(11) DEFAULT '0' COMMENT '是否是子工作流 1 是,0 不是', + `executor_id` int(11) NOT NULL COMMENT '命令执行者', + `locations` text COMMENT '节点坐标信息', + `connects` text COMMENT '节点连线信息', + `history_cmd` text COMMENT '历史命令,记录所有对流程实例的操作', + `dependence_schedule_times` text COMMENT '依赖节点的预估时间', + `process_instance_priority` int(11) DEFAULT NULL COMMENT '流程实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest', + PRIMARY KEY (`id`), + KEY `process_instance_index` (`process_definition_id`,`id`) USING BTREE, + KEY `start_time_index` (`start_time`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_project +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_project`; +CREATE TABLE `t_escheduler_project` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(100) DEFAULT NULL COMMENT '项目名称', + `desc` varchar(200) DEFAULT NULL COMMENT '项目描述', + `user_id` int(11) DEFAULT NULL COMMENT '所属用户', + `flag` tinyint(4) DEFAULT '1' COMMENT '是否可用 1 可用,0 不可用', + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + KEY `user_id_index` (`user_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_queue +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_queue`; +CREATE TABLE `t_escheduler_queue` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `queue_name` varchar(64) DEFAULT NULL COMMENT '队列名称', + `queue` varchar(64) DEFAULT NULL COMMENT 'yarn队列名称', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_datasource_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_datasource_user`; +CREATE TABLE `t_escheduler_relation_datasource_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '用户id', + `datasource_id` int(11) DEFAULT NULL COMMENT '数据源id', + `perm` int(11) DEFAULT '1' COMMENT '权限', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_process_instance +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_process_instance`; +CREATE TABLE `t_escheduler_relation_process_instance` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `parent_process_instance_id` int(11) DEFAULT NULL COMMENT '父流程实例id', + `parent_task_instance_id` int(11) DEFAULT NULL COMMENT '父任务实例id', + `process_instance_id` int(11) DEFAULT NULL COMMENT '子流程实例id', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_project_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_project_user`; +CREATE TABLE `t_escheduler_relation_project_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '用户id', + `project_id` int(11) DEFAULT NULL COMMENT '项目id', + `perm` int(11) DEFAULT '1' COMMENT '权限', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `user_id_index` (`user_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_resources_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_resources_user`; +CREATE TABLE `t_escheduler_relation_resources_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL COMMENT '用户id', + `resources_id` int(11) DEFAULT NULL COMMENT '资源id', + `perm` int(11) DEFAULT '1' COMMENT '权限', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_udfs_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_udfs_user`; +CREATE TABLE `t_escheduler_relation_udfs_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '用户id', + `udf_id` int(11) DEFAULT NULL COMMENT 'udf id', + `perm` int(11) DEFAULT '1' COMMENT '权限', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_relation_user_alertgroup +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_relation_user_alertgroup`; +CREATE TABLE `t_escheduler_relation_user_alertgroup` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `alertgroup_id` int(11) DEFAULT NULL COMMENT '组消息id', + `user_id` int(11) DEFAULT NULL COMMENT '用户id', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_resources +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_resources`; +CREATE TABLE `t_escheduler_resources` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `alias` varchar(64) DEFAULT NULL COMMENT '别名', + `file_name` varchar(64) DEFAULT NULL COMMENT '文件名', + `desc` varchar(256) DEFAULT NULL COMMENT '描述', + `user_id` int(11) DEFAULT NULL COMMENT '用户id', + `type` tinyint(4) DEFAULT NULL COMMENT '资源类型,0 FILE,1 UDF', + `size` bigint(20) DEFAULT NULL COMMENT '资源大小', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_schedules +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_schedules`; +CREATE TABLE `t_escheduler_schedules` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `process_definition_id` int(11) NOT NULL COMMENT '流程定义id', + `start_time` datetime NOT NULL COMMENT '调度开始时间', + `end_time` datetime NOT NULL COMMENT '调度结束时间', + `crontab` varchar(256) NOT NULL COMMENT 'crontab 表达式', + `failure_strategy` tinyint(4) NOT NULL COMMENT '失败策略: 0 结束,1 继续', + `user_id` int(11) NOT NULL COMMENT '用户id', + `release_state` tinyint(4) NOT NULL COMMENT '状态:0 未上线,1 上线', + `warning_type` tinyint(4) NOT NULL COMMENT '告警类型:0 不发,1 流程成功发,2 流程失败发,3 成功失败都发', + `warning_group_id` int(11) DEFAULT NULL COMMENT '告警组id', + `process_instance_priority` int(11) DEFAULT NULL COMMENT '流程实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_session +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_session`; +CREATE TABLE `t_escheduler_session` ( + `id` varchar(64) NOT NULL COMMENT '主键', + `user_id` int(11) DEFAULT NULL COMMENT '用户id', + `ip` varchar(45) DEFAULT NULL COMMENT '登录ip', + `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_task_instance +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_task_instance`; +CREATE TABLE `t_escheduler_task_instance` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `name` varchar(255) DEFAULT NULL COMMENT '任务名称', + `task_type` varchar(64) DEFAULT NULL COMMENT '任务类型', + `process_definition_id` int(11) DEFAULT NULL COMMENT '流程定义id', + `process_instance_id` int(11) DEFAULT NULL COMMENT '流程实例id', + `task_json` longtext COMMENT '任务节点json', + `state` tinyint(4) DEFAULT NULL COMMENT '任务实例状态:0 提交成功,1 正在运行,2 准备暂停,3 暂停,4 准备停止,5 停止,6 失败,7 成功,8 需要容错,9 kill,10 等待线程,11 等待依赖完成', + `submit_time` datetime DEFAULT NULL COMMENT '任务提交时间', + `start_time` datetime DEFAULT NULL COMMENT '任务开始时间', + `end_time` datetime DEFAULT NULL COMMENT '任务结束时间', + `host` varchar(45) DEFAULT NULL COMMENT '执行任务的机器', + `execute_path` varchar(200) DEFAULT NULL COMMENT '任务执行路径', + `log_path` varchar(200) DEFAULT NULL COMMENT '任务日志路径', + `alert_flag` tinyint(4) DEFAULT NULL COMMENT '是否告警', + `retry_times` int(4) DEFAULT '0' COMMENT '重试次数', + `pid` int(4) DEFAULT NULL COMMENT '进程pid', + `app_link` varchar(255) DEFAULT NULL COMMENT 'yarn app id', + `flag` tinyint(4) DEFAULT '1' COMMENT '是否可用:0 不可用,1 可用', + `retry_interval` int(4) DEFAULT NULL COMMENT '重试间隔', + `max_retry_times` int(2) DEFAULT NULL COMMENT '最大重试次数', + `task_instance_priority` int(11) DEFAULT NULL COMMENT '任务实例优先级:0 Highest,1 High,2 Medium,3 Low,4 Lowest', + PRIMARY KEY (`id`), + KEY `process_instance_id` (`process_instance_id`) USING BTREE, + KEY `task_instance_index` (`process_definition_id`,`process_instance_id`) USING BTREE, + CONSTRAINT `foreign_key_instance_id` FOREIGN KEY (`process_instance_id`) REFERENCES `t_escheduler_process_instance` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_tenant +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_tenant`; +CREATE TABLE `t_escheduler_tenant` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `tenant_code` varchar(64) DEFAULT NULL COMMENT '租户编码', + `tenant_name` varchar(64) DEFAULT NULL COMMENT '租户名称', + `desc` varchar(256) DEFAULT NULL COMMENT '描述', + `queue_id` int(11) DEFAULT NULL COMMENT '队列id', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_udfs +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_udfs`; +CREATE TABLE `t_escheduler_udfs` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `user_id` int(11) NOT NULL COMMENT '用户id', + `func_name` varchar(100) NOT NULL COMMENT 'UDF函数名', + `class_name` varchar(255) NOT NULL COMMENT '类名', + `type` tinyint(4) NOT NULL COMMENT 'Udf函数类型', + `arg_types` varchar(255) DEFAULT NULL COMMENT '参数', + `database` varchar(255) DEFAULT NULL COMMENT '库名', + `desc` varchar(255) DEFAULT NULL COMMENT '描述', + `resource_id` int(11) NOT NULL COMMENT '资源id', + `resource_name` varchar(255) NOT NULL COMMENT '资源名称', + `create_time` datetime NOT NULL COMMENT '创建时间', + `update_time` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_user +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_user`; +CREATE TABLE `t_escheduler_user` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id', + `user_name` varchar(64) DEFAULT NULL COMMENT '用户名', + `user_password` varchar(64) DEFAULT NULL COMMENT '用户密码', + `user_type` tinyint(4) DEFAULT NULL COMMENT '用户类型:0 管理员,1 普通用户', + `email` varchar(64) DEFAULT NULL COMMENT '邮箱', + `phone` varchar(11) DEFAULT NULL COMMENT '手机', + `tenant_id` int(11) DEFAULT NULL COMMENT '管理员0,普通用户所属租户id', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `user_name_unique` (`user_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Table structure for t_escheduler_worker_server +-- ---------------------------- +DROP TABLE IF EXISTS `t_escheduler_worker_server`; +CREATE TABLE `t_escheduler_worker_server` ( + `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', + `host` varchar(45) DEFAULT NULL COMMENT 'ip', + `port` int(11) DEFAULT NULL COMMENT '进程号', + `zk_directory` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT 'zk注册目录', + `res_info` varchar(255) DEFAULT NULL COMMENT '集群资源信息:json格式{"cpu":xxx,"memroy":xxx}', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `last_heartbeat_time` datetime DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + /*drop table first */ + DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; + DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; + DROP TABLE IF EXISTS QRTZ_LOCKS; + DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_TRIGGERS; + DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; + DROP TABLE IF EXISTS QRTZ_CALENDARS; + + CREATE TABLE QRTZ_JOB_DETAILS( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE VARCHAR(1) NOT NULL, + IS_NONCONCURRENT VARCHAR(1) NOT NULL, + IS_UPDATE_DATA VARCHAR(1) NOT NULL, + REQUESTS_RECOVERY VARCHAR(1) NOT NULL, + JOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT(13) NULL, + PREV_FIRE_TIME BIGINT(13) NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT(13) NOT NULL, + END_TIME BIGINT(13) NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT(2) NULL, + JOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT(7) NOT NULL, + REPEAT_INTERVAL BIGINT(12) NOT NULL, + TIMES_TRIGGERED BIGINT(10) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_CRON_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_SIMPROP_TRIGGERS + ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13,4) NULL, + DEC_PROP_2 NUMERIC(13,4) NULL, + BOOL_PROP_1 VARCHAR(1) NULL, + BOOL_PROP_2 VARCHAR(1) NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_BLOB_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BLOB NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), + INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_CALENDARS ( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BLOB NOT NULL, + PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_FIRED_TRIGGERS ( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT(13) NOT NULL, + SCHED_TIME BIGINT(13) NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT VARCHAR(1) NULL, + REQUESTS_RECOVERY VARCHAR(1) NULL, + PRIMARY KEY (SCHED_NAME,ENTRY_ID)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_SCHEDULER_STATE ( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT(13) NOT NULL, + CHECKIN_INTERVAL BIGINT(13) NOT NULL, + PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)) + ENGINE=InnoDB; + + CREATE TABLE QRTZ_LOCKS ( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME,LOCK_NAME)) + ENGINE=InnoDB; + + CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); + CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); + + CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); + CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); + CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); + CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); + CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); + CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); + CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); + CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); + CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); + CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); + CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); + CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); + + CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); + CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); + CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); + CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); + CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); + CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); + + commit; + + diff --git a/sql/create/release-1.0.0_schema/mysql/escheduler_dml.sql b/sql/create/release-1.0.0_schema/mysql/escheduler_dml.sql new file mode 100644 index 0000000000..b7f25d76e1 --- /dev/null +++ b/sql/create/release-1.0.0_schema/mysql/escheduler_dml.sql @@ -0,0 +1,7 @@ +-- Records of t_escheduler_user,user : admin , password : escheduler123 +INSERT INTO `t_escheduler_user` VALUES ('1', 'admin', '055a97b5fcd6d120372ad1976518f371', '0', '825193156@qq.com', '15001335629', '0', '2018-03-27 15:48:50', '2018-10-24 17:40:22'); +INSERT INTO `t_escheduler_alertgroup` VALUES (1, 'escheduler管理员告警组', '0', 'escheduler管理员告警组','2018-11-29 10:20:39', '2018-11-29 10:20:39'); +INSERT INTO `t_escheduler_relation_user_alertgroup` VALUES ('1', '1', '1', '2018-11-29 10:22:33', '2018-11-29 10:22:33'); + +-- Records of t_escheduler_queue,default queue name : default +INSERT INTO `t_escheduler_queue` VALUES ('1', 'default', 'default'); \ No newline at end of file diff --git a/sql/soft_version b/sql/soft_version new file mode 100644 index 0000000000..e6d5cb833c --- /dev/null +++ b/sql/soft_version @@ -0,0 +1 @@ +1.0.2 \ No newline at end of file diff --git a/sql/upgrade/1.0.1_schema/mysql/escheduler_ddl.sql b/sql/upgrade/1.0.1_schema/mysql/escheduler_ddl.sql index 40a8d48077..66c03b21ea 100644 --- a/sql/upgrade/1.0.1_schema/mysql/escheduler_ddl.sql +++ b/sql/upgrade/1.0.1_schema/mysql/escheduler_ddl.sql @@ -6,10 +6,10 @@ CREATE PROCEDURE ac_escheduler_T_t_escheduler_queue_C_create_time() BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME='t_escheduler_queue' - AND TABLE_SCHEMA='escheduler' + AND TABLE_SCHEMA=(SELECT DATABASE()) AND COLUMN_NAME='create_time') THEN - ALTER TABLE escheduler.t_escheduler_queue ADD COLUMN create_time datetime DEFAULT NULL COMMENT '创建时间' AFTER queue; + ALTER TABLE t_escheduler_queue ADD COLUMN create_time datetime DEFAULT NULL COMMENT '创建时间' AFTER queue; END IF; END; @@ -27,10 +27,10 @@ CREATE PROCEDURE ac_escheduler_T_t_escheduler_queue_C_update_time() BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_NAME='t_escheduler_queue' - AND TABLE_SCHEMA='escheduler' + AND TABLE_SCHEMA=(SELECT DATABASE()) AND COLUMN_NAME='update_time') THEN - ALTER TABLE escheduler.t_escheduler_queue ADD COLUMN update_time datetime DEFAULT NULL COMMENT '更新时间' AFTER create_time; + ALTER TABLE t_escheduler_queue ADD COLUMN update_time datetime DEFAULT NULL COMMENT '更新时间' AFTER create_time; END IF; END; diff --git a/sql/upgrade/1.0.1_schema/mysql/escheduler_dml.sql b/sql/upgrade/1.0.1_schema/mysql/escheduler_dml.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sql/upgrade/1.0.2_schema/mysql/escheduler_ddl.sql b/sql/upgrade/1.0.2_schema/mysql/escheduler_ddl.sql new file mode 100644 index 0000000000..b89a10480e --- /dev/null +++ b/sql/upgrade/1.0.2_schema/mysql/escheduler_ddl.sql @@ -0,0 +1,21 @@ +SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); +-- ac_escheduler_T_t_escheduler_version +drop PROCEDURE if EXISTS ac_escheduler_T_t_escheduler_version; +delimiter d// +CREATE PROCEDURE ac_escheduler_T_t_escheduler_version() + BEGIN + drop table if exists t_escheduler_version; + CREATE TABLE IF NOT EXISTS `t_escheduler_version` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `version` varchar(200) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `version_UNIQUE` (`version`) + ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='版本表'; + + END; + +d// + +delimiter ; +CALL ac_escheduler_T_t_escheduler_version; +DROP PROCEDURE ac_escheduler_T_t_escheduler_version; \ No newline at end of file diff --git a/sql/upgrade/1.0.2_schema/mysql/escheduler_dml.sql b/sql/upgrade/1.0.2_schema/mysql/escheduler_dml.sql new file mode 100644 index 0000000000..b9c214b7ad --- /dev/null +++ b/sql/upgrade/1.0.2_schema/mysql/escheduler_dml.sql @@ -0,0 +1 @@ +INSERT INTO `t_escheduler_version` (`version`) VALUES ('1.0.0'); \ No newline at end of file