Browse Source

add theme update

main
wangshaoping 1 year ago
parent
commit
6af24ec0ec
  1. 1
      io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue
  2. 53
      io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue
  3. 19
      io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue
  4. 18
      io.sc.platform.core.frontend/src/views/Table.vue
  5. 87
      io.sc.platform.core.frontend/template-project/src/views/Table.vue
  6. 118
      io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue
  7. 4
      io.sc.platform.developer.frontend/package.json
  8. 6
      io.sc.platform.job.core/build.gradle
  9. 7
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java
  10. 14
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java
  11. 6
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java
  12. 11
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java
  13. 7
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java
  14. 6
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java
  15. 179
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java
  16. 110
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java
  17. 152
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java
  18. 204
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java
  19. 368
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java
  20. 150
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java
  21. 53
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java
  22. 63
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java
  23. 62
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java
  24. 143
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java
  25. 189
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java
  26. 63
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorEntity.java
  27. 91
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java
  28. 299
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java
  29. 230
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java
  30. 99
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java
  31. 12
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java
  32. 6
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRepository.java
  33. 8
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java
  34. 7
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java
  35. 8
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java
  36. 10
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java
  37. 58
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java
  38. 166
      io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml
  39. 4
      io.sc.platform.lcdp.frontend/package.json
  40. 4
      io.sc.platform.mvc.frontend/package.json
  41. 4
      io.sc.platform.security.frontend/package.json
  42. 2
      io.sc.platform.system.frontend/package.json
  43. 1
      io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java

1
io.sc.platform.core.frontend/src/platform/components/grid/TableAction.vue

