You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/07/09 16:55:04 UTC
[shardingsphere-elasticjob-lite] branch master updated: Merge
ElasticJob Lite and ElasticJob Cloud to one repo (#1012)
This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob-lite.git
The following commit(s) were added to refs/heads/master by this push:
new bf6aff6 Merge ElasticJob Lite and ElasticJob Cloud to one repo (#1012)
bf6aff6 is described below
commit bf6aff67e2901b0ce6f46ddf1aab29e2f77678ce
Author: Liang Zhang <te...@163.com>
AuthorDate: Fri Jul 10 00:54:52 2020 +0800
Merge ElasticJob Lite and ElasticJob Cloud to one repo (#1012)
* Move elastic-job-cloud and elastic-job-lite to same repo
* Rename shardingsphere-elastic-job-lite to shardingsphere-elastic-job
* Update example pom
* Rename elastic-job to elasticjob
* Add elasticjob-lite module
* Add elasticjob-cloud module
* Rename elastic-job-example to elasticjob-example
* Rename elastic-job-lite to elasticjob-lite
* Rename elastic-job-cloud to elasticjob-cloud
---
README.md | 4 +-
README_ZH.md | 6 +-
docs/content/quick-start/_index.cn.md | 4 +-
docs/content/user-manual/deploy-guide.cn.md | 4 +-
docs/content/user-manual/job-config.cn.md | 4 +-
docs/content/user-manual/web-console.cn.md | 4 +-
elastic-job-lite-console/.dockerignore | 18 -
elastic-job-lite-console/Dockerfile | 23 -
elastic-job-lite-console/README.md | 7 -
elastic-job-lite-console/pom.xml | 147 -
.../src/main/resources/bin/start.sh | 51 -
.../src/main/resources/logback.xml | 75 -
elastic-job-lite-core/pom.xml | 106 -
.../src/test/resources/logback-test.xml | 42 -
.../elastic-job-lite-dataflow-executor/pom.xml | 48 -
.../elastic-job-lite-script-executor/pom.xml | 48 -
.../elastic-job-lite-simple-executor/pom.xml | 48 -
elastic-job-lite-executor/pom.xml | 37 -
elastic-job-lite-lifecycle/pom.xml | 105 -
.../src/test/resources/logback-test.xml | 38 -
elastic-job-lite-spring/pom.xml | 114 -
.../src/test/resources/conf/job/conf.properties | 39 -
.../elastic-job-lite-tracing-api/pom.xml | 79 -
.../src/test/resources/logback-test.xml | 41 -
.../elastic-job-lite-tracing-rdb/pom.xml | 80 -
.../src/test/resources/logback-test.xml | 38 -
elastic-job-lite-tracing/pom.xml | 36 -
elasticjob-cloud/elasticjob-cloud-common/pom.xml | 119 +
.../elasticjob/cloud/api/ElasticJob.java | 24 +
.../elasticjob/cloud/api/JobType.java | 26 +
.../elasticjob/cloud/api/ShardingContext.java | 72 +
.../elasticjob/cloud/api/dataflow/DataflowJob.java | 47 +
.../elasticjob/cloud/api/script/ScriptJob.java | 26 +
.../elasticjob/cloud/api/simple/SimpleJob.java | 34 +
.../cloud/config/JobCoreConfiguration.java | 189 +
.../cloud/config/JobRootConfiguration.java | 31 +
.../cloud/config/JobTypeConfiguration.java | 47 +
.../config/dataflow/DataflowJobConfiguration.java | 40 +
.../config/script/ScriptJobConfiguration.java | 41 +
.../config/simple/SimpleJobConfiguration.java | 38 +
.../elasticjob/cloud/context/ExecutionType.java | 34 +
.../elasticjob/cloud/context/TaskContext.java | 163 +
.../elasticjob/cloud/event/JobEvent.java | 31 +
.../elasticjob/cloud/event/JobEventBus.java | 71 +
.../cloud/event/JobEventConfiguration.java | 32 +
.../elasticjob/cloud/event/JobEventIdentity.java | 31 +
.../elasticjob/cloud/event/JobEventListener.java | 47 +
.../JobEventListenerConfigurationException.java | 30 +
.../elasticjob/cloud/event/rdb/DatabaseType.java | 58 +
.../cloud/event/rdb/JobEventRdbConfiguration.java | 49 +
.../cloud/event/rdb/JobEventRdbIdentity.java | 31 +
.../cloud/event/rdb/JobEventRdbListener.java | 47 +
.../cloud/event/rdb/JobEventRdbSearch.java | 300 +
.../cloud/event/rdb/JobEventRdbStorage.java | 364 ++
.../cloud/event/type/JobExecutionEvent.java | 104 +
.../event/type/JobExecutionEventThrowable.java | 37 +
.../cloud/event/type/JobStatusTraceEvent.java | 68 +
.../cloud/exception/AppConfigurationException.java | 34 +
.../elasticjob/cloud/exception/ExceptionUtil.java | 48 +
.../cloud/exception/JobConfigurationException.java | 34 +
.../JobExecutionEnvironmentException.java | 30 +
.../cloud/exception/JobStatisticException.java | 30 +
.../cloud/exception/JobSystemException.java | 34 +
.../cloud/executor/AbstractElasticJobExecutor.java | 221 +
.../cloud/executor/JobExecutorFactory.java | 56 +
.../elasticjob/cloud/executor/JobFacade.java | 144 +
.../cloud/executor/ShardingContexts.java | 90 +
.../executor/handler/ExecutorServiceHandler.java | 35 +
.../handler/ExecutorServiceHandlerRegistry.java | 57 +
.../executor/handler/JobExceptionHandler.java | 32 +
.../cloud/executor/handler/JobProperties.java | 116 +
.../impl/DefaultExecutorServiceHandler.java | 34 +
.../handler/impl/DefaultJobExceptionHandler.java | 33 +
.../cloud/executor/type/DataflowJobExecutor.java | 75 +
.../cloud/executor/type/ScriptJobExecutor.java | 59 +
.../cloud/executor/type/SimpleJobExecutor.java | 41 +
.../cloud/reg/base/CoordinatorRegistryCenter.java | 96 +
.../cloud/reg/base/ElectionCandidate.java | 42 +
.../elasticjob/cloud/reg/base/RegistryCenter.java | 88 +
.../cloud/reg/exception/RegException.java | 34 +
.../cloud/reg/exception/RegExceptionHandler.java | 55 +
.../reg/zookeeper/ZookeeperConfiguration.java | 77 +
.../reg/zookeeper/ZookeeperElectionService.java | 81 +
.../reg/zookeeper/ZookeeperRegistryCenter.java | 331 +
.../cloud/statistics/StatisticInterval.java | 37 +
.../statistics/rdb/StatisticRdbRepository.java | 495 ++
.../type/job/JobExecutionTypeStatistics.java | 33 +
.../statistics/type/job/JobRegisterStatistics.java | 41 +
.../statistics/type/job/JobRunningStatistics.java | 41 +
.../statistics/type/job/JobTypeStatistics.java | 35 +
.../statistics/type/task/TaskResultStatistics.java | 46 +
.../type/task/TaskRunningStatistics.java | 41 +
.../cloud/util/concurrent/BlockUtils.java | 44 +
.../util/concurrent/ExecutorServiceObject.java | 81 +
.../cloud/util/config/ShardingItemParameters.java | 80 +
.../cloud/util/config/ShardingItems.java | 66 +
.../elasticjob/cloud/util/digest/Encryption.java | 51 +
.../elasticjob/cloud/util/env/HostException.java | 32 +
.../elasticjob/cloud/util/env/IpUtils.java | 98 +
.../elasticjob/cloud/util/env/TimeService.java | 33 +
.../AbstractJobConfigurationGsonTypeAdapter.java | 193 +
.../elasticjob/cloud/util/json/GsonFactory.java | 57 +
.../elasticjob/cloud/AllCoreTests.java | 49 +
.../elasticjob/cloud/api/AllApiTests.java | 27 +
.../elasticjob/cloud/api/ShardingContextTest.java | 45 +
.../elasticjob/cloud/config/AllConfigTests.java | 27 +
.../cloud/config/JobCoreConfigurationTest.java | 87 +
.../elasticjob/cloud/context/AllContextTests.java | 26 +
.../elasticjob/cloud/context/TaskContextTest.java | 121 +
.../elasticjob/cloud/event/AllEventTests.java | 39 +
.../elasticjob/cloud/event/JobEventBusTest.java | 76 +
.../cloud/event/JobExecutionEventTest.java | 57 +
.../cloud/event/fixture/JobEventCaller.java | 26 +
.../event/fixture/TestJobEventConfiguration.java | 34 +
.../fixture/TestJobEventFailureConfiguration.java | 30 +
.../cloud/event/fixture/TestJobEventIdentity.java | 28 +
.../cloud/event/fixture/TestJobEventListener.java | 51 +
.../event/rdb/JobEventRdbConfigurationTest.java | 53 +
.../cloud/event/rdb/JobEventRdbIdentityTest.java | 30 +
.../cloud/event/rdb/JobEventRdbListenerTest.java | 79 +
.../cloud/event/rdb/JobEventRdbSearchTest.java | 241 +
.../cloud/event/rdb/JobEventRdbStorageTest.java | 136 +
.../cloud/exception/AllExceptionTests.java | 33 +
.../cloud/exception/ExceptionUtilTest.java | 40 +
.../exception/JobConfigurationExceptionTest.java | 36 +
.../JobExecutionEnvironmentExceptionTest.java | 30 +
.../cloud/exception/JobStatisticExceptionTest.java | 32 +
.../cloud/exception/JobSystemExceptionTest.java | 36 +
.../cloud/executor/AllExecutorTests.java | 43 +
.../cloud/executor/JobExecutorFactoryTest.java | 75 +
.../ExecutorServiceHandlerRegistryTest.java | 91 +
.../cloud/executor/handler/JobPropertiesTest.java | 86 +
.../impl/DefaultJobExceptionHandlerTest.java | 40 +
.../executor/type/DataflowJobExecutorTest.java | 176 +
.../cloud/executor/type/ElasticJobVerify.java | 54 +
.../cloud/executor/type/ScriptJobExecutorTest.java | 87 +
.../cloud/executor/type/SimpleJobExecutorTest.java | 232 +
.../cloud/executor/type/WrongJobExecutorTest.java | 71 +
.../elasticjob/cloud/fixture/APIJsonConstants.java | 78 +
.../cloud/fixture/EmbedTestingServer.java | 72 +
.../cloud/fixture/ShardingContextsBuilder.java | 52 +
.../config/TestDataflowJobConfiguration.java | 41 +
.../fixture/config/TestJobRootConfiguration.java | 33 +
.../fixture/config/TestScriptJobConfiguration.java | 41 +
.../fixture/config/TestSimpleJobConfiguration.java | 56 +
.../elasticjob/cloud/fixture/context/TaskNode.java | 52 +
.../fixture/handler/IgnoreJobExceptionHandler.java | 27 +
.../fixture/handler/ThrowJobExceptionHandler.java | 29 +
.../elasticjob/cloud/fixture/job/JobCaller.java | 41 +
.../elasticjob/cloud/fixture/job/OtherJob.java | 23 +
.../cloud/fixture/job/TestDataflowJob.java | 42 +
.../cloud/fixture/job/TestSimpleJob.java | 33 +
.../elasticjob/cloud/fixture/job/TestWrongJob.java | 31 +
.../elasticjob/cloud/reg/AllRegTests.java | 49 +
.../reg/exception/RegExceptionHandlerTest.java | 74 +
.../reg/zookeeper/ZookeeperConfigurationTest.java | 35 +
.../zookeeper/ZookeeperElectionServiceTest.java | 69 +
.../ZookeeperRegistryCenterForAuthTest.java | 75 +
.../ZookeeperRegistryCenterInitFailureTest.java | 30 +
.../ZookeeperRegistryCenterMiscellaneousTest.java | 68 +
.../ZookeeperRegistryCenterModifyTest.java | 126 +
.../ZookeeperRegistryCenterQueryWithCacheTest.java | 62 +
...okeeperRegistryCenterQueryWithoutCacheTest.java | 94 +
.../util/ZookeeperRegistryCenterTestUtil.java | 36 +
.../cloud/statistics/AllStatisticsTests.java | 31 +
.../statistics/rdb/StatisticRdbRepositoryTest.java | 216 +
.../elasticjob/cloud/util/AllUtilTests.java | 49 +
.../util/concurrent/ExecutorServiceObjectTest.java | 58 +
.../util/config/ShardingItemParametersTest.java | 55 +
.../cloud/util/config/ShardingItemsTest.java | 59 +
.../cloud/util/digest/EncryptionTest.java | 30 +
.../cloud/util/env/HostExceptionTest.java | 34 +
.../elasticjob/cloud/util/env/IpUtilsTest.java | 35 +
.../elasticjob/cloud/util/env/TimeServiceTest.java | 31 +
.../cloud/util/json/GsonFactoryTest.java | 56 +
.../json/JobConfigurationGsonTypeAdapterTest.java | 105 +
.../src/test/resources/conf/reg}/local.properties | 0
.../resources/conf/reg}/local_overwrite.properties | 0
.../src/test/resources/logback-test.xml | 43 +
elasticjob-cloud/elasticjob-cloud-executor/pom.xml | 97 +
.../elasticjob/cloud/api/JobBootstrap.java | 39 +
.../elasticjob/cloud/executor/CloudJobFacade.java | 115 +
.../cloud/executor/DaemonTaskScheduler.java | 171 +
.../cloud/executor/JobConfigurationContext.java | 85 +
.../elasticjob/cloud/executor/TaskExecutor.java | 177 +
.../executor/local/LocalCloudJobConfiguration.java | 50 +
.../cloud/executor/local/LocalTaskExecutor.java | 114 +
.../cloud/executor/AllCloudExecutorTests.java | 38 +
.../cloud/executor/CloudJobFacadeTest.java | 160 +
.../cloud/executor/DaemonTaskSchedulerTest.java | 93 +
.../executor/JobConfigurationContextTest.java | 79 +
.../cloud/executor/TaskExecutorTest.java | 121 +
.../cloud/executor/TaskExecutorThreadTest.java | 158 +
.../elasticjob/cloud/executor/fixture/TestJob.java | 28 +
.../fixture/TestScriptJobConfiguration.java | 37 +
.../executor/local/AllLocalExecutorTests.java | 29 +
.../executor/local/LocalTaskExecutorTest.java | 103 +
.../executor/local/fixture/TestDataflowJob.java | 52 +
.../executor/local/fixture/TestSimpleJob.java | 45 +
.../src/test/resources/applicationContext.xml | 27 +
.../src/test/resources/logback-test.xml | 40 +
.../src/test/resources/script/TestScriptJob.bat | 18 +
.../src/test/resources/script/TestScriptJob.sh | 19 +
.../elasticjob-cloud-scheduler/pom.xml | 154 +
.../elasticjob/cloud/restful/GsonJsonProvider.java | 82 +
.../elasticjob/cloud/restful/RestfulException.java | 30 +
.../cloud/restful/RestfulExceptionMapper.java | 37 +
.../elasticjob/cloud/restful/RestfulServer.java | 126 +
.../elasticjob/cloud/scheduler/Bootstrap.java | 65 +
.../config/app/CloudAppConfiguration.java | 47 +
.../app/CloudAppConfigurationGsonFactory.java | 120 +
.../config/app/CloudAppConfigurationNode.java | 36 +
.../config/app/CloudAppConfigurationService.java | 93 +
.../constants/CloudConfigurationConstants.java | 46 +
.../config/job/CloudJobConfiguration.java | 56 +
.../job/CloudJobConfigurationGsonFactory.java | 119 +
.../config/job/CloudJobConfigurationListener.java | 114 +
.../config/job/CloudJobConfigurationNode.java | 36 +
.../config/job/CloudJobConfigurationService.java | 93 +
.../config/job/CloudJobExecutionType.java | 26 +
.../cloud/scheduler/context/JobContext.java | 56 +
.../cloud/scheduler/env/BootstrapEnvironment.java | 224 +
.../scheduler/env/FrameworkConfiguration.java | 42 +
.../cloud/scheduler/env/MesosConfiguration.java | 45 +
.../scheduler/env/RestfulServerConfiguration.java | 31 +
.../cloud/scheduler/ha/FrameworkIDService.java | 53 +
.../elasticjob/cloud/scheduler/ha/HANode.java | 39 +
.../scheduler/ha/SchedulerElectionCandidate.java | 53 +
.../scheduler/mesos/AppConstraintEvaluator.java | 163 +
.../cloud/scheduler/mesos/FacadeService.java | 344 +
.../cloud/scheduler/mesos/JobTaskRequest.java | 104 +
.../cloud/scheduler/mesos/LaunchingTasks.java | 94 +
.../cloud/scheduler/mesos/LeasesQueue.java | 69 +
.../cloud/scheduler/mesos/MesosStateService.java | 177 +
.../cloud/scheduler/mesos/ReconcileService.java | 106 +
.../cloud/scheduler/mesos/SchedulerEngine.java | 166 +
.../cloud/scheduler/mesos/SchedulerService.java | 154 +
.../scheduler/mesos/SupportedExtractionType.java | 59 +
.../cloud/scheduler/mesos/TaskInfoData.java | 71 +
.../mesos/TaskLaunchScheduledService.java | 269 +
.../cloud/scheduler/producer/ProducerManager.java | 198 +
.../producer/TransientProducerRepository.java | 72 +
.../producer/TransientProducerScheduler.java | 155 +
.../scheduler/restful/CloudAppRestfulApi.java | 228 +
.../scheduler/restful/CloudJobRestfulApi.java | 478 ++
.../restful/CloudOperationRestfulApi.java | 100 +
.../cloud/scheduler/restful/RestfulService.java | 65 +
.../cloud/scheduler/state/StateNode.java | 33 +
.../state/disable/app/DisableAppNode.java | 37 +
.../state/disable/app/DisableAppService.java | 72 +
.../state/disable/job/DisableJobNode.java | 37 +
.../state/disable/job/DisableJobService.java | 72 +
.../scheduler/state/failover/FailoverNode.java | 44 +
.../scheduler/state/failover/FailoverService.java | 186 +
.../scheduler/state/failover/FailoverTaskInfo.java | 34 +
.../cloud/scheduler/state/ready/ReadyNode.java | 37 +
.../cloud/scheduler/state/ready/ReadyService.java | 185 +
.../cloud/scheduler/state/running/RunningNode.java | 44 +
.../scheduler/state/running/RunningService.java | 267 +
.../scheduler/statistics/StatisticManager.java | 291 +
.../scheduler/statistics/StatisticsScheduler.java | 98 +
.../scheduler/statistics/TaskResultMetaData.java | 79 +
.../statistics/job/AbstractStatisticJob.java | 52 +
.../statistics/job/JobRunningStatisticJob.java | 150 +
.../statistics/job/RegisteredJobStatisticJob.java | 100 +
.../scheduler/statistics/job/StatisticJob.java | 51 +
.../statistics/job/TaskResultStatisticJob.java | 106 +
.../statistics/util/StatisticTimeUtils.java | 72 +
.../elasticjob/cloud/security/WwwAuthFilter.java | 124 +
.../src/main/resources/assembly/assembly.xml | 44 +
.../src/main/resources/bin/dcos.sh | 27 +
.../src/main/resources/bin/start.sh | 35 +
.../src/main/resources/conf/auth.properties | 21 +
.../conf/elastic-job-cloud-scheduler.properties | 62 +
.../src/main/resources/console/css/common.css | 161 +
.../src/main/resources/console/favicon.ico | Bin 0 -> 1150 bytes
.../main/resources/console/html/app/add_app.html | 98 +
.../resources/console/html/app/apps_overview.html | 99 +
.../resources/console/html/app/detail_app.html | 89 +
.../resources/console/html/app/modify_app.html | 98 +
.../console/html/history/job_dashboard.html | 134 +
.../console/html/history/job_exec_details.html | 101 +
.../console/html/history/job_exec_status.html | 122 +
.../main/resources/console/html/job/add_job.html | 191 +
.../resources/console/html/job/detail_job.html | 183 +
.../resources/console/html/job/job_status.html | 117 +
.../resources/console/html/job/jobs_overview.html | 127 +
.../resources/console/html/job/modify_job.html | 191 +
.../main/resources/console/i18n/message.properties | 16 +
.../resources/console/i18n/message_en.properties | 190 +
.../resources/console/i18n/message_zh.properties | 190 +
.../src/main/resources/console/index.html | 301 +
.../src/main/resources/console/js/app/add_app.js | 21 +
.../main/resources/console/js/app/app_common.js | 132 +
.../main/resources/console/js/app/apps_overview.js | 178 +
.../main/resources/console/js/app/modify_app.js | 21 +
.../src/main/resources/console/js/common/common.js | 161 +
.../resources/console/js/history/history_common.js | 59 +
.../resources/console/js/history/job_dashboard.js | 291 +
.../console/js/history/job_exec_details.js | 68 +
.../console/js/history/job_exec_status.js | 82 +
.../src/main/resources/console/js/index.js | 45 +
.../src/main/resources/console/js/job/add_job.js | 22 +
.../main/resources/console/js/job/job_common.js | 257 +
.../main/resources/console/js/job/jobs_overview.js | 230 +
.../main/resources/console/js/job/modify_job.js | 22 +
.../console/lib/AdminLTE/css/AdminLTE.min.css | 0
.../lib/AdminLTE/css/skins/_all-skins.min.css | 0
.../resources/console/lib/AdminLTE/js/app.min.js | 0
.../BootstrapValidator/js/bootstrapValidator.js | 0
.../js/bootstrapValidator_zh_CN.js | 386 ++
.../lib/bootstrap-table/bootstrap-table-zh-CN.js | 44 +
.../lib/bootstrap-table/bootstrap-table.css | 302 +
.../console/lib/bootstrap-table/bootstrap-table.js | 2801 ++++++++
.../lib/bootstrap-table/bootstrap-table.min.css | 1 +
.../lib/bootstrap-table/bootstrap-table.min.js | 8 +
.../console/lib/bootstrap/css/bootstrap.css | 6800 ++++++++++++++++++++
.../console/lib/bootstrap/css/bootstrap.css.map | 1 +
.../console/lib/bootstrap/css/bootstrap.min.css | 0
.../fonts/glyphicons-halflings-regular.eot | Bin
.../fonts/glyphicons-halflings-regular.svg | 0
.../fonts/glyphicons-halflings-regular.ttf | Bin
.../fonts/glyphicons-halflings-regular.woff | Bin
.../fonts/glyphicons-halflings-regular.woff2 | Bin
.../console/lib/bootstrap/js/bootstrap.js | 2317 +++++++
.../console/lib/bootstrap/js/bootstrap.min.js | 7 +
.../main/resources/console/lib/bootstrap/js/npm.js | 13 +
.../lib/daterangepicker/daterangepicker.css | 269 +
.../console/lib/daterangepicker/daterangepicker.js | 1622 +++++
.../console/lib/daterangepicker/moment.js | 4040 ++++++++++++
.../console/lib/daterangepicker/moment.min.js | 0
.../lib/font-awesome-4.5.0/css/font-awesome.css | 2086 ++++++
.../font-awesome-4.5.0/css/font-awesome.min.css | 0
.../lib/font-awesome-4.5.0/fonts/FontAwesome.otf | Bin
.../fonts/fontawesome-webfont.eot | Bin
.../fonts/fontawesome-webfont.svg | 0
.../fonts/fontawesome-webfont.ttf | Bin
.../fonts/fontawesome-webfont.woff | Bin
.../fonts/fontawesome-webfont.woff2 | Bin
.../console/lib/highcharts/js/highcharts.js | 383 ++
.../input-mask/jquery.inputmask.date.extensions.js | 488 ++
.../lib/input-mask/jquery.inputmask.extensions.js | 122 +
.../console/lib/input-mask/jquery.inputmask.js | 1627 +++++
.../jquery.inputmask.numeric.extensions.js | 177 +
.../jquery.inputmask.phone.extensions.js | 50 +
.../jquery.inputmask.regex.extensions.js | 169 +
.../lib/input-mask/phone-codes/phone-be.json | 0
.../lib/input-mask/phone-codes/phone-codes.json | 0
.../console/lib/input-mask/phone-codes/readme.txt | 0
.../console/lib/jQuery/jQuery-2.1.4.min.js | 0
.../lib/jQuery}/jquery.i18n.properties-min.js | 0
.../src/main/resources/logback.xml | 75 +
.../shardingsphere/elasticjob/cloud/AllTests.java | 35 +
.../elasticjob/cloud/restful/AllRestfulTests.java | 33 +
.../cloud/restful/RestfulExceptionTest.java | 30 +
.../cloud/restful/RestfulServerTest.java | 101 +
.../elasticjob/cloud/restful/fixture/Caller.java | 33 +
.../cloud/restful/fixture/TestFilter.java | 46 +
.../cloud/restful/fixture/TestRestfulApi.java | 54 +
.../cloud/scheduler/AllCloudSchedulerTests.java | 45 +
.../cloud/scheduler/config/AllConfigTests.java | 31 +
.../config/app/AllCloudAppConfigTests.java | 29 +
.../config/app/CloudAppConfigurationNodeTest.java | 30 +
.../app/CloudAppConfigurationServiceTest.java | 99 +
.../config/job/AllCloudJobConfigTests.java | 30 +
.../job/CloudJobConfigurationListenerTest.java | 123 +
.../config/job/CloudJobConfigurationNodeTest.java | 30 +
.../job/CloudJobConfigurationServiceTest.java | 115 +
.../cloud/scheduler/context/AllContextTests.java | 26 +
.../cloud/scheduler/context/JobContextTest.java | 38 +
.../cloud/scheduler/env/AllEnvTests.java | 26 +
.../scheduler/env/BootstrapEnvironmentTest.java | 114 +
.../fixture/CloudAppConfigurationBuilder.java | 35 +
.../scheduler/fixture/CloudAppJsonConstants.java | 37 +
.../fixture/CloudJobConfigurationBuilder.java | 146 +
.../scheduler/fixture/CloudJsonConstants.java | 85 +
.../scheduler/fixture/EmbedTestingServer.java | 72 +
.../cloud/scheduler/fixture/TaskNode.java | 61 +
.../cloud/scheduler/fixture/TestSimpleJob.java | 28 +
.../elasticjob/cloud/scheduler/ha/AllHATests.java | 26 +
.../cloud/scheduler/ha/FrameworkIDServiceTest.java | 62 +
.../cloud/scheduler/mesos/AllMesosTests.java | 41 +
.../mesos/AppConstraintEvaluatorTest.java | 197 +
.../cloud/scheduler/mesos/FacadeServiceTest.java | 319 +
.../cloud/scheduler/mesos/JobTaskRequestTest.java | 102 +
.../cloud/scheduler/mesos/LaunchingTasksTest.java | 82 +
.../cloud/scheduler/mesos/LeasesQueueTest.java | 36 +
.../scheduler/mesos/MesosStateServiceTest.java | 72 +
.../scheduler/mesos/ReconcileServiceTest.java | 88 +
.../cloud/scheduler/mesos/SchedulerEngineTest.java | 291 +
.../scheduler/mesos/SchedulerServiceTest.java | 151 +
.../mesos/SupportedExtractionTypeTest.java | 41 +
.../cloud/scheduler/mesos/TaskInfoDataTest.java | 57 +
.../mesos/TaskLaunchScheduledServiceTest.java | 141 +
.../scheduler/mesos/fixture/OfferBuilder.java | 42 +
.../fixture/master/MesosMasterServerMock.java | 78 +
.../mesos/fixture/slave/MesosSlaveServerMock.java | 92 +
.../cloud/scheduler/producer/AllProducerTests.java | 31 +
.../cloud/scheduler/producer/ProducerJobTest.java | 62 +
.../scheduler/producer/ProducerManagerTest.java | 193 +
.../producer/TransientProducerRepositoryTest.java | 84 +
.../producer/TransientProducerSchedulerTest.java | 86 +
.../restful/AbstractCloudRestfulApiTest.java | 95 +
.../cloud/scheduler/restful/AllRestfulTests.java | 30 +
.../scheduler/restful/CloudAppRestfulApiTest.java | 118 +
.../scheduler/restful/CloudJobRestfulApiTest.java | 323 +
.../restful/CloudOperationRestfulApiTest.java | 57 +
.../cloud/scheduler/restful/RestfulTestsUtil.java | 98 +
.../cloud/scheduler/state/AllStateTests.java | 47 +
.../state/disable/app/DisableAppNodeTest.java | 30 +
.../state/disable/app/DisableAppServiceTest.java | 68 +
.../state/disable/job/DisableJobNodeTest.java | 30 +
.../state/disable/job/DisableJobServiceTest.java | 68 +
.../scheduler/state/failover/FailoverNodeTest.java | 38 +
.../state/failover/FailoverServiceTest.java | 218 +
.../cloud/scheduler/state/ready/ReadyNodeTest.java | 30 +
.../scheduler/state/ready/ReadyServiceTest.java | 286 +
.../scheduler/state/running/RunningNodeTest.java | 37 +
.../state/running/RunningServiceTest.java | 161 +
.../scheduler/statistics/AllStatisticTests.java | 40 +
.../scheduler/statistics/StatisticManagerTest.java | 236 +
.../statistics/StatisticsSchedulerTest.java | 63 +
.../statistics/TaskResultMetaDataTest.java | 56 +
.../statistics/job/BaseStatisticJobTest.java | 59 +
.../statistics/job/JobRunningStatisticJobTest.java | 119 +
.../job/RegisteredJobStatisticJobTest.java | 101 +
.../statistics/job/TaskResultStatisticJobTest.java | 109 +
.../scheduler/statistics/job/TestStatisticJob.java | 58 +
.../statistics/util/StatisticTimeUtilsTest.java | 72 +
.../src/test/resources/logback-test.xml | 43 +
elasticjob-cloud/pom.xml | 37 +
.../elasticjob-lite-console/.dockerignore | 18 +
elasticjob-lite/elasticjob-lite-console/Dockerfile | 23 +
elasticjob-lite/elasticjob-lite-console/README.md | 7 +
elasticjob-lite/elasticjob-lite-console/pom.xml | 147 +
.../elasticjob/lite/console/ConsoleBootstrap.java | 0
.../console/config/DynamicDataSourceConfig.java | 0
.../lite/console/config/FilterRegisterConfig.java | 0
.../lite/console/config/WebMvcConfig.java | 0
.../config/advice/ConsoleRestControllerAdvice.java | 0
.../controller/EventTraceDataSourceController.java | 0
.../controller/EventTraceHistoryController.java | 0
.../console/controller/JobConfigController.java | 0
.../console/controller/JobOperationController.java | 0
.../controller/RegistryCenterController.java | 0
.../controller/ServerOperationController.java | 0
.../dao/search/JobExecutionLogRepository.java | 0
.../dao/search/JobStatusTraceLogRepository.java | 0
.../JobRegisterStatisticsRepository.java | 0
.../statistics/JobRunningStatisticsRepository.java | 0
.../console/dao/statistics/StatisticInterval.java | 0
.../statistics/TaskResultStatisticsRepository.java | 0
.../TaskRunningStatisticsRepository.java | 0
.../type/job/JobExecutionTypeStatistics.java | 0
.../dao/statistics/type/job/JobTypeStatistics.java | 0
.../lite/console/domain/DataSourceFactory.java | 0
.../lite/console/domain/EventTraceDataSource.java | 0
.../domain/EventTraceDataSourceConfiguration.java | 0
.../domain/EventTraceDataSourceConfigurations.java | 0
.../domain/EventTraceDataSourceFactory.java | 0
.../lite/console/domain/GlobalConfiguration.java | 0
.../lite/console/domain/JobExecutionLog.java | 0
.../lite/console/domain/JobRegisterStatistics.java | 0
.../lite/console/domain/JobRunningStatistics.java | 0
.../lite/console/domain/JobStatusTraceLog.java | 0
.../domain/RegistryCenterConfiguration.java | 0
.../domain/RegistryCenterConfigurations.java | 0
.../lite/console/domain/TaskResultStatistics.java | 0
.../lite/console/domain/TaskRunningStatistics.java | 0
.../lite/console/dto/request/BasePageRequest.java | 0
.../dto/request/FindJobExecutionEventsRequest.java | 0
.../request/FindJobStatusTraceEventsRequest.java | 0
.../console/dto/response/BasePageResponse.java | 0
.../console/exception/JobConsoleException.java | 0
.../console/filter/GlobalConfigurationFilter.java | 0
.../repository/ConfigurationsXmlRepository.java | 0
.../lite/console/repository/XmlRepository.java | 0
.../repository/impl/AbstractXmlRepositoryImpl.java | 0
.../impl/ConfigurationsXmlRepositoryImpl.java | 0
.../console/security/AuthenticationResult.java | 0
.../security/UserAuthenticationService.java | 0
.../lite/console/security/WwwAuthFilter.java | 0
.../EventTraceDataSourceConfigurationService.java | 0
.../console/service/EventTraceHistoryService.java | 0
.../lite/console/service/JobAPIService.java | 0
.../RegistryCenterConfigurationService.java | 0
...entTraceDataSourceConfigurationServiceImpl.java | 0
.../service/impl/EventTraceHistoryServiceImpl.java | 0
.../console/service/impl/JobAPIServiceImpl.java | 0
.../RegistryCenterConfigurationServiceImpl.java | 0
.../elasticjob/lite/console/util/BeanUtils.java | 0
.../lite/console/util/HomeFolderUtils.java | 0
.../SessionEventTraceDataSourceConfiguration.java | 0
.../util/SessionRegistryCenterConfiguration.java | 0
.../src/main/resources/application.properties | 0
.../src/main/resources/assembly/assembly.xml | 0
.../src/main/resources/bin/start.bat | 0
.../src/main/resources/bin/start.sh | 50 +
.../src/main/resources/console/css/index.css | 0
.../src/main/resources/console/favicon.ico | Bin
.../html/global/event_trace_data_source.html | 0
.../console/html/global/registry_center.html | 0
.../src/main/resources/console/html/help/help.html | 0
.../html/history/job_event_trace_history.html | 0
.../console/html/history/job_status_history.html | 0
.../console/html/status/job/job_config.html | 0
.../console/html/status/job/job_status_detail.html | 0
.../html/status/job/jobs_status_overview.html | 0
.../html/status/server/server_status_detail.html | 0
.../status/server/servers_status_overview.html | 0
.../main/resources/console/i18n/message.properties | 0
.../resources/console/i18n/message_en.properties | 0
.../resources/console/i18n/message_zh.properties | 0
.../src/main/resources/console/index.html | 0
.../console/js/global/event_trace_data_source.js | 0
.../resources/console/js/global/registry_center.js | 0
.../console/js/history/job_event_trace_history.js | 0
.../console/js/history/job_status_history.js | 0
.../src/main/resources/console/js/index.js | 0
.../resources/console/js/status/job/job_config.js | 0
.../console/js/status/job/job_status_detail.js | 0
.../console/js/status/job/jobs_status_overview.js | 0
.../js/status/server/server_status_detail.js | 0
.../js/status/server/servers_status_overview.js | 0
.../src/main/resources/console/js/util/common.js | 0
.../main/resources/console/js/util/dashboard.js | 0
.../main/resources/console/js/util/formatter.js | 0
.../console/lib/AdminLTE/css/AdminLTE.min.css | 0
.../lib/AdminLTE/css/skins/_all-skins.min.css | 0
.../resources/console/lib/AdminLTE/js/app.min.js | 0
.../BootstrapValidator/js/bootstrapValidator.js | 0
.../js/bootstrapValidator_zh_CN.js | 0
.../console/lib/bootstrap-table/bootstrap-table.js | 0
.../lib/bootstrap-table/bootstrap-table.min.css | 0
.../lib/bootstrap/css/bootstrap-theme.min.css | 0
.../console/lib/bootstrap/css/bootstrap.min.css | 0
.../fonts/glyphicons-halflings-regular.eot | Bin
.../fonts/glyphicons-halflings-regular.svg | 0
.../fonts/glyphicons-halflings-regular.ttf | Bin
.../fonts/glyphicons-halflings-regular.woff | Bin
.../fonts/glyphicons-halflings-regular.woff2 | Bin
.../console/lib/bootstrap/js/bootstrap.min.js | 0
.../lib/daterangepicker/daterangepicker.css | 0
.../console/lib/daterangepicker/daterangepicker.js | 0
.../console/lib/daterangepicker/moment.min.js | 0
.../font-awesome-4.5.0/css/font-awesome.min.css | 0
.../lib/font-awesome-4.5.0/fonts/FontAwesome.otf | Bin
.../fonts/fontawesome-webfont.eot | Bin
.../fonts/fontawesome-webfont.svg | 0
.../fonts/fontawesome-webfont.ttf | Bin
.../fonts/fontawesome-webfont.woff | Bin
.../fonts/fontawesome-webfont.woff2 | Bin
.../input-mask/jquery.inputmask.date.extensions.js | 0
.../lib/input-mask/jquery.inputmask.extensions.js | 0
.../console/lib/input-mask/jquery.inputmask.js | 0
.../jquery.inputmask.numeric.extensions.js | 0
.../jquery.inputmask.phone.extensions.js | 0
.../jquery.inputmask.regex.extensions.js | 0
.../lib/input-mask/phone-codes/phone-be.json | 0
.../lib/input-mask/phone-codes/phone-codes.json | 0
.../console/lib/input-mask/phone-codes/readme.txt | 0
.../console/lib/jquery/jquery-2.1.4.min.js | 0
.../lib/jquery/jquery.i18n.properties-min.js | 0
.../src/main/resources/log4j.properties | 0
.../src/main/resources/logback.xml | 75 +
.../console/dao/search/RDBJobEventSearchTest.java | 0
.../search/RDBJobEventSearchTestConfiguration.java | 0
.../statistics/rdb/RDBStatisticRepositoryTest.java | 0
.../lite/console/util/HomeFolderUtilsTest.java | 0
elasticjob-lite/elasticjob-lite-core/pom.xml | 106 +
.../lite/api/bootstrap/JobBootstrap.java | 0
.../api/bootstrap/impl/OneOffJobBootstrap.java | 0
.../api/bootstrap/impl/ScheduleJobBootstrap.java | 0
.../elasticjob/lite/api/job/ElasticJob.java | 0
.../elasticjob/lite/api/job/JobConfiguration.java | 0
.../elasticjob/lite/api/job/ShardingContext.java | 0
.../AbstractDistributeOnceElasticJobListener.java | 0
.../lite/api/listener/ElasticJobListener.java | 0
.../elasticjob/lite/context/ExecutionType.java | 0
.../elasticjob/lite/context/TaskContext.java | 0
.../lite/exception/AppConfigurationException.java | 0
.../elasticjob/lite/exception/ExceptionUtils.java | 0
.../lite/exception/JobConfigurationException.java | 0
.../JobExecutionEnvironmentException.java | 0
.../lite/exception/JobStatisticException.java | 0
.../lite/exception/JobSystemException.java | 0
.../lite/executor/ElasticJobExecutor.java | 0
.../elasticjob/lite/executor/JobFacade.java | 0
.../elasticjob/lite/executor/ShardingContexts.java | 0
.../lite/executor/item/JobItemExecutor.java | 0
.../lite/executor/item/JobItemExecutorFactory.java | 0
.../executor/item/impl/ClassedJobItemExecutor.java | 0
.../executor/item/impl/TypedJobItemExecutor.java | 0
.../lite/handler/error/JobErrorHandler.java | 0
.../lite/handler/error/JobErrorHandlerFactory.java | 0
.../handler/error/impl/IgnoreJobErrorHandler.java | 0
.../handler/error/impl/LogJobErrorHandler.java | 0
.../handler/error/impl/ThrowJobErrorHandler.java | 0
.../lite/handler/sharding/JobInstance.java | 0
.../lite/handler/sharding/JobShardingStrategy.java | 0
.../sharding/JobShardingStrategyFactory.java | 0
.../impl/AverageAllocationJobShardingStrategy.java | 0
.../impl/OdevitySortByNameJobShardingStrategy.java | 0
.../impl/RoundRobinByNameJobShardingStrategy.java | 0
.../threadpool/JobExecutorServiceHandler.java | 0
.../JobExecutorServiceHandlerFactory.java | 0
.../impl/AbstractJobExecutorServiceHandler.java | 0
.../impl/CPUUsageJobExecutorServiceHandler.java | 0
.../SingleThreadJobExecutorServiceHandler.java | 0
.../lite/internal/config/ConfigurationNode.java | 0
.../lite/internal/config/ConfigurationService.java | 0
.../internal/config/RescheduleListenerManager.java | 0
.../internal/config/yaml/YamlJobConfiguration.java | 0
.../internal/election/ElectionListenerManager.java | 0
.../lite/internal/election/LeaderNode.java | 0
.../lite/internal/election/LeaderService.java | 0
.../internal/failover/FailoverListenerManager.java | 0
.../lite/internal/failover/FailoverNode.java | 0
.../lite/internal/failover/FailoverService.java | 0
.../guarantee/GuaranteeListenerManager.java | 0
.../lite/internal/guarantee/GuaranteeNode.java | 0
.../lite/internal/guarantee/GuaranteeService.java | 0
.../lite/internal/instance/InstanceNode.java | 0
.../lite/internal/instance/InstanceOperation.java | 0
.../lite/internal/instance/InstanceService.java | 0
.../internal/instance/ShutdownListenerManager.java | 0
.../internal/instance/TriggerListenerManager.java | 0
.../internal/listener/AbstractJobListener.java | 0
.../internal/listener/AbstractListenerManager.java | 0
.../lite/internal/listener/ListenerManager.java | 0
.../RegistryCenterConnectionStateListener.java | 0
.../lite/internal/reconcile/ReconcileService.java | 0
.../lite/internal/schedule/JobRegistry.java | 0
.../internal/schedule/JobScheduleController.java | 0
.../lite/internal/schedule/JobScheduler.java | 0
.../internal/schedule/JobShutdownHookPlugin.java | 0
.../lite/internal/schedule/JobTriggerListener.java | 0
.../elasticjob/lite/internal/schedule/LiteJob.java | 0
.../lite/internal/schedule/LiteJobFacade.java | 0
.../lite/internal/schedule/SchedulerFacade.java | 0
.../lite/internal/server/ServerNode.java | 0
.../lite/internal/server/ServerService.java | 0
.../lite/internal/server/ServerStatus.java | 0
.../lite/internal/setup/SetUpFacade.java | 0
.../internal/sharding/ExecutionContextService.java | 0
.../lite/internal/sharding/ExecutionService.java | 0
.../sharding/MonitorExecutionListenerManager.java | 0
.../internal/sharding/ShardingListenerManager.java | 0
.../lite/internal/sharding/ShardingNode.java | 0
.../lite/internal/sharding/ShardingService.java | 0
.../lite/internal/snapshot/SnapshotService.java | 0
.../lite/internal/storage/JobNodePath.java | 0
.../lite/internal/storage/JobNodeStorage.java | 0
.../internal/storage/LeaderExecutionCallback.java | 0
.../storage/TransactionExecutionCallback.java | 0
.../lite/internal/util/SensitiveInfoUtils.java | 0
.../lite/reg/base/CoordinatorRegistryCenter.java | 0
.../lite/reg/base/ElectionCandidate.java | 0
.../elasticjob/lite/reg/base/RegistryCenter.java | 0
.../lite/reg/exception/RegException.java | 0
.../lite/reg/exception/RegExceptionHandler.java | 0
.../lite/reg/zookeeper/ZookeeperConfiguration.java | 0
.../reg/zookeeper/ZookeeperElectionService.java | 0
.../reg/zookeeper/ZookeeperRegistryCenter.java | 0
.../elasticjob/lite/spi/TypedSPI.java | 0
.../lite/util/concurrent/BlockUtils.java | 0
.../util/concurrent/ElasticJobExecutorService.java | 0
.../lite/util/config/ShardingItemParameters.java | 0
.../elasticjob/lite/util/config/ShardingItems.java | 0
.../elasticjob/lite/util/env/HostException.java | 0
.../elasticjob/lite/util/env/IpUtils.java | 0
.../elasticjob/lite/util/env/TimeService.java | 0
.../elasticjob/lite/util/json/GsonFactory.java | 0
.../lite/util/yaml/DefaultYamlTupleProcessor.java | 0
.../lite/util/yaml/ElasticJobYamlRepresenter.java | 0
.../elasticjob/lite/util/yaml/YamlEngine.java | 0
...e.elasticjob.lite.handler.error.JobErrorHandler | 0
...icjob.lite.handler.sharding.JobShardingStrategy | 0
...te.handler.threadpool.JobExecutorServiceHandler | 0
.../lite/api/job/JobConfigurationTest.java | 0
.../lite/api/job/ShardingContextTest.java | 0
.../DistributeOnceElasticJobListenerTest.java | 0
.../listener/fixture/ElasticJobListenerCaller.java | 0
.../TestDistributeOnceElasticJobListener.java | 0
.../listener/fixture/TestElasticJobListener.java | 0
.../elasticjob/lite/context/TaskContextTest.java | 0
.../lite/exception/ExceptionUtilsTest.java | 0
.../exception/JobConfigurationExceptionTest.java | 0
.../JobExecutionEnvironmentExceptionTest.java | 0
.../lite/exception/JobStatisticExceptionTest.java | 0
.../lite/exception/JobSystemExceptionTest.java | 0
.../lite/executor/ElasticJobExecutorTest.java | 0
.../executor/item/JobItemExecutorFactoryTest.java | 0
.../lite/fixture/EmbedTestingServer.java | 0
.../elasticjob/lite/fixture/LiteYamlConstants.java | 0
.../elasticjob/lite/fixture/context/TaskNode.java | 0
.../fixture/executor/ClassedFooJobExecutor.java | 0
.../lite/fixture/executor/TypedFooJobExecutor.java | 0
.../lite/fixture/job/DetailedFooJob.java | 0
.../elasticjob/lite/fixture/job/FailedJob.java | 0
.../elasticjob/lite/fixture/job/FooJob.java | 0
.../handler/error/JobErrorHandlerFactoryTest.java | 0
.../error/impl/IgnoreJobErrorHandlerTest.java | 0
.../handler/error/impl/LogJobErrorHandlerTest.java | 0
.../error/impl/ThrowJobErrorHandlerTest.java | 0
.../lite/handler/sharding/JobInstanceTest.java | 0
.../sharding/JobShardingStrategyFactoryTest.java | 0
.../AverageAllocationJobShardingStrategyTest.java | 0
.../OdevitySortByNameJobShardingStrategyTest.java | 0
.../RotateServerByNameJobShardingStrategyTest.java | 0
.../JobExecutorServiceHandlerFactoryTest.java | 0
.../lite/integrate/BaseIntegrateTest.java | 0
.../disable/DisabledJobIntegrateTest.java | 0
.../disable/OneOffDisabledJobIntegrateTest.java | 0
.../disable/ScheduleDisabledJobIntegrateTest.java | 0
.../integrate/enable/EnabledJobIntegrateTest.java | 0
.../enable/OneOffEnabledJobIntegrateTest.java | 0
.../enable/ScheduleEnabledJobIntegrateTest.java | 0
.../internal/config/ConfigurationNodeTest.java | 0
.../internal/config/ConfigurationServiceTest.java | 0
.../config/RescheduleListenerManagerTest.java | 0
.../config/yaml/YamlJobConfigurationTest.java | 0
.../election/ElectionListenerManagerTest.java | 0
.../lite/internal/election/LeaderNodeTest.java | 0
.../lite/internal/election/LeaderServiceTest.java | 0
.../failover/FailoverListenerManagerTest.java | 0
.../lite/internal/failover/FailoverNodeTest.java | 0
.../internal/failover/FailoverServiceTest.java | 0
.../guarantee/GuaranteeListenerManagerTest.java | 0
.../lite/internal/guarantee/GuaranteeNodeTest.java | 0
.../internal/guarantee/GuaranteeServiceTest.java | 0
.../lite/internal/instance/InstanceNodeTest.java | 0
.../internal/instance/InstanceServiceTest.java | 0
.../instance/ShutdownListenerManagerTest.java | 0
.../instance/TriggerListenerManagerTest.java | 0
.../lite/internal/listener/JobListenerTest.java | 0
.../internal/listener/ListenerManagerTest.java | 0
.../RegistryCenterConnectionStateListenerTest.java | 0
.../internal/listener/fixture/FooJobListener.java | 0
.../internal/reconcile/ReconcileServiceTest.java | 0
.../lite/internal/schedule/JobRegistryTest.java | 0
.../schedule/JobScheduleControllerTest.java | 0
.../internal/schedule/JobTriggerListenerTest.java | 0
.../lite/internal/schedule/LiteJobFacadeTest.java | 0
.../internal/schedule/SchedulerFacadeTest.java | 0
.../lite/internal/server/ServerNodeTest.java | 0
.../lite/internal/server/ServerServiceTest.java | 0
.../lite/internal/setup/SetUpFacadeTest.java | 0
.../sharding/ExecutionContextServiceTest.java | 0
.../internal/sharding/ExecutionServiceTest.java | 0
.../MonitorExecutionListenerManagerTest.java | 0
.../sharding/ShardingListenerManagerTest.java | 0
.../lite/internal/sharding/ShardingNodeTest.java | 0
.../internal/sharding/ShardingServiceTest.java | 0
.../internal/snapshot/BaseSnapshotServiceTest.java | 0
.../snapshot/SnapshotServiceDisableTest.java | 0
.../snapshot/SnapshotServiceEnableTest.java | 0
.../lite/internal/snapshot/SocketUtils.java | 0
.../lite/internal/storage/JobNodePathTest.java | 0
.../lite/internal/storage/JobNodeStorageTest.java | 0
.../lite/internal/util/SensitiveInfoUtilsTest.java | 0
.../reg/exception/RegExceptionHandlerTest.java | 0
.../reg/zookeeper/ZookeeperConfigurationTest.java | 0
.../zookeeper/ZookeeperElectionServiceTest.java | 0
.../ZookeeperRegistryCenterForAuthTest.java | 0
.../ZookeeperRegistryCenterInitFailureTest.java | 0
.../ZookeeperRegistryCenterMiscellaneousTest.java | 0
.../ZookeeperRegistryCenterModifyTest.java | 0
.../ZookeeperRegistryCenterQueryWithCacheTest.java | 0
...okeeperRegistryCenterQueryWithoutCacheTest.java | 0
.../util/ZookeeperRegistryCenterTestUtil.java | 0
.../elasticjob/lite/util/ReflectionUtils.java | 0
.../concurrent/ElasticJobExecutorServiceTest.java | 0
.../util/config/ShardingItemParametersTest.java | 0
.../lite/util/config/ShardingItemsTest.java | 0
.../lite/util/env/HostExceptionTest.java | 0
.../elasticjob/lite/util/env/IpUtilsTest.java | 0
.../elasticjob/lite/util/env/TimeServiceTest.java | 0
.../elasticjob/lite/util/json/GsonFactoryTest.java | 0
.../elasticjob/lite/util/yaml/YamlEngineTest.java | 0
...e.elasticjob.lite.executor.item.JobItemExecutor | 0
.../src/test/resources/conf.reg/local.properties | 0
.../resources/conf.reg/local_overwrite.properties | 0
.../src/test/resources/logback-test.xml | 42 +
.../elasticjob-lite-dataflow-executor/pom.xml | 48 +
.../dataflow/executor/DataflowJobExecutor.java | 0
.../elasticjob/lite/dataflow/job/DataflowJob.java | 0
.../lite/dataflow/props/DataflowJobProperties.java | 0
...e.elasticjob.lite.executor.item.JobItemExecutor | 0
.../lite/dataflow/job/BatchDataflowJob.java | 0
.../lite/dataflow/job/StreamingDataflowJob.java | 0
.../elasticjob-lite-script-executor/pom.xml | 48 +
.../lite/script/executor/ScriptJobExecutor.java | 0
.../lite/script/props/ScriptJobProperties.java | 0
...e.elasticjob.lite.executor.item.JobItemExecutor | 0
.../elasticjob-lite-simple-executor/pom.xml | 48 +
.../lite/simple/executor/SimpleJobExecutor.java | 0
.../elasticjob/lite/simple/job/SimpleJob.java | 0
...e.elasticjob.lite.executor.item.JobItemExecutor | 0
.../elasticjob/lite/simple/job/FooSimpleJob.java | 0
elasticjob-lite/elasticjob-lite-executor/pom.xml | 37 +
elasticjob-lite/elasticjob-lite-lifecycle/pom.xml | 105 +
.../lite/lifecycle/api/JobAPIFactory.java | 0
.../lite/lifecycle/api/JobConfigurationAPI.java | 0
.../lite/lifecycle/api/JobOperateAPI.java | 0
.../lite/lifecycle/api/JobStatisticsAPI.java | 0
.../lite/lifecycle/api/ServerStatisticsAPI.java | 0
.../lite/lifecycle/api/ShardingOperateAPI.java | 0
.../lite/lifecycle/api/ShardingStatisticsAPI.java | 0
.../lite/lifecycle/domain/JobBriefInfo.java | 0
.../lite/lifecycle/domain/ServerBriefInfo.java | 0
.../lite/lifecycle/domain/ShardingInfo.java | 0
.../internal/operate/JobOperateAPIImpl.java | 0
.../internal/operate/ShardingOperateAPIImpl.java | 0
.../internal/reg/RegistryCenterFactory.java | 0
.../internal/settings/JobConfigurationAPIImpl.java | 0
.../internal/statistics/JobStatisticsAPIImpl.java | 0
.../statistics/ServerStatisticsAPIImpl.java | 0
.../statistics/ShardingStatisticsAPIImpl.java | 0
.../lifecycle/AbstractEmbedZookeeperBaseTest.java | 0
.../lite/lifecycle/api/JobAPIFactoryTest.java | 0
.../lite/lifecycle/domain/ShardingStatusTest.java | 0
.../lifecycle/fixture/LifecycleYamlConstants.java | 0
.../lite/lifecycle/fixture/TestDataflowJob.java | 0
.../lite/lifecycle/fixture/TestSimpleJob.java | 0
.../internal/operate/JobOperateAPIImplTest.java | 0
.../operate/ShardingOperateAPIImplTest.java | 0
.../internal/reg/RegistryCenterFactoryTest.java | 0
.../settings/JobConfigurationAPIImplTest.java | 0
.../statistics/JobStatisticsAPIImplTest.java | 0
.../statistics/ServerStatisticsAPIImplTest.java | 0
.../statistics/ShardingStatisticsAPIImplTest.java | 0
.../src/test/resources/logback-test.xml | 38 +
elasticjob-lite/elasticjob-lite-spring/pom.xml | 114 +
.../lite/spring/ElasticJobNamespaceHandler.java | 0
.../spring/job/parser/JobBeanDefinitionParser.java | 0
.../lite/spring/job/tag/JobBeanDefinitionTag.java | 0
.../job/tag/JobListenerBeanDefinitionTag.java | 0
.../lite/spring/job/util/AopTargetUtils.java | 0
.../reg/parser/ZookeeperBeanDefinitionParser.java | 0
.../spring/reg/tag/ZookeeperBeanDefinitionTag.java | 0
.../parser/SnapshotBeanDefinitionParser.java | 0
.../snapshot/tag/SnapshotBeanDefinitionTag.java | 0
.../parser/TracingBeanDefinitionParser.java | 0
.../tracing/tag/TracingBeanDefinitionTag.java | 0
.../resources/META-INF/namespace/elasticjob.xsd | 0
.../src/main/resources/META-INF/spring.handlers | 0
.../src/main/resources/META-INF/spring.schemas | 0
.../lite/spring/fixture/aspect/SimpleAspect.java | 0
.../spring/fixture/job/DataflowElasticJob.java | 0
.../spring/fixture/job/FooSimpleElasticJob.java | 0
.../fixture/job/ref/RefFooDataflowElasticJob.java | 0
.../fixture/job/ref/RefFooSimpleElasticJob.java | 0
.../fixture/listener/SimpleCglibListener.java | 0
.../listener/SimpleJdkDynamicProxyListener.java | 0
.../spring/fixture/listener/SimpleListener.java | 0
.../fixture/listener/SimpleOnceListener.java | 0
.../lite/spring/fixture/service/FooService.java | 0
.../spring/fixture/service/FooServiceImpl.java | 0
.../spring/job/AbstractJobSpringIntegrateTest.java | 0
.../JobSpringNamespaceWithEventTraceRdbTest.java | 0
.../job/JobSpringNamespaceWithJobHandlerTest.java | 0
...JobSpringNamespaceWithListenerAndCglibTest.java | 0
...amespaceWithListenerAndJdkDynamicProxyTest.java | 0
.../job/JobSpringNamespaceWithListenerTest.java | 0
.../spring/job/JobSpringNamespaceWithRefTest.java | 0
.../job/JobSpringNamespaceWithoutListenerTest.java | 0
.../SnapshotSpringNamespaceDisableTest.java | 0
.../SnapshotSpringNamespaceEnableTest.java | 0
.../lite/spring/snapshot/SocketUtils.java | 0
.../AbstractZookeeperJUnit4SpringContextTests.java | 0
.../test/EmbedZookeeperTestExecutionListener.java | 0
.../src/test/resources/META-INF/job/base.xml | 0
.../resources/META-INF/job/withEventTraceRdb.xml | 0
.../test/resources/META-INF/job/withJobHandler.xml | 0
.../src/test/resources/META-INF/job/withJobRef.xml | 0
.../test/resources/META-INF/job/withListener.xml | 0
.../META-INF/job/withListenerAndCglib.xml | 0
.../job/withListenerAndJdkDynamicProxy.xml | 0
.../resources/META-INF/job/withoutListener.xml | 0
.../src/test/resources/META-INF/reg/regContext.xml | 0
.../META-INF/snapshot/snapshotDisabled.xml | 0
.../META-INF/snapshot/snapshotEnabled.xml | 0
.../src/test/resources/conf/job/conf.properties | 39 +
.../src/test/resources/conf/reg/conf.properties | 0
.../src/test/resources/logback-test.xml | 0
.../elasticjob-lite-tracing-api/pom.xml | 79 +
.../elasticjob/lite/tracing/JobEventBus.java | 0
.../lite/tracing/api/TracingConfiguration.java | 0
.../elasticjob/lite/tracing/event/JobEvent.java | 0
.../lite/tracing/event/JobExecutionEvent.java | 0
.../lite/tracing/event/JobStatusTraceEvent.java | 0
.../exception/TracingConfigurationException.java | 0
.../lite/tracing/listener/TracingListener.java | 0
.../listener/TracingListenerConfiguration.java | 0
.../tracing/listener/TracingListenerFactory.java | 0
.../elasticjob/lite/tracing/JobEventBusTest.java | 0
.../lite/tracing/event/JobExecutionEventTest.java | 0
.../lite/tracing/fixture/JobEventCaller.java | 0
.../fixture/TestTracingFailureConfiguration.java | 0
.../lite/tracing/fixture/TestTracingListener.java | 0
.../fixture/TestTracingListenerConfiguration.java | 0
.../listener/TracingListenerFactoryTest.java | 0
...e.tracing.listener.TracingListenerConfiguration | 0
.../src/test/resources/logback-test.xml | 41 +
.../elasticjob-lite-tracing-rdb/pom.xml | 80 +
.../tracing/rdb/listener/RDBTracingListener.java | 0
.../listener/RDBTracingListenerConfiguration.java | 0
.../tracing/rdb/storage/RDBJobEventStorage.java | 0
.../tracing/rdb/storage/RDBStorageSQLMapper.java | 0
.../lite/tracing/rdb/type/DatabaseType.java | 0
.../tracing/rdb/type/impl/DB2DatabaseType.java | 0
.../lite/tracing/rdb/type/impl/H2DatabaseType.java | 0
.../tracing/rdb/type/impl/MySQLDatabaseType.java | 0
.../tracing/rdb/type/impl/OracleDatabaseType.java | 0
.../rdb/type/impl/PostgreSQLDatabaseType.java | 0
.../rdb/type/impl/SQLServerDatabaseType.java | 0
...e.tracing.listener.TracingListenerConfiguration | 0
...e.elasticjob.lite.tracing.rdb.type.DatabaseType | 0
.../src/main/resources/META-INF/sql/db2.properties | 0
.../src/main/resources/META-INF/sql/h2.properties | 0
.../main/resources/META-INF/sql/mysql.properties | 0
.../main/resources/META-INF/sql/oracle.properties | 0
.../resources/META-INF/sql/postgresQL.properties | 0
.../main/resources/META-INF/sql/sql92.properties | 0
.../resources/META-INF/sql/sqlserver.properties | 0
.../RDBTracingListenerConfigurationTest.java | 0
.../rdb/listener/RDBTracingListenerTest.java | 0
.../rdb/storage/RDBJobEventStorageTest.java | 0
.../src/test/resources/logback-test.xml | 38 +
elasticjob-lite/elasticjob-lite-tracing/pom.xml | 36 +
elasticjob-lite/pom.xml | 40 +
examples/elastic-job-example-embed-zk/pom.xml | 37 -
examples/elastic-job-example-jobs/pom.xml | 54 -
examples/elastic-job-example-lite-java/pom.xml | 77 -
.../elasticjob/lite/example/JavaMain.java | 110 -
.../src/main/resources/logback.xml | 40 -
examples/elastic-job-example-lite-spring/pom.xml | 81 -
.../src/main/resources/conf/job.properties | 59 -
.../src/main/resources/conf/reg.properties | 22 -
.../src/main/resources/logback.xml | 40 -
.../elastic-job-example-lite-springboot/pom.xml | 97 -
.../src/main/resources/application.yml | 17 -
.../src/main/resources/logback.xml | 40 -
examples/elasticjob-example-cloud/pom.xml | 80 +
examples/elasticjob-example-cloud/src/README.txt | 41 +
.../dangdang/ddframe/job/example/CloudJobMain.java | 29 +
.../main/resources/META-INF/applicationContext.xml | 14 +
.../src/main/resources/assembly/assembly.xml | 25 +
.../src/main/resources/bin/start.sh | 2 +
.../src/main/resources/logback.xml | 23 +
.../src/main/resources/script/demo.sh | 2 +
examples/elasticjob-example-embed-zk/pom.xml | 37 +
.../lite/example/EmbedZookeeperServer.java | 0
examples/elasticjob-example-jobs/pom.xml | 54 +
.../lite/example/fixture/entity/Foo.java | 0
.../example/fixture/repository/FooRepository.java | 0
.../fixture/repository/FooRepositoryFactory.java | 0
.../lite/example/job/dataflow/JavaDataflowJob.java | 0
.../example/job/dataflow/SpringDataflowJob.java | 0
.../lite/example/job/simple/JavaSimpleJob.java | 0
.../lite/example/job/simple/SpringSimpleJob.java | 0
examples/elasticjob-example-lite-java/pom.xml | 77 +
.../elasticjob/lite/example/JavaMain.java | 110 +
.../src/main/resources/logback.xml | 40 +
.../src/main/resources/script/demo.bat | 0
.../src/main/resources/script/demo.sh | 0
examples/elasticjob-example-lite-spring/pom.xml | 81 +
.../elasticjob/lite/example/SpringMain.java | 0
.../main/resources/META-INF/applicationContext.xml | 0
.../src/main/resources/conf/job.properties | 59 +
.../src/main/resources/conf/reg.properties | 22 +
.../src/main/resources/logback.xml | 40 +
.../src/main/resources/script/demo.bat | 0
.../src/main/resources/script/demo.sh | 0
.../elasticjob-example-lite-springboot/pom.xml | 96 +
.../elasticjob/lite/example/SpringBootMain.java | 0
.../lite/example/config/DataflowJobConfig.java | 0
.../lite/example/config/RegistryCenterConfig.java | 0
.../lite/example/config/SimpleJobConfig.java | 0
.../lite/example/config/TracingConfig.java | 0
.../src/main/resources/application-dev.yml | 0
.../src/main/resources/application-prod.yml | 0
.../src/main/resources/application.yml | 17 +
.../src/main/resources/logback.xml | 40 +
examples/pom.xml | 26 +-
pom.xml | 48 +-
987 files changed, 56120 insertions(+), 1927 deletions(-)
diff --git a/README.md b/README.md
index c28a8dc..c486e4c 100644
--- a/README.md
+++ b/README.md
@@ -73,14 +73,14 @@ Welcome communicate with community via [mail list](mailto:dev@shardingsphere.apa
<!-- import elastic-job lite core -->
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
+ <artifactId>elasticjob-lite-core</artifactId>
<version>${lasted.release.version}</version>
</dependency>
<!-- import other module if need -->
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
+ <artifactId>elasticjob-lite-spring</artifactId>
<version>${lasted.release.version}</version>
</dependency>
```
diff --git a/README_ZH.md b/README_ZH.md
index f61e0f8..af53478 100644
--- a/README_ZH.md
+++ b/README_ZH.md
@@ -68,17 +68,17 @@ ElasticJob 已于 2020 年 5 月 28 日成为 [Apache ShardingSphere](https://sh
### 引入maven依赖
```xml
-<!-- 引入elastic-job-lite核心模块 -->
+<!-- 引入elasticjob-lite核心模块 -->
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
+ <artifactId>elasticjob-lite-core</artifactId>
<version>${latest.release.version}</version>
</dependency>
<!-- 使用springframework自定义命名空间时引入 -->
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
+ <artifactId>elasticjob-lite-spring</artifactId>
<version>${latest.release.version}</version>
</dependency>
```
diff --git a/docs/content/quick-start/_index.cn.md b/docs/content/quick-start/_index.cn.md
index 013858e..c6f5494 100644
--- a/docs/content/quick-start/_index.cn.md
+++ b/docs/content/quick-start/_index.cn.md
@@ -12,7 +12,7 @@ chapter = true
```xml
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
+ <artifactId>elasticjob-lite-core</artifactId>
<version>${latest.release.version}</version>
</dependency>
```
@@ -78,7 +78,7 @@ public class JobDemo {
```xml
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
+ <artifactId>elasticjob-lite-spring</artifactId>
<version>${latest.release.version}</version>
</dependency>
```
diff --git a/docs/content/user-manual/deploy-guide.cn.md b/docs/content/user-manual/deploy-guide.cn.md
index 03f9ed1..75571d3 100644
--- a/docs/content/user-manual/deploy-guide.cn.md
+++ b/docs/content/user-manual/deploy-guide.cn.md
@@ -13,10 +13,10 @@ chapter = true
## 运维平台和 RESTFul API 部署(可选)
-1. 解压缩 `elastic-job-lite-console-${version}.tar.gz` 并执行 `bin\start.sh`。
+1. 解压缩 `elasticjob-lite-console-${version}.tar.gz` 并执行 `bin\start.sh`。
2. 打开浏览器访问 `http://localhost:8899/` 即可访问控制台。8899 为默认端口号,可通过启动脚本输入 `-p` 自定义端口号。
3. 访问 RESTFul API 方法同控制台。
-4. `elastic-job-lite-console-${version}.tar.gz`可通过 `mvn install` 编译获取。
+4. `elasticjob-lite-console-${version}.tar.gz`可通过 `mvn install` 编译获取。
diff --git a/docs/content/user-manual/job-config.cn.md b/docs/content/user-manual/job-config.cn.md
index 5b3fb0d..a4d2795 100644
--- a/docs/content/user-manual/job-config.cn.md
+++ b/docs/content/user-manual/job-config.cn.md
@@ -51,12 +51,12 @@ chapter = true
## 2. Spring 命名空间配置
-Spring 命名空间与 Java Code 方式配置类似,大部分属性只是将命名方式由驼峰式改为以减号间隔。使用 Spring 命名空间需在 pom.xml 文件中添加 elastic-job-lite-spring 模块的依赖。
+Spring 命名空间与 Java Code 方式配置类似,大部分属性只是将命名方式由驼峰式改为以减号间隔。使用 Spring 命名空间需在 pom.xml 文件中添加 elasticjob-lite-spring 模块的依赖。
```xml
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-spring</artifactId>
+ <artifactId>elasticjob-lite-spring</artifactId>
<version>${latest.release.version}</version>
</dependency>
```
diff --git a/docs/content/user-manual/web-console.cn.md b/docs/content/user-manual/web-console.cn.md
index d60ba00..d7469ba 100644
--- a/docs/content/user-manual/web-console.cn.md
+++ b/docs/content/user-manual/web-console.cn.md
@@ -5,9 +5,9 @@ weight = 11
chapter = true
+++
-解压缩`elastic-job-lite-console-${version}.tar.gz`并执行bin\start.sh。打开浏览器访问`http://localhost:8899/`即可访问控制台。8899为默认端口号,可通过启动脚本输入-p自定义端口号。
+解压缩`elasticjob-lite-console-${version}.tar.gz`并执行bin\start.sh。打开浏览器访问`http://localhost:8899/`即可访问控制台。8899为默认端口号,可通过启动脚本输入-p自定义端口号。
-`elastic-job-lite-console-${version}.tar.gz`可通过mvn install编译获取。
+`elasticjob-lite-console-${version}.tar.gz`可通过mvn install编译获取。
## 登录
diff --git a/elastic-job-lite-console/.dockerignore b/elastic-job-lite-console/.dockerignore
deleted file mode 100644
index 0743e9c..0000000
--- a/elastic-job-lite-console/.dockerignore
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-*
-!target/elastic-job-lite-console-*-console-bin.tar.gz
diff --git a/elastic-job-lite-console/Dockerfile b/elastic-job-lite-console/Dockerfile
deleted file mode 100644
index de24d4b..0000000
--- a/elastic-job-lite-console/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-FROM adoptopenjdk:8-jre-hotspot
-CMD bin/start.sh -p $CONSOLE_PORT
-ENV CONSOLE_PORT=8899
-ADD target/elastic-job-lite-console-*.tar.gz /
-RUN mv $(ls -d /elastic-job-lite-console-*) /elastic-job-lite-console
-WORKDIR /elastic-job-lite-console
diff --git a/elastic-job-lite-console/README.md b/elastic-job-lite-console/README.md
deleted file mode 100644
index 168b142..0000000
--- a/elastic-job-lite-console/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# ElasticJob Lite Console
-
-Usage:
-1. Execute `mvn install`.
-2. Extract `elastic-job-lite-console/target/elastic-job-lite-console-${version}.tar.gz` and goto the extracted directory.
-3. Add JDBC Driver (Such as `mysql-connector-java-8.0.13.jar`) to directory `ext-lib`.
-4. Run ElasticJob Lite Console with `bin/start.sh`
diff --git a/elastic-job-lite-console/pom.xml b/elastic-job-lite-console/pom.xml
deleted file mode 100644
index 4491c63..0000000
--- a/elastic-job-lite-console/pom.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-console</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
-
- <properties>
- <spring-boot.version>2.3.1.RELEASE</spring-boot.version>
- <springframework.version>5.2.7.RELEASE</springframework.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-lifecycle</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <version>${spring-boot.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-jpa</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- <exclusions>
- <exclusion>
- <artifactId>spring-web</artifactId>
- <groupId>org.springframework</groupId>
- </exclusion>
- <exclusion>
- <artifactId>spring-context</artifactId>
- <groupId>org.springframework</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <scope>compile</scope>
- </dependency>
- </dependencies>
-
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <excludes>
- <exclude>bin/*</exclude>
- <exclude>assembly/*</exclude>
- </excludes>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <descriptors>
- <descriptor>src/main/resources/assembly/assembly.xml</descriptor>
- </descriptors>
- </configuration>
- <executions>
- <execution>
- <id>console-bin</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
diff --git a/elastic-job-lite-console/src/main/resources/bin/start.sh b/elastic-job-lite-console/src/main/resources/bin/start.sh
deleted file mode 100644
index 0501206..0000000
--- a/elastic-job-lite-console/src/main/resources/bin/start.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-
-show_usage() {
- echo "Usage: $0 [OPTIONS]"
- echo " -p <port> Server port (default: 8899)"
- exit 1
-}
-
-if [ $# -ne 0 ] && [ $# -ne 2 ]; then
- show_usage
-fi
-
-port="8899"
-
-if [ $# -eq 2 ]; then
- while getopts p: arg
- do case "$arg" in
- p) port="$OPTARG";;
- [?]) show_usage;;
- esac
- done
-fi
-
-if [ "$port" = "" ]; then
- show_usage
-fi
-
-cd `dirname $0`
-cd ..
-DEPLOY_DIR=`pwd`
-CLASS_PATH=.:${DEPLOY_DIR}/conf:${DEPLOY_DIR}/lib/*:${DEPLOY_DIR}/ext-lib/*
-CONSOLE_MAIN=org.apache.shardingsphere.elasticjob.lite.console.ConsoleBootstrap
-
-exec java -classpath ${CLASS_PATH}:. ${CONSOLE_MAIN} ${port}
diff --git a/elastic-job-lite-console/src/main/resources/logback.xml b/elastic-job-lite-console/src/main/resources/logback.xml
deleted file mode 100644
index f6f1bae..0000000
--- a/elastic-job-lite-console/src/main/resources/logback.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<configuration>
- <property name="log.directory" value="logs/" />
- <property name="log.context.name" value="elastic-job-lite-console" />
- <property name="log.charset" value="UTF-8" />
- <property name="log.maxHistory" value="30" />
- <property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
- <property name="log.error.log.level" value="WARN" />
- <property name="log.async.queue.size" value="1024" />
-
- <include resource="includedLogbackConfig.xml" optional="true" />
- <include resource="conf/includedLogbackConfig.xml" optional="true" />
-
- <contextName>${log.context.name}</contextName>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${log.directory}${log.context.name}-log.%d{yyyy-MM-dd}.log</fileNamePattern>
- <maxHistory>${log.maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <!-- Asynchronized log, for FILE only -->
- <appender name ="ASYNC_FILE" class= "ch.qos.logback.classic.AsyncAppender">
- <!-- Don't discard log, logback will discard TRACE, DEBUG, INFO log when queue 80% capacity reached by default. -->
- <discardingThreshold >0</discardingThreshold>
- <queueSize>${log.async.queue.size}</queueSize>
- <appender-ref ref = "FILE"/>
- </appender>
-
- <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>${log.error.log.level}</level>
- </filter>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${log.directory}${log.context.name}-error.%d{yyyy-MM-dd}.log</fileNamePattern>
- <maxHistory>${log.maxHistory}</maxHistory>
- </rollingPolicy>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <root>
- <level value="INFO" />
- <appender-ref ref="STDOUT" />
- <appender-ref ref="ASYNC_FILE" />
- <appender-ref ref="ERROR" />
- </root>
-</configuration>
diff --git a/elastic-job-lite-core/pom.xml b/elastic-job-lite-core/pom.xml
deleted file mode 100644
index 91f4cff..0000000
--- a/elastic-job-lite-core/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-core</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-tracing-rdb</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>org.yaml</groupId>
- <artifactId>snakeyaml</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- </dependency>
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-exec</artifactId>
- <version>${commons-exec.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-framework</artifactId>
- <version>${curator.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-test</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-inline</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-core/src/test/resources/logback-test.xml b/elastic-job-lite-core/src/test/resources/logback-test.xml
deleted file mode 100644
index 9faa73f..0000000
--- a/elastic-job-lite-core/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<configuration>
- <property name="log.context.name" value="elastic-job-lite-core-test" />
- <property name="log.charset" value="UTF-8" />
- <property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
-
- <contextName>${log.context.name}</contextName>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>ERROR</level>
- </filter>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-
- <logger name="org.apache.curator.framework.recipes.leader.LeaderSelector" level="OFF" />
- <logger name="org.apache.shardingsphere.elasticjob.lite.handler.error.impl.LogJobErrorHandler" level="OFF" />
- <logger name="org.apache.shardingsphere.elasticjob.lite.internal.snapshot.SnapshotService" level="OFF" />
-</configuration>
diff --git a/elastic-job-lite-executor/elastic-job-lite-dataflow-executor/pom.xml b/elastic-job-lite-executor/elastic-job-lite-dataflow-executor/pom.xml
deleted file mode 100644
index e5f5bfe..0000000
--- a/elastic-job-lite-executor/elastic-job-lite-dataflow-executor/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>elastic-job-lite-executor</artifactId>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-dataflow-executor</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-executor/elastic-job-lite-script-executor/pom.xml b/elastic-job-lite-executor/elastic-job-lite-script-executor/pom.xml
deleted file mode 100644
index 0214e7d..0000000
--- a/elastic-job-lite-executor/elastic-job-lite-script-executor/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-executor</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-script-executor</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-executor/elastic-job-lite-simple-executor/pom.xml b/elastic-job-lite-executor/elastic-job-lite-simple-executor/pom.xml
deleted file mode 100644
index 9fec728..0000000
--- a/elastic-job-lite-executor/elastic-job-lite-simple-executor/pom.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-executor</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-simple-executor</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-executor/pom.xml b/elastic-job-lite-executor/pom.xml
deleted file mode 100644
index ee3c603..0000000
--- a/elastic-job-lite-executor/pom.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-executor</artifactId>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <modules>
- <module>elastic-job-lite-simple-executor</module>
- <module>elastic-job-lite-dataflow-executor</module>
- <module>elastic-job-lite-script-executor</module>
- </modules>
-</project>
diff --git a/elastic-job-lite-lifecycle/pom.xml b/elastic-job-lite-lifecycle/pom.xml
deleted file mode 100644
index aa8c395..0000000
--- a/elastic-job-lite-lifecycle/pom.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>elastic-job-lite</artifactId>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-lifecycle</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-simple-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-dataflow-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-script-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-codec</groupId>
- <artifactId>commons-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-servlet</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-json</artifactId>
- </dependency>
- <dependency>
- <groupId>com.sun.jersey</groupId>
- <artifactId>jersey-client</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-test</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-inline</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-lifecycle/src/test/resources/logback-test.xml b/elastic-job-lite-lifecycle/src/test/resources/logback-test.xml
deleted file mode 100644
index ed8f9ea..0000000
--- a/elastic-job-lite-lifecycle/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<configuration>
- <property name="log.context.name" value="elastic-job-lite-lifecycle-core-test" />
- <property name="log.charset" value="UTF-8" />
- <property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
-
- <contextName>${log.context.name}</contextName>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>ERROR</level>
- </filter>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
diff --git a/elastic-job-lite-spring/pom.xml b/elastic-job-lite-spring/pom.xml
deleted file mode 100644
index 80dfe32..0000000
--- a/elastic-job-lite-spring/pom.xml
+++ /dev/null
@@ -1,114 +0,0 @@
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-spring</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-core</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-simple-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-dataflow-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-script-executor</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>spring-context</artifactId>
- <groupId>org.springframework</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-test</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-spring/src/test/resources/conf/job/conf.properties b/elastic-job-lite-spring/src/test/resources/conf/job/conf.properties
deleted file mode 100644
index 4344ae1..0000000
--- a/elastic-job-lite-spring/src/test/resources/conf/job/conf.properties
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-regCenter.serverLists=localhost:3181
-regCenter.namespace=elastic-job-lite-spring-test
-regCenter.baseSleepTimeMilliseconds=1000
-regCenter.maxSleepTimeMilliseconds=3000
-regCenter.maxRetries=3
-
-simpleJob.id=simpleElasticJob_namespace_listener
-simpleJob.cron=0/1 * * * * ?
-simpleJob.shardingTotalCount=3
-simpleJob.shardingItemParameters=0=A,1=B,2=C
-simpleJob.disabled=false
-simpleJob.overwrite=true
-
-dataflowJob.cron=0/1 * * * * ?
-dataflowJob.shardingTotalCount=3
-dataflowJob.shardingItemParameters=0=A,1=B,2=C
-dataflowJob.monitorExecution=true
-dataflowJob.failover=true
-dataflowJob.description=Examples of jobs that do not stop running
-dataflowJob.disabled=false
-dataflowJob.overwrite=true
-dataflowJob.streamingProcess=true
diff --git a/elastic-job-lite-tracing/elastic-job-lite-tracing-api/pom.xml b/elastic-job-lite-tracing/elastic-job-lite-tracing-api/pom.xml
deleted file mode 100644
index bb9cc52..0000000
--- a/elastic-job-lite-tracing/elastic-job-lite-tracing-api/pom.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-tracing</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-tracing-api</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-inline</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-tracing/elastic-job-lite-tracing-api/src/test/resources/logback-test.xml b/elastic-job-lite-tracing/elastic-job-lite-tracing-api/src/test/resources/logback-test.xml
deleted file mode 100644
index bb2bcb0..0000000
--- a/elastic-job-lite-tracing/elastic-job-lite-tracing-api/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<configuration>
- <property name="log.context.name" value="elastic-job-lite-core-test" />
- <property name="log.charset" value="UTF-8" />
- <property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
-
- <contextName>${log.context.name}</contextName>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>ERROR</level>
- </filter>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-
- <logger name="org.apache.shardingsphere.elasticjob.lite.tracing.rdb.config.RDBTracingListenerConfiguration" level="OFF" />
- <logger name="org.apache.shardingsphere.elasticjob.lite.tracing.JobEventBus" level="OFF" />
-</configuration>
diff --git a/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/pom.xml b/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/pom.xml
deleted file mode 100644
index b44ec30..0000000
--- a/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-tracing</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-tracing-rdb</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite-tracing-api</artifactId>
- <version>${project.parent.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <version>${commons-dbcp.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-inline</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>jcl-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- </dependency>
- </dependencies>
-</project>
diff --git a/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/src/test/resources/logback-test.xml b/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/src/test/resources/logback-test.xml
deleted file mode 100644
index 3a12ed9..0000000
--- a/elastic-job-lite-tracing/elastic-job-lite-tracing-rdb/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<configuration>
- <property name="log.context.name" value="elastic-job-lite-core-test" />
- <property name="log.charset" value="UTF-8" />
- <property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
-
- <contextName>${log.context.name}</contextName>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
- <level>ERROR</level>
- </filter>
- <encoder charset="${log.charset}">
- <pattern>${log.pattern}</pattern>
- </encoder>
- </appender>
-
- <root>
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
diff --git a/elastic-job-lite-tracing/pom.xml b/elastic-job-lite-tracing/pom.xml
deleted file mode 100644
index 9483e5e..0000000
--- a/elastic-job-lite-tracing/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to You under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.shardingsphere.elasticjob</groupId>
- <artifactId>elastic-job-lite</artifactId>
- <version>3.0.0.M1-SNAPSHOT</version>
- </parent>
- <artifactId>elastic-job-lite-tracing</artifactId>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <modules>
- <module>elastic-job-lite-tracing-api</module>
- <module>elastic-job-lite-tracing-rdb</module>
- </modules>
-</project>
diff --git a/elasticjob-cloud/elasticjob-cloud-common/pom.xml b/elasticjob-cloud/elasticjob-cloud-common/pom.xml
new file mode 100755
index 0000000..1c913b3
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.shardingsphere.elasticjob</groupId>
+ <artifactId>elasticjob-cloud</artifactId>
+ <version>3.0.0.M1-SNAPSHOT</version>
+ </parent>
+ <artifactId>elasticjob-cloud-common</artifactId>
+ <name>${project.artifactId}</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-client</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-recipes</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-test</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.quartz-scheduler</groupId>
+ <artifactId>quartz</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-exec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.projectlombok</groupId>
+ <artifactId>lombok</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.unitils</groupId>
+ <artifactId>unitils-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-inline</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-dbcp</groupId>
+ <artifactId>commons-dbcp</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ElasticJob.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ElasticJob.java
new file mode 100755
index 0000000..32e1636
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ElasticJob.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api;
+
+/**
+ * ElasticJob interface.
+ */
+public interface ElasticJob {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/JobType.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/JobType.java
new file mode 100755
index 0000000..b44b445
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/JobType.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api;
+
+/**
+ * Job type.
+ */
+public enum JobType {
+
+ SIMPLE, DATAFLOW, SCRIPT
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContext.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContext.java
new file mode 100755
index 0000000..4f8ae8b
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContext.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api;
+
+import org.apache.shardingsphere.elasticjob.cloud.executor.ShardingContexts;
+import lombok.Getter;
+import lombok.ToString;
+
+/**
+ * Sharding context.
+ */
+@Getter
+@ToString
+public final class ShardingContext {
+
+ /**
+ * job name.
+ */
+ private final String jobName;
+
+ /**
+ * task ID.
+ */
+ private final String taskId;
+
+ /**
+ * sharding total count.
+ */
+ private final int shardingTotalCount;
+
+ /**
+ * job parameter.
+ *
+ * <p>Can configure for same job class, but use different parameter for different job schedule instance.</p>
+ *
+ */
+ private final String jobParameter;
+
+ /**
+ * Sharding item assigned for this sharding.
+ */
+ private final int shardingItem;
+
+ /**
+ * Sharding parameter assigned for this sharding.
+ */
+ private final String shardingParameter;
+
+ public ShardingContext(final ShardingContexts shardingContexts, final int shardingItem) {
+ jobName = shardingContexts.getJobName();
+ taskId = shardingContexts.getTaskId();
+ shardingTotalCount = shardingContexts.getShardingTotalCount();
+ jobParameter = shardingContexts.getJobParameter();
+ this.shardingItem = shardingItem;
+ shardingParameter = shardingContexts.getShardingItemParameters().get(shardingItem);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/dataflow/DataflowJob.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/dataflow/DataflowJob.java
new file mode 100755
index 0000000..d2157c1
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/dataflow/DataflowJob.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api.dataflow;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ElasticJob;
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+
+import java.util.List;
+
+/**
+ * Dataflow job.
+ *
+ * @param <T> type of data
+ */
+public interface DataflowJob<T> extends ElasticJob {
+
+ /**
+ * Fetch to be processed data.
+ *
+ * @param shardingContext sharding context
+ * @return to be processed data
+ */
+ List<T> fetchData(ShardingContext shardingContext);
+
+ /**
+ * Process data.
+ *
+ * @param shardingContext sharding context
+ * @param data to be processed data
+ */
+ void processData(ShardingContext shardingContext, List<T> data);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/script/ScriptJob.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/script/ScriptJob.java
new file mode 100755
index 0000000..0c32588
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/script/ScriptJob.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api.script;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ElasticJob;
+
+/**
+ * Script job.
+ */
+public interface ScriptJob extends ElasticJob {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/simple/SimpleJob.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/simple/SimpleJob.java
new file mode 100755
index 0000000..a2ac08e
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/api/simple/SimpleJob.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api.simple;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ElasticJob;
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+
+/**
+ * Simple job.
+ */
+public interface SimpleJob extends ElasticJob {
+
+ /**
+ * Execute job.
+ *
+ * @param shardingContext sharding context
+ */
+ void execute(ShardingContext shardingContext);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfiguration.java
new file mode 100755
index 0000000..72cf1f4
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfiguration.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobProperties;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Job core configuration.
+ */
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+@Getter
+public final class JobCoreConfiguration {
+
+ private final String jobName;
+
+ private final String cron;
+
+ private final int shardingTotalCount;
+
+ private final String shardingItemParameters;
+
+ private final String jobParameter;
+
+ private final boolean failover;
+
+ private final boolean misfire;
+
+ private final String description;
+
+ private final JobProperties jobProperties;
+
+ /**
+ * Create simple job configuration builder.
+ *
+ * @param jobName job name
+ * @param cron cron expression for job trigger
+ * @param shardingTotalCount sharding total count
+ * @return simple job configuration builder
+ */
+ public static Builder newBuilder(final String jobName, final String cron, final int shardingTotalCount) {
+ return new Builder(jobName, cron, shardingTotalCount);
+ }
+
+ @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class Builder {
+
+ private final String jobName;
+
+ private final String cron;
+
+ private final int shardingTotalCount;
+
+ private String shardingItemParameters = "";
+
+ private String jobParameter = "";
+
+ private boolean failover;
+
+ private boolean misfire = true;
+
+ private String description = "";
+
+ private final JobProperties jobProperties = new JobProperties();
+
+ /**
+ * Set mapper of sharding items and sharding parameters.
+ *
+ * <p>
+ * sharding item and sharding parameter split by =, multiple sharding items and sharding parameters split by comma, just like map.
+ * Sharding item start from zero, cannot equal to great than sharding total count.
+ *
+ * For example:
+ * 0=a,1=b,2=c
+ * </p>
+ *
+ * @param shardingItemParameters mapper of sharding items and sharding parameters
+ *
+ * @return job configuration builder
+ */
+ public Builder shardingItemParameters(final String shardingItemParameters) {
+ if (null != shardingItemParameters) {
+ this.shardingItemParameters = shardingItemParameters;
+ }
+ return this;
+ }
+
+ /**
+ * Set job parameter.
+ *
+ * @param jobParameter job parameter
+ *
+ * @return job configuration builder
+ */
+ public Builder jobParameter(final String jobParameter) {
+ if (null != jobParameter) {
+ this.jobParameter = jobParameter;
+ }
+ return this;
+ }
+
+ /**
+ * Set enable failover.
+ *
+ * <p>
+ * Only for `monitorExecution` enabled.
+ * </p>
+ *
+ * @param failover enable or disable failover
+ *
+ * @return job configuration builder
+ */
+ public Builder failover(final boolean failover) {
+ this.failover = failover;
+ return this;
+ }
+
+ /**
+ * Set enable misfire.
+ *
+ * @param misfire enable or disable misfire
+ *
+ * @return job configuration builder
+ */
+ public Builder misfire(final boolean misfire) {
+ this.misfire = misfire;
+ return this;
+ }
+
+ /**
+ * Set job description.
+ *
+ * @param description job description
+ *
+ * @return job configuration builder
+ */
+ public Builder description(final String description) {
+ if (null != description) {
+ this.description = description;
+ }
+ return this;
+ }
+
+ /**
+ * Set job properties.
+ *
+ * @param key property key
+ * @param value property value
+ *
+ * @return job configuration builder
+ */
+ public Builder jobProperties(final String key, final String value) {
+ jobProperties.put(key, value);
+ return this;
+ }
+
+ /**
+ * Build Job.
+ *
+ * @return job configuration builder
+ */
+ public final JobCoreConfiguration build() {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(jobName), "jobName can not be empty.");
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(cron), "cron can not be empty.");
+ Preconditions.checkArgument(shardingTotalCount > 0, "shardingTotalCount should larger than zero.");
+ return new JobCoreConfiguration(jobName, cron, shardingTotalCount, shardingItemParameters, jobParameter, failover, misfire, description, jobProperties);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobRootConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobRootConfiguration.java
new file mode 100755
index 0000000..1be7357
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobRootConfiguration.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config;
+
+/**
+ * Job root configuration.
+ */
+public interface JobRootConfiguration {
+
+ /**
+ * Get type Configuration.
+ *
+ * @return Job type configuration
+ */
+ JobTypeConfiguration getTypeConfig();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobTypeConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobTypeConfiguration.java
new file mode 100755
index 0000000..0c8bfda
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/JobTypeConfiguration.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.JobType;
+
+/**
+ * Job type configuration.
+ */
+public interface JobTypeConfiguration {
+
+ /**
+ * Get job type.
+ *
+ * @return job type
+ */
+ JobType getJobType();
+
+ /**
+ * Get job class name.
+ *
+ * @return job class name
+ */
+ String getJobClass();
+
+ /**
+ * Get job core configuration.
+ *
+ * @return job core configuration
+ */
+ JobCoreConfiguration getCoreConfig();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/dataflow/DataflowJobConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/dataflow/DataflowJobConfiguration.java
new file mode 100755
index 0000000..04aa42c
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/dataflow/DataflowJobConfiguration.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config.dataflow;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.JobType;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobCoreConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobTypeConfiguration;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Dataflow job configuration.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class DataflowJobConfiguration implements JobTypeConfiguration {
+
+ private final JobCoreConfiguration coreConfig;
+
+ private final JobType jobType = JobType.DATAFLOW;
+
+ private final String jobClass;
+
+ private final boolean streamingProcess;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/script/ScriptJobConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/script/ScriptJobConfiguration.java
new file mode 100755
index 0000000..acd0289
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/script/ScriptJobConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config.script;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.JobType;
+import org.apache.shardingsphere.elasticjob.cloud.api.script.ScriptJob;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobTypeConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobCoreConfiguration;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Script job configuration.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ScriptJobConfiguration implements JobTypeConfiguration {
+
+ private final JobCoreConfiguration coreConfig;
+
+ private final JobType jobType = JobType.SCRIPT;
+
+ private final String jobClass = ScriptJob.class.getCanonicalName();
+
+ private final String scriptCommandLine;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/simple/SimpleJobConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/simple/SimpleJobConfiguration.java
new file mode 100755
index 0000000..856bd35
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/config/simple/SimpleJobConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config.simple;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.JobType;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobCoreConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobTypeConfiguration;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Simple job configuration.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class SimpleJobConfiguration implements JobTypeConfiguration {
+
+ private final JobCoreConfiguration coreConfig;
+
+ private final JobType jobType = JobType.SIMPLE;
+
+ private final String jobClass;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/ExecutionType.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/ExecutionType.java
new file mode 100755
index 0000000..08444b2
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/ExecutionType.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.context;
+
+/**
+ * Execution type.
+ */
+public enum ExecutionType {
+
+ /**
+ * Ready of execute.
+ */
+ READY,
+
+ /**
+ * Failover execution.
+ */
+ FAILOVER
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContext.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContext.java
new file mode 100755
index 0000000..55403ca
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContext.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.context;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Task runtime context.
+ */
+@Getter
+@EqualsAndHashCode(of = "id")
+@ToString(of = "id")
+public final class TaskContext {
+
+ private static final String DELIMITER = "@-@";
+
+ private static final String UNASSIGNED_SLAVE_ID = "unassigned-slave";
+
+ private String id;
+
+ private final MetaInfo metaInfo;
+
+ private final ExecutionType type;
+
+ private String slaveId;
+
+ @Setter
+ private boolean idle;
+
+ public TaskContext(final String jobName, final List<Integer> shardingItem, final ExecutionType type) {
+ this(jobName, shardingItem, type, UNASSIGNED_SLAVE_ID);
+ }
+
+ public TaskContext(final String jobName, final List<Integer> shardingItem, final ExecutionType type, final String slaveId) {
+ metaInfo = new MetaInfo(jobName, shardingItem);
+ this.type = type;
+ this.slaveId = slaveId;
+ id = Joiner.on(DELIMITER).join(metaInfo, type, slaveId, UUID.randomUUID().toString());
+ }
+
+ private TaskContext(final String id, final MetaInfo metaInfo, final ExecutionType type, final String slaveId) {
+ this.id = id;
+ this.metaInfo = metaInfo;
+ this.type = type;
+ this.slaveId = slaveId;
+ }
+
+ /**
+ * Get task context via task ID.
+ *
+ * @param id task ID
+ * @return task context
+ */
+ public static TaskContext from(final String id) {
+ String[] result = id.split(DELIMITER);
+ Preconditions.checkState(5 == result.length);
+ return new TaskContext(id, MetaInfo.from(result[0] + DELIMITER + result[1]), ExecutionType.valueOf(result[2]), result[3]);
+ }
+
+ /**
+ * Get unassigned task ID before job execute.
+ *
+ * @param id task ID
+ * @return unassigned task ID before job execute
+ */
+ public static String getIdForUnassignedSlave(final String id) {
+ return id.replaceAll(TaskContext.from(id).getSlaveId(), UNASSIGNED_SLAVE_ID);
+ }
+
+ /**
+ * Set job server ID.
+ *
+ * @param slaveId job server ID
+ */
+ public void setSlaveId(final String slaveId) {
+ id = id.replaceAll(this.slaveId, slaveId);
+ this.slaveId = slaveId;
+ }
+
+ /**
+ * Get task name.
+ *
+ * @return task name
+ */
+ public String getTaskName() {
+ return Joiner.on(DELIMITER).join(metaInfo, type, slaveId);
+ }
+
+ /**
+ * Get executor ID.
+ *
+ * @param appName application name
+ * @return executor ID
+ */
+ public String getExecutorId(final String appName) {
+ return Joiner.on(DELIMITER).join(appName, slaveId);
+ }
+
+ /**
+ * Task meta data.
+ */
+ @RequiredArgsConstructor
+ @Getter
+ @EqualsAndHashCode
+ public static class MetaInfo {
+
+ private final String jobName;
+
+ private final List<Integer> shardingItems;
+
+ /**
+ * Get task meta data info via string.
+ *
+ * @param value task meta data info string
+ * @return task meta data info
+ */
+ public static MetaInfo from(final String value) {
+ String[] result = value.split(DELIMITER);
+ Preconditions.checkState(1 == result.length || 2 == result.length || 5 == result.length);
+ return new MetaInfo(result[0], 1 == result.length || "".equals(result[1]) ? Collections.<Integer>emptyList() : Lists.transform(Splitter.on(",").splitToList(result[1]),
+ new Function<String, Integer>() {
+
+ @Override
+ public Integer apply(final String input) {
+ return Integer.parseInt(input);
+ }
+ }));
+ }
+
+ @Override
+ public String toString() {
+ return Joiner.on(DELIMITER).join(jobName, Joiner.on(",").join(shardingItems));
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEvent.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEvent.java
new file mode 100755
index 0000000..95223b6
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEvent.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+/**
+ * Job event.
+ */
+public interface JobEvent {
+
+ /**
+ * Get job name.
+ *
+ * @return job name
+ */
+ String getJobName();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBus.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBus.java
new file mode 100755
index 0000000..4bffc03
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBus.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+import com.google.common.eventbus.AsyncEventBus;
+import com.google.common.eventbus.EventBus;
+import org.apache.shardingsphere.elasticjob.cloud.util.concurrent.ExecutorServiceObject;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Job event bus.
+ */
+@Slf4j
+public final class JobEventBus {
+
+ private final JobEventConfiguration jobEventConfig;
+
+ private final ExecutorServiceObject executorServiceObject;
+
+ private final EventBus eventBus;
+
+ private boolean isRegistered;
+
+ public JobEventBus() {
+ jobEventConfig = null;
+ executorServiceObject = null;
+ eventBus = null;
+ }
+
+ public JobEventBus(final JobEventConfiguration jobEventConfig) {
+ this.jobEventConfig = jobEventConfig;
+ executorServiceObject = new ExecutorServiceObject("job-event", Runtime.getRuntime().availableProcessors() * 2);
+ eventBus = new AsyncEventBus(executorServiceObject.createExecutorService());
+ register();
+ }
+
+ private void register() {
+ try {
+ eventBus.register(jobEventConfig.createJobEventListener());
+ isRegistered = true;
+ } catch (final JobEventListenerConfigurationException ex) {
+ log.error("Elastic job: create JobEventListener failure, error is: ", ex);
+ }
+ }
+
+ /**
+ * Post event.
+ *
+ * @param event job event
+ */
+ public void post(final JobEvent event) {
+ if (isRegistered && !executorServiceObject.isShutdown()) {
+ eventBus.post(event);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventConfiguration.java
new file mode 100755
index 0000000..8de6952
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventConfiguration.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+/**
+ * Job event configuration.
+ */
+public interface JobEventConfiguration extends JobEventIdentity {
+
+ /**
+ * Create job event listener.
+ *
+ * @return Job event listener
+ * @throws JobEventListenerConfigurationException job event listener configuration exception
+ */
+ JobEventListener createJobEventListener() throws JobEventListenerConfigurationException;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventIdentity.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventIdentity.java
new file mode 100755
index 0000000..a3367fb
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventIdentity.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+/**
+ * Job event identity.
+ */
+public interface JobEventIdentity {
+
+ /**
+ * Get identity.
+ *
+ * @return identity
+ */
+ String getIdentity();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListener.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListener.java
new file mode 100755
index 0000000..36a2111
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListener.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+
+/**
+ * Job event listener.
+ */
+public interface JobEventListener extends JobEventIdentity {
+
+ /**
+ * Listen job execution event.
+ *
+ * @param jobExecutionEvent job execution event
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ void listen(JobExecutionEvent jobExecutionEvent);
+
+ /**
+ * Listen job status trace event.
+ *
+ * @param jobStatusTraceEvent job status trace event
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ void listen(JobStatusTraceEvent jobStatusTraceEvent);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListenerConfigurationException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListenerConfigurationException.java
new file mode 100755
index 0000000..ac33ae6
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventListenerConfigurationException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+/**
+ * Job event listener configuration exception.
+ */
+public final class JobEventListenerConfigurationException extends Exception {
+
+ private static final long serialVersionUID = 4069519372148227761L;
+
+ public JobEventListenerConfigurationException(final Exception ex) {
+ super(ex);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/DatabaseType.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/DatabaseType.java
new file mode 100755
index 0000000..126ebdf
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/DatabaseType.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterators;
+
+import java.util.Arrays;
+
+/**
+ * Database type.
+ */
+public enum DatabaseType {
+
+ H2("H2"), MySQL("MySQL"), Oracle("Oracle"), SQLServer("Microsoft SQL Server"), DB2("DB2"), PostgreSQL("PostgreSQL");
+
+ private final String productName;
+
+ DatabaseType(final String productName) {
+ this.productName = productName;
+ }
+
+ /**
+ * Get database type.
+ *
+ * @param databaseProductName database product name
+ * @return database type
+ */
+ public static DatabaseType valueFrom(final String databaseProductName) {
+ Optional<DatabaseType> databaseTypeOptional = Iterators.tryFind(Arrays.asList(DatabaseType.values()).iterator(), new Predicate<DatabaseType>() {
+ @Override
+ public boolean apply(final DatabaseType input) {
+ return input.productName.equals(databaseProductName);
+ }
+ });
+ if (databaseTypeOptional.isPresent()) {
+ return databaseTypeOptional.get();
+ } else {
+ throw new RuntimeException("Unsupported database:" + databaseProductName);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfiguration.java
new file mode 100755
index 0000000..f608caf
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfiguration.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListenerConfigurationException;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import javax.sql.DataSource;
+import java.io.Serializable;
+import java.sql.SQLException;
+
+/**
+ * Job event RDB configuration.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class JobEventRdbConfiguration extends JobEventRdbIdentity implements JobEventConfiguration, Serializable {
+
+ private static final long serialVersionUID = 3344410699286435226L;
+
+ private final transient DataSource dataSource;
+
+ @Override
+ public JobEventListener createJobEventListener() throws JobEventListenerConfigurationException {
+ try {
+ return new JobEventRdbListener(dataSource);
+ } catch (final SQLException ex) {
+ throw new JobEventListenerConfigurationException(ex);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentity.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentity.java
new file mode 100755
index 0000000..1857f44
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentity.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventIdentity;
+
+/**
+ * Job event RDB identity.
+ */
+public class JobEventRdbIdentity implements JobEventIdentity {
+
+ @Override
+ public String getIdentity() {
+ return "rdb";
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListener.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListener.java
new file mode 100755
index 0000000..9027db0
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListener.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+/**
+ * Job event RDB listener.
+ */
+public final class JobEventRdbListener extends JobEventRdbIdentity implements JobEventListener {
+
+ private final JobEventRdbStorage repository;
+
+ public JobEventRdbListener(final DataSource dataSource) throws SQLException {
+ repository = new JobEventRdbStorage(dataSource);
+ }
+
+ @Override
+ public void listen(final JobExecutionEvent executionEvent) {
+ repository.addJobExecutionEvent(executionEvent);
+ }
+
+ @Override
+ public void listen(final JobStatusTraceEvent jobStatusTraceEvent) {
+ repository.addJobStatusTraceEvent(jobStatusTraceEvent);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearch.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearch.java
new file mode 100755
index 0000000..54fa230
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearch.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEventThrowable;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Job event RDB search.
+ */
+@RequiredArgsConstructor
+@Slf4j
+public final class JobEventRdbSearch {
+
+ private static final String TABLE_JOB_EXECUTION_LOG = "JOB_EXECUTION_LOG";
+
+ private static final String TABLE_JOB_STATUS_TRACE_LOG = "JOB_STATUS_TRACE_LOG";
+
+ private static final List<String> FIELDS_JOB_EXECUTION_LOG =
+ Lists.newArrayList("id", "hostname", "ip", "task_id", "job_name", "execution_source", "sharding_item", "start_time", "complete_time", "is_success", "failure_cause");
+
+ private static final List<String> FIELDS_JOB_STATUS_TRACE_LOG =
+ Lists.newArrayList("id", "job_name", "original_task_id", "task_id", "slave_id", "source", "execution_type", "sharding_item", "state", "message", "creation_time");
+
+ private final DataSource dataSource;
+
+ /**
+ * Find job execution events.
+ *
+ * @param condition query condition
+ * @return job execution events
+ */
+ public Result<JobExecutionEvent> findJobExecutionEvents(final Condition condition) {
+ return new Result<>(getEventCount(TABLE_JOB_EXECUTION_LOG, FIELDS_JOB_EXECUTION_LOG, condition), getJobExecutionEvents(condition));
+ }
+
+ /**
+ * Find job status trace events.
+ *
+ * @param condition query condition
+ * @return job status trace events
+ */
+ public Result<JobStatusTraceEvent> findJobStatusTraceEvents(final Condition condition) {
+ return new Result<>(getEventCount(TABLE_JOB_STATUS_TRACE_LOG, FIELDS_JOB_STATUS_TRACE_LOG, condition), getJobStatusTraceEvents(condition));
+ }
+
+ private List<JobExecutionEvent> getJobExecutionEvents(final Condition condition) {
+ List<JobExecutionEvent> result = new LinkedList<>();
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = createDataPreparedStatement(conn, TABLE_JOB_EXECUTION_LOG, FIELDS_JOB_EXECUTION_LOG, condition);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ JobExecutionEvent jobExecutionEvent = new JobExecutionEvent(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4),
+ resultSet.getString(5), JobExecutionEvent.ExecutionSource.valueOf(resultSet.getString(6)), Integer.valueOf(resultSet.getString(7)),
+ new Date(resultSet.getTimestamp(8).getTime()), resultSet.getTimestamp(9) == null ? null : new Date(resultSet.getTimestamp(9).getTime()),
+ resultSet.getBoolean(10), new JobExecutionEventThrowable(null, resultSet.getString(11))
+ );
+ result.add(jobExecutionEvent);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch JobExecutionEvent from DB error:", ex);
+ }
+ return result;
+ }
+
+ private List<JobStatusTraceEvent> getJobStatusTraceEvents(final Condition condition) {
+ List<JobStatusTraceEvent> result = new LinkedList<>();
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = createDataPreparedStatement(conn, TABLE_JOB_STATUS_TRACE_LOG, FIELDS_JOB_STATUS_TRACE_LOG, condition);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4),
+ resultSet.getString(5), JobStatusTraceEvent.Source.valueOf(resultSet.getString(6)), ExecutionType.valueOf(resultSet.getString(7)), resultSet.getString(8),
+ JobStatusTraceEvent.State.valueOf(resultSet.getString(9)), resultSet.getString(10), new Date(resultSet.getTimestamp(11).getTime()));
+ result.add(jobStatusTraceEvent);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch JobStatusTraceEvent from DB error:", ex);
+ }
+ return result;
+ }
+
+ private int getEventCount(final String tableName, final Collection<String> tableFields, final Condition condition) {
+ int result = 0;
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = createCountPreparedStatement(conn, tableName, tableFields, condition);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ resultSet.next();
+ result = resultSet.getInt(1);
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch EventCount from DB error:", ex);
+ }
+ return result;
+ }
+
+ private PreparedStatement createDataPreparedStatement(final Connection conn, final String tableName, final Collection<String> tableFields, final Condition condition) throws SQLException {
+ String sql = buildDataSql(tableName, tableFields, condition);
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ setBindValue(preparedStatement, tableFields, condition);
+ return preparedStatement;
+ }
+
+ private PreparedStatement createCountPreparedStatement(final Connection conn, final String tableName, final Collection<String> tableFields, final Condition condition) throws SQLException {
+ String sql = buildCountSql(tableName, tableFields, condition);
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ setBindValue(preparedStatement, tableFields, condition);
+ return preparedStatement;
+ }
+
+ private String buildDataSql(final String tableName, final Collection<String> tableFields, final Condition condition) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ String selectSql = buildSelect(tableName, tableFields);
+ String whereSql = buildWhere(tableName, tableFields, condition);
+ String orderSql = buildOrder(tableFields, condition.getSort(), condition.getOrder());
+ String limitSql = buildLimit(condition.getPage(), condition.getPerPage());
+ sqlBuilder.append(selectSql).append(whereSql).append(orderSql).append(limitSql);
+ return sqlBuilder.toString();
+ }
+
+ private String buildCountSql(final String tableName, final Collection<String> tableFields, final Condition condition) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ String selectSql = buildSelectCount(tableName);
+ String whereSql = buildWhere(tableName, tableFields, condition);
+ sqlBuilder.append(selectSql).append(whereSql);
+ return sqlBuilder.toString();
+ }
+
+ private String buildSelectCount(final String tableName) {
+ return String.format("SELECT COUNT(1) FROM %s", tableName);
+ }
+
+ private String buildSelect(final String tableName, final Collection<String> tableFields) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append("SELECT ");
+ for (String each : tableFields) {
+ sqlBuilder.append(each).append(",");
+ }
+ sqlBuilder.deleteCharAt(sqlBuilder.length() - 1);
+ sqlBuilder.append(" FROM ").append(tableName);
+ return sqlBuilder.toString();
+ }
+
+ private String buildWhere(final String tableName, final Collection<String> tableFields, final Condition condition) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append(" WHERE 1=1");
+ if (null != condition.getFields() && !condition.getFields().isEmpty()) {
+ for (Map.Entry<String, Object> entry : condition.getFields().entrySet()) {
+ String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
+ if (null != entry.getValue() && tableFields.contains(lowerUnderscore)) {
+ sqlBuilder.append(" AND ").append(lowerUnderscore).append("=?");
+ }
+ }
+ }
+ if (null != condition.getStartTime()) {
+ sqlBuilder.append(" AND ").append(getTableTimeField(tableName)).append(">=?");
+ }
+ if (null != condition.getEndTime()) {
+ sqlBuilder.append(" AND ").append(getTableTimeField(tableName)).append("<=?");
+ }
+ return sqlBuilder.toString();
+ }
+
+ private void setBindValue(final PreparedStatement preparedStatement, final Collection<String> tableFields, final Condition condition) throws SQLException {
+ int index = 1;
+ if (null != condition.getFields() && !condition.getFields().isEmpty()) {
+ for (Map.Entry<String, Object> entry : condition.getFields().entrySet()) {
+ String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
+ if (null != entry.getValue() && tableFields.contains(lowerUnderscore)) {
+ preparedStatement.setString(index++, String.valueOf(entry.getValue()));
+ }
+ }
+ }
+ if (null != condition.getStartTime()) {
+ preparedStatement.setTimestamp(index++, new Timestamp(condition.getStartTime().getTime()));
+ }
+ if (null != condition.getEndTime()) {
+ preparedStatement.setTimestamp(index, new Timestamp(condition.getEndTime().getTime()));
+ }
+ }
+
+ private String getTableTimeField(final String tableName) {
+ String result = "";
+ if (TABLE_JOB_EXECUTION_LOG.equals(tableName)) {
+ result = "start_time";
+ } else if (TABLE_JOB_STATUS_TRACE_LOG.equals(tableName)) {
+ result = "creation_time";
+ }
+ return result;
+ }
+
+ private String buildOrder(final Collection<String> tableFields, final String sortName, final String sortOrder) {
+ if (Strings.isNullOrEmpty(sortName)) {
+ return "";
+ }
+ String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, sortName);
+ if (!tableFields.contains(lowerUnderscore)) {
+ return "";
+ }
+ StringBuilder sqlBuilder = new StringBuilder();
+ sqlBuilder.append(" ORDER BY ").append(lowerUnderscore);
+ switch (sortOrder.toUpperCase()) {
+ case "ASC":
+ sqlBuilder.append(" ASC");
+ break;
+ case "DESC":
+ sqlBuilder.append(" DESC");
+ break;
+ default :
+ sqlBuilder.append(" ASC");
+ }
+ return sqlBuilder.toString();
+ }
+
+ private String buildLimit(final int page, final int perPage) {
+ StringBuilder sqlBuilder = new StringBuilder();
+ if (page > 0 && perPage > 0) {
+ sqlBuilder.append(" LIMIT ").append((page - 1) * perPage).append(",").append(perPage);
+ } else {
+ sqlBuilder.append(" LIMIT ").append(Condition.DEFAULT_PAGE_SIZE);
+ }
+ return sqlBuilder.toString();
+ }
+
+ /**
+ * Query condition.
+ */
+ @RequiredArgsConstructor
+ @Getter
+ public static class Condition {
+
+ private static final int DEFAULT_PAGE_SIZE = 10;
+
+ private final int perPage;
+
+ private final int page;
+
+ private final String sort;
+
+ private final String order;
+
+ private final Date startTime;
+
+ private final Date endTime;
+
+ private final Map<String, Object> fields;
+ }
+
+ @RequiredArgsConstructor
+ @Getter
+ public static class Result<T> {
+
+ private final Integer total;
+
+ private final List<T> rows;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorage.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorage.java
new file mode 100755
index 0000000..7dd30ce
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorage.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Job event RDB storage.
+ */
+@Slf4j
+final class JobEventRdbStorage {
+
+ private static final String TABLE_JOB_EXECUTION_LOG = "JOB_EXECUTION_LOG";
+
+ private static final String TABLE_JOB_STATUS_TRACE_LOG = "JOB_STATUS_TRACE_LOG";
+
+ private static final String TASK_ID_STATE_INDEX = "TASK_ID_STATE_INDEX";
+
+ private final DataSource dataSource;
+
+ private DatabaseType databaseType;
+
+ JobEventRdbStorage(final DataSource dataSource) throws SQLException {
+ this.dataSource = dataSource;
+ initTablesAndIndexes();
+ }
+
+ private void initTablesAndIndexes() throws SQLException {
+ try (Connection conn = dataSource.getConnection()) {
+ createJobExecutionTableAndIndexIfNeeded(conn);
+ createJobStatusTraceTableAndIndexIfNeeded(conn);
+ databaseType = DatabaseType.valueFrom(conn.getMetaData().getDatabaseProductName());
+ }
+ }
+
+ private void createJobExecutionTableAndIndexIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_JOB_EXECUTION_LOG, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createJobExecutionTable(conn);
+ }
+ }
+ }
+
+ private void createJobStatusTraceTableAndIndexIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_JOB_STATUS_TRACE_LOG, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createJobStatusTraceTable(conn);
+ }
+ }
+ createTaskIdIndexIfNeeded(conn, TABLE_JOB_STATUS_TRACE_LOG, TASK_ID_STATE_INDEX);
+ }
+
+ private void createTaskIdIndexIfNeeded(final Connection conn, final String tableName, final String indexName) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getIndexInfo(null, null, tableName, false, false)) {
+ boolean hasTaskIdIndex = false;
+ while (resultSet.next()) {
+ if (indexName.equals(resultSet.getString("INDEX_NAME"))) {
+ hasTaskIdIndex = true;
+ }
+ }
+ if (!hasTaskIdIndex) {
+ createTaskIdAndStateIndex(conn, tableName);
+ }
+ }
+ }
+
+ private void createJobExecutionTable(final Connection conn) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_JOB_EXECUTION_LOG + "` ("
+ + "`id` VARCHAR(40) NOT NULL, "
+ + "`job_name` VARCHAR(100) NOT NULL, "
+ + "`task_id` VARCHAR(255) NOT NULL, "
+ + "`hostname` VARCHAR(255) NOT NULL, "
+ + "`ip` VARCHAR(50) NOT NULL, "
+ + "`sharding_item` INT NOT NULL, "
+ + "`execution_source` VARCHAR(20) NOT NULL, "
+ + "`failure_cause` VARCHAR(4000) NULL, "
+ + "`is_success` INT NOT NULL, "
+ + "`start_time` TIMESTAMP NULL, "
+ + "`complete_time` TIMESTAMP NULL, "
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ private void createJobStatusTraceTable(final Connection conn) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_JOB_STATUS_TRACE_LOG + "` ("
+ + "`id` VARCHAR(40) NOT NULL, "
+ + "`job_name` VARCHAR(100) NOT NULL, "
+ + "`original_task_id` VARCHAR(255) NOT NULL, "
+ + "`task_id` VARCHAR(255) NOT NULL, "
+ + "`slave_id` VARCHAR(50) NOT NULL, "
+ + "`source` VARCHAR(50) NOT NULL, "
+ + "`execution_type` VARCHAR(20) NOT NULL, "
+ + "`sharding_item` VARCHAR(100) NOT NULL, "
+ + "`state` VARCHAR(20) NOT NULL, "
+ + "`message` VARCHAR(4000) NULL, "
+ + "`creation_time` TIMESTAMP NULL, "
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ private void createTaskIdAndStateIndex(final Connection conn, final String tableName) throws SQLException {
+ String sql = "CREATE INDEX " + TASK_ID_STATE_INDEX + " ON " + tableName + " (`task_id`, `state`);";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.execute();
+ }
+ }
+
+ boolean addJobExecutionEvent(final JobExecutionEvent jobExecutionEvent) {
+ if (null == jobExecutionEvent.getCompleteTime()) {
+ return insertJobExecutionEvent(jobExecutionEvent);
+ } else {
+ if (jobExecutionEvent.isSuccess()) {
+ return updateJobExecutionEventWhenSuccess(jobExecutionEvent);
+ } else {
+ return updateJobExecutionEventFailure(jobExecutionEvent);
+ }
+ }
+ }
+
+ private boolean insertJobExecutionEvent(final JobExecutionEvent jobExecutionEvent) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_EXECUTION_LOG + "` (`id`, `job_name`, `task_id`, `hostname`, `ip`, `sharding_item`, `execution_source`, `is_success`, `start_time`) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setString(1, jobExecutionEvent.getId());
+ preparedStatement.setString(2, jobExecutionEvent.getJobName());
+ preparedStatement.setString(3, jobExecutionEvent.getTaskId());
+ preparedStatement.setString(4, jobExecutionEvent.getHostname());
+ preparedStatement.setString(5, jobExecutionEvent.getIp());
+ preparedStatement.setInt(6, jobExecutionEvent.getShardingItem());
+ preparedStatement.setString(7, jobExecutionEvent.getSource().toString());
+ preparedStatement.setBoolean(8, jobExecutionEvent.isSuccess());
+ preparedStatement.setTimestamp(9, new Timestamp(jobExecutionEvent.getStartTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ if (!isDuplicateRecord(ex)) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ }
+ return result;
+ }
+
+ private boolean isDuplicateRecord(final SQLException ex) {
+ return DatabaseType.MySQL.equals(databaseType) && 1062 == ex.getErrorCode() || DatabaseType.H2.equals(databaseType) && 23505 == ex.getErrorCode()
+ || DatabaseType.SQLServer.equals(databaseType) && 1 == ex.getErrorCode() || DatabaseType.DB2.equals(databaseType) && -803 == ex.getErrorCode()
+ || DatabaseType.PostgreSQL.equals(databaseType) && 0 == ex.getErrorCode() || DatabaseType.Oracle.equals(databaseType) && 1 == ex.getErrorCode();
+ }
+
+ private boolean updateJobExecutionEventWhenSuccess(final JobExecutionEvent jobExecutionEvent) {
+ boolean result = false;
+ String sql = "UPDATE `" + TABLE_JOB_EXECUTION_LOG + "` SET `is_success` = ?, `complete_time` = ? WHERE id = ?";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setBoolean(1, jobExecutionEvent.isSuccess());
+ preparedStatement.setTimestamp(2, new Timestamp(jobExecutionEvent.getCompleteTime().getTime()));
+ preparedStatement.setString(3, jobExecutionEvent.getId());
+ if (0 == preparedStatement.executeUpdate()) {
+ return insertJobExecutionEventWhenSuccess(jobExecutionEvent);
+ }
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ private boolean insertJobExecutionEventWhenSuccess(final JobExecutionEvent jobExecutionEvent) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_EXECUTION_LOG + "` (`id`, `job_name`, `task_id`, `hostname`, `ip`, `sharding_item`, `execution_source`, `is_success`, `start_time`, `complete_time`) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setString(1, jobExecutionEvent.getId());
+ preparedStatement.setString(2, jobExecutionEvent.getJobName());
+ preparedStatement.setString(3, jobExecutionEvent.getTaskId());
+ preparedStatement.setString(4, jobExecutionEvent.getHostname());
+ preparedStatement.setString(5, jobExecutionEvent.getIp());
+ preparedStatement.setInt(6, jobExecutionEvent.getShardingItem());
+ preparedStatement.setString(7, jobExecutionEvent.getSource().toString());
+ preparedStatement.setBoolean(8, jobExecutionEvent.isSuccess());
+ preparedStatement.setTimestamp(9, new Timestamp(jobExecutionEvent.getStartTime().getTime()));
+ preparedStatement.setTimestamp(10, new Timestamp(jobExecutionEvent.getCompleteTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ if (isDuplicateRecord(ex)) {
+ return updateJobExecutionEventWhenSuccess(jobExecutionEvent);
+ }
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ private boolean updateJobExecutionEventFailure(final JobExecutionEvent jobExecutionEvent) {
+ boolean result = false;
+ String sql = "UPDATE `" + TABLE_JOB_EXECUTION_LOG + "` SET `is_success` = ?, `complete_time` = ?, `failure_cause` = ? WHERE id = ?";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setBoolean(1, jobExecutionEvent.isSuccess());
+ preparedStatement.setTimestamp(2, new Timestamp(jobExecutionEvent.getCompleteTime().getTime()));
+ preparedStatement.setString(3, truncateString(jobExecutionEvent.getFailureCause()));
+ preparedStatement.setString(4, jobExecutionEvent.getId());
+ if (0 == preparedStatement.executeUpdate()) {
+ return insertJobExecutionEventWhenFailure(jobExecutionEvent);
+ }
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ private boolean insertJobExecutionEventWhenFailure(final JobExecutionEvent jobExecutionEvent) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_EXECUTION_LOG + "` (`id`, `job_name`, `task_id`, `hostname`, `ip`, `sharding_item`, `execution_source`, `failure_cause`, `is_success`, `start_time`) "
+ + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setString(1, jobExecutionEvent.getId());
+ preparedStatement.setString(2, jobExecutionEvent.getJobName());
+ preparedStatement.setString(3, jobExecutionEvent.getTaskId());
+ preparedStatement.setString(4, jobExecutionEvent.getHostname());
+ preparedStatement.setString(5, jobExecutionEvent.getIp());
+ preparedStatement.setInt(6, jobExecutionEvent.getShardingItem());
+ preparedStatement.setString(7, jobExecutionEvent.getSource().toString());
+ preparedStatement.setString(8, truncateString(jobExecutionEvent.getFailureCause()));
+ preparedStatement.setBoolean(9, jobExecutionEvent.isSuccess());
+ preparedStatement.setTimestamp(10, new Timestamp(jobExecutionEvent.getStartTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ if (isDuplicateRecord(ex)) {
+ return updateJobExecutionEventFailure(jobExecutionEvent);
+ }
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ boolean addJobStatusTraceEvent(final JobStatusTraceEvent jobStatusTraceEvent) {
+ String originalTaskId = jobStatusTraceEvent.getOriginalTaskId();
+ if (JobStatusTraceEvent.State.TASK_STAGING != jobStatusTraceEvent.getState()) {
+ originalTaskId = getOriginalTaskId(jobStatusTraceEvent.getTaskId());
+ }
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_STATUS_TRACE_LOG + "` (`id`, `job_name`, `original_task_id`, `task_id`, `slave_id`, `source`, `execution_type`, `sharding_item`, "
+ + "`state`, `message`, `creation_time`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setString(1, UUID.randomUUID().toString());
+ preparedStatement.setString(2, jobStatusTraceEvent.getJobName());
+ preparedStatement.setString(3, originalTaskId);
+ preparedStatement.setString(4, jobStatusTraceEvent.getTaskId());
+ preparedStatement.setString(5, jobStatusTraceEvent.getSlaveId());
+ preparedStatement.setString(6, jobStatusTraceEvent.getSource().toString());
+ preparedStatement.setString(7, jobStatusTraceEvent.getExecutionType().name());
+ preparedStatement.setString(8, jobStatusTraceEvent.getShardingItems());
+ preparedStatement.setString(9, jobStatusTraceEvent.getState().toString());
+ preparedStatement.setString(10, truncateString(jobStatusTraceEvent.getMessage()));
+ preparedStatement.setTimestamp(11, new Timestamp(jobStatusTraceEvent.getCreationTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ private String getOriginalTaskId(final String taskId) {
+ String sql = String.format("SELECT original_task_id FROM %s WHERE task_id = '%s' and state='%s' LIMIT 1", TABLE_JOB_STATUS_TRACE_LOG, taskId, JobStatusTraceEvent.State.TASK_STAGING);
+ String result = "";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ if (resultSet.next()) {
+ return resultSet.getString("original_task_id");
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+
+ private String truncateString(final String str) {
+ return !Strings.isNullOrEmpty(str) && str.length() > 4000 ? str.substring(0, 4000) : str;
+ }
+
+ List<JobStatusTraceEvent> getJobStatusTraceEvents(final String taskId) {
+ String sql = String.format("SELECT * FROM %s WHERE task_id = '%s'", TABLE_JOB_STATUS_TRACE_LOG, taskId);
+ List<JobStatusTraceEvent> result = new ArrayList<>();
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4),
+ resultSet.getString(5), JobStatusTraceEvent.Source.valueOf(resultSet.getString(6)), ExecutionType.valueOf(resultSet.getString(7)), resultSet.getString(8),
+ JobStatusTraceEvent.State.valueOf(resultSet.getString(9)), resultSet.getString(10), new SimpleDateFormat("yyyy-mm-dd HH:MM:SS").parse(resultSet.getString(11)));
+ result.add(jobStatusTraceEvent);
+ }
+ } catch (final SQLException | ParseException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error(ex.getMessage());
+ }
+ return result;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEvent.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEvent.java
new file mode 100755
index 0000000..931c656
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEvent.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.type;
+
+import org.apache.shardingsphere.elasticjob.cloud.exception.ExceptionUtil;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEvent;
+import org.apache.shardingsphere.elasticjob.cloud.util.env.IpUtils;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * Job execution event.
+ */
+@RequiredArgsConstructor
+@AllArgsConstructor
+@Getter
+public final class JobExecutionEvent implements JobEvent {
+
+ private String id = UUID.randomUUID().toString();
+
+ private String hostname = IpUtils.getHostName();
+
+ private String ip = IpUtils.getIp();
+
+ private final String taskId;
+
+ private final String jobName;
+
+ private final ExecutionSource source;
+
+ private final int shardingItem;
+
+ private Date startTime = new Date();
+
+ @Setter
+ private Date completeTime;
+
+ @Setter
+ private boolean success;
+
+ @Setter
+ private JobExecutionEventThrowable failureCause;
+
+ /**
+ * Execution success.
+ *
+ * @return job execution event
+ */
+ public JobExecutionEvent executionSuccess() {
+ JobExecutionEvent result = new JobExecutionEvent(id, hostname, ip, taskId, jobName, source, shardingItem, startTime, completeTime, success, failureCause);
+ result.setCompleteTime(new Date());
+ result.setSuccess(true);
+ return result;
+ }
+
+ /**
+ * execution failure.
+ *
+ * @param failureCause failure cause
+ * @return job execution event
+ */
+ public JobExecutionEvent executionFailure(final Throwable failureCause) {
+ JobExecutionEvent result = new JobExecutionEvent(id, hostname, ip, taskId, jobName, source, shardingItem, startTime, completeTime, success, new JobExecutionEventThrowable(failureCause));
+ result.setCompleteTime(new Date());
+ result.setSuccess(false);
+ return result;
+ }
+
+ /**
+ * Get failure cause.
+ *
+ * @return failure cause
+ */
+ public String getFailureCause() {
+ return ExceptionUtil.transform(failureCause == null ? null : failureCause.getThrowable());
+ }
+
+ /**
+ * Execution source.
+ */
+ public enum ExecutionSource {
+ NORMAL_TRIGGER, MISFIRE, FAILOVER
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEventThrowable.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEventThrowable.java
new file mode 100755
index 0000000..a0d0a17
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobExecutionEventThrowable.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.type;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+/**
+ * Job execution event throwable.
+ */
+@RequiredArgsConstructor
+@AllArgsConstructor
+@Getter
+@ToString(of = "plainText")
+public final class JobExecutionEventThrowable {
+
+ private final Throwable throwable;
+
+ private String plainText;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobStatusTraceEvent.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobStatusTraceEvent.java
new file mode 100755
index 0000000..70f1229
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/event/type/JobStatusTraceEvent.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.type;
+
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEvent;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * Job status trace event.
+ */
+@RequiredArgsConstructor
+@AllArgsConstructor
+@Getter
+public final class JobStatusTraceEvent implements JobEvent {
+
+ private String id = UUID.randomUUID().toString();
+
+ private final String jobName;
+
+ @Setter
+ private String originalTaskId = "";
+
+ private final String taskId;
+
+ private final String slaveId;
+
+ private final Source source;
+
+ private final ExecutionType executionType;
+
+ private final String shardingItems;
+
+ private final State state;
+
+ private final String message;
+
+ private Date creationTime = new Date();
+
+ public enum State {
+ TASK_STAGING, TASK_RUNNING, TASK_FINISHED, TASK_KILLED, TASK_LOST, TASK_FAILED, TASK_ERROR, TASK_DROPPED, TASK_GONE, TASK_GONE_BY_OPERATOR, TASK_UNREACHABLE, TASK_UNKNOWN
+ }
+
+ public enum Source {
+ CLOUD_SCHEDULER, CLOUD_EXECUTOR, LITE_EXECUTOR
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/AppConfigurationException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/AppConfigurationException.java
new file mode 100755
index 0000000..1e6c661
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/AppConfigurationException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+/**
+ * Application configuration exception.
+ */
+public final class AppConfigurationException extends RuntimeException {
+
+ private static final long serialVersionUID = -1466479389299512371L;
+
+ public AppConfigurationException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+
+ public AppConfigurationException(final Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/ExceptionUtil.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/ExceptionUtil.java
new file mode 100755
index 0000000..ec6a710
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/ExceptionUtil.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Exception utility.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ExceptionUtil {
+
+ /**
+ * Transform throwable to string.
+ *
+ * @param cause cause
+ * @return string
+ */
+ public static String transform(final Throwable cause) {
+ if (null == cause) {
+ return "";
+ }
+ StringWriter result = new StringWriter();
+ try (PrintWriter writer = new PrintWriter(result)) {
+ cause.printStackTrace(writer);
+ }
+ return result.toString();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobConfigurationException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobConfigurationException.java
new file mode 100755
index 0000000..e82e205
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobConfigurationException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+/**
+ * Job configuration exception.
+ */
+public final class JobConfigurationException extends RuntimeException {
+
+ private static final long serialVersionUID = 3244988974343209468L;
+
+ public JobConfigurationException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+
+ public JobConfigurationException(final Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobExecutionEnvironmentException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobExecutionEnvironmentException.java
new file mode 100755
index 0000000..f29c232
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobExecutionEnvironmentException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+/**
+ * Job execution environment exception.
+ */
+public final class JobExecutionEnvironmentException extends Exception {
+
+ private static final long serialVersionUID = -6670738108926897433L;
+
+ public JobExecutionEnvironmentException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobStatisticException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobStatisticException.java
new file mode 100755
index 0000000..9bfcd18
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobStatisticException.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+/**
+ * Job statistic exception.
+ */
+public final class JobStatisticException extends RuntimeException {
+
+ private static final long serialVersionUID = -2502533914008085601L;
+
+ public JobStatisticException(final Exception ex) {
+ super(ex);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobSystemException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobSystemException.java
new file mode 100755
index 0000000..b52ff05
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/exception/JobSystemException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.exception;
+
+/**
+ * Job system exception.
+ */
+public final class JobSystemException extends RuntimeException {
+
+ private static final long serialVersionUID = 5018901344199973515L;
+
+ public JobSystemException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+
+ public JobSystemException(final Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/AbstractElasticJobExecutor.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/AbstractElasticJobExecutor.java
new file mode 100755
index 0000000..8e0d2a3
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/AbstractElasticJobExecutor.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+import org.apache.shardingsphere.elasticjob.cloud.exception.ExceptionUtil;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobExceptionHandler;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobRootConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobExecutionEnvironmentException;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobSystemException;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.ExecutorServiceHandler;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.ExecutorServiceHandlerRegistry;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobProperties;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * ElasticJob executor.
+ */
+@Slf4j
+public abstract class AbstractElasticJobExecutor {
+
+ @Getter(AccessLevel.PROTECTED)
+ private final JobFacade jobFacade;
+
+ @Getter(AccessLevel.PROTECTED)
+ private final JobRootConfiguration jobRootConfig;
+
+ private final String jobName;
+
+ private final ExecutorService executorService;
+
+ private final JobExceptionHandler jobExceptionHandler;
+
+ private final Map<Integer, String> itemErrorMessages;
+
+ protected AbstractElasticJobExecutor(final JobFacade jobFacade) {
+ this.jobFacade = jobFacade;
+ jobRootConfig = jobFacade.loadJobRootConfiguration(true);
+ jobName = jobRootConfig.getTypeConfig().getCoreConfig().getJobName();
+ executorService = ExecutorServiceHandlerRegistry.getExecutorServiceHandler(jobName, (ExecutorServiceHandler) getHandler(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER));
+ jobExceptionHandler = (JobExceptionHandler) getHandler(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER);
+ itemErrorMessages = new ConcurrentHashMap<>(jobRootConfig.getTypeConfig().getCoreConfig().getShardingTotalCount(), 1);
+ }
+
+ private Object getHandler(final JobProperties.JobPropertiesEnum jobPropertiesEnum) {
+ String handlerClassName = jobRootConfig.getTypeConfig().getCoreConfig().getJobProperties().get(jobPropertiesEnum);
+ try {
+ Class<?> handlerClass = Class.forName(handlerClassName);
+ if (jobPropertiesEnum.getClassType().isAssignableFrom(handlerClass)) {
+ return handlerClass.newInstance();
+ }
+ return getDefaultHandler(jobPropertiesEnum, handlerClassName);
+ } catch (final ReflectiveOperationException ex) {
+ return getDefaultHandler(jobPropertiesEnum, handlerClassName);
+ }
+ }
+
+ private Object getDefaultHandler(final JobProperties.JobPropertiesEnum jobPropertiesEnum, final String handlerClassName) {
+ log.warn("Cannot instantiation class '{}', use default '{}' class.", handlerClassName, jobPropertiesEnum.getKey());
+ try {
+ return Class.forName(jobPropertiesEnum.getDefaultValue()).newInstance();
+ } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ throw new JobSystemException(e);
+ }
+ }
+
+ /**
+ * Execute job.
+ */
+ public final void execute() {
+ try {
+ jobFacade.checkJobExecutionEnvironment();
+ } catch (final JobExecutionEnvironmentException cause) {
+ jobExceptionHandler.handleException(jobName, cause);
+ }
+ ShardingContexts shardingContexts = jobFacade.getShardingContexts();
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), JobStatusTraceEvent.State.TASK_STAGING, String.format("Job '%s' execute begin.", jobName));
+ }
+ if (jobFacade.misfireIfRunning(shardingContexts.getShardingItemParameters().keySet())) {
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), JobStatusTraceEvent.State.TASK_FINISHED, String.format(
+ "Previous job '%s' - shardingItems '%s' is still running, misfired job will start after previous job completed.", jobName,
+ shardingContexts.getShardingItemParameters().keySet()));
+ }
+ return;
+ }
+ try {
+ jobFacade.beforeJobExecuted(shardingContexts);
+ //CHECKSTYLE:OFF
+ } catch (final Throwable cause) {
+ //CHECKSTYLE:ON
+ jobExceptionHandler.handleException(jobName, cause);
+ }
+ execute(shardingContexts, JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER);
+ while (jobFacade.isExecuteMisfired(shardingContexts.getShardingItemParameters().keySet())) {
+ jobFacade.clearMisfire(shardingContexts.getShardingItemParameters().keySet());
+ execute(shardingContexts, JobExecutionEvent.ExecutionSource.MISFIRE);
+ }
+ jobFacade.failoverIfNecessary();
+ try {
+ jobFacade.afterJobExecuted(shardingContexts);
+ //CHECKSTYLE:OFF
+ } catch (final Throwable cause) {
+ //CHECKSTYLE:ON
+ jobExceptionHandler.handleException(jobName, cause);
+ }
+ }
+
+ private void execute(final ShardingContexts shardingContexts, final JobExecutionEvent.ExecutionSource executionSource) {
+ if (shardingContexts.getShardingItemParameters().isEmpty()) {
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), JobStatusTraceEvent.State.TASK_FINISHED, String.format("Sharding item for job '%s' is empty.", jobName));
+ }
+ return;
+ }
+ jobFacade.registerJobBegin(shardingContexts);
+ String taskId = shardingContexts.getTaskId();
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(taskId, JobStatusTraceEvent.State.TASK_RUNNING, "");
+ }
+ try {
+ process(shardingContexts, executionSource);
+ } finally {
+ // TODO Consider increasing the status of job failure, and how to handle the overall loop of job failure
+ jobFacade.registerJobCompleted(shardingContexts);
+ if (itemErrorMessages.isEmpty()) {
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(taskId, JobStatusTraceEvent.State.TASK_FINISHED, "");
+ }
+ } else {
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobStatusTraceEvent(taskId, JobStatusTraceEvent.State.TASK_ERROR, itemErrorMessages.toString());
+ }
+ }
+ }
+ }
+
+ private void process(final ShardingContexts shardingContexts, final JobExecutionEvent.ExecutionSource executionSource) {
+ Collection<Integer> items = shardingContexts.getShardingItemParameters().keySet();
+ if (1 == items.size()) {
+ int item = shardingContexts.getShardingItemParameters().keySet().iterator().next();
+ JobExecutionEvent jobExecutionEvent = new JobExecutionEvent(shardingContexts.getTaskId(), jobName, executionSource, item);
+ process(shardingContexts, item, jobExecutionEvent);
+ return;
+ }
+ final CountDownLatch latch = new CountDownLatch(items.size());
+ for (final int each : items) {
+ final JobExecutionEvent jobExecutionEvent = new JobExecutionEvent(shardingContexts.getTaskId(), jobName, executionSource, each);
+ if (executorService.isShutdown()) {
+ return;
+ }
+ executorService.submit(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ process(shardingContexts, each, jobExecutionEvent);
+ } finally {
+ latch.countDown();
+ }
+ }
+ });
+ }
+ try {
+ latch.await();
+ } catch (final InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private void process(final ShardingContexts shardingContexts, final int item, final JobExecutionEvent startEvent) {
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobExecutionEvent(startEvent);
+ }
+ log.trace("Job '{}' executing, item is: '{}'.", jobName, item);
+ JobExecutionEvent completeEvent;
+ try {
+ process(new ShardingContext(shardingContexts, item));
+ completeEvent = startEvent.executionSuccess();
+ log.trace("Job '{}' executed, item is: '{}'.", jobName, item);
+ if (shardingContexts.isAllowSendJobEvent()) {
+ jobFacade.postJobExecutionEvent(completeEvent);
+ }
+ // CHECKSTYLE:OFF
+ } catch (final Throwable cause) {
+ // CHECKSTYLE:ON
+ completeEvent = startEvent.executionFailure(cause);
+ jobFacade.postJobExecutionEvent(completeEvent);
+ itemErrorMessages.put(item, ExceptionUtil.transform(cause));
+ jobExceptionHandler.handleException(jobName, cause);
+ }
+ }
+
+ protected abstract void process(ShardingContext shardingContext);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobExecutorFactory.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobExecutorFactory.java
new file mode 100755
index 0000000..2ed1aa7
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobExecutorFactory.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ElasticJob;
+import org.apache.shardingsphere.elasticjob.cloud.api.dataflow.DataflowJob;
+import org.apache.shardingsphere.elasticjob.cloud.api.simple.SimpleJob;
+import org.apache.shardingsphere.elasticjob.cloud.executor.type.DataflowJobExecutor;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobConfigurationException;
+import org.apache.shardingsphere.elasticjob.cloud.executor.type.ScriptJobExecutor;
+import org.apache.shardingsphere.elasticjob.cloud.executor.type.SimpleJobExecutor;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+/**
+ * Job executor factory.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class JobExecutorFactory {
+
+ /**
+ * Get job executor.
+ *
+ * @param elasticJob elasticJob object
+ * @param jobFacade job facade
+ * @return job executor
+ */
+ @SuppressWarnings("unchecked")
+ public static AbstractElasticJobExecutor getJobExecutor(final ElasticJob elasticJob, final JobFacade jobFacade) {
+ if (null == elasticJob) {
+ return new ScriptJobExecutor(jobFacade);
+ }
+ if (elasticJob instanceof SimpleJob) {
+ return new SimpleJobExecutor((SimpleJob) elasticJob, jobFacade);
+ }
+ if (elasticJob instanceof DataflowJob) {
+ return new DataflowJobExecutor((DataflowJob) elasticJob, jobFacade);
+ }
+ throw new JobConfigurationException("Cannot support job type '%s'", elasticJob.getClass().getCanonicalName());
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobFacade.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobFacade.java
new file mode 100755
index 0000000..8f00324
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/JobFacade.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor;
+
+import org.apache.shardingsphere.elasticjob.cloud.config.JobRootConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent.State;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobExecutionEnvironmentException;
+
+import java.util.Collection;
+
+/**
+ * Job facade.
+ */
+public interface JobFacade {
+
+ /**
+ * Load job root configuration.
+ *
+ * @param fromCache load from cache or not
+ * @return job root configuration
+ */
+ JobRootConfiguration loadJobRootConfiguration(boolean fromCache);
+
+ /**
+ * check job execution environment.
+ *
+ * @throws JobExecutionEnvironmentException job execution environment exception
+ */
+ void checkJobExecutionEnvironment() throws JobExecutionEnvironmentException;
+
+ /**
+ * Failover If necessary.
+ */
+ void failoverIfNecessary();
+
+ /**
+ * Register job begin.
+ *
+ * @param shardingContexts sharding contexts
+ */
+ void registerJobBegin(ShardingContexts shardingContexts);
+
+ /**
+ * Register job completed.
+ *
+ * @param shardingContexts sharding contexts
+ */
+ void registerJobCompleted(ShardingContexts shardingContexts);
+
+ /**
+ * Get sharding contexts.
+ *
+ * @return sharding contexts
+ */
+ ShardingContexts getShardingContexts();
+
+ /**
+ * Set task misfire flag.
+ *
+ * @param shardingItems sharding items to be set misfire flag
+ * @return whether satisfy misfire condition
+ */
+ boolean misfireIfRunning(Collection<Integer> shardingItems);
+
+ /**
+ * Clear misfire flag.
+ *
+ * @param shardingItems sharding items to be cleared misfire flag
+ */
+ void clearMisfire(Collection<Integer> shardingItems);
+
+ /**
+ * Judge job whether need to execute misfire tasks.
+ *
+ * @param shardingItems sharding items
+ * @return whether need to execute misfire tasks
+ */
+ boolean isExecuteMisfired(Collection<Integer> shardingItems);
+
+ /**
+ * Judge job whether eligible running.
+ *
+ * <p>The ineligible job includes:
+ * 1. Need to shutdown;
+ * 2. Need to resharding;
+ * 3. Not stream job.
+ *
+ * @return job is eligible running or not
+ */
+ boolean isEligibleForJobRunning();
+
+ /**
+ * Judge job whether need resharding.
+ *
+ * @return whether need resharding
+ */
+ boolean isNeedSharding();
+
+ /**
+ * Call before job executed.
+ *
+ * @param shardingContexts sharding contexts
+ */
+ void beforeJobExecuted(ShardingContexts shardingContexts);
+
+ /**
+ * Call after job executed.
+ *
+ * @param shardingContexts sharding contexts
+ */
+ void afterJobExecuted(ShardingContexts shardingContexts);
+
+ /**
+ * Post job execution event.
+ *
+ * @param jobExecutionEvent job execution event
+ */
+ void postJobExecutionEvent(JobExecutionEvent jobExecutionEvent);
+
+ /**
+ * Post job status trace event.
+ *
+ * @param taskId task Id
+ * @param state job state
+ * @param message job message
+ */
+ void postJobStatusTraceEvent(String taskId, State state, String message);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/ShardingContexts.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/ShardingContexts.java
new file mode 100755
index 0000000..48be43f
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/ShardingContexts.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Sharding contexts.
+ */
+@RequiredArgsConstructor
+@Getter
+@ToString
+public final class ShardingContexts implements Serializable {
+
+ private static final long serialVersionUID = -4585977349142082152L;
+
+ /**
+ * task ID.
+ */
+ private final String taskId;
+
+ /**
+ * job name.
+ */
+ private final String jobName;
+
+ /**
+ * sharding total count.
+ */
+ private final int shardingTotalCount;
+
+ /**
+ * Job parameter.
+ * Can configure multiple identical jobs, but use different parameters as different scheduling instances
+ */
+ private final String jobParameter;
+
+ /**
+ * Sharding items and parameters map.
+ */
+ private final Map<Integer, String> shardingItemParameters;
+
+ /**
+ * Job event sampling count.
+ */
+ private int jobEventSamplingCount;
+
+ /**
+ * Current job event sampling count.
+ */
+ @Setter
+ private int currentJobEventSamplingCount;
+
+ /**
+ * Whether allow send job event.
+ */
+ @Setter
+ private boolean allowSendJobEvent = true;
+
+ public ShardingContexts(final String taskId, final String jobName, final int shardingTotalCount, final String jobParameter,
+ final Map<Integer, String> shardingItemParameters, final int jobEventSamplingCount) {
+ this.taskId = taskId;
+ this.jobName = jobName;
+ this.shardingTotalCount = shardingTotalCount;
+ this.jobParameter = jobParameter;
+ this.shardingItemParameters = shardingItemParameters;
+ this.jobEventSamplingCount = jobEventSamplingCount;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandler.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandler.java
new file mode 100755
index 0000000..0018d36
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandler.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Executor service handler.
+ */
+public interface ExecutorServiceHandler {
+
+ /**
+ * Create executor service.
+ *
+ * @param jobName job name
+ *
+ * @return executor service
+ */
+ ExecutorService createExecutorService(String jobName);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandlerRegistry.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandlerRegistry.java
new file mode 100755
index 0000000..e36dd94
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/ExecutorServiceHandlerRegistry.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Executor service handler registry.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ExecutorServiceHandlerRegistry {
+
+ private static final Map<String, ExecutorService> REGISTRY = new HashMap<>();
+
+ /**
+ * Get executor service handler.
+ *
+ * @param jobName job name
+ * @param executorServiceHandler executor service handler
+ * @return executor service
+ */
+ public static synchronized ExecutorService getExecutorServiceHandler(final String jobName, final ExecutorServiceHandler executorServiceHandler) {
+ if (!REGISTRY.containsKey(jobName)) {
+ REGISTRY.put(jobName, executorServiceHandler.createExecutorService(jobName));
+ }
+ return REGISTRY.get(jobName);
+ }
+
+ /**
+ * Remove executor service from executor service handler registry.
+ *
+ * @param jobName job name
+ */
+ public static synchronized void remove(final String jobName) {
+ REGISTRY.remove(jobName);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobExceptionHandler.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobExceptionHandler.java
new file mode 100755
index 0000000..51ede85
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobExceptionHandler.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler;
+
+/**
+ * Job exception handler.
+ */
+public interface JobExceptionHandler {
+
+ /**
+ * Handle exception.
+ *
+ * @param jobName job name
+ * @param cause cause
+ */
+ void handleException(String jobName, Throwable cause);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobProperties.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobProperties.java
new file mode 100755
index 0000000..2fbf548
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/JobProperties.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler;
+
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.impl.DefaultJobExceptionHandler;
+import org.apache.shardingsphere.elasticjob.cloud.util.json.GsonFactory;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.impl.DefaultExecutorServiceHandler;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
+
+import java.util.EnumMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Job properties.
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+public final class JobProperties {
+
+ private EnumMap<JobPropertiesEnum, String> map = new EnumMap<>(JobPropertiesEnum.class);
+
+ /**
+ * Put job property.
+ *
+ * @param key property key
+ * @param value property value
+ */
+ public void put(final String key, final String value) {
+ JobPropertiesEnum jobPropertiesEnum = JobPropertiesEnum.from(key);
+ if (null == jobPropertiesEnum || null == value) {
+ return;
+ }
+ map.put(jobPropertiesEnum, value);
+ }
+
+ /**
+ * Get job property.
+ *
+ * @param jobPropertiesEnum job properties enum
+ * @return property value
+ */
+ public String get(final JobPropertiesEnum jobPropertiesEnum) {
+ return map.containsKey(jobPropertiesEnum) ? map.get(jobPropertiesEnum) : jobPropertiesEnum.getDefaultValue();
+ }
+
+ /**
+ * Get all keys.
+ *
+ * @return all keys
+ */
+ public String json() {
+ Map<String, String> jsonMap = new LinkedHashMap<>(JobPropertiesEnum.values().length, 1);
+ for (JobPropertiesEnum each : JobPropertiesEnum.values()) {
+ jsonMap.put(each.getKey(), get(each));
+ }
+ return GsonFactory.getGson().toJson(jsonMap);
+ }
+
+ /**
+ * Job properties enum.
+ */
+ @RequiredArgsConstructor
+ @Getter
+ public enum JobPropertiesEnum {
+
+ /**
+ * Job execution handler.
+ */
+ JOB_EXCEPTION_HANDLER("job_exception_handler", JobExceptionHandler.class, DefaultJobExceptionHandler.class.getCanonicalName()),
+
+ /**
+ * Executor service handler.
+ */
+ EXECUTOR_SERVICE_HANDLER("executor_service_handler", ExecutorServiceHandler.class, DefaultExecutorServiceHandler.class.getCanonicalName());
+
+ private final String key;
+
+ private final Class<?> classType;
+
+ private final String defaultValue;
+
+ /**
+ * Get job properties enum via key.
+ *
+ * @param key property key
+ * @return job properties enum
+ */
+ public static JobPropertiesEnum from(final String key) {
+ for (JobPropertiesEnum each : JobPropertiesEnum.values()) {
+ if (each.getKey().equals(key)) {
+ return each;
+ }
+ }
+ return null;
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultExecutorServiceHandler.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultExecutorServiceHandler.java
new file mode 100755
index 0000000..e9f6eac
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultExecutorServiceHandler.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler.impl;
+
+import org.apache.shardingsphere.elasticjob.cloud.util.concurrent.ExecutorServiceObject;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.ExecutorServiceHandler;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * Default executor service handler.
+ */
+public final class DefaultExecutorServiceHandler implements ExecutorServiceHandler {
+
+ @Override
+ public ExecutorService createExecutorService(final String jobName) {
+ return new ExecutorServiceObject("inner-job-" + jobName, Runtime.getRuntime().availableProcessors() * 2).createExecutorService();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultJobExceptionHandler.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultJobExceptionHandler.java
new file mode 100755
index 0000000..6402bf7
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/handler/impl/DefaultJobExceptionHandler.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.handler.impl;
+
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobExceptionHandler;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Default job exception handler.
+ */
+@Slf4j
+public final class DefaultJobExceptionHandler implements JobExceptionHandler {
+
+ @Override
+ public void handleException(final String jobName, final Throwable cause) {
+ log.error(String.format("Job '%s' exception occur in job processing", jobName), cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/DataflowJobExecutor.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/DataflowJobExecutor.java
new file mode 100755
index 0000000..83a33d3
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/DataflowJobExecutor.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.type;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+import org.apache.shardingsphere.elasticjob.cloud.api.dataflow.DataflowJob;
+import org.apache.shardingsphere.elasticjob.cloud.config.dataflow.DataflowJobConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.executor.AbstractElasticJobExecutor;
+import org.apache.shardingsphere.elasticjob.cloud.executor.JobFacade;
+
+import java.util.List;
+
+/**
+ * Dataflow job executor.
+ */
+public final class DataflowJobExecutor extends AbstractElasticJobExecutor {
+
+ private final DataflowJob<Object> dataflowJob;
+
+ public DataflowJobExecutor(final DataflowJob<Object> dataflowJob, final JobFacade jobFacade) {
+ super(jobFacade);
+ this.dataflowJob = dataflowJob;
+ }
+
+ @Override
+ protected void process(final ShardingContext shardingContext) {
+ DataflowJobConfiguration dataflowConfig = (DataflowJobConfiguration) getJobRootConfig().getTypeConfig();
+ if (dataflowConfig.isStreamingProcess()) {
+ streamingExecute(shardingContext);
+ } else {
+ oneOffExecute(shardingContext);
+ }
+ }
+
+ private void streamingExecute(final ShardingContext shardingContext) {
+ List<Object> data = fetchData(shardingContext);
+ while (null != data && !data.isEmpty()) {
+ processData(shardingContext, data);
+ if (!getJobFacade().isEligibleForJobRunning()) {
+ break;
+ }
+ data = fetchData(shardingContext);
+ }
+ }
+
+ private void oneOffExecute(final ShardingContext shardingContext) {
+ List<Object> data = fetchData(shardingContext);
+ if (null != data && !data.isEmpty()) {
+ processData(shardingContext, data);
+ }
+ }
+
+ private List<Object> fetchData(final ShardingContext shardingContext) {
+ return dataflowJob.fetchData(shardingContext);
+ }
+
+ private void processData(final ShardingContext shardingContext, final List<Object> data) {
+ dataflowJob.processData(shardingContext, data);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/ScriptJobExecutor.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/ScriptJobExecutor.java
new file mode 100755
index 0000000..87b9a20
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/ScriptJobExecutor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.type;
+
+import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+import org.apache.shardingsphere.elasticjob.cloud.config.script.ScriptJobConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobConfigurationException;
+import org.apache.shardingsphere.elasticjob.cloud.executor.AbstractElasticJobExecutor;
+import org.apache.shardingsphere.elasticjob.cloud.executor.JobFacade;
+import org.apache.shardingsphere.elasticjob.cloud.util.json.GsonFactory;
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+
+import java.io.IOException;
+
+/**
+ * Script job executor.
+ */
+public final class ScriptJobExecutor extends AbstractElasticJobExecutor {
+
+ public ScriptJobExecutor(final JobFacade jobFacade) {
+ super(jobFacade);
+ }
+
+ @Override
+ protected void process(final ShardingContext shardingContext) {
+ final String scriptCommandLine = ((ScriptJobConfiguration) getJobRootConfig().getTypeConfig()).getScriptCommandLine();
+ if (Strings.isNullOrEmpty(scriptCommandLine)) {
+ throw new JobConfigurationException("Cannot find script command line for job '%s', job is not executed.", shardingContext.getJobName());
+ }
+ executeScript(shardingContext, scriptCommandLine);
+ }
+
+ private void executeScript(final ShardingContext shardingContext, final String scriptCommandLine) {
+ CommandLine commandLine = CommandLine.parse(scriptCommandLine);
+ commandLine.addArgument(GsonFactory.getGson().toJson(shardingContext), false);
+ try {
+ new DefaultExecutor().execute(commandLine);
+ } catch (final IOException ex) {
+ throw new JobConfigurationException("Execute script failure.", ex);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/SimpleJobExecutor.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/SimpleJobExecutor.java
new file mode 100755
index 0000000..90f5208
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/executor/type/SimpleJobExecutor.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.executor.type;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.ShardingContext;
+import org.apache.shardingsphere.elasticjob.cloud.api.simple.SimpleJob;
+import org.apache.shardingsphere.elasticjob.cloud.executor.AbstractElasticJobExecutor;
+import org.apache.shardingsphere.elasticjob.cloud.executor.JobFacade;
+
+/**
+ * Simple job executor.
+ */
+public final class SimpleJobExecutor extends AbstractElasticJobExecutor {
+
+ private final SimpleJob simpleJob;
+
+ public SimpleJobExecutor(final SimpleJob simpleJob, final JobFacade jobFacade) {
+ super(jobFacade);
+ this.simpleJob = simpleJob;
+ }
+
+ @Override
+ protected void process(final ShardingContext shardingContext) {
+ simpleJob.execute(shardingContext);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/CoordinatorRegistryCenter.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/CoordinatorRegistryCenter.java
new file mode 100755
index 0000000..8d9025a
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/CoordinatorRegistryCenter.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.base;
+
+import java.util.List;
+
+/**
+ * Coordinator registry center.
+ */
+public interface CoordinatorRegistryCenter extends RegistryCenter {
+
+ /**
+ * Get value from registry center directly.
+ *
+ * @param key key
+ * @return value
+ */
+ String getDirectly(String key);
+
+ /**
+ * Get children keys.
+ *
+ * @param key key
+ * @return children keys
+ */
+ List<String> getChildrenKeys(String key);
+
+ /**
+ * Get children number.
+ *
+ * @param key key
+ * @return children number
+ */
+ int getNumChildren(String key);
+
+ /**
+ * Persist ephemeral data.
+ *
+ * @param key key
+ * @param value value
+ */
+ void persistEphemeral(String key, String value);
+
+ /**
+ * Persist sequential data.
+ *
+ * @param key key
+ * @param value value
+ * @return value which include 10 digital
+ */
+ String persistSequential(String key, String value);
+
+ /**
+ * Persist ephemeral sequential data.
+ *
+ * @param key key
+ */
+ void persistEphemeralSequential(String key);
+
+ /**
+ * Add data to cache.
+ *
+ * @param cachePath cache path
+ */
+ void addCacheData(String cachePath);
+
+ /**
+ * Evict data from cache.
+ *
+ * @param cachePath cache path
+ */
+ void evictCacheData(String cachePath);
+
+ /**
+ * Get raw cache object of registry center.
+ *
+ * @param cachePath cache path
+ * @return raw cache object of registry center
+ */
+ Object getRawCache(String cachePath);
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/ElectionCandidate.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/ElectionCandidate.java
new file mode 100755
index 0000000..bae16b3
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/ElectionCandidate.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.base;
+
+/**
+ * Election candidate.
+ *
+ * <p>
+ * Guarantee {@link #startLeadership()} and {@link #stopLeadership()} method run in same thread.
+ * </p>
+ */
+public interface ElectionCandidate {
+
+ /**
+ * Start leadership.
+ *
+ * @throws Exception exception
+ */
+ void startLeadership() throws Exception;
+
+ /**
+ * Stop leadership.
+ *
+ * <p>Should not throw any exception for the implementation class.</p>
+ */
+ void stopLeadership();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/RegistryCenter.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/RegistryCenter.java
new file mode 100755
index 0000000..1f95c8b
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/base/RegistryCenter.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.base;
+
+/**
+ * Registry center.
+ */
+public interface RegistryCenter {
+
+ /**
+ * Initialize registry center.
+ */
+ void init();
+
+ /**
+ * Close registry center.
+ */
+ void close();
+
+ /**
+ * Get value.
+ *
+ * @param key key
+ * @return value
+ */
+ String get(String key);
+
+ /**
+ * Judge node is exist or not.
+ *
+ * @param key key
+ * @return node is exist or not
+ */
+ boolean isExisted(String key);
+
+ /**
+ * Persist data.
+ *
+ * @param key key
+ * @param value value
+ */
+ void persist(String key, String value);
+
+ /**
+ * Update data.
+ *
+ * @param key key
+ * @param value value
+ */
+ void update(String key, String value);
+
+ /**
+ * Remove data.
+ *
+ * @param key key
+ */
+ void remove(String key);
+
+ /**
+ * Get current time from registry center.
+ *
+ * @param key key
+ * @return current time from registry center
+ */
+ long getRegistryCenterTime(String key);
+
+ /**
+ * Get raw client for registry center client.
+ **
+ * @return registry center raw client
+ */
+ Object getRawClient();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegException.java
new file mode 100755
index 0000000..381a87e
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.exception;
+
+/**
+ * Registry center exception.
+ */
+public final class RegException extends RuntimeException {
+
+ private static final long serialVersionUID = -6417179023552012152L;
+
+ public RegException(final String errorMessage, final Object... args) {
+ super(String.format(errorMessage, args));
+ }
+
+ public RegException(final Exception cause) {
+ super(cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegExceptionHandler.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegExceptionHandler.java
new file mode 100755
index 0000000..63ad3f6
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/exception/RegExceptionHandler.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.exception;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.zookeeper.KeeperException.ConnectionLossException;
+import org.apache.zookeeper.KeeperException.NoNodeException;
+import org.apache.zookeeper.KeeperException.NodeExistsException;
+
+/**
+ * Registry center exception handler.
+ */
+@Slf4j
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class RegExceptionHandler {
+
+ /**
+ * Handle exception.
+ *
+ * @param cause exception to be handled
+ */
+ public static void handleException(final Exception cause) {
+ if (null == cause) {
+ return;
+ }
+ if (isIgnoredException(cause) || null != cause.getCause() && isIgnoredException(cause.getCause())) {
+ log.debug("Elastic job: ignored exception for: {}", cause.getMessage());
+ } else if (cause instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ } else {
+ throw new RegException(cause);
+ }
+ }
+
+ private static boolean isIgnoredException(final Throwable cause) {
+ return cause instanceof ConnectionLossException || cause instanceof NoNodeException || cause instanceof NodeExistsException;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperConfiguration.java
new file mode 100755
index 0000000..73b69a2
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperConfiguration.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.zookeeper;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+
+/**
+ * Zookeeper configuration.
+ */
+@Getter
+@Setter
+@RequiredArgsConstructor
+public final class ZookeeperConfiguration {
+
+ /**
+ * Server list of ZooKeeper.
+ *
+ * <p>
+ * Include IP addresses and ports,
+ * Multiple IP address split by comma.
+ * For example: host1:2181,host2:2181
+ * </p>
+ */
+ private final String serverLists;
+
+ /**
+ * Namespace.
+ */
+ private final String namespace;
+
+ /**
+ * Base sleep time milliseconds.
+ */
+ private int baseSleepTimeMilliseconds = 1000;
+
+ /**
+ * Max sleep time milliseconds.
+ */
+ private int maxSleepTimeMilliseconds = 3000;
+
+ /**
+ * Max retry times.
+ */
+ private int maxRetries = 3;
+
+ /**
+ * Session timeout milliseconds.
+ */
+ private int sessionTimeoutMilliseconds;
+
+ /**
+ * Connection timeout milliseconds.
+ */
+ private int connectionTimeoutMilliseconds;
+
+ /**
+ * Zookeeper digest.
+ */
+ private String digest;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperElectionService.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperElectionService.java
new file mode 100755
index 0000000..6935713
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperElectionService.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.zookeeper;
+
+import org.apache.shardingsphere.elasticjob.cloud.reg.base.ElectionCandidate;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobSystemException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.recipes.leader.LeaderSelector;
+import org.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Use {@link LeaderSelector} to implement election service.
+ */
+@Slf4j
+public final class ZookeeperElectionService {
+
+ private final CountDownLatch leaderLatch = new CountDownLatch(1);
+
+ private final LeaderSelector leaderSelector;
+
+ public ZookeeperElectionService(final String identity, final CuratorFramework client, final String electionPath, final ElectionCandidate electionCandidate) {
+ leaderSelector = new LeaderSelector(client, electionPath, new LeaderSelectorListenerAdapter() {
+
+ @Override
+ public void takeLeadership(final CuratorFramework client) throws Exception {
+ log.info("Elastic job: {} has leadership", identity);
+ try {
+ electionCandidate.startLeadership();
+ leaderLatch.await();
+ log.warn("Elastic job: {} lost leadership.", identity);
+ electionCandidate.stopLeadership();
+ } catch (final JobSystemException exception) {
+ log.error("Elastic job: Starting error", exception);
+ System.exit(1);
+ }
+ }
+ });
+ leaderSelector.autoRequeue();
+ leaderSelector.setId(identity);
+ }
+
+ /**
+ * Start election.
+ */
+ public void start() {
+ log.debug("Elastic job: {} start to elect leadership", leaderSelector.getId());
+ leaderSelector.start();
+ }
+
+ /**
+ * Stop election.
+ */
+ public void stop() {
+ log.info("Elastic job: stop leadership election");
+ leaderLatch.countDown();
+ try {
+ leaderSelector.close();
+ // CHECKSTYLE:OFF
+ } catch (final Exception ignored) {
+ }
+ // CHECKSTYLE:ON
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperRegistryCenter.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperRegistryCenter.java
new file mode 100755
index 0000000..2a3caaf
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/reg/zookeeper/ZookeeperRegistryCenter.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.reg.zookeeper;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.cloud.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.cloud.reg.exception.RegExceptionHandler;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.framework.api.ACLProvider;
+import org.apache.curator.framework.recipes.cache.ChildData;
+import org.apache.curator.framework.recipes.cache.TreeCache;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.apache.curator.utils.CloseableUtils;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Registry center of ZooKeeper.
+ */
+@Slf4j
+public final class ZookeeperRegistryCenter implements CoordinatorRegistryCenter {
+
+ @Getter(AccessLevel.PROTECTED)
+ private ZookeeperConfiguration zkConfig;
+
+ private final Map<String, TreeCache> caches = new HashMap<>();
+
+ @Getter
+ private CuratorFramework client;
+
+ public ZookeeperRegistryCenter(final ZookeeperConfiguration zkConfig) {
+ this.zkConfig = zkConfig;
+ }
+
+ @Override
+ public void init() {
+ log.debug("Elastic job: zookeeper registry center init, server lists is: {}.", zkConfig.getServerLists());
+ CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
+ .connectString(zkConfig.getServerLists())
+ .retryPolicy(new ExponentialBackoffRetry(zkConfig.getBaseSleepTimeMilliseconds(), zkConfig.getMaxRetries(), zkConfig.getMaxSleepTimeMilliseconds()))
+ .namespace(zkConfig.getNamespace());
+ if (0 != zkConfig.getSessionTimeoutMilliseconds()) {
+ builder.sessionTimeoutMs(zkConfig.getSessionTimeoutMilliseconds());
+ }
+ if (0 != zkConfig.getConnectionTimeoutMilliseconds()) {
+ builder.connectionTimeoutMs(zkConfig.getConnectionTimeoutMilliseconds());
+ }
+ if (!Strings.isNullOrEmpty(zkConfig.getDigest())) {
+ builder.authorization("digest", zkConfig.getDigest().getBytes(Charsets.UTF_8))
+ .aclProvider(new ACLProvider() {
+
+ @Override
+ public List<ACL> getDefaultAcl() {
+ return ZooDefs.Ids.CREATOR_ALL_ACL;
+ }
+
+ @Override
+ public List<ACL> getAclForPath(final String path) {
+ return ZooDefs.Ids.CREATOR_ALL_ACL;
+ }
+ });
+ }
+ client = builder.build();
+ client.start();
+ try {
+ if (!client.blockUntilConnected(zkConfig.getMaxSleepTimeMilliseconds() * zkConfig.getMaxRetries(), TimeUnit.MILLISECONDS)) {
+ client.close();
+ throw new KeeperException.OperationTimeoutException();
+ }
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public void close() {
+ for (Entry<String, TreeCache> each : caches.entrySet()) {
+ each.getValue().close();
+ }
+ waitForCacheClose();
+ CloseableUtils.closeQuietly(client);
+ }
+
+ /*
+ * TODO
+ * sleep 500ms, let cache client close first and then client, otherwise will throw exception
+ * reference:https://issues.apache.org/jira/browse/CURATOR-157
+ */
+ private void waitForCacheClose() {
+ try {
+ Thread.sleep(500L);
+ } catch (final InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Override
+ public String get(final String key) {
+ TreeCache cache = findTreeCache(key);
+ if (null == cache) {
+ return getDirectly(key);
+ }
+ ChildData resultInCache = cache.getCurrentData(key);
+ if (null != resultInCache) {
+ return null == resultInCache.getData() ? null : new String(resultInCache.getData(), Charsets.UTF_8);
+ }
+ return getDirectly(key);
+ }
+
+ private TreeCache findTreeCache(final String key) {
+ for (Entry<String, TreeCache> entry : caches.entrySet()) {
+ if (key.startsWith(entry.getKey())) {
+ return entry.getValue();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getDirectly(final String key) {
+ try {
+ return new String(client.getData().forPath(key), Charsets.UTF_8);
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ return null;
+ }
+ }
+
+ @Override
+ public List<String> getChildrenKeys(final String key) {
+ try {
+ List<String> result = client.getChildren().forPath(key);
+ Collections.sort(result, new Comparator<String>() {
+
+ @Override
+ public int compare(final String o1, final String o2) {
+ return o2.compareTo(o1);
+ }
+ });
+ return result;
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ public int getNumChildren(final String key) {
+ try {
+ Stat stat = client.checkExists().forPath(key);
+ if (null != stat) {
+ return stat.getNumChildren();
+ }
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ return 0;
+ }
+
+ @Override
+ public boolean isExisted(final String key) {
+ try {
+ return null != client.checkExists().forPath(key);
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ return false;
+ }
+ }
+
+ @Override
+ public void persist(final String key, final String value) {
+ try {
+ if (!isExisted(key)) {
+ client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(key, value.getBytes(Charsets.UTF_8));
+ } else {
+ update(key, value);
+ }
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public void update(final String key, final String value) {
+ try {
+ client.inTransaction().check().forPath(key).and().setData().forPath(key, value.getBytes(Charsets.UTF_8)).and().commit();
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public void persistEphemeral(final String key, final String value) {
+ try {
+ if (isExisted(key)) {
+ client.delete().deletingChildrenIfNeeded().forPath(key);
+ }
+ client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(key, value.getBytes(Charsets.UTF_8));
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public String persistSequential(final String key, final String value) {
+ try {
+ return client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(key, value.getBytes(Charsets.UTF_8));
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ return null;
+ }
+
+ @Override
+ public void persistEphemeralSequential(final String key) {
+ try {
+ client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(key);
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public void remove(final String key) {
+ try {
+ client.delete().deletingChildrenIfNeeded().forPath(key);
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ }
+
+ @Override
+ public long getRegistryCenterTime(final String key) {
+ long result = 0L;
+ try {
+ persist(key, "");
+ result = client.checkExists().forPath(key).getMtime();
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ Preconditions.checkState(0L != result, "Cannot get registry center time.");
+ return result;
+ }
+
+ @Override
+ public Object getRawClient() {
+ return client;
+ }
+
+ @Override
+ public void addCacheData(final String cachePath) {
+ TreeCache cache = new TreeCache(client, cachePath);
+ try {
+ cache.start();
+ //CHECKSTYLE:OFF
+ } catch (final Exception ex) {
+ //CHECKSTYLE:ON
+ RegExceptionHandler.handleException(ex);
+ }
+ caches.put(cachePath + "/", cache);
+ }
+
+ @Override
+ public void evictCacheData(final String cachePath) {
+ TreeCache cache = caches.remove(cachePath + "/");
+ if (null != cache) {
+ cache.close();
+ }
+ }
+
+ @Override
+ public Object getRawCache(final String cachePath) {
+ return caches.get(cachePath + "/");
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/StatisticInterval.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/StatisticInterval.java
new file mode 100755
index 0000000..fc9f7e3
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/StatisticInterval.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Task running statistics.
+ */
+@Getter
+@RequiredArgsConstructor
+public enum StatisticInterval {
+
+ MINUTE("0 * * * * ?"),
+
+ HOUR("0 0 * * * ?"),
+
+ DAY("0 0 0 * * ?");
+
+ private final String cron;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/rdb/StatisticRdbRepository.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/rdb/StatisticRdbRepository.java
new file mode 100755
index 0000000..46833a1
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/rdb/StatisticRdbRepository.java
@@ -0,0 +1,495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.rdb;
+
+import com.google.common.base.Optional;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.StatisticInterval;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.job.JobRegisterStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.job.JobRunningStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.task.TaskResultStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.task.TaskRunningStatistics;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Statistic RDB repository.
+ */
+@Slf4j
+public class StatisticRdbRepository {
+
+ private static final String TABLE_TASK_RESULT_STATISTICS = "TASK_RESULT_STATISTICS";
+
+ private static final String TABLE_TASK_RUNNING_STATISTICS = "TASK_RUNNING_STATISTICS";
+
+ private static final String TABLE_JOB_RUNNING_STATISTICS = "JOB_RUNNING_STATISTICS";
+
+ private static final String TABLE_JOB_REGISTER_STATISTICS = "JOB_REGISTER_STATISTICS";
+
+ private final DataSource dataSource;
+
+ public StatisticRdbRepository(final DataSource dataSource) throws SQLException {
+ this.dataSource = dataSource;
+ initTables();
+ }
+
+ private void initTables() throws SQLException {
+ try (Connection conn = dataSource.getConnection()) {
+ createTaskResultTableIfNeeded(conn);
+ createTaskRunningTableIfNeeded(conn);
+ createJobRunningTableIfNeeded(conn);
+ createJobRegisterTableIfNeeded(conn);
+ }
+ }
+
+ private void createTaskResultTableIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ for (StatisticInterval each : StatisticInterval.values()) {
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_TASK_RESULT_STATISTICS + "_" + each, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createTaskResultTable(conn, each);
+ }
+ }
+ }
+ }
+
+ private void createTaskResultTable(final Connection conn, final StatisticInterval statisticInterval) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_TASK_RESULT_STATISTICS + "_" + statisticInterval + "` ("
+ + "`id` BIGINT NOT NULL AUTO_INCREMENT, "
+ + "`success_count` INT(11),"
+ + "`failed_count` INT(11),"
+ + "`statistics_time` TIMESTAMP NOT NULL,"
+ + "`creation_time` TIMESTAMP NOT NULL,"
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ private void createTaskRunningTableIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_TASK_RUNNING_STATISTICS, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createTaskRunningTable(conn);
+ }
+ }
+ }
+
+ private void createTaskRunningTable(final Connection conn) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_TASK_RUNNING_STATISTICS + "` ("
+ + "`id` BIGINT NOT NULL AUTO_INCREMENT, "
+ + "`running_count` INT(11),"
+ + "`statistics_time` TIMESTAMP NOT NULL,"
+ + "`creation_time` TIMESTAMP NOT NULL,"
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ private void createJobRunningTableIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_JOB_RUNNING_STATISTICS, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createJobRunningTable(conn);
+ }
+ }
+ }
+
+ private void createJobRunningTable(final Connection conn) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_JOB_RUNNING_STATISTICS + "` ("
+ + "`id` BIGINT NOT NULL AUTO_INCREMENT, "
+ + "`running_count` INT(11),"
+ + "`statistics_time` TIMESTAMP NOT NULL,"
+ + "`creation_time` TIMESTAMP NOT NULL,"
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ private void createJobRegisterTableIfNeeded(final Connection conn) throws SQLException {
+ DatabaseMetaData dbMetaData = conn.getMetaData();
+ try (ResultSet resultSet = dbMetaData.getTables(null, null, TABLE_JOB_REGISTER_STATISTICS, new String[]{"TABLE"})) {
+ if (!resultSet.next()) {
+ createJobRegisterTable(conn);
+ }
+ }
+ }
+
+ private void createJobRegisterTable(final Connection conn) throws SQLException {
+ String dbSchema = "CREATE TABLE `" + TABLE_JOB_REGISTER_STATISTICS + "` ("
+ + "`id` BIGINT NOT NULL AUTO_INCREMENT, "
+ + "`registered_count` INT(11),"
+ + "`statistics_time` TIMESTAMP NOT NULL,"
+ + "`creation_time` TIMESTAMP NOT NULL,"
+ + "PRIMARY KEY (`id`));";
+ try (PreparedStatement preparedStatement = conn.prepareStatement(dbSchema)) {
+ preparedStatement.execute();
+ }
+ }
+
+ /**
+ * Add task result statistics.
+ *
+ * @param taskResultStatistics task result statistics
+ * @return add success or not
+ */
+ public boolean add(final TaskResultStatistics taskResultStatistics) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_TASK_RESULT_STATISTICS + "_" + taskResultStatistics.getStatisticInterval()
+ + "` (`success_count`, `failed_count`, `statistics_time`, `creation_time`) VALUES (?, ?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setInt(1, taskResultStatistics.getSuccessCount());
+ preparedStatement.setInt(2, taskResultStatistics.getFailedCount());
+ preparedStatement.setTimestamp(3, new Timestamp(taskResultStatistics.getStatisticsTime().getTime()));
+ preparedStatement.setTimestamp(4, new Timestamp(taskResultStatistics.getCreationTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Insert taskResultStatistics to DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Add task running statistics.
+ *
+ * @param taskRunningStatistics task running statistics
+ * @return add success or not
+ */
+ public boolean add(final TaskRunningStatistics taskRunningStatistics) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_TASK_RUNNING_STATISTICS + "` (`running_count`, `statistics_time`, `creation_time`) VALUES (?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setInt(1, taskRunningStatistics.getRunningCount());
+ preparedStatement.setTimestamp(2, new Timestamp(taskRunningStatistics.getStatisticsTime().getTime()));
+ preparedStatement.setTimestamp(3, new Timestamp(taskRunningStatistics.getCreationTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Insert taskRunningStatistics to DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Add job running statistics.
+ *
+ * @param jobRunningStatistics job running statistics
+ * @return add success or not
+ */
+ public boolean add(final JobRunningStatistics jobRunningStatistics) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_RUNNING_STATISTICS + "` (`running_count`, `statistics_time`, `creation_time`) VALUES (?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setInt(1, jobRunningStatistics.getRunningCount());
+ preparedStatement.setTimestamp(2, new Timestamp(jobRunningStatistics.getStatisticsTime().getTime()));
+ preparedStatement.setTimestamp(3, new Timestamp(jobRunningStatistics.getCreationTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Insert jobRunningStatistics to DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Add job register statistics.
+ *
+ * @param jobRegisterStatistics job register statistics
+ * @return add success or not
+ */
+ public boolean add(final JobRegisterStatistics jobRegisterStatistics) {
+ boolean result = false;
+ String sql = "INSERT INTO `" + TABLE_JOB_REGISTER_STATISTICS + "` (`registered_count`, `statistics_time`, `creation_time`) VALUES (?, ?, ?);";
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
+ preparedStatement.setInt(1, jobRegisterStatistics.getRegisteredCount());
+ preparedStatement.setTimestamp(2, new Timestamp(jobRegisterStatistics.getStatisticsTime().getTime()));
+ preparedStatement.setTimestamp(3, new Timestamp(jobRegisterStatistics.getCreationTime().getTime()));
+ preparedStatement.execute();
+ result = true;
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Insert jobRegisterStatistics to DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Find task result statistics.
+ *
+ * @param from from date to statistics
+ * @param statisticInterval statistic interval
+ * @return task result statistics
+ */
+ public List<TaskResultStatistics> findTaskResultStatistics(final Date from, final StatisticInterval statisticInterval) {
+ List<TaskResultStatistics> result = new LinkedList<>();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sql = String.format("SELECT id, success_count, failed_count, statistics_time, creation_time FROM %s WHERE statistics_time >= '%s' order by id ASC",
+ TABLE_TASK_RESULT_STATISTICS + "_" + statisticInterval, formatter.format(from));
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ TaskResultStatistics taskResultStatistics = new TaskResultStatistics(resultSet.getLong(1), resultSet.getInt(2), resultSet.getInt(3),
+ statisticInterval, new Date(resultSet.getTimestamp(4).getTime()), new Date(resultSet.getTimestamp(5).getTime()));
+ result.add(taskResultStatistics);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch taskResultStatistics from DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Get summed task result statistics.
+ *
+ * @param from from date to statistics
+ * @param statisticInterval statistic interval
+ * @return summed task result statistics
+ */
+ public TaskResultStatistics getSummedTaskResultStatistics(final Date from, final StatisticInterval statisticInterval) {
+ TaskResultStatistics result = new TaskResultStatistics(0, 0, statisticInterval, new Date());
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sql = String.format("SELECT sum(success_count), sum(failed_count) FROM %s WHERE statistics_time >= '%s'",
+ TABLE_TASK_RESULT_STATISTICS + "_" + statisticInterval, formatter.format(from));
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ result = new TaskResultStatistics(resultSet.getInt(1), resultSet.getInt(2), statisticInterval, new Date());
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch summed taskResultStatistics from DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Find latest task result statistics.
+ *
+ * @param statisticInterval statistic interval
+ * @return task result statistics
+ */
+ public Optional<TaskResultStatistics> findLatestTaskResultStatistics(final StatisticInterval statisticInterval) {
+ TaskResultStatistics result = null;
+ String sql = String.format("SELECT id, success_count, failed_count, statistics_time, creation_time FROM %s order by id DESC LIMIT 1",
+ TABLE_TASK_RESULT_STATISTICS + "_" + statisticInterval);
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ result = new TaskResultStatistics(resultSet.getLong(1), resultSet.getInt(2), resultSet.getInt(3),
+ statisticInterval, new Date(resultSet.getTimestamp(4).getTime()), new Date(resultSet.getTimestamp(5).getTime()));
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch latest taskResultStatistics from DB error:", ex);
+ }
+ return Optional.fromNullable(result);
+ }
+
+ /**
+ * Find task running statistics.
+ *
+ * @param from from date to statistics
+ * @return Task running statistics
+ */
+ public List<TaskRunningStatistics> findTaskRunningStatistics(final Date from) {
+ List<TaskRunningStatistics> result = new LinkedList<>();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sql = String.format("SELECT id, running_count, statistics_time, creation_time FROM %s WHERE statistics_time >= '%s' order by id ASC",
+ TABLE_TASK_RUNNING_STATISTICS, formatter.format(from));
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ TaskRunningStatistics taskRunningStatistics = new TaskRunningStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ result.add(taskRunningStatistics);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch taskRunningStatistics from DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Find job running statistics.
+ *
+ * @param from from date to statistics
+ * @return job running statistics
+ */
+ public List<JobRunningStatistics> findJobRunningStatistics(final Date from) {
+ List<JobRunningStatistics> result = new LinkedList<>();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sql = String.format("SELECT id, running_count, statistics_time, creation_time FROM %s WHERE statistics_time >= '%s' order by id ASC",
+ TABLE_JOB_RUNNING_STATISTICS, formatter.format(from));
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ JobRunningStatistics jobRunningStatistics = new JobRunningStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ result.add(jobRunningStatistics);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch jobRunningStatistics from DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Find latest task running statistics.
+ *
+ * @return latest task running statistics
+ */
+ public Optional<TaskRunningStatistics> findLatestTaskRunningStatistics() {
+ TaskRunningStatistics result = null;
+ String sql = String.format("SELECT id, running_count, statistics_time, creation_time FROM %s order by id DESC LIMIT 1",
+ TABLE_TASK_RUNNING_STATISTICS);
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ result = new TaskRunningStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch latest taskRunningStatistics from DB error:", ex);
+ }
+ return Optional.fromNullable(result);
+ }
+
+ /**
+ * Find latest job running statistics.
+ *
+ * @return job running statistics
+ */
+ public Optional<JobRunningStatistics> findLatestJobRunningStatistics() {
+ JobRunningStatistics result = null;
+ String sql = String.format("SELECT id, running_count, statistics_time, creation_time FROM %s order by id DESC LIMIT 1",
+ TABLE_JOB_RUNNING_STATISTICS);
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ result = new JobRunningStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch latest jobRunningStatistics from DB error:", ex);
+ }
+ return Optional.fromNullable(result);
+ }
+
+ /**
+ * Find job register statistics.
+ *
+ * @param from from date to statistics
+ * @return job register statistics
+ */
+ public List<JobRegisterStatistics> findJobRegisterStatistics(final Date from) {
+ List<JobRegisterStatistics> result = new LinkedList<>();
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ String sql = String.format("SELECT id, registered_count, statistics_time, creation_time FROM %s WHERE statistics_time >= '%s' order by id ASC",
+ TABLE_JOB_REGISTER_STATISTICS, formatter.format(from));
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ JobRegisterStatistics jobRegisterStatistics = new JobRegisterStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ result.add(jobRegisterStatistics);
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch jobRegisterStatistics from DB error:", ex);
+ }
+ return result;
+ }
+
+ /**
+ * Find latest job register statistics.
+ *
+ * @return job register statistics
+ */
+ public Optional<JobRegisterStatistics> findLatestJobRegisterStatistics() {
+ JobRegisterStatistics result = null;
+ String sql = String.format("SELECT id, registered_count, statistics_time, creation_time FROM %s order by id DESC LIMIT 1",
+ TABLE_JOB_REGISTER_STATISTICS);
+ try (
+ Connection conn = dataSource.getConnection();
+ PreparedStatement preparedStatement = conn.prepareStatement(sql);
+ ResultSet resultSet = preparedStatement.executeQuery()
+ ) {
+ while (resultSet.next()) {
+ result = new JobRegisterStatistics(resultSet.getLong(1), resultSet.getInt(2),
+ new Date(resultSet.getTimestamp(3).getTime()), new Date(resultSet.getTimestamp(4).getTime()));
+ }
+ } catch (final SQLException ex) {
+ // TODO log failure directly to output log, consider to be configurable in the future
+ log.error("Fetch latest jobRegisterStatistics from DB error:", ex);
+ }
+ return Optional.fromNullable(result);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobExecutionTypeStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobExecutionTypeStatistics.java
new file mode 100755
index 0000000..706fe32
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobExecutionTypeStatistics.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.job;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Job execution type statistics.
+ */
+@Getter
+@AllArgsConstructor
+public final class JobExecutionTypeStatistics {
+
+ private int transientJobCount;
+
+ private int daemonJobCount;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRegisterStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRegisterStatistics.java
new file mode 100755
index 0000000..bf62a2a
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRegisterStatistics.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.job;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * Job register statistics.
+ */
+@Getter
+@RequiredArgsConstructor
+@AllArgsConstructor
+public final class JobRegisterStatistics {
+
+ private long id;
+
+ private final int registeredCount;
+
+ private final Date statisticsTime;
+
+ private Date creationTime = new Date();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRunningStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRunningStatistics.java
new file mode 100755
index 0000000..dc74a66
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobRunningStatistics.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.job;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * Job running statistics.
+ */
+@Getter
+@RequiredArgsConstructor
+@AllArgsConstructor
+public final class JobRunningStatistics {
+
+ private long id;
+
+ private final int runningCount;
+
+ private final Date statisticsTime;
+
+ private Date creationTime = new Date();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobTypeStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobTypeStatistics.java
new file mode 100755
index 0000000..679c0e0
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/job/JobTypeStatistics.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.job;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Job type statistics.
+ */
+@Getter
+@AllArgsConstructor
+public final class JobTypeStatistics {
+
+ private int scriptJobCount;
+
+ private int simpleJobCount;
+
+ private int dataflowJobCount;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskResultStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskResultStatistics.java
new file mode 100755
index 0000000..fb3045e
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskResultStatistics.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.task;
+
+import org.apache.shardingsphere.elasticjob.cloud.statistics.StatisticInterval;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * Task result statistics.
+ */
+@Getter
+@AllArgsConstructor
+@RequiredArgsConstructor
+public final class TaskResultStatistics {
+
+ private long id;
+
+ private final int successCount;
+
+ private final int failedCount;
+
+ private final StatisticInterval statisticInterval;
+
+ private final Date statisticsTime;
+
+ private Date creationTime = new Date();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskRunningStatistics.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskRunningStatistics.java
new file mode 100755
index 0000000..b90af6c
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/statistics/type/task/TaskRunningStatistics.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.statistics.type.task;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * Task running statistics.
+ */
+@Getter
+@RequiredArgsConstructor
+@AllArgsConstructor
+public final class TaskRunningStatistics {
+
+ private long id;
+
+ private final int runningCount;
+
+ private final Date statisticsTime;
+
+ private Date creationTime = new Date();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/BlockUtils.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/BlockUtils.java
new file mode 100755
index 0000000..556a26a
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/BlockUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.concurrent;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class BlockUtils {
+
+ /**
+ * Wait for short time.
+ */
+ public static void waitingShortTime() {
+ sleep(100L);
+ }
+
+ /**
+ * Sleep for millis.
+ * @param millis the time for sleep
+ */
+ public static void sleep(final long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (final InterruptedException ex) {
+ Thread.currentThread().interrupt();
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/ExecutorServiceObject.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/ExecutorServiceObject.java
new file mode 100755
index 0000000..c40980b
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/concurrent/ExecutorServiceObject.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.concurrent;
+
+import com.google.common.base.Joiner;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Executor service object.
+ */
+public final class ExecutorServiceObject {
+
+ private final ThreadPoolExecutor threadPoolExecutor;
+
+ private final BlockingQueue<Runnable> workQueue;
+
+ public ExecutorServiceObject(final String namingPattern, final int threadSize) {
+ workQueue = new LinkedBlockingQueue<>();
+ threadPoolExecutor = new ThreadPoolExecutor(threadSize, threadSize, 5L, TimeUnit.MINUTES, workQueue,
+ new BasicThreadFactory.Builder().namingPattern(Joiner.on("-").join(namingPattern, "%s")).build());
+ threadPoolExecutor.allowCoreThreadTimeOut(true);
+ }
+
+ /**
+ * Create executor service.
+ *
+ * @return executor service
+ */
+ public ExecutorService createExecutorService() {
+ return MoreExecutors.listeningDecorator(MoreExecutors.getExitingExecutorService(threadPoolExecutor));
+ }
+
+ /**
+ * Whether the threadPoolExecutor has been shut down.
+ *
+ * @return Whether the threadPoolExecutor has been shut down
+ */
+ public boolean isShutdown() {
+ return threadPoolExecutor.isShutdown();
+ }
+
+ /**
+ * Get active thread count.
+ *
+ * @return active thread count
+ */
+ public int getActiveThreadCount() {
+ return threadPoolExecutor.getActiveCount();
+ }
+
+ /**
+ * Get work queue size.
+ *
+ * @return work queue size
+ */
+ public int getWorkQueueSize() {
+ return workQueue.size();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItemParameters.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItemParameters.java
new file mode 100755
index 0000000..93caf15
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItemParameters.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.config;
+
+import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobConfigurationException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Sharding item parameters.
+ */
+@Getter
+public final class ShardingItemParameters {
+
+ private static final String PARAMETER_DELIMITER = ",";
+
+ private static final String KEY_VALUE_DELIMITER = "=";
+
+ private final Map<Integer, String> map;
+
+ public ShardingItemParameters(final String shardingItemParameters) {
+ map = toMap(shardingItemParameters);
+ }
+
+ private Map<Integer, String> toMap(final String originalShardingItemParameters) {
+ if (Strings.isNullOrEmpty(originalShardingItemParameters)) {
+ return Collections.emptyMap();
+ }
+ String[] shardingItemParameters = originalShardingItemParameters.split(PARAMETER_DELIMITER);
+ Map<Integer, String> result = new HashMap<>(shardingItemParameters.length);
+ for (String each : shardingItemParameters) {
+ ShardingItem shardingItem = parse(each, originalShardingItemParameters);
+ result.put(shardingItem.item, shardingItem.parameter);
+ }
+ return result;
+ }
+
+ private ShardingItem parse(final String shardingItemParameter, final String originalShardingItemParameters) {
+ String[] pair = shardingItemParameter.trim().split(KEY_VALUE_DELIMITER);
+ if (2 != pair.length) {
+ throw new JobConfigurationException("Sharding item parameters '%s' format error, should be int=xx,int=xx", originalShardingItemParameters);
+ }
+ try {
+ return new ShardingItem(Integer.parseInt(pair[0].trim()), pair[1].trim());
+ } catch (final NumberFormatException ex) {
+ throw new JobConfigurationException("Sharding item parameters key '%s' is not an integer.", pair[0]);
+ }
+ }
+
+ /**
+ * Sharding item.
+ */
+ @AllArgsConstructor
+ private static final class ShardingItem {
+
+ private final int item;
+
+ private final String parameter;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItems.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItems.java
new file mode 100755
index 0000000..0709968
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/config/ShardingItems.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.config;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import lombok.Getter;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Sharding items.
+ */
+@Getter
+public final class ShardingItems {
+
+ private static final String DELIMITER = ",";
+
+ /**
+ * Get sharding items via string.
+ *
+ * @param itemsString sharding items string
+ * @return sharding items
+ */
+ public static List<Integer> toItemList(final String itemsString) {
+ if (Strings.isNullOrEmpty(itemsString)) {
+ return Collections.emptyList();
+ }
+ String[] items = itemsString.split(DELIMITER);
+ List<Integer> result = new ArrayList<>(items.length);
+ for (String each : items) {
+ int item = Integer.parseInt(each);
+ if (!result.contains(item)) {
+ result.add(item);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get sharding items string.
+ *
+ * @param items sharding items
+ * @return sharding items string
+ */
+ public static String toItemsString(final List<Integer> items) {
+ return items.isEmpty() ? "" : Joiner.on(DELIMITER).join(items);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/digest/Encryption.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/digest/Encryption.java
new file mode 100755
index 0000000..17fb18b
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/digest/Encryption.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.digest;
+
+import org.apache.shardingsphere.elasticjob.cloud.exception.JobSystemException;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Encryption.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class Encryption {
+
+ private static final String MD5 = "MD5";
+
+ /**
+ * Use md5 to encrypt string.
+ *
+ * @param str string to be encrypted
+ * @return encrypted string
+ */
+ public static String md5(final String str) {
+ try {
+ MessageDigest messageDigest = MessageDigest.getInstance(MD5);
+ messageDigest.update(str.getBytes());
+ return new BigInteger(1, messageDigest.digest()).toString(16);
+ } catch (final NoSuchAlgorithmException ex) {
+ throw new JobSystemException(ex);
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/HostException.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/HostException.java
new file mode 100755
index 0000000..d786762
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/HostException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.env;
+
+import java.io.IOException;
+
+/**
+ * Host exception.
+ */
+public final class HostException extends RuntimeException {
+
+ private static final long serialVersionUID = 3589264847881174997L;
+
+ public HostException(final IOException cause) {
+ super(cause);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/IpUtils.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/IpUtils.java
new file mode 100755
index 0000000..6e2d1ae
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/IpUtils.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.env;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+
+/**
+ * IP address utility.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class IpUtils {
+
+ public static final String IP_REGEX = "((\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})";
+
+ private static volatile String cachedIpAddress;
+
+ /**
+ * Get IP address for localhost.
+ *
+ * @return IP address for localhost
+ */
+ public static String getIp() {
+ if (null != cachedIpAddress) {
+ return cachedIpAddress;
+ }
+ Enumeration<NetworkInterface> netInterfaces;
+ try {
+ netInterfaces = NetworkInterface.getNetworkInterfaces();
+ } catch (final SocketException ex) {
+ throw new HostException(ex);
+ }
+ String localIpAddress = null;
+ while (netInterfaces.hasMoreElements()) {
+ NetworkInterface netInterface = netInterfaces.nextElement();
+ Enumeration<InetAddress> ipAddresses = netInterface.getInetAddresses();
+ while (ipAddresses.hasMoreElements()) {
+ InetAddress ipAddress = ipAddresses.nextElement();
+ if (isPublicIpAddress(ipAddress)) {
+ String publicIpAddress = ipAddress.getHostAddress();
+ cachedIpAddress = publicIpAddress;
+ return publicIpAddress;
+ }
+ if (isLocalIpAddress(ipAddress)) {
+ localIpAddress = ipAddress.getHostAddress();
+ }
+ }
+ }
+ cachedIpAddress = localIpAddress;
+ return localIpAddress;
+ }
+
+ private static boolean isPublicIpAddress(final InetAddress ipAddress) {
+ return !ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress);
+ }
+
+ private static boolean isLocalIpAddress(final InetAddress ipAddress) {
+ return ipAddress.isSiteLocalAddress() && !ipAddress.isLoopbackAddress() && !isV6IpAddress(ipAddress);
+ }
+
+ private static boolean isV6IpAddress(final InetAddress ipAddress) {
+ return ipAddress.getHostAddress().contains(":");
+ }
+
+ /**
+ * Get host name for localhost.
+ *
+ * @return host name for localhost
+ */
+ public static String getHostName() {
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (final UnknownHostException ex) {
+ return "unknown";
+ }
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/TimeService.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/TimeService.java
new file mode 100755
index 0000000..d8fc2c7
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/env/TimeService.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.env;
+
+/**
+ * Time service.
+ */
+public final class TimeService {
+
+ /**
+ * Get current millis.
+ *
+ * @return current millis
+ */
+ public long getCurrentMillis() {
+ return System.currentTimeMillis();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/AbstractJobConfigurationGsonTypeAdapter.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/AbstractJobConfigurationGsonTypeAdapter.java
new file mode 100755
index 0000000..c7652cc
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/AbstractJobConfigurationGsonTypeAdapter.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.json;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import org.apache.shardingsphere.elasticjob.cloud.api.JobType;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobTypeConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.script.ScriptJobConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobCoreConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.JobRootConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.dataflow.DataflowJobConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.config.simple.SimpleJobConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobProperties;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Job configuration gson type adapter.
+ *
+ * @param <T> type of job root configuration
+ */
+public abstract class AbstractJobConfigurationGsonTypeAdapter<T extends JobRootConfiguration> extends TypeAdapter<T> {
+
+ @Override
+ public T read(final JsonReader in) throws IOException {
+ String jobName = "";
+ String cron = "";
+ int shardingTotalCount = 0;
+ String shardingItemParameters = "";
+ String jobParameter = "";
+ boolean failover = false;
+ boolean misfire = failover;
+ String description = "";
+ JobProperties jobProperties = new JobProperties();
+ JobType jobType = null;
+ String jobClass = "";
+ boolean streamingProcess = false;
+ String scriptCommandLine = "";
+ Map<String, Object> customizedValueMap = new HashMap<>(32, 1);
+ in.beginObject();
+ while (in.hasNext()) {
+ String jsonName = in.nextName();
+ switch (jsonName) {
+ case "jobName":
+ jobName = in.nextString();
+ break;
+ case "cron":
+ cron = in.nextString();
+ break;
+ case "shardingTotalCount":
+ shardingTotalCount = in.nextInt();
+ break;
+ case "shardingItemParameters":
+ shardingItemParameters = in.nextString();
+ break;
+ case "jobParameter":
+ jobParameter = in.nextString();
+ break;
+ case "failover":
+ failover = in.nextBoolean();
+ break;
+ case "misfire":
+ misfire = in.nextBoolean();
+ break;
+ case "description":
+ description = in.nextString();
+ break;
+ case "jobProperties":
+ jobProperties = getJobProperties(in);
+ break;
+ case "jobType":
+ jobType = JobType.valueOf(in.nextString());
+ break;
+ case "jobClass":
+ jobClass = in.nextString();
+ break;
+ case "streamingProcess":
+ streamingProcess = in.nextBoolean();
+ break;
+ case "scriptCommandLine":
+ scriptCommandLine = in.nextString();
+ break;
+ default:
+ addToCustomizedValueMap(jsonName, in, customizedValueMap);
+ break;
+ }
+ }
+ in.endObject();
+ JobCoreConfiguration coreConfig = getJobCoreConfiguration(jobName, cron, shardingTotalCount, shardingItemParameters,
+ jobParameter, failover, misfire, description, jobProperties);
+ JobTypeConfiguration typeConfig = getJobTypeConfiguration(coreConfig, jobType, jobClass, streamingProcess, scriptCommandLine);
+ return getJobRootConfiguration(typeConfig, customizedValueMap);
+ }
+
+ private JobProperties getJobProperties(final JsonReader in) throws IOException {
+ JobProperties result = new JobProperties();
+ in.beginObject();
+ while (in.hasNext()) {
+ switch (in.nextName()) {
+ case "job_exception_handler":
+ result.put(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), in.nextString());
+ break;
+ case "executor_service_handler":
+ result.put(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), in.nextString());
+ break;
+ default:
+ break;
+ }
+ }
+ in.endObject();
+ return result;
+ }
+
+ protected abstract void addToCustomizedValueMap(String jsonName, JsonReader in, Map<String, Object> customizedValueMap) throws IOException;
+
+ private JobCoreConfiguration getJobCoreConfiguration(final String jobName, final String cron, final int shardingTotalCount,
+ final String shardingItemParameters, final String jobParameter, final boolean failover,
+ final boolean misfire, final String description,
+ final JobProperties jobProperties) {
+ return JobCoreConfiguration.newBuilder(jobName, cron, shardingTotalCount)
+ .shardingItemParameters(shardingItemParameters).jobParameter(jobParameter).failover(failover).misfire(misfire).description(description)
+ .jobProperties(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER.getKey(), jobProperties.get(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER))
+ .jobProperties(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER.getKey(), jobProperties.get(JobProperties.JobPropertiesEnum.EXECUTOR_SERVICE_HANDLER))
+ .build();
+ }
+
+ private JobTypeConfiguration getJobTypeConfiguration(
+ final JobCoreConfiguration coreConfig, final JobType jobType, final String jobClass, final boolean streamingProcess, final String scriptCommandLine) {
+ Preconditions.checkNotNull(jobType, "jobType cannot be null.");
+ switch (jobType) {
+ case SIMPLE:
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(jobClass), "jobClass cannot be empty.");
+ return new SimpleJobConfiguration(coreConfig, jobClass);
+ case DATAFLOW:
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(jobClass), "jobClass cannot be empty.");
+ return new DataflowJobConfiguration(coreConfig, jobClass, streamingProcess);
+ case SCRIPT:
+ return new ScriptJobConfiguration(coreConfig, scriptCommandLine);
+ default:
+ throw new UnsupportedOperationException(String.valueOf(jobType));
+ }
+ }
+
+ protected abstract T getJobRootConfiguration(JobTypeConfiguration typeConfig, Map<String, Object> customizedValueMap);
+
+ @Override
+ public void write(final JsonWriter out, final T value) throws IOException {
+ out.beginObject();
+ out.name("jobName").value(value.getTypeConfig().getCoreConfig().getJobName());
+ out.name("jobClass").value(value.getTypeConfig().getJobClass());
+ out.name("jobType").value(value.getTypeConfig().getJobType().name());
+ out.name("cron").value(value.getTypeConfig().getCoreConfig().getCron());
+ out.name("shardingTotalCount").value(value.getTypeConfig().getCoreConfig().getShardingTotalCount());
+ out.name("shardingItemParameters").value(value.getTypeConfig().getCoreConfig().getShardingItemParameters());
+ out.name("jobParameter").value(value.getTypeConfig().getCoreConfig().getJobParameter());
+ out.name("failover").value(value.getTypeConfig().getCoreConfig().isFailover());
+ out.name("misfire").value(value.getTypeConfig().getCoreConfig().isMisfire());
+ out.name("description").value(value.getTypeConfig().getCoreConfig().getDescription());
+ out.name("jobProperties").jsonValue(value.getTypeConfig().getCoreConfig().getJobProperties().json());
+ if (value.getTypeConfig().getJobType() == JobType.DATAFLOW) {
+ DataflowJobConfiguration dataflowJobConfig = (DataflowJobConfiguration) value.getTypeConfig();
+ out.name("streamingProcess").value(dataflowJobConfig.isStreamingProcess());
+ } else if (value.getTypeConfig().getJobType() == JobType.SCRIPT) {
+ ScriptJobConfiguration scriptJobConfig = (ScriptJobConfiguration) value.getTypeConfig();
+ out.name("scriptCommandLine").value(scriptJobConfig.getScriptCommandLine());
+ }
+ writeCustomized(out, value);
+ out.endObject();
+ }
+
+ protected abstract void writeCustomized(JsonWriter out, T value) throws IOException;
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/GsonFactory.java b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/GsonFactory.java
new file mode 100755
index 0000000..6297965
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/main/java/org/apache/shardingsphere/elasticjob/cloud/util/json/GsonFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.util.json;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapter;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.lang.reflect.Type;
+
+/**
+ * Gson factory.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class GsonFactory {
+
+ private static final GsonBuilder GSON_BUILDER = new GsonBuilder();
+
+ private static volatile Gson gson = GSON_BUILDER.create();
+
+ /**
+ * Register type adapter.
+ *
+ * @param type Gson type
+ * @param typeAdapter Gson type adapter
+ */
+ public static synchronized void registerTypeAdapter(final Type type, final TypeAdapter typeAdapter) {
+ GSON_BUILDER.registerTypeAdapter(type, typeAdapter);
+ gson = GSON_BUILDER.create();
+ }
+
+ /**
+ * Get gson instance.
+ *
+ * @return gson instance
+ */
+ public static Gson getGson() {
+ return gson;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/AllCoreTests.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/AllCoreTests.java
new file mode 100755
index 0000000..4251621
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/AllCoreTests.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud;
+
+import org.apache.shardingsphere.elasticjob.cloud.api.AllApiTests;
+import org.apache.shardingsphere.elasticjob.cloud.executor.AllExecutorTests;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.AllStatisticsTests;
+import org.apache.shardingsphere.elasticjob.cloud.config.AllConfigTests;
+import org.apache.shardingsphere.elasticjob.cloud.context.AllContextTests;
+import org.apache.shardingsphere.elasticjob.cloud.event.AllEventTests;
+import org.apache.shardingsphere.elasticjob.cloud.exception.AllExceptionTests;
+import org.apache.shardingsphere.elasticjob.cloud.reg.AllRegTests;
+import org.apache.shardingsphere.elasticjob.cloud.util.AllUtilTests;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ AllRegTests.class,
+ AllContextTests.class,
+ AllApiTests.class,
+ AllConfigTests.class,
+ AllExecutorTests.class,
+ AllEventTests.class,
+ AllExceptionTests.class,
+ AllStatisticsTests.class,
+ AllUtilTests.class
+ })
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class AllCoreTests {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/AllApiTests.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/AllApiTests.java
new file mode 100755
index 0000000..312f511
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/AllApiTests.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses(ShardingContextTest.class)
+public final class AllApiTests {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContextTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContextTest.java
new file mode 100755
index 0000000..72a082a
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/api/ShardingContextTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.api;
+
+import org.apache.shardingsphere.elasticjob.cloud.executor.ShardingContexts;
+import org.apache.shardingsphere.elasticjob.cloud.fixture.ShardingContextsBuilder;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class ShardingContextTest {
+
+ @Test
+ public void assertNew() {
+ ShardingContexts shardingContexts = ShardingContextsBuilder.getMultipleShardingContexts();
+ ShardingContext actual = new ShardingContext(shardingContexts, 1);
+ Assert.assertThat(actual.getJobName(), Is.is(shardingContexts.getJobName()));
+ Assert.assertThat(actual.getTaskId(), Is.is(shardingContexts.getTaskId()));
+ Assert.assertThat(actual.getShardingTotalCount(), Is.is(shardingContexts.getShardingTotalCount()));
+ Assert.assertThat(actual.getJobParameter(), Is.is(shardingContexts.getJobParameter()));
+ Assert.assertThat(actual.getShardingItem(), Is.is(1));
+ Assert.assertThat(actual.getShardingParameter(), Is.is(shardingContexts.getShardingItemParameters().get(1)));
+ }
+
+ @Test
+ public void assertToString() {
+ Assert.assertThat(new ShardingContext(ShardingContextsBuilder.getMultipleShardingContexts(), 1).toString(),
+ Is.is("ShardingContext(jobName=test_job, taskId=fake_task_id, shardingTotalCount=2, jobParameter=, shardingItem=1, shardingParameter=B)"));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/AllConfigTests.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/AllConfigTests.java
new file mode 100755
index 0000000..6044682
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/AllConfigTests.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses(JobCoreConfigurationTest.class)
+public final class AllConfigTests {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfigurationTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfigurationTest.java
new file mode 100755
index 0000000..32df8f1
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/config/JobCoreConfigurationTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.config;
+
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.impl.DefaultJobExceptionHandler;
+import org.apache.shardingsphere.elasticjob.cloud.fixture.handler.IgnoreJobExceptionHandler;
+import org.apache.shardingsphere.elasticjob.cloud.executor.handler.JobProperties;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class JobCoreConfigurationTest {
+
+ @Test
+ public void assertBuildAllProperties() {
+ JobCoreConfiguration actual = JobCoreConfiguration.newBuilder("test_job", "0/1 * * * * ?", 3)
+ .shardingItemParameters("0=a,1=b,2=c").jobParameter("param").failover(true).misfire(false).description("desc")
+ .jobProperties("job_exception_handler", IgnoreJobExceptionHandler.class.getName()).build();
+ assertRequiredProperties(actual);
+ Assert.assertThat(actual.getShardingItemParameters(), Is.is("0=a,1=b,2=c"));
+ Assert.assertThat(actual.getJobParameter(), Is.is("param"));
+ Assert.assertTrue(actual.isFailover());
+ Assert.assertFalse(actual.isMisfire());
+ Assert.assertThat(actual.getDescription(), Is.is("desc"));
+ Assert.assertThat(actual.getJobProperties().get(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER), Is.is(IgnoreJobExceptionHandler.class.getName()));
+ }
+
+ @Test
+ public void assertBuildRequiredProperties() {
+ JobCoreConfiguration actual = JobCoreConfiguration.newBuilder("test_job", "0/1 * * * * ?", 3).build();
+ assertRequiredProperties(actual);
+ assertDefaultValues(actual);
+ }
+
+ @Test
+ public void assertBuildWhenOptionalParametersIsNull() {
+ //noinspection NullArgumentToVariableArgMethod
+ JobCoreConfiguration actual = JobCoreConfiguration.newBuilder("test_job", "0/1 * * * * ?", 3).shardingItemParameters(null).jobParameter(null).description(null).build();
+ assertRequiredProperties(actual);
+ assertDefaultValues(actual);
+ }
+
+ private void assertRequiredProperties(final JobCoreConfiguration actual) {
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getCron(), Is.is("0/1 * * * * ?"));
+ Assert.assertThat(actual.getShardingTotalCount(), Is.is(3));
+ }
+
+ private void assertDefaultValues(final JobCoreConfiguration actual) {
+ Assert.assertThat(actual.getShardingItemParameters(), Is.is(""));
+ Assert.assertThat(actual.getJobParameter(), Is.is(""));
+ Assert.assertFalse(actual.isFailover());
+ Assert.assertTrue(actual.isMisfire());
+ Assert.assertThat(actual.getDescription(), Is.is(""));
+ Assert.assertThat(actual.getJobProperties().get(JobProperties.JobPropertiesEnum.JOB_EXCEPTION_HANDLER), Is.is(DefaultJobExceptionHandler.class.getName()));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void assertBuildWhenJobNameIsNull() {
+ JobCoreConfiguration.newBuilder(null, "0/1 * * * * ?", 3).build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void assertBuildWhenCronIsNull() {
+ JobCoreConfiguration.newBuilder("test_job", null, 3).build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void assertBuildWhenTotalSHardingCountIsNegative() {
+ JobCoreConfiguration.newBuilder(null, "0/1 * * * * ?", -1).build();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/AllContextTests.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/AllContextTests.java
new file mode 100755
index 0000000..aeaabed
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/AllContextTests.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.context;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses(TaskContextTest.class)
+public final class AllContextTests {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContextTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContextTest.java
new file mode 100755
index 0000000..84ab679
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/context/TaskContextTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.context;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.elasticjob.cloud.fixture.context.TaskNode;
+import org.hamcrest.core.Is;
+import org.hamcrest.core.StringStartsWith;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class TaskContextTest {
+
+ @Test
+ public void assertNew() {
+ TaskContext actual = new TaskContext("test_job", Lists.newArrayList(0), ExecutionType.READY, "slave-S0");
+ Assert.assertThat(actual.getMetaInfo().getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getMetaInfo().getShardingItems().get(0), Is.is(0));
+ Assert.assertThat(actual.getType(), Is.is(ExecutionType.READY));
+ Assert.assertThat(actual.getSlaveId(), Is.is("slave-S0"));
+ Assert.assertThat(actual.getId(), StringStartsWith.startsWith(TaskNode.builder().build().getTaskNodeValue().substring(0, TaskNode.builder().build().getTaskNodeValue().length() - 1)));
+ }
+
+ @Test
+ public void assertNewWithoutSlaveId() {
+ TaskContext actual = new TaskContext("test_job", Lists.newArrayList(0), ExecutionType.READY);
+ Assert.assertThat(actual.getSlaveId(), Is.is("unassigned-slave"));
+ }
+
+ @Test
+ public void assertGetMetaInfo() {
+ TaskContext actual = new TaskContext("test_job", Lists.newArrayList(0), ExecutionType.READY, "slave-S0");
+ Assert.assertThat(actual.getMetaInfo().toString(), Is.is("test_job@-@0"));
+ }
+
+ @Test
+ public void assertTaskContextFrom() {
+ TaskContext actual = TaskContext.from(TaskNode.builder().build().getTaskNodeValue());
+ Assert.assertThat(actual.getId(), Is.is(TaskNode.builder().build().getTaskNodeValue()));
+ Assert.assertThat(actual.getMetaInfo().getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getMetaInfo().getShardingItems().get(0), Is.is(0));
+ Assert.assertThat(actual.getType(), Is.is(ExecutionType.READY));
+ Assert.assertThat(actual.getSlaveId(), Is.is("slave-S0"));
+ }
+
+ @Test
+ public void assertMetaInfoFromWithMetaInfo() {
+ TaskContext.MetaInfo actual = TaskContext.MetaInfo.from("test_job@-@1");
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getShardingItems().get(0), Is.is(1));
+ }
+
+ @Test
+ public void assertMetaInfoFromWithTaskId() {
+ TaskContext.MetaInfo actual = TaskContext.MetaInfo.from("test_job@-@1@-@READY@-@unassigned-slave@-@0");
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getShardingItems().get(0), Is.is(1));
+ }
+
+ @Test
+ public void assertMetaInfoFromWithMetaInfoWithoutShardingItems() {
+ TaskContext.MetaInfo actual = TaskContext.MetaInfo.from("test_job@-@");
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertTrue(actual.getShardingItems().isEmpty());
+ }
+
+ @Test
+ public void assertMetaInfoFromWithTaskIdWithoutShardingItems() {
+ TaskContext.MetaInfo actual = TaskContext.MetaInfo.from("test_job@-@@-@READY@-@unassigned-slave@-@0");
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertTrue(actual.getShardingItems().isEmpty());
+ }
+
+ @Test
+ public void assertGetIdForUnassignedSlave() {
+ Assert.assertThat(TaskContext.getIdForUnassignedSlave("test_job@-@0@-@READY@-@slave-S0@-@0"), Is.is("test_job@-@0@-@READY@-@unassigned-slave@-@0"));
+ }
+
+ @Test
+ public void assertGetTaskName() {
+ TaskContext actual = TaskContext.from(TaskNode.builder().build().getTaskNodeValue());
+ Assert.assertThat(actual.getTaskName(), Is.is("test_job@-@0@-@READY@-@slave-S0"));
+ }
+
+ @Test
+ public void assertGetExecutorId() {
+ TaskContext actual = TaskContext.from(TaskNode.builder().build().getTaskNodeValue());
+ Assert.assertThat(actual.getExecutorId("app"), Is.is("app@-@slave-S0"));
+ }
+
+ @Test
+ public void assertSetSlaveId() {
+ TaskContext actual = new TaskContext("test_job", Lists.newArrayList(0), ExecutionType.READY, "slave-S0");
+ Assert.assertThat(actual.getSlaveId(), Is.is("slave-S0"));
+ actual.setSlaveId("slave-S1");
+ Assert.assertThat(actual.getSlaveId(), Is.is("slave-S1"));
+ }
+
+ @Test
+ public void assertSetIdle() {
+ TaskContext actual = new TaskContext("test_job", Lists.newArrayList(0), ExecutionType.READY, "slave-S0");
+ Assert.assertFalse(actual.isIdle());
+ actual.setIdle(true);
+ Assert.assertTrue(actual.isIdle());
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/AllEventTests.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/AllEventTests.java
new file mode 100755
index 0000000..d50c85c
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/AllEventTests.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.rdb.JobEventRdbConfigurationTest;
+import org.apache.shardingsphere.elasticjob.cloud.event.rdb.JobEventRdbIdentityTest;
+import org.apache.shardingsphere.elasticjob.cloud.event.rdb.JobEventRdbListenerTest;
+import org.apache.shardingsphere.elasticjob.cloud.event.rdb.JobEventRdbSearchTest;
+import org.apache.shardingsphere.elasticjob.cloud.event.rdb.JobEventRdbStorageTest;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ JobExecutionEventTest.class,
+ JobEventBusTest.class,
+ JobEventRdbIdentityTest.class,
+ JobEventRdbConfigurationTest.class,
+ JobEventRdbListenerTest.class,
+ JobEventRdbStorageTest.class,
+ JobEventRdbSearchTest.class
+ })
+public final class AllEventTests {
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBusTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBusTest.java
new file mode 100755
index 0000000..a45ca39
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobEventBusTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+import com.google.common.eventbus.EventBus;
+import org.apache.shardingsphere.elasticjob.cloud.event.fixture.JobEventCaller;
+import org.apache.shardingsphere.elasticjob.cloud.event.fixture.TestJobEventConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.fixture.TestJobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.fixture.TestJobEventFailureConfiguration;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.unitils.util.ReflectionUtils;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class JobEventBusTest {
+
+ @Mock
+ private JobEventCaller jobEventCaller;
+
+ @Mock
+ private EventBus eventBus;
+
+ private JobEventBus jobEventBus;
+
+ @Test
+ public void assertRegisterFailure() throws NoSuchFieldException {
+ jobEventBus = new JobEventBus(new TestJobEventFailureConfiguration());
+ assertIsRegistered(false);
+ }
+
+ @Test
+ public void assertPost() throws InterruptedException, NoSuchFieldException {
+ jobEventBus = new JobEventBus(new TestJobEventConfiguration(jobEventCaller));
+ assertIsRegistered(true);
+ jobEventBus.post(new JobExecutionEvent("fake_task_id", "test_event_bus_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0));
+ while (!TestJobEventListener.isExecutionEventCalled()) {
+ Thread.sleep(100L);
+ }
+ Mockito.verify(jobEventCaller).call();
+ }
+
+ @Test
+ public void assertPostWithoutListener() throws NoSuchFieldException {
+ jobEventBus = new JobEventBus();
+ assertIsRegistered(false);
+ ReflectionUtils.setFieldValue(jobEventBus, "eventBus", eventBus);
+ jobEventBus.post(new JobExecutionEvent("fake_task_id", "test_event_bus_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0));
+ Mockito.verify(eventBus, Mockito.times(0)).post(ArgumentMatchers.<JobEvent>any());
+ }
+
+ private void assertIsRegistered(final boolean actual) throws NoSuchFieldException {
+ Assert.assertThat((boolean) ReflectionUtils.getFieldValue(jobEventBus, JobEventBus.class.getDeclaredField("isRegistered")), Is.is(actual));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobExecutionEventTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobExecutionEventTest.java
new file mode 100755
index 0000000..f5284c6
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/JobExecutionEventTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class JobExecutionEventTest {
+
+ @Test
+ public void assertNewJobExecutionEvent() {
+ JobExecutionEvent actual = new JobExecutionEvent("fake_task_id", "test_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
+ Assert.assertThat(actual.getJobName(), Is.is("test_job"));
+ Assert.assertThat(actual.getSource(), Is.is(JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER));
+ Assert.assertThat(actual.getShardingItem(), Is.is(0));
+ Assert.assertNotNull(actual.getHostname());
+ Assert.assertNotNull(actual.getStartTime());
+ Assert.assertNull(actual.getCompleteTime());
+ Assert.assertFalse(actual.isSuccess());
+ Assert.assertThat(actual.getFailureCause(), Is.is(""));
+ }
+
+ @Test
+ public void assertExecutionSuccess() {
+ JobExecutionEvent startEvent = new JobExecutionEvent("fake_task_id", "test_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
+ JobExecutionEvent successEvent = startEvent.executionSuccess();
+ Assert.assertNotNull(successEvent.getCompleteTime());
+ Assert.assertTrue(successEvent.isSuccess());
+ }
+
+ @Test
+ public void assertExecutionFailure() {
+ JobExecutionEvent startEvent = new JobExecutionEvent("fake_task_id", "test_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
+ JobExecutionEvent failureEvent = startEvent.executionFailure(new RuntimeException("failure"));
+ Assert.assertNotNull(failureEvent.getCompleteTime());
+ Assert.assertFalse(failureEvent.isSuccess());
+ Assert.assertThat(failureEvent.getFailureCause(), CoreMatchers.startsWith("java.lang.RuntimeException: failure"));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/JobEventCaller.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/JobEventCaller.java
new file mode 100755
index 0000000..d00cb41
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/JobEventCaller.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.fixture;
+
+public interface JobEventCaller {
+
+ /**
+ * Call method.
+ */
+ void call();
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventConfiguration.java
new file mode 100755
index 0000000..4f6cd5b
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventConfiguration.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.fixture;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListenerConfigurationException;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public final class TestJobEventConfiguration extends TestJobEventIdentity implements JobEventConfiguration {
+
+ private final JobEventCaller jobEventCaller;
+
+ @Override
+ public JobEventListener createJobEventListener() throws JobEventListenerConfigurationException {
+ return new TestJobEventListener(jobEventCaller);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventFailureConfiguration.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventFailureConfiguration.java
new file mode 100755
index 0000000..43decde
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventFailureConfiguration.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.fixture;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListenerConfigurationException;
+
+public final class TestJobEventFailureConfiguration extends TestJobEventIdentity implements JobEventConfiguration {
+
+ @Override
+ public JobEventListener createJobEventListener() throws JobEventListenerConfigurationException {
+ throw new JobEventListenerConfigurationException(new RuntimeException("assert failure"));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventIdentity.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventIdentity.java
new file mode 100755
index 0000000..75bc221
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventIdentity.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.fixture;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventIdentity;
+
+public class TestJobEventIdentity implements JobEventIdentity {
+
+ @Override
+ public String getIdentity() {
+ return "test";
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventListener.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventListener.java
new file mode 100755
index 0000000..096337d
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/fixture/TestJobEventListener.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.fixture;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListener;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public final class TestJobEventListener extends TestJobEventIdentity implements JobEventListener {
+
+ @Getter
+ private static volatile boolean executionEventCalled;
+
+ private final JobEventCaller jobEventCaller;
+
+ @Override
+ public void listen(final JobExecutionEvent jobExecutionEvent) {
+ jobEventCaller.call();
+ executionEventCalled = true;
+ }
+
+ @Override
+ public void listen(final JobStatusTraceEvent jobStatusTraceEvent) {
+ jobEventCaller.call();
+ }
+
+ /**
+ * Reset the event.
+ */
+ public static void reset() {
+ executionEventCalled = false;
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfigurationTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfigurationTest.java
new file mode 100755
index 0000000..b52d827
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbConfigurationTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListenerConfigurationException;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class JobEventRdbConfigurationTest {
+
+ @Test
+ public void assertGetDataSource() throws JobEventListenerConfigurationException {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(org.h2.Driver.class.getName());
+ dataSource.setUrl("jdbc:h2:mem:job_event_storage");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ Assert.assertThat((BasicDataSource) (new JobEventRdbConfiguration(dataSource).getDataSource()), Is.is(dataSource));
+ }
+
+ @Test
+ public void assertCreateJobEventListenerSuccess() throws JobEventListenerConfigurationException {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(org.h2.Driver.class.getName());
+ dataSource.setUrl("jdbc:h2:mem:job_event_storage");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ Assert.assertThat(new JobEventRdbConfiguration(dataSource).createJobEventListener(), CoreMatchers.instanceOf(JobEventRdbListener.class));
+ }
+
+ @Test(expected = JobEventListenerConfigurationException.class)
+ public void assertCreateJobEventListenerFailure() throws JobEventListenerConfigurationException {
+ new JobEventRdbConfiguration(new BasicDataSource()).createJobEventListener();
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentityTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentityTest.java
new file mode 100755
index 0000000..5a70e6a
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbIdentityTest.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Test;
+
+public final class JobEventRdbIdentityTest {
+
+ @Test
+ public void assertGetIdentity() {
+ Assert.assertThat(new JobEventRdbIdentity().getIdentity(), Is.is("rdb"));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListenerTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListenerTest.java
new file mode 100755
index 0000000..93865a1
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbListenerTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventBus;
+import org.apache.shardingsphere.elasticjob.cloud.event.JobEventListenerConfigurationException;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.unitils.util.ReflectionUtils;
+
+import java.sql.SQLException;
+
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public final class JobEventRdbListenerTest {
+
+ private static final String JOB_NAME = "test_rdb_event_listener";
+
+ @Mock
+ private JobEventRdbConfiguration jobEventRdbConfiguration;
+
+ @Mock
+ private JobEventRdbStorage repository;
+
+ private JobEventBus jobEventBus;
+
+ @Before
+ public void setUp() throws JobEventListenerConfigurationException, SQLException, NoSuchFieldException {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(org.h2.Driver.class.getName());
+ dataSource.setUrl("jdbc:h2:mem:job_event_storage");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ JobEventRdbListener jobEventRdbListener = new JobEventRdbListener(dataSource);
+ ReflectionUtils.setFieldValue(jobEventRdbListener, "repository", repository);
+ when(jobEventRdbConfiguration.createJobEventListener()).thenReturn(jobEventRdbListener);
+ jobEventBus = new JobEventBus(jobEventRdbConfiguration);
+ }
+
+ @Test
+ public void assertPostJobExecutionEvent() {
+ JobExecutionEvent jobExecutionEvent = new JobExecutionEvent("fake_task_id", JOB_NAME, JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
+ jobEventBus.post(jobExecutionEvent);
+ verify(repository, atMost(1)).addJobExecutionEvent(jobExecutionEvent);
+ }
+
+ @Test
+ public void assertPostJobStatusTraceEvent() {
+ JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent(
+ JOB_NAME, "fake_task_id", "fake_slave_id", JobStatusTraceEvent.Source.LITE_EXECUTOR, ExecutionType.READY, "0", JobStatusTraceEvent.State.TASK_RUNNING, "message is empty.");
+ jobEventBus.post(jobStatusTraceEvent);
+ verify(repository, atMost(1)).addJobStatusTraceEvent(jobStatusTraceEvent);
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearchTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearchTest.java
new file mode 100755
index 0000000..a1b3b24
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbSearchTest.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class JobEventRdbSearchTest {
+
+ private static JobEventRdbStorage storage;
+
+ private static JobEventRdbSearch repository;
+
+ @BeforeClass
+ public static void setUpClass() throws SQLException {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(org.h2.Driver.class.getName());
+ dataSource.setUrl("jdbc:h2:mem:");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ storage = new JobEventRdbStorage(dataSource);
+ repository = new JobEventRdbSearch(dataSource);
+ initStorage();
+ }
+
+ private static void initStorage() {
+ for (int i = 1; i <= 500; i++) {
+ JobExecutionEvent startEvent = new JobExecutionEvent("fake_task_id", "test_job_" + i, JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
+ storage.addJobExecutionEvent(startEvent);
+ if (i % 2 == 0) {
+ JobExecutionEvent successEvent = startEvent.executionSuccess();
+ storage.addJobExecutionEvent(successEvent);
+ }
+ storage.addJobStatusTraceEvent(
+ new JobStatusTraceEvent("test_job_" + i, "fake_failed_failover_task_id", "fake_slave_id",
+ JobStatusTraceEvent.Source.LITE_EXECUTOR, ExecutionType.FAILOVER, "0", JobStatusTraceEvent.State.TASK_FAILED, "message is empty."));
+ }
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithPageSizeAndNumber() {
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(50, 1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(50));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(100, 5, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(100));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(100, 6, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(0));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithErrorPageSizeAndNumber() {
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(-1, -1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithSort() {
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "ASC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_1"));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "DESC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_99"));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithErrorSort() {
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "ERROR_SORT", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_1"));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, "notExistField", "ASC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithTime() {
+ Date now = new Date();
+ Date tenMinutesBefore = new Date(now.getTime() - 10 * 60 * 1000);
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, tenMinutesBefore, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, now, null, null));
+ assertThat(result.getTotal(), is(0));
+ assertThat(result.getRows().size(), is(0));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, tenMinutesBefore, null));
+ assertThat(result.getTotal(), is(0));
+ assertThat(result.getRows().size(), is(0));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, now, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, tenMinutesBefore, now, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithFields() {
+ Map<String, Object> fields = new HashMap<>();
+ fields.put("isSuccess", "1");
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, fields));
+ assertThat(result.getTotal(), is(250));
+ assertThat(result.getRows().size(), is(10));
+ fields.put("isSuccess", null);
+ fields.put("jobName", "test_job_1");
+ result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, fields));
+ assertThat(result.getTotal(), is(1));
+ assertThat(result.getRows().size(), is(1));
+ }
+
+ @Test
+ public void assertFindJobExecutionEventsWithErrorFields() {
+ Map<String, Object> fields = new HashMap<>();
+ fields.put("notExistField", "some value");
+ JobEventRdbSearch.Result<JobExecutionEvent> result = repository.findJobExecutionEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, fields));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithPageSizeAndNumber() {
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(50, 1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(50));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(100, 5, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(100));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(100, 6, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(0));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithErrorPageSizeAndNumber() {
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(-1, -1, null, null, null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithSort() {
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "ASC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_1"));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "DESC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_99"));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithErrorSort() {
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, "jobName", "ERROR_SORT", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ assertThat(result.getRows().get(0).getJobName(), is("test_job_1"));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, "notExistField", "ASC", null, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithTime() {
+ Date now = new Date();
+ Date tenMinutesBefore = new Date(now.getTime() - 10 * 60 * 1000);
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, tenMinutesBefore, null, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, now, null, null));
+ assertThat(result.getTotal(), is(0));
+ assertThat(result.getRows().size(), is(0));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, tenMinutesBefore, null));
+ assertThat(result.getTotal(), is(0));
+ assertThat(result.getRows().size(), is(0));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, now, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, tenMinutesBefore, now, null));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithFields() {
+ Map<String, Object> fields = new HashMap<>();
+ fields.put("jobName", "test_job_1");
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, fields));
+ assertThat(result.getTotal(), is(1));
+ assertThat(result.getRows().size(), is(1));
+ }
+
+ @Test
+ public void assertFindJobStatusTraceEventsWithErrorFields() {
+ Map<String, Object> fields = new HashMap<>();
+ fields.put("notExistField", "some value");
+ JobEventRdbSearch.Result<JobStatusTraceEvent> result = repository.findJobStatusTraceEvents(new JobEventRdbSearch.Condition(10, 1, null, null, null, null, fields));
+ assertThat(result.getTotal(), is(500));
+ assertThat(result.getRows().size(), is(10));
+ }
+}
diff --git a/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorageTest.java b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorageTest.java
new file mode 100755
index 0000000..c549576
--- /dev/null
+++ b/elasticjob-cloud/elasticjob-cloud-common/src/test/java/org/apache/shardingsphere/elasticjob/cloud/event/rdb/JobEventRdbStorageTest.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.event.rdb;
+
+import org.apache.shardingsphere.elasticjob.cloud.context.ExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.cloud.event.type.JobStatusTraceEvent;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.core.Is;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.util.List;
+
+public class JobEventRdbStorageTest {
+
+ private JobEventRdbStorage storage;
+
+ @Before
+ public void setup() throws SQLException {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(org.h2.Driver.class.getName());
+ dataSource.setUrl("jdbc:h2:mem:job_event_storage");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+ storage = new JobEventRdbStorage(dataSource);
+ }
+
+ @Test
+ public void assertAddJobExecutionEvent() throws SQLException {
+ Assert.assertTrue(storage.addJobExecutionEvent(new JobExecutionEvent("fake_task_id", "test_job", JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0)));
+ }
+
+ @Test
+ public void assertAddJobStatusTraceEvent() throws SQLException {
+ Assert.assertTrue(storage.addJobStatusTraceEvent(new JobStatusTraceEvent("test_job", "fake_task_id", "fake_slave_id", JobStatusTraceEvent.Source.LITE_EXECUTOR, ExecutionType.READY, "0",
+ JobStatusTraceEvent.State.TASK_RUNNING, "message is empty.")));
+ }
+
+ @Test
+ public void assertAddJobStatusTraceEventWhenFailoverWithTaskStagingState() throws SQLException {
+ JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent("test_job", "fake_failover_task_id", "fake_slave_id", JobStatusTraceEvent.Source.LITE_EXECUTOR, ExecutionType.FAILOVER, "0",
+ JobStatusTraceEvent.State.TASK_STAGING, "message is empty.");
+ jobStatusTraceEvent.setOriginalTaskId("original_fake_failover_task_id");
+ Assert.assertThat(storage.getJobStatusTraceEvents("fake_failover_task_id").size(), Is.is(0));
+ storage.addJobStatusTraceEvent(jobStatusTraceEvent);
+ Assert.assertThat(storage.getJobStatusTraceEvents("fake_failover_task_id").size(), Is.is(1));
+ }
+
+ @Test
+ public void assertAddJobStatusTraceEventWhenFailoverWithTaskFailedState() throws SQLException {
+ JobStatusTraceEvent stagingJobStatusTraceEvent = new JobStatusTraceEvent("test_job", "fake_failed_failover_task_id", "fake_slave_id", JobStatusTraceEvent.Source.LITE_EXECUTOR,
+ ExecutionType.FAILOVER, "0", JobStatusTraceEvent.State.TASK_STAGING, "message is empty.");
+ stagingJobStatusTraceEvent.setOriginalTaskId("original_fake_failed_failover_task_id");
+ storage.addJobStatusTraceEvent(stagingJobStatusTraceEvent);
+ JobStatusTraceEvent failedJobStatusTraceEvent = new JobStatusTraceEvent("test_job", "fake_failed_failover_task_id", "fake_slave_id", JobStatusTraceEvent.Source.LITE_EXECUTOR,
+ ExecutionType.FAILOVER, "0", JobStatusTraceEvent.State.TASK_FAILED, "message is empty.");
+ storage.addJobStatusTraceEvent(failedJobStatusTraceEvent);
+ List<JobStatusTraceEvent> jobStatusTraceEvents = storage.getJobStatusTraceEvents("fake_failed_failover_task_id");
+ Assert.assertThat(jobStatusTraceEvents.size(), Is.is(2));
+ for (JobStatusTraceEvent jobStatusTraceEvent : jobStatusTraceEvents) {
... 54144 lines suppressed ...