diff --git a/.github/workflows/graalvm.yml b/.github/workflows/graalvm.yml index fcff1f14e3..1216b9307f 100644 --- a/.github/workflows/graalvm.yml +++ b/.github/workflows/graalvm.yml @@ -34,7 +34,7 @@ jobs: os: [ 'ubuntu-latest' ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up GraalVM CE ${{ matrix.java }} uses: graalvm/setup-graalvm@v1 with: @@ -42,6 +42,7 @@ jobs: distribution: 'graalvm-community' github-token: ${{ secrets.GITHUB_TOKEN }} cache: 'maven' + native-image-job-reports: 'true' - name: Run nativeTest with GraalVM CE for ${{ matrix.java-version }} continue-on-error: true run: ./mvnw -PnativeTestInElasticJob -T1C -B -e clean test diff --git a/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java b/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java index dc0599ccdd..31cfe784d1 100644 --- a/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java +++ b/bootstrap/src/main/java/org/apache/shardingsphere/elasticjob/bootstrap/type/OneOffJobBootstrap.java @@ -30,7 +30,7 @@ /** * One off job bootstrap. */ -public final class OneOffJobBootstrap implements JobBootstrap { +public class OneOffJobBootstrap implements JobBootstrap { private final JobScheduler jobScheduler; diff --git a/docs/content/user-manual/configuration/graalvm-native-image.cn.md b/docs/content/user-manual/configuration/graalvm-native-image.cn.md index 8a892fa376..3744146324 100644 --- a/docs/content/user-manual/configuration/graalvm-native-image.cn.md +++ b/docs/content/user-manual/configuration/graalvm-native-image.cn.md @@ -104,10 +104,29 @@ graalvmNative { 若 `script.command.line` 设置为构建 GraalVM Native Image 时, 私有项目的 classpath 下的某个 `.sh` 文件在 GraalVM Native Image 下的相对路径, 则此 `.sh` 文件至少提前设置 `rwxr-xr-x` 的 POSIX 文件权限。 因为 `com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystem` 显然不支持 `java.nio.file.attribute.PosixFileAttributeView`。 +长话短说,用户应该避免在作业内包含类似如下的逻辑, + +```java +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermissions; + +public class ExampleUtils { + public void setPosixFilePermissions() throws IOException { + URL resource = ExampleUtils.class.getResource("/script/demo.sh"); + assert resource != null; + Path path = Paths.get(resource.getPath()); + Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-xr-x")); + } +} +``` -3. ElasticJob 的 Spring 命名空间集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` 尚未在 GraalVM Native Image 下可用。 +3. `企业微信通知策略`,`钉钉通知策略`,`邮件通知策略`尚未在 GraalVM Native Image 下可用。 -4. ElasticJob 的 Spring Boot Starter 集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-boot-starter` 尚未在 GraalVM Native Image 下可用。 +4. ElasticJob 的 Spring 命名空间集成模块 `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` 尚未在 GraalVM Native Image 下可用。 ## 贡献 GraalVM Reachability Metadata diff --git a/docs/content/user-manual/configuration/graalvm-native-image.en.md b/docs/content/user-manual/configuration/graalvm-native-image.en.md index 5b9018c8c5..028f20afc9 100644 --- a/docs/content/user-manual/configuration/graalvm-native-image.en.md +++ b/docs/content/user-manual/configuration/graalvm-native-image.en.md @@ -106,10 +106,29 @@ Users can quickly collect GraalVM Reachability Metadata through the GraalVM Trac if `script.command.line` is set to the relative path of a `.sh` file in the private project's classpath under the GraalVM Native Image when building the GraalVM Native Image, then the `.sh` file must at least have the POSIX file permission of `rwxr-xr-x` set in advance. This is because `com.oracle.svm.core.jdk.resources.NativeImageResourceFileSystem` obviously does not support `java.nio.file.attribute.PosixFileAttributeView`. +Long story short, users should avoid including logic like the following in their jobs, + +```java +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.PosixFilePermissions; + +public class ExampleUtils { + public void setPosixFilePermissions() throws IOException { + URL resource = ExampleUtils.class.getResource("/script/demo.sh"); + assert resource != null; + Path path = Paths.get(resource.getPath()); + Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-xr-x")); + } +} +``` -3. The Spring namespace integration module `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` of ElasticJob is not yet available under GraalVM Native Image. +3. `WeCom Notification Policy`, `DingTalk Notification Policy`, and `Email Notification Policy` are not yet available in GraalVM Native Image. -4. The Spring Boot Starter integration module `org.apache.shardingsphere.elasticjob:elasticjob-spring-boot-starter` for ElasticJob is not yet available under GraalVM Native Image. +4. The Spring namespace integration module `org.apache.shardingsphere.elasticjob:elasticjob-spring-namespace` of ElasticJob is not yet available under GraalVM Native Image. ## Contribute GraalVM Reachability Metadata diff --git a/pom.xml b/pom.xml index 15a3aa9ca4..db8ce221dd 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,9 @@ 2.2.224 4.0.3 + + 3.2.8 + 3.2.1 3.11.0 @@ -1015,6 +1018,19 @@ + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-dependencies.version} + + + process-test-aot + + process-test-aot + + + + diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json index fd2d4325f4..25cf820544 100644 --- a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json +++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/proxy-config.json @@ -1,6 +1,6 @@ [ { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.converter.RDBTracingStorageConfigurationConverter"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"}, "interfaces":["java.sql.Connection"] } ] \ No newline at end of file diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json index b934e85204..49e892502b 100644 --- a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json +++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/reflect-config.json @@ -4,9 +4,12 @@ "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, - "name":"java.util.Properties", - "methods":[{"name":"","parameterTypes":[] }] + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.repository.RDBJobEventRepository"}, + "name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"}, + "name":"[Ljava.sql.Statement;" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"}, @@ -23,6 +26,11 @@ "name":"java.util.Properties", "methods":[{"name":"","parameterTypes":[] }] }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ListenServersChangedJobListener"}, + "name":"java.util.Properties", + "methods":[{"name":"","parameterTypes":[] }] +}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"}, "name":"java.util.Properties", @@ -48,7 +56,7 @@ "methods":[{"name":"","parameterTypes":[] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "name":"org.apache.shardingsphere.elasticjob.http.executor.HttpJobExecutor" }, { @@ -59,16 +67,10 @@ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"}, "name":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.type.SingleThreadJobExecutorThreadPoolSizeProvider" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", - "queryAllPublicMethods":true -}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", - "queryAllPublicMethods":true, - "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }] + "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }] }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"}, @@ -76,16 +78,15 @@ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.facade.JobFacade"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", - "allDeclaredFields":true, - "methods":[{"name":"","parameterTypes":[] }, {"name":"setDescription","parameterTypes":["java.lang.String"] }, {"name":"setDisabled","parameterTypes":["boolean"] }, {"name":"setFailover","parameterTypes":["boolean"] }, {"name":"setJobExtraConfigurations","parameterTypes":["java.util.Collection"] }, {"name":"setJobName","parameterTypes":["java.lang.String"] }, {"name":"setJobParameter","parameterTypes":["java.lang.String"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }] + "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }] }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", "allDeclaredFields":true, - "methods":[{"name":"getCron","parameterTypes":[] }, {"name":"getDescription","parameterTypes":[] }, {"name":"getJobErrorHandlerType","parameterTypes":[] }, {"name":"getJobExecutorThreadPoolSizeProviderType","parameterTypes":[] }, {"name":"getJobExtraConfigurations","parameterTypes":[] }, {"name":"getJobListenerTypes","parameterTypes":[] }, {"name":"getJobName","parameterTypes":[] }, {"name":"getJobParameter","parameterTypes":[] }, {"name":"getJobShardingStrategyType","parameterTypes":[] }, {"name":"getLabel","parameterTypes":[] }, {"name":"getMaxTimeDiffSeconds","parameterTypes":[] }, {"name":"getProps","parameterTypes":[] }, {"name":"getReconcileIntervalMinutes","parameterTypes":[] }, {"name":"getShardingItemParameters","parameterTypes":[] }, {"name":"getShardingTotalCount","parameterTypes":[] }, {"name":"getTimeZone","parameterTypes":[] }, {"name":"isDisabled","parameterTypes":[] }, {"name":"isFailover","parameterTypes":[] }, {"name":"isMisfire","parameterTypes":[] }, {"name":"isMonitorExecution","parameterTypes":[] }, {"name":"isOverwrite","parameterTypes":[] }, {"name":"isStaticSharding","parameterTypes":[] }] + "methods":[{"name":"","parameterTypes":[] }, {"name":"getCron","parameterTypes":[] }, {"name":"getDescription","parameterTypes":[] }, {"name":"getJobErrorHandlerType","parameterTypes":[] }, {"name":"getJobExecutorThreadPoolSizeProviderType","parameterTypes":[] }, {"name":"getJobExtraConfigurations","parameterTypes":[] }, {"name":"getJobListenerTypes","parameterTypes":[] }, {"name":"getJobName","parameterTypes":[] }, {"name":"getJobParameter","parameterTypes":[] }, {"name":"getJobShardingStrategyType","parameterTypes":[] }, {"name":"getLabel","parameterTypes":[] }, {"name":"getMaxTimeDiffSeconds","parameterTypes":[] }, {"name":"getProps","parameterTypes":[] }, {"name":"getReconcileIntervalMinutes","parameterTypes":[] }, {"name":"getShardingItemParameters","parameterTypes":[] }, {"name":"getShardingTotalCount","parameterTypes":[] }, {"name":"getTimeZone","parameterTypes":[] }, {"name":"isDisabled","parameterTypes":[] }, {"name":"isFailover","parameterTypes":[] }, {"name":"isMisfire","parameterTypes":[] }, {"name":"isMonitorExecution","parameterTypes":[] }, {"name":"isOverwrite","parameterTypes":[] }, {"name":"isStaticSharding","parameterTypes":[] }, {"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setDescription","parameterTypes":["java.lang.String"] }, {"name":"setDisabled","parameterTypes":["boolean"] }, {"name":"setFailover","parameterTypes":["boolean"] }, {"name":"setJobExtraConfigurations","parameterTypes":["java.util.Collection"] }, {"name":"setJobName","parameterTypes":["java.lang.String"] }, {"name":"setJobParameter","parameterTypes":["java.lang.String"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }] }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.failover.FailoverListenerManager"}, @@ -98,15 +99,36 @@ "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ExecutionContextService"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", - "queryAllPublicMethods":true + "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ExecutionService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", + "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ListenServersChangedJobListener"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }] }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setCron","parameterTypes":["java.lang.String"] }, {"name":"setDescription","parameterTypes":["java.lang.String"] }, {"name":"setDisabled","parameterTypes":["boolean"] }, {"name":"setFailover","parameterTypes":["boolean"] }, {"name":"setJobExtraConfigurations","parameterTypes":["java.util.Collection"] }, {"name":"setJobName","parameterTypes":["java.lang.String"] }, {"name":"setJobParameter","parameterTypes":["java.lang.String"] }, {"name":"setMaxTimeDiffSeconds","parameterTypes":["int"] }, {"name":"setMisfire","parameterTypes":["boolean"] }, {"name":"setMonitorExecution","parameterTypes":["boolean"] }, {"name":"setOverwrite","parameterTypes":["boolean"] }, {"name":"setProps","parameterTypes":["java.util.Properties"] }, {"name":"setReconcileIntervalMinutes","parameterTypes":["int"] }, {"name":"setShardingItemParameters","parameterTypes":["java.lang.String"] }, {"name":"setShardingTotalCount","parameterTypes":["int"] }, {"name":"setStaticSharding","parameterTypes":["boolean"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", + "methods":[{"name":"setCron","parameterTypes":["java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJO", + "queryAllPublicMethods":true +}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJOBeanInfo" @@ -115,22 +137,20 @@ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.config.JobConfigurationPOJOCustomizer" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin", - "queryAllPublicMethods":true -}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin", - "queryAllPublicMethods":true + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin", - "queryAllPublicMethods":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"setCleanShutdown","parameterTypes":["boolean"] }] }, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPlugin", + "queryAllPublicMethods":true +}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPluginBeanInfo" @@ -139,15 +159,9 @@ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobShutdownHookPluginCustomizer" }, -{ - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance", - "queryAllPublicMethods":true -}, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance", - "queryAllPublicMethods":true + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceNode"}, @@ -157,16 +171,20 @@ }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.instance.InstanceService"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance" + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, {"name":"setServerIp","parameterTypes":["java.lang.String"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.schedule.JobScheduler"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance", - "queryAllPublicMethods":true + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setJobInstanceId","parameterTypes":["java.lang.String"] }, {"name":"setServerIp","parameterTypes":["java.lang.String"] }] }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.SetUpFacade"}, - "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance" + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstance", + "queryAllPublicMethods":true }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, @@ -177,7 +195,28 @@ "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.JobInstanceCustomizer" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.AverageAllocationJobShardingStrategy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.OdevitySortByNameJobShardingStrategy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.type.RoundRobinByNameJobShardingStrategy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"}, + "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setTracingStorageConfiguration","parameterTypes":["org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingStorageConfiguration"] }, {"name":"setType","parameterTypes":["java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"}, "name":"org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingConfiguration", "allDeclaredFields":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"setTracingStorageConfiguration","parameterTypes":["org.apache.shardingsphere.elasticjob.kernel.tracing.yaml.YamlTracingStorageConfiguration"] }, {"name":"setType","parameterTypes":["java.lang.String"] }] @@ -191,7 +230,7 @@ "name":"org.apache.shardingsphere.elasticjob.reg.zookeeper.exception.ZookeeperCuratorIgnoredExceptionProvider" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "name":"org.apache.shardingsphere.elasticjob.script.executor.ScriptJobExecutor" }, { @@ -199,17 +238,21 @@ "name":"org.apache.shardingsphere.elasticjob.simple.executor.SimpleJobExecutor" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "name":"org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListener", "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProviderFactory"}, + "name":"org.apache.shardingsphere.elasticjob.spring.core.setup.SpringProxyJobClassNameProvider" +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListener", "queryAllDeclaredMethods":true }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.listener.RDBTracingListenerFactory" }, { @@ -241,7 +284,13 @@ "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.type.impl.SQLServerTracingStorageDatabaseType" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.infra.yaml.YamlEngine"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.config.ConfigurationService"}, + "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.yaml.YamlDataSourceConfiguration", + "allDeclaredFields":true, + "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSourceClassName","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Map"] }] +}, +{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingListenerManager$ShardingTotalCountChangedJobListener"}, "name":"org.apache.shardingsphere.elasticjob.tracing.rdb.yaml.YamlDataSourceConfiguration", "allDeclaredFields":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"setDataSourceClassName","parameterTypes":["java.lang.String"] }, {"name":"setProps","parameterTypes":["java.util.Map"] }] diff --git a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json index 101e57e2fc..7fe2417552 100644 --- a/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json +++ b/reachability-metadata/src/main/resources/META-INF/native-image/org.apache.shardingsphere.elasticjob/generated-reachability-metadata/resource-config.json @@ -1,25 +1,31 @@ { "resources":{ "includes":[{ + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"}, + "pattern":"\\QMETA-INF/services/java.sql.Driver\\E" + }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.ExecutorServiceReloader"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.executor.threadpool.JobExecutorThreadPoolSizeProvider\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProviderFactory"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.internal.setup.JobClassNameProvider\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.internal.sharding.ShardingService"}, + "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.kernel.internal.sharding.strategy.JobShardingStrategy\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.reg.exception.RegExceptionHandler"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.reg.exception.IgnoredExceptionProvider\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.error.handler.JobErrorHandler\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.item.JobItemExecutorFactory"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.item.type.ClassedJobItemExecutor\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.executor.ElasticJobExecutor"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.executor.item.type.TypedJobItemExecutor\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.event.JobTracingEventBus"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "pattern":"\\QMETA-INF/services/org.apache.shardingsphere.elasticjob.spi.tracing.listener.TracingListenerFactory\\E" }, { "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.kernel.tracing.storage.TracingStorageConverterFactory"}, @@ -34,7 +40,10 @@ "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.tracing.rdb.storage.sql.SQLPropertiesFactory"}, "pattern":"\\QMETA-INF/sql/H2.properties\\E" }, { - "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.bootstrap.type.ScheduleJobBootstrap"}, + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.tracing.ElasticJobTracingConfiguration$RDBTracingConfiguration"}, + "pattern":"\\Qorg/h2/util/data.zip\\E" + }, { + "condition":{"typeReachable":"org.apache.shardingsphere.elasticjob.spring.boot.job.ElasticJobBootstrapConfiguration"}, "pattern":"\\Qorg/quartz/core/quartz-build.properties\\E" }]}, "bundles":[] diff --git a/spring/boot-starter/pom.xml b/spring/boot-starter/pom.xml index 7fa77d5704..f685104a77 100644 --- a/spring/boot-starter/pom.xml +++ b/spring/boot-starter/pom.xml @@ -42,6 +42,7 @@ org.springframework.boot spring-boot-starter + true org.springframework.boot diff --git a/test/native/native-image-filter/extra-filter.json b/test/native/native-image-filter/extra-filter.json index 9e706a39d4..fdf91f4da0 100644 --- a/test/native/native-image-filter/extra-filter.json +++ b/test/native/native-image-filter/extra-filter.json @@ -2,13 +2,12 @@ "rules": [ {"includeClasses": "**"}, - {"excludeClasses": "com.google.common.util.concurrent.**"}, - {"excludeClasses": "com.zaxxer.hikari.**"}, + {"excludeClasses": "com.**"}, {"excludeClasses": "java.**"}, {"includeClasses": "java.util.Properties"}, - {"excludeClasses": "org.apache.zookeeper.**"}, - {"excludeClasses": "org.quartz.**"}, - {"excludeClasses": "sun.misc.**"}, + {"excludeClasses": "org.**"}, + {"includeClasses": "org.apache.shardingsphere.elasticjob.**"}, + {"excludeClasses": "sun.**"}, {"excludeClasses": "org.apache.shardingsphere.elasticjob.test.natived.**"} ], diff --git a/test/native/pom.xml b/test/native/pom.xml index 459222a528..f3cca8f28e 100644 --- a/test/native/pom.xml +++ b/test/native/pom.xml @@ -28,12 +28,14 @@ true + 2.0.7 + 1.4.14 org.apache.shardingsphere.elasticjob - elasticjob-bootstrap + elasticjob-spring-boot-starter ${project.version} test @@ -53,6 +55,24 @@ curator-test test + + org.springframework.boot + spring-boot-starter-jdbc + ${spring-boot-dependencies.version} + test + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot-dependencies.version} + test + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot-dependencies.version} + test + @@ -62,6 +82,11 @@ native-maven-plugin ${native-maven-plugin.version} + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-dependencies.version} + diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.java new file mode 100644 index 0000000000..e62b3d87b5 --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/ElasticJobSpringBootStarterApplication.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.test.natived; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ElasticJobSpringBootStarterApplication { + + // CHECKSTYLE:OFF + public static void main(final String[] args) { + // CHECKSTYLE:ON + SpringApplication.run(ElasticJobSpringBootStarterApplication.class, args); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java index 1abcead7ef..8b8212854c 100644 --- a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/JavaTest.java @@ -157,7 +157,7 @@ void testScriptJob() { ScheduleJobBootstrap jobBootstrap = new ScheduleJobBootstrap(regCenter, "SCRIPT", JobConfiguration.newBuilder("scriptElasticJob", 3) .cron("0/5 * * * * ?") - .setProperty(ScriptJobProperties.SCRIPT_KEY, Paths.get("src/test/resources/script/demo.sh").toString()) + .setProperty(ScriptJobProperties.SCRIPT_KEY, Paths.get("src/test/resources/test-native/sh/demo.sh").toString()) .addExtraConfigurations(tracingConfig) .build()); assertDoesNotThrow(() -> { diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java new file mode 100644 index 0000000000..73e6d9752d --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/SpirngBootTest.java @@ -0,0 +1,108 @@ +/* + * 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.test.natived; + +import org.apache.curator.CuratorZookeeperClient; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.test.TestingServer; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledInNativeImage; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.time.Duration; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +@SpringBootTest( + classes = ElasticJobSpringBootStarterApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = "classpath:application.yml") +@EnabledInNativeImage +public class SpirngBootTest { + + private static TestingServer testingServer; + + private MockMvc mockMvc; + + @BeforeAll + static void beforeAll() throws Exception { + testingServer = new TestingServer(6181); + try ( + CuratorZookeeperClient client = new CuratorZookeeperClient(testingServer.getConnectString(), + 60 * 1000, 500, null, + new ExponentialBackoffRetry(500, 3, 500 * 3))) { + client.start(); + Awaitility.await().atMost(Duration.ofMillis(500 * 60)).until(client::isConnected); + } + } + + @AfterAll + static void afterAll() throws IOException { + testingServer.close(); + } + + @BeforeEach + void setup(final WebApplicationContext webApplicationContext) { + this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) + .defaultResponseCharacterEncoding(StandardCharsets.UTF_8) + .build(); + } + + @DynamicPropertySource + static void elasticjobProperties(final DynamicPropertyRegistry registry) { + registry.add("elasticjob.regCenter.serverLists", () -> testingServer.getConnectString()); + } + + /** + * ElasticJob Spring Boot Starter requires that all Spring Boot Applications be shut down before shutting down Zookeeper Server. + * That's why this unit test uses {@link DirtiesContext}. + * Refer to spring-projects/spring-framework#26196 . + */ + @DirtiesContext + @Test + public void testOneOffJob() throws Exception { + String contentAsString = mockMvc.perform( + MockMvcRequestBuilders.get("/execute/manualScriptJob") + .characterEncoding(StandardCharsets.UTF_8)) + .andDo(MockMvcResultHandlers.print()) + .andExpectAll( + MockMvcResultMatchers.status().isOk(), + MockMvcResultMatchers.content().encoding(StandardCharsets.UTF_8)) + .andReturn() + .getResponse() + .getContentAsString(); + assertThat(contentAsString, is("{\"msg\":\"OK\"}")); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java new file mode 100644 index 0000000000..64a6be94ed --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/controller/OneOffJobController.java @@ -0,0 +1,52 @@ +/* + * 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.test.natived.commons.controller; + +import org.apache.shardingsphere.elasticjob.bootstrap.type.OneOffJobBootstrap; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Objects; + +@RestController +public class OneOffJobController { + + private static final String RES_TEXT = "{\"msg\":\"OK\"}"; + + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") + @Autowired + @Qualifier("manualScriptJobBean") + private ObjectProvider manualScriptJobProvider; + + /** + * Execute manual script job. + * + * @return a String + */ + @GetMapping("/execute/manualScriptJob") + public String executeManualScriptJob() { + OneOffJobBootstrap manualScriptJob = manualScriptJobProvider.getIfAvailable(); + Objects.requireNonNull(manualScriptJob); + manualScriptJob.execute(); + manualScriptJob.shutdown(); + return RES_TEXT; + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java new file mode 100644 index 0000000000..992ca14dca --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/dataflow/SpringBootDataflowJob.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow; + +import org.apache.shardingsphere.elasticjob.dataflow.job.DataflowJob; +import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext; +import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo; +import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.SpringBootFooRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.invoke.MethodHandles; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +@SuppressWarnings("LoggingSimilarMessage") +@Component +public class SpringBootDataflowJob implements DataflowJob { + + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Autowired + private SpringBootFooRepository springBootFooRepository; + + @Override + public List fetchData(final ShardingContext shardingContext) { + logger.info("Item: {} | Time: {} | Thread: {} | {}", + shardingContext.getShardingItem(), + new SimpleDateFormat("HH:mm:ss").format(new Date()), + Thread.currentThread().getId(), + "DATAFLOW FETCH"); + return springBootFooRepository.findTodoData(shardingContext.getShardingParameter(), 10); + } + + @Override + public void processData(final ShardingContext shardingContext, final List data) { + logger.info("Item: {} | Time: {} | Thread: {} | {}", + shardingContext.getShardingItem(), + new SimpleDateFormat("HH:mm:ss").format(new Date()), + Thread.currentThread().getId(), + "DATAFLOW PROCESS"); + data.forEach(each -> springBootFooRepository.setCompleted(each.getId())); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.java new file mode 100644 index 0000000000..1185636d26 --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/job/simple/SpringBootSimpleJob.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.test.natived.commons.job.simple; + +import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob; +import org.apache.shardingsphere.elasticjob.spi.executor.item.param.ShardingContext; +import org.apache.shardingsphere.elasticjob.test.natived.commons.repository.SpringBootFooRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.invoke.MethodHandles; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SpringBootSimpleJob implements SimpleJob { + + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Autowired + private SpringBootFooRepository springBootFooRepository; + + @Override + public void execute(final ShardingContext shardingContext) { + logger.info( + "Item: {} | Time: {} | Thread: {} | {}", + shardingContext.getShardingItem(), + new SimpleDateFormat("HH:mm:ss").format(new Date()), + Thread.currentThread().getId(), + "SIMPLE"); + springBootFooRepository.findTodoData(shardingContext.getShardingParameter(), 10) + .forEach(each -> springBootFooRepository.setCompleted(each.getId())); + } +} diff --git a/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java new file mode 100644 index 0000000000..cafe2bb023 --- /dev/null +++ b/test/native/src/test/java/org/apache/shardingsphere/elasticjob/test/natived/commons/repository/SpringBootFooRepository.java @@ -0,0 +1,74 @@ +/* + * 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.test.natived.commons.repository; + +import org.apache.shardingsphere.elasticjob.test.natived.commons.entity.Foo; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.LongStream; + +@Repository +public class SpringBootFooRepository { + + private final Map data = new ConcurrentHashMap<>(300, 1); + + public SpringBootFooRepository() { + addData(0L, 100L, "Beijing"); + addData(100L, 200L, "Shanghai"); + addData(200L, 300L, "Guangzhou"); + } + + private void addData(final long idFrom, final long idTo, final String location) { + LongStream.range(idFrom, idTo) + .forEachOrdered(i -> data.put(i, new Foo(i, location, Foo.Status.TODO))); + } + + /** + * Find todoData. + * @param location location + * @param limit limit + * @return An ordered collection, where the user has precise control over where in the list each element is inserted. + */ + public List findTodoData(final String location, final int limit) { + List result = new ArrayList<>(limit); + int count = 0; + for (Map.Entry each : data.entrySet()) { + Foo foo = each.getValue(); + if (foo.getLocation().equals(location) && foo.getStatus() == Foo.Status.TODO) { + result.add(foo); + count++; + if (count == limit) { + break; + } + } + } + return result; + } + + /** + * Set completed. + * @param id id + */ + public void setCompleted(final long id) { + data.get(id).setStatus(Foo.Status.COMPLETED); + } +} diff --git a/test/native/src/test/resources/application.yml b/test/native/src/test/resources/application.yml new file mode 100644 index 0000000000..1a99cecae9 --- /dev/null +++ b/test/native/src/test/resources/application.yml @@ -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. +# + +spring: + datasource: + url: jdbc:h2:mem:job_event_storage + driver-class-name: org.h2.Driver + username: sa + password: + +elasticjob: + tracing: + type: RDB + # `elasticjob.regCenter.serverLists` is dynamically defined in `org.apache.shardingsphere.elasticjob.test.natived.SpirngBootTest` + regCenter: + namespace: elasticjob-springboot + jobs: + simpleJob: + elasticJobClass: org.apache.shardingsphere.elasticjob.test.natived.commons.job.simple.SpringBootSimpleJob + cron: 0/5 * * * * ? + shardingTotalCount: 3 + shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou + dataflowJob: + elasticJobClass: org.apache.shardingsphere.elasticjob.test.natived.commons.job.dataflow.SpringBootDataflowJob + cron: 0/5 * * * * ? + shardingTotalCount: 3 + shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou + scriptJob: + elasticJobType: SCRIPT + cron: 0/10 * * * * ? + shardingTotalCount: 3 + props: + script.command.line: "echo SCRIPT Job: " + manualScriptJob: + elasticJobType: SCRIPT + jobBootstrapBeanName: manualScriptJobBean + shardingTotalCount: 9 + props: + script.command.line: "echo Manual SCRIPT Job: " + dump: + port: 9888 diff --git a/test/native/src/test/resources/script/demo.sh b/test/native/src/test/resources/test-native/sh/demo.sh similarity index 100% rename from test/native/src/test/resources/script/demo.sh rename to test/native/src/test/resources/test-native/sh/demo.sh