@ -99,7 +99,6 @@ const onResize = (size) => {
let index = 0; let index = 0;
for (; index < length; index++) { for (; index < length; index++) {
console.log(index, width + actions[index].width, availableWidth);
if (width + actions[index].width > availableWidth) { if (width + actions[index].width > availableWidth) {
availableWidth -= moreActionWidth; availableWidth -= moreActionWidth;
while (width > availableWidth) { while (width > availableWidth) {

53
io.sc.platform.core.frontend/src/platform/components/grid/TableRow.vue

@ -0,0 +1,53 @@
<template>
<q-tr>
<q-td v-for="(col, index) in cols" :key="col.name" :style="{ 'padding-left': index == 0 ? '2px' : '7px' }">
<div class="flex flex-nowrap items-center">
<template v-if="index == 0">
<!--层级占位符-->
<span :style="`width:${27 * props.level}px;`"></span>
<!--展开按钮-->
<q-btn
v-if="data.children && data.children.length > 0"
flat
size="16px"
dense
padding="0px 0px"
:icon="data.expand ? 'bi-dash' : 'bi-plus'"
@click="data.expand = !data.expand"
/>
<!--展开按钮占位符-->
<span v-else style="width: 27px"></span>
<!--选择框-->
<q-checkbox v-model="data.selected" flat size="40px" dense />
<!--文件夹图标-->
<q-icon v-if="data.children && data.children.length > 0" name="sym_o_folder_open" size="20px" class="px-1"></q-icon>
<!--文件图标-->
<q-icon v-else name="bi-file-earmark" size="16px" class="px-1"></q-icon>
</template>
<div v-dompurify-html="col.format ? col.format(data[col.name], data) : col.value"></div>
</div>
</q-td>
</q-tr>
<template v-for="child in data.children" :key="child.id">
<TableRow v-if="data.expand" :cols="cols" :data="child" :level="props.level + 1"></TableRow>
</template>
</template>
<script setup lang="ts">
const props = defineProps({
level: { type: Number, default: 0 },
cols: {
type: Array,
default: () => {
return [];
},
},
data: {
type: Array,
default: () => {
return [];
},
},
});
const cols = props.cols;
const data = props.data;
</script>

19
io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue

@ -17,7 +17,6 @@
<q-table flat bordered separator="cell" :rows="data" :columns="columns" row-key="name"> <q-table flat bordered separator="cell" :rows="data" :columns="columns" row-key="name">
<template #header="headerProps"> <template #header="headerProps">
<q-tr :props="headerProps"> <q-tr :props="headerProps">
<q-th auto-width />
<q-th v-for="col in headerProps.cols" :key="col.name" :props="headerProps"> <q-th v-for="col in headerProps.cols" :key="col.name" :props="headerProps">
{{ col.label }} {{ col.label }}
</q-th> </q-th>
@ -25,22 +24,7 @@
</template> </template>
<template #body="bodyProps"> <template #body="bodyProps">
<q-tr :props="bodyProps"> <TableRow :cols="bodyProps.cols" :data="bodyProps.row"></TableRow>
<q-td auto-width>
<q-checkbox v-model="bodyProps.row.selected" flat />
<q-btn size="sm" dense flat :icon="bodyProps.expand ? 'bi-dash-lg' : 'bi-plus-lg'" @click="bodyProps.expand = !bodyProps.expand" />
<q-icon name="sym_o_folder_open" size="sm"></q-icon>
</q-td>
<q-td v-for="col in bodyProps.cols" :key="col.name" :props="bodyProps">
<div v-dompurify-html="col.value"></div>
</q-td>
</q-tr>
<q-tr v-for="child in bodyProps.row.children" v-show="bodyProps.expand" :key="child.name" :props="bodyProps">
<q-td auto-width></q-td>
<q-td v-for="col in bodyProps.cols" :key="col.name" :props="bodyProps">
{{ child[col.name] }}
</q-td>
</q-tr>
</template> </template>
</q-table> </q-table>
</div> </div>
@ -51,6 +35,7 @@ import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { axios, Tools, TreeBuilder } from '@/platform'; import { axios, Tools, TreeBuilder } from '@/platform';
import TableAction from './TableAction.vue'; import TableAction from './TableAction.vue';
import TableRow from './TableRow.vue';
const props = defineProps({ const props = defineProps({
tree: { type: Boolean, default: false }, tree: { type: Boolean, default: false },

18
io.sc.platform.core.frontend/src/views/Table.vue

@ -38,17 +38,19 @@ const columns = [
{ {
name: 'name', name: 'name',
required: true, required: true,
label: 'Dessert (100g serving)', label: t('name'),
align: 'left', align: 'left',
field: 'name', field: 'name',
sortable: true, sortable: true,
format: (value, data) => {
return t(data.titleI18nKey);
}, },
{ name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true }, },
{ name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true }, { name: 'type', align: 'center', label: 'type', field: 'type', sortable: true },
{ name: 'carbs', label: 'Carbs (g)', field: 'carbs' }, { name: 'enable', label: 'enable', field: 'enable', sortable: true },
{ name: 'protein', label: 'Protein (g)', field: 'protein' }, { name: 'dataComeFrom', label: 'dataComeFrom', field: 'dataComeFrom' },
{ name: 'sodium', label: 'Sodium (mg)', field: 'sodium' }, { name: 'lastModifier', label: 'lastModifier', field: 'lastModifier' },
{ name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, { name: 'lastModifyDate', label: 'lastModifyDate', field: 'lastModifyDate' },
{ name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }, { name: 'corporationCode', label: 'corporationCode', field: 'corporationCode', sortable: true },
]; ];
</script> </script>

87
io.sc.platform.core.frontend/template-project/src/views/Table.vue

@ -1,53 +1,54 @@
<template> <template>
<div> <w-list-grid
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> :tree="true"
</div> title="User List"
:no-action-icon="true"
:target-object-name="$t('菜单')"
:actions="[
'query',
'refresh',
'expandAll',
'selectAll',
'separator',
'add',
'clone',
'edit',
'remove',
'removeAll',
'separator',
'detail',
'addTop',
'addChild',
]"
:columns="columns"
:auto-fetch-data="true"
:data-url="Environment.apiContextPath('/api/system/menu/allMenus')"
></w-list-grid>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, toRaw } from 'vue'; import { ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { Environment, axios } from '@/platform'; import { Environment } from '@/platform';
const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const corporationTreeGridRef = ref(); const columns = [
const corporationConfigure = {
actions: [
{ {
name: 'refresh', name: 'name',
label: t('refresh'), required: true,
click: () => {}, label: 'Dessert (100g serving)',
align: 'left',
field: 'name',
sortable: true,
}, },
{ name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true },
{ { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true },
name: 'addRoot', { name: 'carbs', label: 'Carbs (g)', field: 'carbs' },
label: t('system.corporation.action.addTop'), { name: 'protein', label: 'Protein (g)', field: 'protein' },
click: () => {}, { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' },
}, { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
{ { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
name: 'addChild', ];
label: t('system.corporation.action.addChild'),
click: () => {},
},
{
name: 'edit',
label: t('edit'),
click: () => {},
},
{
name: 'delete',
label: t('delete'),
click: () => {},
},
],
};
onMounted(() => {
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => {
corporationTreeGridRef.value.setNodes(response.data.content);
});
});
</script> </script>

118
io.sc.platform.core.frontend/template-project/src/views/TableTitle.vue

@ -0,0 +1,118 @@
<template>
<div class="flex flex-nowrap py-2">
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div>
<q-space />
<div ref="actionContainerRef" class="flex flex-nowrap">
<!-- baseActions -->
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index">
<q-separator
v-if="action.separator"
vertical
class="class-action-item"
:style="{
'margin-left': '5px',
'margin-right': '5px',
}"
/>
<q-btn
v-else
v-bind="action"
:id="action.name"
:disable="action.enableIf ? !action.enableIf() : false"
no-wrap
class="class-action-item"
:style="{
'margin-left': '5px',
'margin-right': '5px',
}"
@click="action.click"
/>
</template>
<!-- moreActions -->
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px">
<q-list>
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index">
<q-separator v-if="action.separator" />
<q-item v-else v-close-popup clickable @click="action.click">
<q-item-section avatar style="min-width: 28px; padding-right: 0px">
<q-icon :name="action.icon" size="20px" />
</q-item-section>
<q-item-section>
<q-item-label :v-bind="action">{{ action.label }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-list>
</q-btn-dropdown>
</div>
<q-resize-observer @resize="onResize" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { Tools } from '@/platform/utils';
const props = defineProps({
title: { type: String, default: '' },
actions: {
type: Array,
default: () => {
return [];
},
},
});
const titleContainerRef = ref();
const actionContainerRef = ref();
const actions = props.actions;
const baseActions = ref(actions);
const moreActions = ref([]);
const isActionWidthInitializedRef = ref(false);
const moreActionWidth = 100;
const onResize = (size) => {
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) {
return;
}
if (!isActionWidthInitializedRef.value) {
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item');
for (let i = 0; i < actions.length; i++) {
actions[i].width = nodes[i].clientWidth + 10;
}
isActionWidthInitializedRef.value = true;
}
const _baseActions = [];
const _moreActions = [];
const length = actions.length;
let availableWidth = size.width - titleContainerRef.value.clientWidth;
let width = 0;
let index = 0;
for (; index < length; index++) {
console.log(index, width + actions[index].width, availableWidth);
if (width + actions[index].width > availableWidth) {
availableWidth -= moreActionWidth;
while (width > availableWidth) {
index--;
width -= actions[index].width;
_baseActions.pop();
}
break;
} else {
_baseActions.push(actions[index]);
width += actions[index].width;
}
}
for (; index < length; index++) {
_moreActions.push(actions[index]);
}
baseActions.value = _baseActions;
moreActions.value = _moreActions;
};
</script>

4
io.sc.platform.developer.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.developer.frontend", "name": "io.sc.platform.developer.frontend",
"version": "8.1.19", "version": "8.1.20",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
@ -79,7 +79,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.45", "platform-core": "8.1.47",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

6
io.sc.platform.job.core/build.gradle

@ -0,0 +1,6 @@
dependencies {
api(
project(":io.sc.platform.core"),
project(":io.sc.platform.orm.api"),
)
}

7
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/BlockStrategy.java

@ -0,0 +1,7 @@
package io.sc.platform.job.core.enums;
public enum BlockStrategy {
SERIAL_EXECUTION, //单机串行
DISCARD_LATER, //丢弃后续调度
COVER_EARLY; //覆盖先前调度
}

14
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorRouteStrategy.java

@ -0,0 +1,14 @@
package io.sc.platform.job.core.enums;
public enum ExecutorRouteStrategy {
FIRST, //第一个
LAST, //最后一个
ROUND, //轮询
RANDOM, //随机
CONSISTENT_HASH, //一致性 Hash
LEAST_FREQUENTLY_USED, //最不经常使用
LEAST_RECENTLY_USED, //最近最久未使用
FAILOVER, //故障转移
BUSYOVER, //忙碌转义
SHARDING_BROADCAST; //分片广播
}

6
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExpirationPolicy.java

@ -0,0 +1,6 @@
package io.sc.platform.job.core.enums;
public enum ExpirationPolicy {
DO_NOTHING, //忽略
FIRE_ONCE_NOW; //立即执行一次
}

11
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/GlueType.java

@ -0,0 +1,11 @@
package io.sc.platform.job.core.enums;
public enum GlueType {
BEAN, // Bean
GLUE_GROOVY, // groovy
GLUE_SHELL, // shell
GLUE_PYTHON, // python
GLUE_PHP, // php
GLUE_NODEJS, // nodejs
GLUE_POWERSHELL;// powershell
}

7
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TaskScheduleType.java

@ -0,0 +1,7 @@
package io.sc.platform.job.core.enums;
public enum TaskScheduleType {
NONE, //无
CRON, //Cron
FIX_RATE; //固定周期
}

6
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/TriggerStatus.java

@ -0,0 +1,6 @@
package io.sc.platform.job.core.enums;
public enum TriggerStatus {
STOPED, //已停止
RUNNING; //运行中
}

179
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobCompleteHelper.java

@ -0,0 +1,179 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.complete.XxlJobCompleter;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.core.biz.model.HandleCallbackParam;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
public class JobCompleteHelper {
private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
private static JobCompleteHelper instance = new JobCompleteHelper();
public static JobCompleteHelper getInstance(){
return instance;
}
// ---------------------- monitor ----------------------
private ThreadPoolExecutor callbackThreadPool = null;
private Thread monitorThread;
private volatile boolean toStop = false;
public void start(){
// for callback
callbackThreadPool = new ThreadPoolExecutor(
2,
20,
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode());
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now).");
}
});
// for monitor
monitorThread = new Thread(new Runnable() {
@Override
public void run() {
// wait for JobTriggerPoolHelper-init
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
// monitor
while (!toStop) {
try {
// 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败;
Date losedTime = DateUtil.addMinutes(new Date(), -10);
List<Long> losedJobIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);
if (losedJobIds!=null && losedJobIds.size()>0) {
for (Long logId: losedJobIds) {
XxlJobLog jobLog = new XxlJobLog();
jobLog.setId(logId);
jobLog.setHandleTime(new Date());
jobLog.setHandleCode(ReturnT.FAIL_CODE);
jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") );
XxlJobCompleter.updateHandleInfoAndFinish(jobLog);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(60);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop");
}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobLosedMonitorHelper");
monitorThread.start();
}
public void toStop(){
toStop = true;
// stop registryOrRemoveThreadPool
callbackThreadPool.shutdownNow();
// stop monitorThread (interrupt and wait)
monitorThread.interrupt();
try {
monitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// ---------------------- helper ----------------------
public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
callbackThreadPool.execute(new Runnable() {
@Override
public void run() {
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
ReturnT<String> callbackResult = callback(handleCallbackParam);
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult);
}
}
});
return ReturnT.SUCCESS;
}
private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) {
// valid log item
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId());
if (log == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found.");
}
if (log.getHandleCode() > 0) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback."); // avoid repeat callback, trigger child job etc
}
// handle msg
StringBuffer handleMsg = new StringBuffer();
if (log.getHandleMsg()!=null) {
handleMsg.append(log.getHandleMsg()).append("<br>");
}
if (handleCallbackParam.getHandleMsg() != null) {
handleMsg.append(handleCallbackParam.getHandleMsg());
}
// success, save log
log.setHandleTime(new Date());
log.setHandleCode(handleCallbackParam.getHandleCode());
log.setHandleMsg(handleMsg.toString());
XxlJobCompleter.updateHandleInfoAndFinish(log);
return ReturnT.SUCCESS;
}
}

110
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobFailMonitorHelper.java

@ -0,0 +1,110 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.util.I18nUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* job monitor instance
*
* @author xuxueli 2015-9-1 18:05:56
*/
public class JobFailMonitorHelper {
private static Logger logger = LoggerFactory.getLogger(JobFailMonitorHelper.class);
private static JobFailMonitorHelper instance = new JobFailMonitorHelper();
public static JobFailMonitorHelper getInstance(){
return instance;
}
// ---------------------- monitor ----------------------
private Thread monitorThread;
private volatile boolean toStop = false;
public void start(){
monitorThread = new Thread(new Runnable() {
@Override
public void run() {
// monitor
while (!toStop) {
try {
List<Long> failLogIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findFailJobLogIds(1000);
if (failLogIds!=null && !failLogIds.isEmpty()) {
for (long failLogId: failLogIds) {
// lock log
int lockRet = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, 0, -1);
if (lockRet < 1) {
continue;
}
XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(failLogId);
XxlJobInfo info = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(log.getJobId());
// 1、fail retry monitor
if (log.getExecutorFailRetryCount() > 0) {
JobTriggerPoolHelper.trigger(log.getJobId(), TriggerTypeEnum.RETRY, (log.getExecutorFailRetryCount()-1), log.getExecutorShardingParam(), log.getExecutorParam(), null);
String retryMsg = "<br><br><span style=\"color:#F39C12;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_type_retry") +"<<<<<<<<<<< </span><br>";
log.setTriggerMsg(log.getTriggerMsg() + retryMsg);
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateTriggerInfo(log);
}
// 2、fail alarm monitor
int newAlarmStatus = 0; // 告警状态:0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
if (info != null) {
boolean alarmResult = XxlJobAdminConfig.getAdminConfig().getJobAlarmer().alarm(info, log);
newAlarmStatus = alarmResult?2:3;
} else {
newAlarmStatus = 1;
}
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().updateAlarmStatus(failLogId, -1, newAlarmStatus);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(10);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job fail monitor thread stop");
}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobFailMonitorHelper");
monitorThread.start();
}
public void toStop(){
toStop = true;
// interrupt and wait
monitorThread.interrupt();
try {
monitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
}

152
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobLogReportHelper.java

@ -0,0 +1,152 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobLogReport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* job log report helper
*
* @author xuxueli 2019-11-22
*/
public class JobLogReportHelper {
private static Logger logger = LoggerFactory.getLogger(JobLogReportHelper.class);
private static JobLogReportHelper instance = new JobLogReportHelper();
public static JobLogReportHelper getInstance(){
return instance;
}
private Thread logrThread;
private volatile boolean toStop = false;
public void start(){
logrThread = new Thread(new Runnable() {
@Override
public void run() {
// last clean log time
long lastCleanLogTime = 0;
while (!toStop) {
// 1、log-report refresh: refresh log report in 3 days
try {
for (int i = 0; i < 3; i++) {
// today
Calendar itemDay = Calendar.getInstance();
itemDay.add(Calendar.DAY_OF_MONTH, -i);
itemDay.set(Calendar.HOUR_OF_DAY, 0);
itemDay.set(Calendar.MINUTE, 0);
itemDay.set(Calendar.SECOND, 0);
itemDay.set(Calendar.MILLISECOND, 0);
Date todayFrom = itemDay.getTime();
itemDay.set(Calendar.HOUR_OF_DAY, 23);
itemDay.set(Calendar.MINUTE, 59);
itemDay.set(Calendar.SECOND, 59);
itemDay.set(Calendar.MILLISECOND, 999);
Date todayTo = itemDay.getTime();
// refresh log-report every minute
XxlJobLogReport xxlJobLogReport = new XxlJobLogReport();
xxlJobLogReport.setTriggerDay(todayFrom);
xxlJobLogReport.setRunningCount(0);
xxlJobLogReport.setSucCount(0);
xxlJobLogReport.setFailCount(0);
Map<String, Object> triggerCountMap = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLogReport(todayFrom, todayTo);
if (triggerCountMap!=null && triggerCountMap.size()>0) {
int triggerDayCount = triggerCountMap.containsKey("triggerDayCount")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCount"))):0;
int triggerDayCountRunning = triggerCountMap.containsKey("triggerDayCountRunning")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountRunning"))):0;
int triggerDayCountSuc = triggerCountMap.containsKey("triggerDayCountSuc")?Integer.valueOf(String.valueOf(triggerCountMap.get("triggerDayCountSuc"))):0;
int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc;
xxlJobLogReport.setRunningCount(triggerDayCountRunning);
xxlJobLogReport.setSucCount(triggerDayCountSuc);
xxlJobLogReport.setFailCount(triggerDayCountFail);
}
// do refresh
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().update(xxlJobLogReport);
if (ret < 1) {
XxlJobAdminConfig.getAdminConfig().getXxlJobLogReportDao().save(xxlJobLogReport);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job log report thread error:{}", e);
}
}
// 2、log-clean: switch open & once each day
if (XxlJobAdminConfig.getAdminConfig().getLogretentiondays()>0
&& System.currentTimeMillis() - lastCleanLogTime > 24*60*60*1000) {
// expire-time
Calendar expiredDay = Calendar.getInstance();
expiredDay.add(Calendar.DAY_OF_MONTH, -1 * XxlJobAdminConfig.getAdminConfig().getLogretentiondays());
expiredDay.set(Calendar.HOUR_OF_DAY, 0);
expiredDay.set(Calendar.MINUTE, 0);
expiredDay.set(Calendar.SECOND, 0);
expiredDay.set(Calendar.MILLISECOND, 0);
Date clearBeforeTime = expiredDay.getTime();
// clean expired log
List<Long> logIds = null;
do {
logIds = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findClearLogIds(0, 0, clearBeforeTime, 0, 1000);
if (logIds!=null && logIds.size()>0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().clearLog(logIds);
}
} while (logIds!=null && logIds.size()>0);
// update clean time
lastCleanLogTime = System.currentTimeMillis();
}
try {
TimeUnit.MINUTES.sleep(1);
} catch (Exception e) {
if (!toStop) {
logger.error(e.getMessage(), e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job log report thread stop");
}
});
logrThread.setDaemon(true);
logrThread.setName("xxl-job, admin JobLogReportHelper");
logrThread.start();
}
public void toStop(){
toStop = true;
// interrupt and wait
logrThread.interrupt();
try {
logrThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
}

204
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobRegistryHelper.java

@ -0,0 +1,204 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.model.XxlJobGroup;
import com.xxl.job.admin.core.model.XxlJobRegistry;
import com.xxl.job.core.biz.model.RegistryParam;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.enums.RegistryConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.concurrent.*;
/**
* job registry instance
* @author xuxueli 2016-10-02 19:10:24
*/
public class JobRegistryHelper {
private static Logger logger = LoggerFactory.getLogger(JobRegistryHelper.class);
private static JobRegistryHelper instance = new JobRegistryHelper();
public static JobRegistryHelper getInstance(){
return instance;
}
private ThreadPoolExecutor registryOrRemoveThreadPool = null;
private Thread registryMonitorThread;
private volatile boolean toStop = false;
public void start(){
// for registry or remove
registryOrRemoveThreadPool = new ThreadPoolExecutor(
2,
10,
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
}
});
// for monitor
registryMonitorThread = new Thread(new Runnable() {
@Override
public void run() {
while (!toStop) {
try {
// auto registry group
List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
if (groupList!=null && !groupList.isEmpty()) {
// remove dead address (admin/executor)
List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
if (ids!=null && ids.size()>0) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
}
// fresh online address (admin/executor)
HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
if (list != null) {
for (XxlJobRegistry item: list) {
if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
String appname = item.getRegistryKey();
List<String> registryList = appAddressMap.get(appname);
if (registryList == null) {
registryList = new ArrayList<String>();
}
if (!registryList.contains(item.getRegistryValue())) {
registryList.add(item.getRegistryValue());
}
appAddressMap.put(appname, registryList);
}
}
}
// fresh group address
for (XxlJobGroup group: groupList) {
List<String> registryList = appAddressMap.get(group.getAppname());
String addressListStr = null;
if (registryList!=null && !registryList.isEmpty()) {
Collections.sort(registryList);
StringBuilder addressListSB = new StringBuilder();
for (String item:registryList) {
addressListSB.append(item).append(",");
}
addressListStr = addressListSB.toString();
addressListStr = addressListStr.substring(0, addressListStr.length()-1);
}
group.setAddressList(addressListStr);
group.setUpdateTime(new Date());
XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
}
}
} catch (Exception e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
try {
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
} catch (InterruptedException e) {
if (!toStop) {
logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
}
});
registryMonitorThread.setDaemon(true);
registryMonitorThread.setName("xxl-job, admin JobRegistryMonitorHelper-registryMonitorThread");
registryMonitorThread.start();
}
public void toStop(){
toStop = true;
// stop registryOrRemoveThreadPool
registryOrRemoveThreadPool.shutdownNow();
// stop monitir (interrupt and wait)
registryMonitorThread.interrupt();
try {
registryMonitorThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// ---------------------- helper ----------------------
public ReturnT<String> registry(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
if (ret < 1) {
XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
public ReturnT<String> registryRemove(RegistryParam registryParam) {
// valid
if (!StringUtils.hasText(registryParam.getRegistryGroup())
|| !StringUtils.hasText(registryParam.getRegistryKey())
|| !StringUtils.hasText(registryParam.getRegistryValue())) {
return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
}
// async execute
registryOrRemoveThreadPool.execute(new Runnable() {
@Override
public void run() {
int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryDelete(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue());
if (ret > 0) {
// fresh
freshGroupRegistryInfo(registryParam);
}
}
});
return ReturnT.SUCCESS;
}
private void freshGroupRegistryInfo(RegistryParam registryParam){
// Under consideration, prevent affecting core tables
}
}

368
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobScheduleHelper.java

@ -0,0 +1,368 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.cron.CronExpression;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import io.sc.platform.core.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class JobScheduleHelper {
private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class);
public static final long PRE_READ_MS = 5000; // pre read
private Thread scheduleThread;
private Thread ringThread;
private volatile boolean scheduleThreadToStop = false;
private volatile boolean ringThreadToStop = false;
private volatile static Map<Integer, List<Integer>> ringData = new ConcurrentHashMap<>();
private static class JobScheduleHelperHolder{
private static JobScheduleHelper instance =new JobScheduleHelper();
}
private JobScheduleHelper(){}
public static JobScheduleHelper getInstance(){
return JobScheduleHelperHolder.instance;
}
public void start(){
// schedule thread
scheduleThread = new Thread(new Runnable() {
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis()%1000 );
} catch (InterruptedException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
logger.info(">>>>>>>>> init xxl-job admin scheduler success.");
// pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20;
while (!scheduleThreadToStop) {
// Scan Job
long start = System.currentTimeMillis();
Connection conn = null;
Boolean connAutoCommit = null;
PreparedStatement preparedStatement = null;
boolean preReadSuc = true;
try {
conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();
connAutoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );
preparedStatement.execute();
// tx start
// 1、pre read
long nowTime = System.currentTimeMillis();
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
if (scheduleList!=null && scheduleList.size()>0) {
// 2、push time-ring
for (XxlJobInfo jobInfo: scheduleList) {
// time-ring jump
if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
// 2.1、trigger-expire > 5s:pass && make next-trigger-time
logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
// 1、misfire match
MisfireStrategyEnum misfireStrategyEnum = MisfireStrategyEnum.match(jobInfo.getMisfireStrategy(), MisfireStrategyEnum.DO_NOTHING);
if (MisfireStrategyEnum.FIRE_ONCE_NOW == misfireStrategyEnum) {
// FIRE_ONCE_NOW 》 trigger
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.MISFIRE, -1, null, null, null);
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );
}
// 2、fresh next
refreshNextValidTime(jobInfo, new Date());
} else if (nowTime > jobInfo.getTriggerNextTime()) {
// 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time
// 1、trigger
JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null, null);
logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );
// 2、fresh next
refreshNextValidTime(jobInfo, new Date());
// next-trigger-time in 5s, pre-read again
if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {
// 1、make ring second
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
// 2、push time ring
pushTimeRing(ringSecond, jobInfo.getId());
// 3、fresh next
refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
}
} else {
// 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time
// 1、make ring second
int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
// 2、push time ring
pushTimeRing(ringSecond, jobInfo.getId());
// 3、fresh next
refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));
}
}
// 3、update trigger info
for (XxlJobInfo jobInfo: scheduleList) {
XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);
}
} else {
preReadSuc = false;
}
// tx stop
} catch (Exception e) {
if (!scheduleThreadToStop) {
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e);
}
} finally {
// commit
if (conn != null) {
try {
conn.commit();
} catch (SQLException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
try {
conn.setAutoCommit(connAutoCommit);
} catch (SQLException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
try {
conn.close();
} catch (SQLException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
}
// close PreparedStatement
if (null != preparedStatement) {
try {
preparedStatement.close();
} catch (SQLException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
}
}
long cost = System.currentTimeMillis()-start;
// Wait seconds, align second
if (cost < 1000) { // scan-overtime, not wait
try {
// pre-read period: success > scan each second; fail > skip this period;
TimeUnit.MILLISECONDS.sleep((preReadSuc?1000:PRE_READ_MS) - System.currentTimeMillis()%1000);
} catch (InterruptedException e) {
if (!scheduleThreadToStop) {
logger.error(e.getMessage(), e);
}
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");
}
});
scheduleThread.setDaemon(true);
scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread");
scheduleThread.start();
// ring thread
ringThread = new Thread(new Runnable() {
@Override
public void run() {
while (!ringThreadToStop) {
// align second
try {
TimeUnit.MILLISECONDS.sleep(1000 - System.currentTimeMillis() % 1000);
} catch (InterruptedException e) {
if (!ringThreadToStop) {
logger.error(e.getMessage(), e);
}
}
try {
// second data
List<Integer> ringItemData = new ArrayList<>();
int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验一个刻度;
for (int i = 0; i < 2; i++) {
List<Integer> tmpData = ringData.remove( (nowSecond+60-i)%60 );
if (tmpData != null) {
ringItemData.addAll(tmpData);
}
}
// ring trigger
logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) );
if (ringItemData.size() > 0) {
// do trigger
for (int jobId: ringItemData) {
// do trigger
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null, null);
}
// clear
ringItemData.clear();
}
} catch (Exception e) {
if (!ringThreadToStop) {
logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e);
}
}
}
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");
}
});
ringThread.setDaemon(true);
ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread");
ringThread.start();
}
private void refreshNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
Date nextValidTime = generateNextValidTime(jobInfo, fromTime);
if (nextValidTime != null) {
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
jobInfo.setTriggerNextTime(nextValidTime.getTime());
} else {
jobInfo.setTriggerStatus(0);
jobInfo.setTriggerLastTime(0);
jobInfo.setTriggerNextTime(0);
logger.warn(">>>>>>>>>>> xxl-job, refreshNextValidTime fail for job: jobId={}, scheduleType={}, scheduleConf={}",
jobInfo.getId(), jobInfo.getScheduleType(), jobInfo.getScheduleConf());
}
}
private void pushTimeRing(int ringSecond, int jobId){
// push async ring
List<Integer> ringItemData = ringData.get(ringSecond);
if (ringItemData == null) {
ringItemData = new ArrayList<Integer>();
ringData.put(ringSecond, ringItemData);
}
ringItemData.add(jobId);
logger.debug(">>>>>>>>>>> xxl-job, schedule push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) );
}
public void toStop(){
// 1、stop schedule
scheduleThreadToStop = true;
try {
TimeUnit.SECONDS.sleep(1); // wait
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
if (scheduleThread.getState() != Thread.State.TERMINATED){
// interrupt and wait
scheduleThread.interrupt();
try {
scheduleThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// if has ring data
boolean hasRingData = false;
if (!ringData.isEmpty()) {
for (int second : ringData.keySet()) {
List<Integer> tmpData = ringData.get(second);
if (tmpData!=null && tmpData.size()>0) {
hasRingData = true;
break;
}
}
}
if (hasRingData) {
try {
TimeUnit.SECONDS.sleep(8);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
// stop ring (wait job-in-memory stop)
ringThreadToStop = true;
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
if (ringThread.getState() != Thread.State.TERMINATED){
// interrupt and wait
ringThread.interrupt();
try {
ringThread.join();
} catch (InterruptedException e) {
logger.error(e.getMessage(), e);
}
}
logger.info(">>>>>>>>>>> xxl-job, JobScheduleHelper stop");
}
// ---------------------- tools ----------------------
public static Date generateNextValidTime(XxlJobInfo jobInfo, Date fromTime) throws Exception {
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(jobInfo.getScheduleType(), null);
if (ScheduleTypeEnum.CRON == scheduleTypeEnum) {
Date nextValidTime = new CronExpression(jobInfo.getScheduleConf()).getNextValidTimeAfter(fromTime);
return nextValidTime;
} else if (ScheduleTypeEnum.FIX_RATE == scheduleTypeEnum /*|| ScheduleTypeEnum.FIX_DELAY == scheduleTypeEnum*/) {
return new Date(fromTime.getTime() + Integer.valueOf(jobInfo.getScheduleConf())*1000 );
}
return null;
}
}

150
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/thread/JobTriggerPoolHelper.java

@ -0,0 +1,150 @@
package io.sc.platform.job.core.thread;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
import com.xxl.job.admin.core.trigger.XxlJobTrigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* job trigger thread pool helper
*
* @author xuxueli 2018-07-03 21:08:07
*/
public class JobTriggerPoolHelper {
private static Logger logger = LoggerFactory.getLogger(JobTriggerPoolHelper.class);
// ---------------------- trigger pool ----------------------
// fast/slow thread pool
private ThreadPoolExecutor fastTriggerPool = null;
private ThreadPoolExecutor slowTriggerPool = null;
public void start(){
fastTriggerPool = new ThreadPoolExecutor(
10,
XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
}
});
slowTriggerPool = new ThreadPoolExecutor(
10,
XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
}
});
}
public void stop() {
//triggerPool.shutdown();
fastTriggerPool.shutdownNow();
slowTriggerPool.shutdownNow();
logger.info(">>>>>>>>> xxl-job trigger thread pool shutdown success.");
}
// job timeout count
private volatile long minTim = System.currentTimeMillis()/60000; // ms > min
private volatile ConcurrentMap<Integer, AtomicInteger> jobTimeoutCountMap = new ConcurrentHashMap<>();
/**
* add trigger
*/
public void addTrigger(final int jobId,
final TriggerTypeEnum triggerType,
final int failRetryCount,
final String executorShardingParam,
final String executorParam,
final String addressList) {
// choose thread pool
ThreadPoolExecutor triggerPool_ = fastTriggerPool;
AtomicInteger jobTimeoutCount = jobTimeoutCountMap.get(jobId);
if (jobTimeoutCount!=null && jobTimeoutCount.get() > 10) { // job-timeout 10 times in 1 min
triggerPool_ = slowTriggerPool;
}
// trigger
triggerPool_.execute(new Runnable() {
@Override
public void run() {
long start = System.currentTimeMillis();
try {
// do trigger
XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
// check timeout-count-map
long minTim_now = System.currentTimeMillis()/60000;
if (minTim != minTim_now) {
minTim = minTim_now;
jobTimeoutCountMap.clear();
}
// incr timeout-count-map
long cost = System.currentTimeMillis()-start;
if (cost > 500) { // ob-timeout threshold 500ms
AtomicInteger timeoutCount = jobTimeoutCountMap.putIfAbsent(jobId, new AtomicInteger(1));
if (timeoutCount != null) {
timeoutCount.incrementAndGet();
}
}
}
}
});
}
// ---------------------- helper ----------------------
private static JobTriggerPoolHelper helper = new JobTriggerPoolHelper();
public static void toStart() {
helper.start();
}
public static void toStop() {
helper.stop();
}
/**
* @param jobId
* @param triggerType
* @param failRetryCount
* >=0: use this param
* <0: use param from job info config
* @param executorShardingParam
* @param executorParam
* null: use job param
* not null: cover job param
*/
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam, String addressList) {
helper.addTrigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam, addressList);
}
}

53
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorRegistryVo.java

@ -0,0 +1,53 @@
package io.sc.platform.job.core.vo;
import io.sc.platform.orm.api.vo.BaseVo;
import java.util.Date;
public class ExecutorRegistryVo extends BaseVo {
private String id;
private String registryGroup;
private String registryKey;
private String registryValue;
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRegistryGroup() {
return registryGroup;
}
public void setRegistryGroup(String registryGroup) {
this.registryGroup = registryGroup;
}
public String getRegistryKey() {
return registryKey;
}
public void setRegistryKey(String registryKey) {
this.registryKey = registryKey;
}
public String getRegistryValue() {
return registryValue;
}
public void setRegistryValue(String registryValue) {
this.registryValue = registryValue;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

63
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/ExecutorVo.java

@ -0,0 +1,63 @@
package io.sc.platform.job.core.vo;
import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import java.util.Set;
public class ExecutorVo extends CorporationAuditorVo {
private String id;
private String appName;
private String name;
private String description;
private ExecutorAddressType addressType;
private Set<String> addresses;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ExecutorAddressType getAddressType() {
return addressType;
}
public void setAddressType(ExecutorAddressType addressType) {
this.addressType = addressType;
}
public Set<String> getAddresses() {
return addresses;
}
public void setAddresses(Set<String> addresses) {
this.addresses = addresses;
}
}

62
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogReportVo.java

@ -0,0 +1,62 @@
package io.sc.platform.job.core.vo;
import io.sc.platform.orm.api.vo.BaseVo;
import java.util.Date;
public class TaskLogReportVo extends BaseVo {
private String id;
private Date triggerDay;
private int runningCount;
private int sucCount;
private int failCount;
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getTriggerDay() {
return triggerDay;
}
public void setTriggerDay(Date triggerDay) {
this.triggerDay = triggerDay;
}
public int getRunningCount() {
return runningCount;
}
public void setRunningCount(int runningCount) {
this.runningCount = runningCount;
}
public int getSucCount() {
return sucCount;
}
public void setSucCount(int sucCount) {
this.sucCount = sucCount;
}
public int getFailCount() {
return failCount;
}
public void setFailCount(int failCount) {
this.failCount = failCount;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

143
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskLogVo.java

@ -0,0 +1,143 @@
package io.sc.platform.job.core.vo;
import io.sc.platform.orm.api.vo.BaseVo;
import java.util.Date;
public class TaskLogVo extends BaseVo {
private String id;
private String executorId;
private String taskId;
private String executorAddress;
private String executorHandler;
private String executorParam;
private String executorShardingParam;
private int executorFailRetryCount;
private Date triggerTime;
private int triggerCode;
private String triggerMsg;
private Date handleTime;
private int handleCode;
private String handleMsg;
private int alarmStatus;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getExecutorId() {
return executorId;
}
public void setExecutorId(String executorId) {
this.executorId = executorId;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getExecutorAddress() {
return executorAddress;
}
public void setExecutorAddress(String executorAddress) {
this.executorAddress = executorAddress;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public String getExecutorShardingParam() {
return executorShardingParam;
}
public void setExecutorShardingParam(String executorShardingParam) {
this.executorShardingParam = executorShardingParam;
}
public int getExecutorFailRetryCount() {
return executorFailRetryCount;
}
public void setExecutorFailRetryCount(int executorFailRetryCount) {
this.executorFailRetryCount = executorFailRetryCount;
}
public Date getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(Date triggerTime) {
this.triggerTime = triggerTime;
}
public int getTriggerCode() {
return triggerCode;
}
public void setTriggerCode(int triggerCode) {
this.triggerCode = triggerCode;
}
public String getTriggerMsg() {
return triggerMsg;
}
public void setTriggerMsg(String triggerMsg) {
this.triggerMsg = triggerMsg;
}
public Date getHandleTime() {
return handleTime;
}
public void setHandleTime(Date handleTime) {
this.handleTime = handleTime;
}
public int getHandleCode() {
return handleCode;
}
public void setHandleCode(int handleCode) {
this.handleCode = handleCode;
}
public String getHandleMsg() {
return handleMsg;
}
public void setHandleMsg(String handleMsg) {
this.handleMsg = handleMsg;
}
public int getAlarmStatus() {
return alarmStatus;
}
public void setAlarmStatus(int alarmStatus) {
this.alarmStatus = alarmStatus;
}
}

189
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/vo/TaskVo.java

@ -0,0 +1,189 @@
package io.sc.platform.job.core.vo;
import io.sc.platform.job.core.enums.*;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import java.util.Set;
public class TaskVo extends CorporationAuditorVo {
private String id;
private String name;
private String description;
private String executor;
private String alarmEmail;
private TaskScheduleType scheduleType;
private String scheduleConf;
private ExpirationPolicy expirationPolicy;
private ExecutorRouteStrategy routeStrategy;
private String executorHandler;
private String executorParam;
private BlockStrategy blockStrategy;
private int timeout;
private int failRetryCount;
private GlueType glueType;
private String glueSource;
private String parent;
private TriggerStatus triggerStatus;
private long triggerLastTime;
private long triggerNextTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getExecutor() {
return executor;
}
public void setExecutor(String executor) {
this.executor = executor;
}
public String getAlarmEmail() {
return alarmEmail;
}
public void setAlarmEmail(String alarmEmail) {
this.alarmEmail = alarmEmail;
}
public TaskScheduleType getScheduleType() {
return scheduleType;
}
public void setScheduleType(TaskScheduleType scheduleType) {
this.scheduleType = scheduleType;
}
public String getScheduleConf() {
return scheduleConf;
}
public void setScheduleConf(String scheduleConf) {
this.scheduleConf = scheduleConf;
}
public ExpirationPolicy getExpirationPolicy() {
return expirationPolicy;
}
public void setExpirationPolicy(ExpirationPolicy expirationPolicy) {
this.expirationPolicy = expirationPolicy;
}
public ExecutorRouteStrategy getRouteStrategy() {
return routeStrategy;
}
public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) {
this.routeStrategy = routeStrategy;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public BlockStrategy getBlockStrategy() {
return blockStrategy;
}
public void setBlockStrategy(BlockStrategy blockStrategy) {
this.blockStrategy = blockStrategy;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getFailRetryCount() {
return failRetryCount;
}
public void setFailRetryCount(int failRetryCount) {
this.failRetryCount = failRetryCount;
}
public GlueType getGlueType() {
return glueType;
}
public void setGlueType(GlueType glueType) {
this.glueType = glueType;
}
public String getGlueSource() {
return glueSource;
}
public void setGlueSource(String glueSource) {
this.glueSource = glueSource;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public TriggerStatus getTriggerStatus() {
return triggerStatus;
}
public void setTriggerStatus(TriggerStatus triggerStatus) {
this.triggerStatus = triggerStatus;
}
public long getTriggerLastTime() {
return triggerLastTime;
}
public void setTriggerLastTime(long triggerLastTime) {
this.triggerLastTime = triggerLastTime;
}
public long getTriggerNextTime() {
return triggerNextTime;
}
public void setTriggerNextTime(long triggerNextTime) {
this.triggerNextTime = triggerNextTime;
}
}

63
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java → io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorEntity.java

@ -1,15 +1,18 @@
package io.sc.platform.job.manager.jpa.entity; package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.enums.ExecutorAddressType; import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.job.core.vo.ExecutorVo;
import io.sc.platform.orm.converter.SetStringConverter; import io.sc.platform.orm.converter.SetStringConverter;
import io.sc.platform.orm.entity.CorporationAuditorEntity;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.util.Date;
import java.util.Set; import java.util.Set;
public class JobGroupEntity { @Entity
@Table(name="JOB_EXECUTOR")
public class ExecutorEntity extends CorporationAuditorEntity<ExecutorVo> {
//主键 //主键
@Id @Id
@GeneratedValue(generator = "system-uuid") @GeneratedValue(generator = "system-uuid")
@ -18,25 +21,41 @@ public class JobGroupEntity {
@Size(max=36) @Size(max=36)
private String id; private String id;
@Column(name="APP_NAME", length=255) //应用名称
@Column(name="APP_NAME_", length=255)
@Size(min=1,max=255) @Size(min=1,max=255)
private String appName; private String appName;
@Column(name="TITLE", length=255) //名称
@Column(name="NAME_", length=255)
@Size(min=1,max=255) @Size(min=1,max=255)
private String title; private String name;
@Column(name="ADDRESS_TYPE") //描述
@Column(name="DESCRIPTION_", length=255)
@Size(max=255)
private String description;
//地址类型
@Column(name="ADDRESS_TYPE_")
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private ExecutorAddressType addressType; private ExecutorAddressType addressType;
@Column(name="ADDRESS_LIST") //地址列表
@Column(name="ADDRESS_LIST_")
@Convert(converter = SetStringConverter.class) @Convert(converter = SetStringConverter.class)
private Set<String> addresses; private Set<String> addresses;
@Column(name="UPDATE_TIME") @Override
@Temporal(TemporalType.TIMESTAMP) public ExecutorVo toVo() {
private Date updateTime; ExecutorVo vo =new ExecutorVo();
CorporationAuditorEntity.toVo(vo,this);
vo.setId(this.getId());
vo.setAppName(this.getAppName());
vo.setName(this.getName());
vo.setDescription(this.getDescription());
return vo;
}
public String getId() { public String getId() {
return id; return id;
@ -54,12 +73,20 @@ public class JobGroupEntity {
this.appName = appName; this.appName = appName;
} }
public String getTitle() { public String getName() {
return title; return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
} }
public void setTitle(String title) { public void setDescription(String description) {
this.title = title; this.description = description;
} }
public ExecutorAddressType getAddressType() { public ExecutorAddressType getAddressType() {
@ -77,12 +104,4 @@ public class JobGroupEntity {
public void setAddresses(Set<String> addresses) { public void setAddresses(Set<String> addresses) {
this.addresses = addresses; this.addresses = addresses;
} }
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
} }

91
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/ExecutorRegistryEntity.java

@ -0,0 +1,91 @@
package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.vo.ExecutorRegistryVo;
import io.sc.platform.orm.entity.BaseEntity;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
@Entity
@Table(name="JOB_EXECUTOR")
public class ExecutorRegistryEntity extends BaseEntity<ExecutorRegistryVo> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
private String id;
//名称
@Column(name="REGISTRY_GROUP_", length=255)
@Size(max=255)
private String registryGroup;
//名称
@Column(name="REGISTRY_KEY_", length=255)
@Size(max=255)
private String registryKey;
//名称
@Column(name="REGISTRY_VALUE_", length=255)
@Size(max=255)
private String registryValue;
@Column(name="UPDATE_TIME_")
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
@Override
public ExecutorRegistryVo toVo() {
ExecutorRegistryVo vo =new ExecutorRegistryVo();
vo.setId(this.getId());
vo.setRegistryGroup(this.getRegistryGroup());
vo.setRegistryKey(this.getRegistryKey());
vo.setRegistryValue(this.getRegistryValue());
vo.setUpdateTime(this.getUpdateTime());
return vo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRegistryGroup() {
return registryGroup;
}
public void setRegistryGroup(String registryGroup) {
this.registryGroup = registryGroup;
}
public String getRegistryKey() {
return registryKey;
}
public void setRegistryKey(String registryKey) {
this.registryKey = registryKey;
}
public String getRegistryValue() {
return registryValue;
}
public void setRegistryValue(String registryValue) {
this.registryValue = registryValue;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

299
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskEntity.java

@ -0,0 +1,299 @@
package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.enums.*;
import io.sc.platform.job.core.vo.TaskVo;
import io.sc.platform.orm.entity.CorporationAuditorEntity;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
@Entity
@Table(name="JOB_TASK")
public class TaskEntity extends CorporationAuditorEntity<TaskVo> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
private String id;
//名称
@Column(name="NAME_", length=255)
@Size(min=1,max=255)
private String name;
//描述
@Column(name="DESCRIPTION_", length=255)
@Size(max=255)
private String description;
//执行器
@ManyToOne(fetch= FetchType.LAZY)
@JoinColumn(name="EXECUTOR_ID_")
private ExecutorEntity executor;
//报警邮件
@Column(name="ALARM_EMAIL_", length=255)
@Size(max=255)
private String alarmEmail;
//调度类型
@Column(name="SCHEDULE_TYPE_")
@Enumerated(EnumType.STRING)
private TaskScheduleType scheduleType;
//调度配置,值含义取决于调度类型
@Column(name="SCHEDULE_CONF_", length=255)
@Size(max=255)
private String scheduleConf;
//调度过期策略
@Column(name="EXPIRATION_POLICY_")
@Enumerated(EnumType.STRING)
private ExpirationPolicy expirationPolicy;
//执行器路由策略
@Column(name="ROUTE_STRATEGY_")
@Enumerated(EnumType.STRING)
private ExecutorRouteStrategy routeStrategy;
//执行器,任务Handler名称
@Column(name="EXECUTOR_HANDLER_", length=255)
@Size(max=255)
private String executorHandler;
//执行器,任务参数
@Column(name="EXECUTOR_PARAM_", length=255)
@Size(max=255)
private String executorParam;
//阻塞处理策略
@Column(name="BLOCK_STRATEGY_")
@Enumerated(EnumType.STRING)
private BlockStrategy blockStrategy;
//任务执行超时时间,单位秒
@Column(name="TIMEOUT_")
private int timeout;
//失败重试次数
@Column(name="FAIL_RETRY_COUNT_")
private int failRetryCount;
//GLUE类型
@Column(name="GLUE_TYPE_")
@Enumerated(EnumType.STRING)
private GlueType glueType;
//GLUE源代码
@Column(name="GLUE_SOURCE_")
private String glueSource;
//父任务
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="PARENT_ID_")
private TaskEntity parent;
//调度状态
@Column(name="TRIGGER_STATUS_")
@Enumerated(EnumType.STRING)
private TriggerStatus triggerStatus;
//上次调度时间
@Column(name="TRIGGER_LAST_TIME_")
private long triggerLastTime;
//下次调度时间
@Column(name="TRIGGER_NEXT_TIME_")
private long triggerNextTime;
@Override
public TaskVo toVo() {
TaskVo vo =new TaskVo();
CorporationAuditorEntity.toVo(vo,this);
vo.setId(this.getId());
vo.setName(this.getName());
vo.setDescription(this.getDescription());
vo.setExecutor(this.getExecutor()==null?null:this.getExecutor().getId());
vo.setAlarmEmail(this.getAlarmEmail());
vo.setScheduleType(this.getScheduleType());
vo.setScheduleConf(this.getScheduleConf());
vo.setExpirationPolicy(this.getExpirationPolicy());
vo.setRouteStrategy(this.getRouteStrategy());
vo.setExecutorHandler(this.getExecutorHandler());
vo.setExecutorParam(this.getExecutorParam());
vo.setBlockStrategy(this.getBlockStrategy());
vo.setTimeout(this.getTimeout());
vo.setFailRetryCount(this.getFailRetryCount());
vo.setGlueType(this.getGlueType());
vo.setGlueSource(this.getGlueSource());
vo.setParent(this.getParent()==null?null:this.getParent().getId());
vo.setTriggerStatus(this.getTriggerStatus());
vo.setTriggerLastTime(this.getTriggerLastTime());
vo.setTriggerNextTime(this.getTriggerNextTime());
return vo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ExecutorEntity getExecutor() {
return executor;
}
public void setExecutor(ExecutorEntity executor) {
this.executor = executor;
}
public String getAlarmEmail() {
return alarmEmail;
}
public void setAlarmEmail(String alarmEmail) {
this.alarmEmail = alarmEmail;
}
public TaskScheduleType getScheduleType() {
return scheduleType;
}
public void setScheduleType(TaskScheduleType scheduleType) {
this.scheduleType = scheduleType;
}
public String getScheduleConf() {
return scheduleConf;
}
public void setScheduleConf(String scheduleConf) {
this.scheduleConf = scheduleConf;
}
public ExpirationPolicy getExpirationPolicy() {
return expirationPolicy;
}
public void setExpirationPolicy(ExpirationPolicy expirationPolicy) {
this.expirationPolicy = expirationPolicy;
}
public ExecutorRouteStrategy getRouteStrategy() {
return routeStrategy;
}
public void setRouteStrategy(ExecutorRouteStrategy routeStrategy) {
this.routeStrategy = routeStrategy;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public BlockStrategy getBlockStrategy() {
return blockStrategy;
}
public void setBlockStrategy(BlockStrategy blockStrategy) {
this.blockStrategy = blockStrategy;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getFailRetryCount() {
return failRetryCount;
}
public void setFailRetryCount(int failRetryCount) {
this.failRetryCount = failRetryCount;
}
public GlueType getGlueType() {
return glueType;
}
public void setGlueType(GlueType glueType) {
this.glueType = glueType;
}
public String getGlueSource() {
return glueSource;
}
public void setGlueSource(String glueSource) {
this.glueSource = glueSource;
}
public TaskEntity getParent() {
return parent;
}
public void setParent(TaskEntity parent) {
this.parent = parent;
}
public TriggerStatus getTriggerStatus() {
return triggerStatus;
}
public void setTriggerStatus(TriggerStatus triggerStatus) {
this.triggerStatus = triggerStatus;
}
public long getTriggerLastTime() {
return triggerLastTime;
}
public void setTriggerLastTime(long triggerLastTime) {
this.triggerLastTime = triggerLastTime;
}
public long getTriggerNextTime() {
return triggerNextTime;
}
public void setTriggerNextTime(long triggerNextTime) {
this.triggerNextTime = triggerNextTime;
}
}

230
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogEntity.java

@ -0,0 +1,230 @@
package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.vo.TaskLogVo;
import io.sc.platform.job.core.vo.TaskVo;
import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.entity.CorporationAuditorEntity;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
@Entity
@Table(name="JOB_TASK_LOG")
public class TaskLogEntity extends BaseEntity<TaskLogVo> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
private String id;
//执行器ID
@Column(name="EXECUTOR_ID_", length=36)
private String executorId;
//任务ID
@Column(name="TASK_ID_", length=36)
private String taskId;
// execute info
//执行器地址,本次执行的地址
@Column(name="EXECUTOR_ADDRESS_", length=255)
@Size(max=255)
private String executorAddress;
//执行器任务handler
@Column(name="EXECUTOR_HANDLER_", length=255)
@Size(max=255)
private String executorHandler;
//执行器任务参数
@Column(name="EXECUTOR_PARAM_", length=255)
@Size(max=255)
private String executorParam;
//执行器任务分片参数,格式如 1/2
@Column(name="EXECUTOR_SHARDING_PARAM_", length=20)
@Size(max=20)
private String executorShardingParam;
//失败重试次数
@Column(name="EXECUTOR_FAIL_RETRY_COUNT_")
private int executorFailRetryCount;
// trigger info
//调度-时间
@Column(name="TRIGGER_TIME_")
@Temporal(TemporalType.TIMESTAMP)
private Date triggerTime;
//调度-结果
@Column(name="TRIGGER_CODE_")
private int triggerCode;
//调度-日志
@Column(name="TRIGGER_MSG_")
private String triggerMsg;
// handle info
//执行-时间
@Column(name="HANDLE_TIME_")
@Temporal(TemporalType.TIMESTAMP)
private Date handleTime;
//执行-状态
@Column(name="HANDLE_CODE_")
private int handleCode;
//执行-日志
@Column(name="HANDLE_MSG_")
private String handleMsg;
// alarm info
//告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败
@Column(name="ALARM_STATUS_")
private int alarmStatus;
@Override
public TaskLogVo toVo() {
TaskLogVo vo =new TaskLogVo();
vo.setId(this.getId());
vo.setExecutorId(this.getExecutorId());
vo.setTaskId(this.getTaskId());
vo.setExecutorAddress(this.getExecutorAddress());
vo.setExecutorHandler(this.getExecutorHandler());
vo.setExecutorParam(this.getExecutorParam());
vo.setExecutorShardingParam(this.getExecutorShardingParam());
vo.setExecutorFailRetryCount(this.getExecutorFailRetryCount());
vo.setTriggerTime(this.getTriggerTime());
vo.setTriggerCode(this.getTriggerCode());
vo.setTriggerMsg(this.getTriggerMsg());
vo.setHandleTime(this.getHandleTime());
vo.setHandleCode(this.getHandleCode());
vo.setHandleMsg(this.getHandleMsg());
vo.setAlarmStatus(this.getAlarmStatus());
return vo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getExecutorId() {
return executorId;
}
public void setExecutorId(String executorId) {
this.executorId = executorId;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getExecutorAddress() {
return executorAddress;
}
public void setExecutorAddress(String executorAddress) {
this.executorAddress = executorAddress;
}
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() {
return executorParam;
}
public void setExecutorParam(String executorParam) {
this.executorParam = executorParam;
}
public String getExecutorShardingParam() {
return executorShardingParam;
}
public void setExecutorShardingParam(String executorShardingParam) {
this.executorShardingParam = executorShardingParam;
}
public int getExecutorFailRetryCount() {
return executorFailRetryCount;
}
public void setExecutorFailRetryCount(int executorFailRetryCount) {
this.executorFailRetryCount = executorFailRetryCount;
}
public Date getTriggerTime() {
return triggerTime;
}
public void setTriggerTime(Date triggerTime) {
this.triggerTime = triggerTime;
}
public int getTriggerCode() {
return triggerCode;
}
public void setTriggerCode(int triggerCode) {
this.triggerCode = triggerCode;
}
public String getTriggerMsg() {
return triggerMsg;
}
public void setTriggerMsg(String triggerMsg) {
this.triggerMsg = triggerMsg;
}
public Date getHandleTime() {
return handleTime;
}
public void setHandleTime(Date handleTime) {
this.handleTime = handleTime;
}
public int getHandleCode() {
return handleCode;
}
public void setHandleCode(int handleCode) {
this.handleCode = handleCode;
}
public String getHandleMsg() {
return handleMsg;
}
public void setHandleMsg(String handleMsg) {
this.handleMsg = handleMsg;
}
public int getAlarmStatus() {
return alarmStatus;
}
public void setAlarmStatus(int alarmStatus) {
this.alarmStatus = alarmStatus;
}
}

99
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/TaskLogReportEntity.java

@ -0,0 +1,99 @@
package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.vo.TaskLogReportVo;
import io.sc.platform.job.core.vo.TaskLogVo;
import io.sc.platform.orm.entity.BaseEntity;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
@Entity
@Table(name="JOB_TASK_LOG_REPORT")
public class TaskLogReportEntity extends BaseEntity<TaskLogReportVo> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
private String id;
@Column(name="TRIGGER_DAY_")
@Temporal(TemporalType.TIMESTAMP)
private Date triggerDay;
@Column(name="RUNNING_COUNT_")
private int runningCount;
@Column(name="SUC_COUNT_")
private int sucCount;
@Column(name="FAIL_COUNT_")
private int failCount;
@Column(name="UPDATE_TIME_")
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
@Override
public TaskLogReportVo toVo() {
TaskLogReportVo vo =new TaskLogReportVo();
vo.setId(this.getId());
vo.setTriggerDay(this.getTriggerDay());
vo.setRunningCount(this.getRunningCount());
vo.setSucCount(this.getSucCount());
vo.setFailCount(this.getFailCount());
vo.setUpdateTime(this.getUpdateTime());
return vo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getTriggerDay() {
return triggerDay;
}
public void setTriggerDay(Date triggerDay) {
this.triggerDay = triggerDay;
}
public int getRunningCount() {
return runningCount;
}
public void setRunningCount(int runningCount) {
this.runningCount = runningCount;
}
public int getSucCount() {
return sucCount;
}
public void setSucCount(int sucCount) {
this.sucCount = sucCount;
}
public int getFailCount() {
return failCount;
}
public void setFailCount(int failCount) {
this.failCount = failCount;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

12
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRegistryRepository.java

@ -0,0 +1,12 @@
package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.job.manager.jpa.entity.ExecutorEntity;
import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity;
import io.sc.platform.orm.repository.DaoRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface ExecutorRegistryRepository extends DaoRepository<ExecutorRegistryEntity,String> {
}

6
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java → io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/ExecutorRepository.java

@ -1,12 +1,12 @@
package io.sc.platform.job.manager.jpa.repository; package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.core.enums.ExecutorAddressType; import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.job.manager.jpa.entity.JobGroupEntity; import io.sc.platform.job.manager.jpa.entity.ExecutorEntity;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import java.util.List; import java.util.List;
public interface JobGroupRepository extends DaoRepository<JobGroupEntity,String> { public interface ExecutorRepository extends DaoRepository<ExecutorEntity,String> {
public List<JobGroupEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType); public List<ExecutorEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType);
} }

8
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogReportRepository.java

@ -0,0 +1,8 @@
package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.manager.jpa.entity.TaskLogEntity;
import io.sc.platform.job.manager.jpa.entity.TaskLogReportEntity;
import io.sc.platform.orm.repository.DaoRepository;
public interface TaskLogReportRepository extends DaoRepository<TaskLogReportEntity,String> {
}

7
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskLogRepository.java

@ -0,0 +1,7 @@
package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.manager.jpa.entity.TaskLogEntity;
import io.sc.platform.orm.repository.DaoRepository;
public interface TaskLogRepository extends DaoRepository<TaskLogEntity,String> {
}

8
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/TaskRepository.java

@ -0,0 +1,8 @@
package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.manager.jpa.entity.ExecutorRegistryEntity;
import io.sc.platform.job.manager.jpa.entity.TaskEntity;
import io.sc.platform.orm.repository.DaoRepository;
public interface TaskRepository extends DaoRepository<TaskEntity,String> {
}

10
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/TaskService.java

@ -0,0 +1,10 @@
package io.sc.platform.job.manager.service;
import io.sc.platform.job.manager.jpa.entity.TaskEntity;
import io.sc.platform.job.manager.jpa.repository.TaskRepository;
import io.sc.platform.orm.service.DaoService;
public interface TaskService extends DaoService<TaskEntity, String, TaskRepository> {
public void start(int id);
public void stop(int id);
}

58
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/service/impl/TaskServiceImpl.java

@ -0,0 +1,58 @@
package io.sc.platform.job.manager.service.impl;
import io.sc.platform.job.core.enums.TaskScheduleType;
import io.sc.platform.job.manager.jpa.entity.TaskEntity;
import io.sc.platform.job.manager.jpa.repository.TaskRepository;
import io.sc.platform.job.manager.service.TaskService;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import java.util.Date;
public class TaskServiceImpl extends DaoServiceImpl<TaskEntity, String, TaskRepository> implements TaskService {
@Override
public void start(String id) {
TaskEntity taskEntity =this.findById(id);
if(taskEntity==null){
return;
}
if(TaskScheduleType.NONE.equals(taskEntity.getScheduleType())){
throw new RuntimeException();
}
long nextTriggerTime = 0;
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
// valid
ScheduleTypeEnum scheduleTypeEnum = ScheduleTypeEnum.match(xxlJobInfo.getScheduleType(), ScheduleTypeEnum.NONE);
if (ScheduleTypeEnum.NONE == scheduleTypeEnum) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type_none_limit_start")) );
}
// next trigger time (5s后生效,避开预读周期)
long nextTriggerTime = 0;
try {
Date nextValidTime = JobScheduleHelper.generateNextValidTime(xxlJobInfo, new Date(System.currentTimeMillis() + JobScheduleHelper.PRE_READ_MS));
if (nextValidTime == null) {
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
nextTriggerTime = nextValidTime.getTime();
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new ReturnT<String>(ReturnT.FAIL_CODE, (I18nUtil.getString("schedule_type")+I18nUtil.getString("system_unvalid")) );
}
xxlJobInfo.setTriggerStatus(1);
xxlJobInfo.setTriggerLastTime(0);
xxlJobInfo.setTriggerNextTime(nextTriggerTime);
xxlJobInfo.setUpdateTime(new Date());
xxlJobInfoDao.update(xxlJobInfo);
return ReturnT.SUCCESS;
}
@Override
public void stop(int id) {
}
}

166
io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml

@ -17,7 +17,173 @@
<property name="now" value="now()" dbms="postgresql"/> <property name="now" value="now()" dbms="postgresql"/>
<property name="now" value="GETDATE()" dbms="mssql"/> <property name="now" value="GETDATE()" dbms="mssql"/>
<changeSet id="PF_8.0.0_20220606__Job_DDL" author="platform"> <changeSet id="PF_8.0.0_20220606__Job_DDL" author="platform">
<!-- JOB 执行器表 -->
<createTable tableName="JOB_EXECUTOR" remarks="JOB 执行器表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/>
</column>
<column name="APP_NAME_" type="NVARCHAR(255)" remarks="执行器AppName"/>
<column name="NAME_" type="NVARCHAR(255)" remarks="执行器名称"/>
<column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"></column>
<column name="ADDRESS_TYPE_" type="NVARCHAR(20)" remarks="执行器地址类型:AUTO=自动注册、MANUAL=手动录入"/>
<column name="ADDRESS_LIST_" type="NVARCHAR(2000)" remarks="执行器地址列表"/>
<column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
<column name="DATA_COME_FROM_" type="NVARCHAR(10)" remarks="数据来源(INPUT:手工录入,IMPORT:系统自动导入)"/>
<column name="CREATOR_" type="NVARCHAR(255)" remarks="创建人"/>
<column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"/>
<column name="LAST_MODIFIER_" type="NVARCHAR(255)" remarks="最后修改人"/>
<column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"/>
<column name="CORP_CODE_" type="NVARCHAR(255)" remarks="所属法人代码"/>
</createTable>
<addNotNullConstraint columnName="APP_NAME_" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR" constraintName="CONST_JOB_EXECUTOR_APP_NAME"/>
<addNotNullConstraint columnName="NAME_" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR" constraintName="CONST_JOB_EXECUTOR_NAME"/>
<addNotNullConstraint columnName="ADDRESS_TYPE_" columnDataType="NVARCHAR(20)" tableName="JOB_EXECUTOR" constraintName="CONST_JOB_EXECUTOR_ADDRESS_TYPE"/>
<addNotNullConstraint columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="JOB_EXECUTOR" constraintName="CONST_JOB_EXECUTOR_DCF"/>
<addNotNullConstraint columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR" constraintName="CONST_JOB_EXECUTOR_CORP"/>
<addDefaultValue columnName="ADDRESS_TYPE_" columnDataType="NVARCHAR(20)" tableName="JOB_EXECUTOR" defaultValue="AUTO"/>
<addDefaultValue columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="JOB_EXECUTOR" defaultValue="INPUT"/>
<addDefaultValue columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR" defaultValue="_PRIMARY_"/>
<!-- JOB 任务表 -->
<createTable tableName="JOB_TASK" remarks="JOB 任务表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/>
</column>
<column name="NAME_" type="NVARCHAR(255)" remarks="名称"/>
<column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"></column>
<column name="EXECUTOR_ID_" type="NVARCHAR(36)" remarks="执行器ID"></column>
<column name="ALARM_EMAIL_" type="NVARCHAR(255)" remarks="告警邮箱"/>
<column name="SCHEDULE_TYPE_" type="NVARCHAR(20)" remarks="调度类型"/>
<column name="SCHEDULE_CONF_" type="NVARCHAR(255)" remarks="调度配置"/>
<column name="EXPIRATION_POLICY_" type="NVARCHAR(20)" remarks="调度过期策略"/>
<column name="ROUTE_STRATEGY_" type="NVARCHAR(30)" remarks="执行器路由策略"/>
<column name="EXECUTOR_HANDLER_" type="NVARCHAR(255)" remarks="执行器,任务Handler名称"/>
<column name="EXECUTOR_PARAM_" type="NVARCHAR(255)" remarks="执行器,任务参数"/>
<column name="BLOCK_STRATEGY_" type="NVARCHAR(20)" remarks="阻塞处理策略"/>
<column name="TIMEOUT_" type="INTEGER" remarks="任务执行超时时间,单位秒"/>
<column name="FAIL_RETRY_COUNT_" type="INTEGER" remarks="失败重试次数"/>
<column name="GLUE_TYPE_" type="NVARCHAR(20)" remarks="GLUE类型"/>
<column name="GLUE_SOURCE_" type="CLOB" remarks="GLUE源代码"/>
<column name="PARENT_ID_" type="NVARCHAR(36)" remarks="父任务ID"></column>
<column name="TRIGGER_STATUS_" type="NVARCHAR(20)" remarks="调度状态"/>
<column name="TRIGGER_LAST_TIME_" type="BIGINT" remarks="上次调度时间"/>
<column name="TRIGGER_NEXT_TIME_" type="BIGINT" remarks="下次调度时间"/>
<column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
<column name="DATA_COME_FROM_" type="NVARCHAR(10)" remarks="数据来源(INPUT:手工录入,IMPORT:系统自动导入)"/>
<column name="CREATOR_" type="NVARCHAR(255)" remarks="创建人"/>
<column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"/>
<column name="LAST_MODIFIER_" type="NVARCHAR(255)" remarks="最后修改人"/>
<column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"/>
<column name="CORP_CODE_" type="NVARCHAR(255)" remarks="所属法人代码"/>
</createTable>
<addNotNullConstraint columnName="EXECUTOR_ID_" columnDataType="NVARCHAR(36)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_EXECUTOR_ID"/>
<addNotNullConstraint columnName="NAME_" columnDataType="NVARCHAR(255)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_NAME_"/>
<addNotNullConstraint columnName="SCHEDULE_TYPE_" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_SCHEDULE_TYPE"/>
<addDefaultValue columnName="SCHEDULE_TYPE" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" defaultValue="NONE"/>
<addNotNullConstraint columnName="EXPIRATION_POLICY_" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_EXPIRATION_POLICY"/>
<addDefaultValue columnName="EXPIRATION_POLICY_" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" defaultValue="DO_NOTHING"/>
<addNotNullConstraint columnName="TIMEOUT_" columnDataType="INTEGER" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_TIMEOUT"/>
<addDefaultValue columnName="TIMEOUT_" columnDataType="INTEGER" tableName="JOB_TASK" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="FAIL_RETRY_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_FAIL_RETRY_COUNT"/>
<addDefaultValue columnName="FAIL_RETRY_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_STATUS_" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_TRIGGER_STATUS"/>
<addDefaultValue columnName="TRIGGER_STATUS_" columnDataType="NVARCHAR(20)" tableName="JOB_TASK" defaultValue="STOPED"/>
<addNotNullConstraint columnName="TRIGGER_LAST_TIME_" columnDataType="BIGINT" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_TRIGGER_LAST_TIME"/>
<addDefaultValue columnName="TRIGGER_LAST_TIME_" columnDataType="BIGINT" tableName="JOB_TASK" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_NEXT_TIME_" columnDataType="BIGINT" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_TRIGGER_NEXT_TIME"/>
<addDefaultValue columnName="TRIGGER_NEXT_TIME_" columnDataType="BIGINT" tableName="JOB_TASK" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_DCF"/>
<addNotNullConstraint columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="JOB_TASK" constraintName="CONST_JOB_TASK_CORP"/>
<addDefaultValue columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="JOB_TASK" defaultValue="INPUT"/>
<addDefaultValue columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="JOB_TASK" defaultValue="_PRIMARY_"/>
<!-- JOB 任务执行日志表 -->
<createTable tableName="JOB_TASK_LOG" remarks="JOB 任务执行日志表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/>
</column>
<column name="EXECUTOR_ID_" type="NVARCHAR(36)" remarks="执行器ID" />
<column name="TASK_ID_" type="NVARCHAR(36)" remarks="任务ID"/>
<column name="EXECUTOR_ADDRESS_" type="NVARCHAR(255)" remarks="执行器地址,本次执行的地址"/>
<column name="EXECUTOR_HANDLER_" type="NVARCHAR(255)" remarks="执行器任务handler"/>
<column name="EXECUTOR_PARAM_" type="NVARCHAR(255)" remarks="执行器任务参数"/>
<column name="EXECUTOR_SHARDING_PARAM_" type="NVARCHAR(20)" remarks="执行器任务分片参数,格式如 1/2"/>
<column name="EXECUTOR_FAIL_RETRY_COUNT_" type="INTEGER" remarks="失败重试次数"/>
<column name="TRIGGER_TIME_" type="DATETIME" remarks="调度-时间"/>
<column name="TRIGGER_CODE_" type="INTEGER" remarks="调度-结果"/>
<column name="TRIGGER_MSG_" type="CLOB" remarks="调度-日志"/>
<column name="HANDLE_TIME_" type="DATETIME" remarks="执行-时间"/>
<column name="HANDLE_CODE_" type="INTEGER" remarks="执行-状态"/>
<column name="HANDLE_MSG_" type="CLOB" remarks="执行-日志"/>
<column name="ALARM_STATUS_" type="TINYINT" remarks="告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败" defaultValueNumeric="0"/>
</createTable>
<addNotNullConstraint columnName="EXECUTOR_ID_" columnDataType="NVARCHAR(36)" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_EXECUTOR_ID"/>
<addNotNullConstraint columnName="TASK_ID_" columnDataType="NVARCHAR(36)" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_TASK_ID"/>
<addNotNullConstraint columnName="EXECUTOR_FAIL_RETRY_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_EXECUTOR_FRC"/>
<addDefaultValue columnName="EXECUTOR_FAIL_RETRY_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_CODE_" columnDataType="INTEGER" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_TRIGGER_CODE"/>
<addNotNullConstraint columnName="HANDLE_CODE_" columnDataType="INTEGER" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_HANDLE_CODE"/>
<addNotNullConstraint columnName="ALARM_STATUS_" columnDataType="TINYINT" tableName="JOB_TASK_LOG" constraintName="CONST_JOB_TASK_LOG_ALARM_STATUS"/>
<addDefaultValue columnName="ALARM_STATUS_" columnDataType="TINYINT" tableName="JOB_TASK_LOG" defaultValueNumeric="0"/>
<createIndex tableName="JOB_TASK_LOG" indexName="IDX_JOB_TASK_LOG_TRIGGER_TIME">
<column name="TRIGGER_TIME_"></column>
</createIndex>
<createIndex tableName="JOB_TASK_LOG" indexName="IDX_JOB_TASK_LOG_HANDLE_CODE">
<column name="HANDLE_CODE_"></column>
</createIndex>
<!-- JOB 执行器注册表 -->
<createTable tableName="JOB_EXECUTOR_REGISTRY" remarks="JOB 执行器注册表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/>
</column>
<column name="REGISTRY_GROUP_" type="NVARCHAR(255)" remarks=""/>
<column name="REGISTRY_KEY_" type="NVARCHAR(255)" remarks=""/>
<column name="REGISTRY_VALUE_" type="NVARCHAR(255)" remarks=""/>
<column name="UPDATE_TIME_" type="DATETIME" remarks="更新日期"/>
</createTable>
<addUniqueConstraint tableName="JOB_EXECUTOR_REGISTRY" columnNames="REGISTRY_GROUP,REGISTRY_KEY,REGISTRY_VALUE"></addUniqueConstraint>
<addNotNullConstraint columnName="REGISTRY_GROUP" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR_REGISTRY" constraintName="CONST_JOB_EXECUTOR_REGISTRY_REGISTRY_GROUP"/>
<addNotNullConstraint columnName="REGISTRY_KEY" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR_REGISTRY" constraintName="CONST_JOB_EXECUTOR_REGISTRY_REGISTRY_KEY"/>
<addNotNullConstraint columnName="REGISTRY_VALUE" columnDataType="NVARCHAR(255)" tableName="JOB_EXECUTOR_REGISTRY" constraintName="CONST_JOB_EXECUTOR_REGISTRY_REGISTRY_VALUE"/>
<!-- JOB 任务日志报告表 -->
<createTable tableName="JOB_TASK_LOG_REPORT" remarks="JOB 任务日志报告表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/>
</column>
<column name="TRIGGER_DAY_" type="DATETIME" remarks="调度-时间"/>
<column name="RUNNING_COUNT_" type="INTEGER" remarks="运行中-日志数量" defaultValueNumeric="0"/>
<column name="SUC_COUNT_" type="INTEGER" remarks="执行成功-日志数量" defaultValueNumeric="0"/>
<column name="FAIL_COUNT_" type="INTEGER" remarks="执行失败-日志数量" defaultValueNumeric="0"/>
<column name="UPDATE_TIME_" type="DATETIME" remarks="更新日期"></column>
</createTable>
<addNotNullConstraint columnName="RUNNING_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" constraintName="CONST_JOB_TASK_LOG_REPORT_RUNNING_COUNT"/>
<addDefaultValue columnName="RUNNING_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="SUC_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" constraintName="CONST_JOB_TASK_LOG_REPORT_SUC_COUNT"/>
<addDefaultValue columnName="SUC_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="FAIL_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" constraintName="CONST_JOB_TASK_LOG_REPORT_FAIL_COUNT"/>
<addDefaultValue columnName="FAIL_COUNT_" columnDataType="INTEGER" tableName="JOB_TASK_LOG_REPORT" defaultValueNumeric="0"/>
<createIndex tableName="JOB_TASK_LOG_REPORT" indexName="IDX_JOB_TASK_LOG_REPORT_TRIGGER_DAY" unique="true">
<column name="TRIGGER_DAY_"></column>
</createIndex>
<!-- JOB信息表 --> <!-- JOB信息表 -->
<createTable tableName="XXL_JOB_INFO" remarks="JOB信息表"> <createTable tableName="XXL_JOB_INFO" remarks="JOB信息表">
<column name="ID" type="INTEGER" remarks="主键ID"/> <column name="ID" type="INTEGER" remarks="主键ID"/>

4
io.sc.platform.lcdp.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.lcdp.frontend", "name": "io.sc.platform.lcdp.frontend",
"version": "8.1.19", "version": "8.1.20",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
@ -92,7 +92,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.45", "platform-core": "8.1.47",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

4
io.sc.platform.mvc.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.mvc.frontend", "name": "io.sc.platform.mvc.frontend",
"version": "8.1.19", "version": "8.1.20",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
@ -79,7 +79,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.45", "platform-core": "8.1.47",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

4
io.sc.platform.security.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.security.frontend", "name": "io.sc.platform.security.frontend",
"version": "8.1.19", "version": "8.1.20",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [
@ -79,7 +79,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.45", "platform-core": "8.1.47",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

2
io.sc.platform.system.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.system.frontend", "name": "io.sc.platform.system.frontend",
"version": "8.1.19", "version": "8.1.20",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [ "keywords": [

1
io.sc.platform.system/src/main/java/io/sc/platform/system/role/jpa/entity/RoleEntity.java

@ -22,7 +22,6 @@ import java.util.Set;
*/ */
@Entity @Entity
@Table(name="SYS_ROLE") @Table(name="SYS_ROLE")
@JsonSerialize(using = RoleEntityJsonSerializer.class)
public class RoleEntity extends CorporationAuditorEntity<RoleVo> { public class RoleEntity extends CorporationAuditorEntity<RoleVo> {
//主键 //主键
@Id @Id

Loading…
Cancel
Save