You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2021/08/08 02:12:08 UTC

[shardingsphere-elasticjob] branch master updated: support timezone (#1955)

This is an automated email from the ASF dual-hosted git repository.

wuweijie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git


The following commit(s) were added to refs/heads/master by this push:
     new c63c9aa  support timezone (#1955)
c63c9aa is described below

commit c63c9aa586dae2aeef61a7e565d724321cf4d593
Author: skai <su...@gmail.com>
AuthorDate: Sun Aug 8 10:12:02 2021 +0800

    support timezone (#1955)
    
    * support timezone
    
    * using `Preconditions` to check the param && Use static import for `ArgumentMatchers.any`
    
    * remove the redundant line.
    
    Co-authored-by: 蔡顺铠 <sk...@gmail.com>
---
 .../elasticjob/api/JobConfiguration.java           | 19 ++++++++++++-
 .../elasticjob/api/JobConfigurationTest.java       |  5 +++-
 .../infra/pojo/JobConfigurationPOJO.java           |  5 +++-
 .../api/bootstrap/impl/ScheduleJobBootstrap.java   |  2 +-
 .../internal/config/RescheduleListenerManager.java |  2 +-
 .../internal/schedule/JobScheduleController.java   | 32 ++++++++++++++++++----
 .../config/RescheduleListenerManagerTest.java      |  9 +++---
 .../schedule/JobScheduleControllerTest.java        |  8 +++---
 .../job/parser/JobBeanDefinitionParser.java        |  2 ++
 9 files changed, 65 insertions(+), 19 deletions(-)

diff --git a/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
index d927a93..0fe7ab4 100644
--- a/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
+++ b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
@@ -41,6 +41,8 @@ public final class JobConfiguration {
     
     private final String cron;
     
+    private final String timeZone;
+    
     private final int shardingTotalCount;
     
     private final String shardingItemParameters;
@@ -97,6 +99,8 @@ public final class JobConfiguration {
         
         private String cron;
         
+        private String timeZone;
+        
         private final int shardingTotalCount;
         
         private String shardingItemParameters = "";
@@ -147,6 +151,19 @@ public final class JobConfiguration {
             }
             return this;
         }
+    
+        /**
+         * time zone.
+         *
+         * @param timeZone the time zone
+         * @return job configuration builder
+         */
+        public Builder timeZone(final String timeZone) {
+            if (null != timeZone) {
+                this.timeZone = timeZone;
+            }
+            return this;
+        }
         
         /**
          * Set mapper of sharding items and sharding parameters.
@@ -404,7 +421,7 @@ public final class JobConfiguration {
         public final JobConfiguration build() {
             Preconditions.checkArgument(!Strings.isNullOrEmpty(jobName), "jobName can not be empty.");
             Preconditions.checkArgument(shardingTotalCount > 0, "shardingTotalCount should larger than zero.");
-            return new JobConfiguration(jobName, cron, shardingTotalCount, shardingItemParameters, jobParameter, 
+            return new JobConfiguration(jobName, cron, timeZone, shardingTotalCount, shardingItemParameters, jobParameter,
                     monitorExecution, failover, misfire, maxTimeDiffSeconds, reconcileIntervalMinutes,
                     jobShardingStrategyType, jobExecutorServiceHandlerType, jobErrorHandlerType, jobListenerTypes,
                     extraConfigurations, description, props, disabled, overwrite, label, staticSharding);
diff --git a/elasticjob-api/src/test/java/org/apache/shardingsphere/elasticjob/api/JobConfigurationTest.java b/elasticjob-api/src/test/java/org/apache/shardingsphere/elasticjob/api/JobConfigurationTest.java
index a1e85ef..5fdd702 100644
--- a/elasticjob-api/src/test/java/org/apache/shardingsphere/elasticjob/api/JobConfigurationTest.java
+++ b/elasticjob-api/src/test/java/org/apache/shardingsphere/elasticjob/api/JobConfigurationTest.java
@@ -31,6 +31,7 @@ public final class JobConfigurationTest {
     public void assertBuildAllProperties() {
         JobConfiguration actual = JobConfiguration.newBuilder("test_job", 3)
                 .cron("0/1 * * * * ?")
+                .timeZone("GMT+8")
                 .shardingItemParameters("0=a,1=b,2=c").jobParameter("param")
                 .monitorExecution(false).failover(true).misfire(false)
                 .maxTimeDiffSeconds(1000).reconcileIntervalMinutes(60)
@@ -39,6 +40,7 @@ public final class JobConfigurationTest {
                 .disabled(true).overwrite(true).build();
         assertThat(actual.getJobName(), is("test_job"));
         assertThat(actual.getCron(), is("0/1 * * * * ?"));
+        assertThat(actual.getTimeZone(), is("GMT+8"));
         assertThat(actual.getShardingTotalCount(), is(3));
         assertThat(actual.getShardingItemParameters(), is("0=a,1=b,2=c"));
         assertThat(actual.getJobParameter(), is("param"));
@@ -58,9 +60,10 @@ public final class JobConfigurationTest {
     
     @Test
     public void assertBuildRequiredProperties() {
-        JobConfiguration actual = JobConfiguration.newBuilder("test_job", 3).cron("0/1 * * * * ?").build();
+        JobConfiguration actual = JobConfiguration.newBuilder("test_job", 3).cron("0/1 * * * * ?").timeZone("GMT+8").build();
         assertThat(actual.getJobName(), is("test_job"));
         assertThat(actual.getCron(), is("0/1 * * * * ?"));
+        assertThat(actual.getTimeZone(), is("GMT+8"));
         assertThat(actual.getShardingTotalCount(), is(3));
         assertThat(actual.getShardingItemParameters(), is(""));
         assertThat(actual.getJobParameter(), is(""));
diff --git a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/pojo/JobConfigurationPOJO.java b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/pojo/JobConfigurationPOJO.java
index dce1fb6..3cdfd35 100644
--- a/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/pojo/JobConfigurationPOJO.java
+++ b/elasticjob-infra/elasticjob-infra-common/src/main/java/org/apache/shardingsphere/elasticjob/infra/pojo/JobConfigurationPOJO.java
@@ -41,6 +41,8 @@ public final class JobConfigurationPOJO {
     
     private String cron;
     
+    private String timeZone;
+    
     private int shardingTotalCount;
     
     private String shardingItemParameters;
@@ -86,7 +88,7 @@ public final class JobConfigurationPOJO {
      */
     public JobConfiguration toJobConfiguration() {
         JobConfiguration result = JobConfiguration.newBuilder(jobName, shardingTotalCount)
-                .cron(cron).shardingItemParameters(shardingItemParameters).jobParameter(jobParameter)
+                .cron(cron).timeZone(timeZone).shardingItemParameters(shardingItemParameters).jobParameter(jobParameter)
                 .monitorExecution(monitorExecution).failover(failover).misfire(misfire)
                 .maxTimeDiffSeconds(maxTimeDiffSeconds).reconcileIntervalMinutes(reconcileIntervalMinutes)
                 .jobShardingStrategyType(jobShardingStrategyType).jobExecutorServiceHandlerType(jobExecutorServiceHandlerType)
@@ -110,6 +112,7 @@ public final class JobConfigurationPOJO {
         JobConfigurationPOJO result = new JobConfigurationPOJO();
         result.setJobName(jobConfiguration.getJobName());
         result.setCron(jobConfiguration.getCron());
+        result.setTimeZone(jobConfiguration.getTimeZone());
         result.setShardingTotalCount(jobConfiguration.getShardingTotalCount());
         result.setShardingItemParameters(jobConfiguration.getShardingItemParameters());
         result.setJobParameter(jobConfiguration.getJobParameter());
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
index 2dba62b..bb49199 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
@@ -45,7 +45,7 @@ public final class ScheduleJobBootstrap implements JobBootstrap {
      */
     public void schedule() {
         Preconditions.checkArgument(!Strings.isNullOrEmpty(jobScheduler.getJobConfig().getCron()), "Cron can not be empty.");
-        jobScheduler.getJobScheduleController().scheduleJob(jobScheduler.getJobConfig().getCron());
+        jobScheduler.getJobScheduleController().scheduleJob(jobScheduler.getJobConfig().getCron(), jobScheduler.getJobConfig().getTimeZone());
     }
     
     @Override
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManager.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManager.java
index c9dbc5a..04fe773 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManager.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManager.java
@@ -55,7 +55,7 @@ public final class RescheduleListenerManager extends AbstractListenerManager {
                 if (StringUtils.isEmpty(jobConfiguration.getCron())) {
                     JobRegistry.getInstance().getJobScheduleController(jobName).rescheduleJob();
                 } else {
-                    JobRegistry.getInstance().getJobScheduleController(jobName).rescheduleJob(jobConfiguration.getCron());
+                    JobRegistry.getInstance().getJobScheduleController(jobName).rescheduleJob(jobConfiguration.getCron(), jobConfiguration.getTimeZone());
                 }
             }
         }
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleController.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleController.java
index 09679ae..df69b6b 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleController.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleController.java
@@ -17,6 +17,8 @@
 
 package org.apache.shardingsphere.elasticjob.lite.internal.schedule;
 
+import com.google.common.base.Preconditions;
+import java.util.TimeZone;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
 import org.quartz.CronScheduleBuilder;
@@ -46,11 +48,12 @@ public final class JobScheduleController {
      * Schedule job.
      * 
      * @param cron CRON expression
+     * @param timeZone the time zone
      */
-    public void scheduleJob(final String cron) {
+    public void scheduleJob(final String cron, final String timeZone) {
         try {
             if (!scheduler.checkExists(jobDetail.getKey())) {
-                scheduler.scheduleJob(jobDetail, createCronTrigger(cron));
+                scheduler.scheduleJob(jobDetail, createCronTrigger(cron, timeZone));
             }
             scheduler.start();
         } catch (final SchedulerException ex) {
@@ -62,12 +65,13 @@ public final class JobScheduleController {
      * Reschedule job.
      * 
      * @param cron CRON expression
+     * @param timeZone the time zone
      */
-    public synchronized void rescheduleJob(final String cron) {
+    public synchronized void rescheduleJob(final String cron, final String timeZone) {
         try {
             CronTrigger trigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(triggerIdentity));
             if (!scheduler.isShutdown() && null != trigger && !cron.equals(trigger.getCronExpression())) {
-                scheduler.rescheduleJob(TriggerKey.triggerKey(triggerIdentity), createCronTrigger(cron));
+                scheduler.rescheduleJob(TriggerKey.triggerKey(triggerIdentity), createCronTrigger(cron, timeZone));
             }
         } catch (final SchedulerException ex) {
             throw new JobSystemException(ex);
@@ -88,8 +92,24 @@ public final class JobScheduleController {
         }
     }
     
-    private Trigger createCronTrigger(final String cron) {
-        return TriggerBuilder.newTrigger().withIdentity(triggerIdentity).withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()).build();
+    private Trigger createCronTrigger(final String cron, final String timeZoneString) {
+        return TriggerBuilder.newTrigger().withIdentity(triggerIdentity).withSchedule(
+                CronScheduleBuilder.cronSchedule(cron).inTimeZone(parseTimeZoneString(timeZoneString)).withMisfireHandlingInstructionDoNothing()
+        ).build();
+    }
+
+    /**
+     * Get the TimeZone for the time zone specification.
+     *
+     * @param timeZoneString must start with "GMT", such as "GMT+8:00"
+     * @return the specified TimeZone, or the GMT zone if the `timeZoneString` cannot be understood.
+     */
+    private TimeZone parseTimeZoneString(final String timeZoneString) {
+        if (null == timeZoneString) {
+            return TimeZone.getDefault();
+        }
+        Preconditions.checkArgument(!timeZoneString.startsWith("GMT"), "Invalid time zone specification '%s'.", timeZoneString);
+        return TimeZone.getTimeZone(timeZoneString);
     }
     
     /**
diff --git a/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManagerTest.java b/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManagerTest.java
index 8dfba56..68be1f0 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManagerTest.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/config/RescheduleListenerManagerTest.java
@@ -34,6 +34,7 @@ import org.mockito.junit.MockitoJUnitRunner;
 
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.ArgumentMatchers.any;
 
 @RunWith(MockitoJUnitRunner.class)
 public final class RescheduleListenerManagerTest {
@@ -63,19 +64,19 @@ public final class RescheduleListenerManagerTest {
     @Test
     public void assertCronSettingChangedJobListenerWhenIsNotCronPath() {
         rescheduleListenerManager.new CronSettingAndJobEventChangedJobListener().dataChanged("/test_job/config/other", Type.NODE_CREATED, LiteYamlConstants.getJobYaml());
-        verify(jobScheduleController, times(0)).rescheduleJob(ArgumentMatchers.any());
+        verify(jobScheduleController, times(0)).rescheduleJob(any(), any());
     }
     
     @Test
     public void assertCronSettingChangedJobListenerWhenIsCronPathButNotUpdate() {
         rescheduleListenerManager.new CronSettingAndJobEventChangedJobListener().dataChanged("/test_job/config", Type.NODE_CREATED, LiteYamlConstants.getJobYaml());
-        verify(jobScheduleController, times(0)).rescheduleJob(ArgumentMatchers.any());
+        verify(jobScheduleController, times(0)).rescheduleJob(any(), any());
     }
     
     @Test
     public void assertCronSettingChangedJobListenerWhenIsCronPathAndUpdateButCannotFindJob() {
         rescheduleListenerManager.new CronSettingAndJobEventChangedJobListener().dataChanged("/test_job/config", Type.NODE_CHANGED, LiteYamlConstants.getJobYaml());
-        verify(jobScheduleController, times(0)).rescheduleJob(ArgumentMatchers.any());
+        verify(jobScheduleController, times(0)).rescheduleJob(any(), any());
     }
     
     @Test
@@ -84,7 +85,7 @@ public final class RescheduleListenerManagerTest {
         JobRegistry.getInstance().registerRegistryCenter("test_job", regCenter);
         JobRegistry.getInstance().registerJob("test_job", jobScheduleController);
         rescheduleListenerManager.new CronSettingAndJobEventChangedJobListener().dataChanged("/test_job/config", Type.NODE_CHANGED, LiteYamlConstants.getJobYaml());
-        verify(jobScheduleController).rescheduleJob("0/1 * * * * ?");
+        verify(jobScheduleController).rescheduleJob("0/1 * * * * ?", null);
         JobRegistry.getInstance().shutdown("test_job");
     }
 }
diff --git a/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleControllerTest.java b/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleControllerTest.java
index f6b4b45..459e012 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleControllerTest.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/test/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduleControllerTest.java
@@ -223,7 +223,7 @@ public final class JobScheduleControllerTest {
     public void assertRescheduleJobIfShutdown() throws SchedulerException {
         ReflectionUtils.setFieldValue(jobScheduleController, "scheduler", scheduler);
         when(scheduler.isShutdown()).thenReturn(true);
-        jobScheduleController.rescheduleJob("0/1 * * * * ?");
+        jobScheduleController.rescheduleJob("0/1 * * * * ?", null);
         verify(scheduler, times(0)).rescheduleJob(eq(TriggerKey.triggerKey("test_job_Trigger")), any());
     }
     
@@ -233,7 +233,7 @@ public final class JobScheduleControllerTest {
         doThrow(SchedulerException.class).when(scheduler).rescheduleJob(eq(TriggerKey.triggerKey("test_job_Trigger")), any());
         ReflectionUtils.setFieldValue(jobScheduleController, "scheduler", scheduler);
         try {
-            jobScheduleController.rescheduleJob("0/1 * * * * ?");
+            jobScheduleController.rescheduleJob("0/1 * * * * ?", null);
         } finally {
             verify(scheduler).rescheduleJob(eq(TriggerKey.triggerKey("test_job_Trigger")), any());
         }
@@ -243,14 +243,14 @@ public final class JobScheduleControllerTest {
     public void assertRescheduleJobSuccess() throws SchedulerException {
         when(scheduler.getTrigger(TriggerKey.triggerKey("test_job_Trigger"))).thenReturn(new CronTriggerImpl());
         ReflectionUtils.setFieldValue(jobScheduleController, "scheduler", scheduler);
-        jobScheduleController.rescheduleJob("0/1 * * * * ?");
+        jobScheduleController.rescheduleJob("0/1 * * * * ?", null);
         verify(scheduler).rescheduleJob(eq(TriggerKey.triggerKey("test_job_Trigger")), any());
     }
     
     @Test
     public void assertRescheduleJobWhenTriggerIsNull() throws SchedulerException {
         ReflectionUtils.setFieldValue(jobScheduleController, "scheduler", scheduler);
-        jobScheduleController.rescheduleJob("0/1 * * * * ?");
+        jobScheduleController.rescheduleJob("0/1 * * * * ?", null);
         verify(scheduler, times(0)).rescheduleJob(eq(TriggerKey.triggerKey("test_job_Trigger")), any());
     }
     
diff --git a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
index e532d69..87166e7 100644
--- a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
+++ b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
@@ -66,6 +66,8 @@ public final class JobBeanDefinitionParser extends AbstractBeanDefinitionParser
         BeanDefinitionBuilder result = BeanDefinitionBuilder.rootBeanDefinition(JobConfiguration.class);
         result.addConstructorArgValue(element.getAttribute(ID_ATTRIBUTE));
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.CRON_ATTRIBUTE));
+        //TODO Need support the timeZone
+        result.addConstructorArgValue(null);
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.SHARDING_TOTAL_COUNT_ATTRIBUTE));
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.SHARDING_ITEM_PARAMETERS_ATTRIBUTE));
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.JOB_PARAMETER_ATTRIBUTE));