Skip to content

Commit 623bcfe

Browse files
committed
Fixed a bug in cron and daily interval trigger caused by missing serialized timezone
1 parent 36ad28b commit 623bcfe

File tree

7 files changed

+132
-17
lines changed

7 files changed

+132
-17
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Linq;
3+
4+
using Machine.Specifications;
5+
6+
using Quartz.Impl.Triggers;
7+
using Quartz.Spi;
8+
9+
namespace Quartz.Impl.MongoDB.Tests
10+
{
11+
public class CronTriggerSpecs
12+
{
13+
public class When_a_cron_trigger_with_a_daily_schedule_at_5_o_clock_german_local_time_is_retrieved_from_the_job_store
14+
{
15+
private Establish context = () =>
16+
{
17+
expectedTimeZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
18+
SystemTime.UtcNow = () => new DateTimeOffset(new DateTime(2012, 12, 12, 8, 0, 0));
19+
var tomorrow = new DateTime(2012, 12, 13, 5, 0, 0);
20+
expectedNextFireTime = new DateTimeOffset(tomorrow, expectedTimeZone.GetUtcOffset(tomorrow));
21+
22+
jobStore = new JobStore();
23+
jobStore.ClearAllSchedulingData();
24+
25+
trigger =
26+
TriggerBuilder.Create()
27+
.ForJob(jobKey)
28+
.WithCronSchedule("0 0 5 ? * *", x => x.InTimeZone(expectedTimeZone))
29+
.Build();
30+
jobDetail = JobBuilder.Create<TestJob>().WithIdentity("test").Build();
31+
jobStore.StoreJobAndTrigger(jobDetail, (IOperableTrigger)trigger);
32+
};
33+
34+
private Because of =
35+
() => retrievedCronTrigger = (CronTriggerImpl)jobStore.GetTriggersForJob(jobKey).Single();
36+
37+
private It should_still_be_configured_for_the_german_time_zone = () => retrievedCronTrigger.TimeZone.ShouldEqual(expectedTimeZone);
38+
39+
private It should_schedule_the_trigger_next_time_on_5_o_clock_german_local_time = () =>
40+
{
41+
retrievedCronTrigger.Triggered(null);
42+
var nextFireTimeUtc = retrievedCronTrigger.GetNextFireTimeUtc();
43+
nextFireTimeUtc.ShouldEqual(expectedNextFireTime);
44+
};
45+
46+
private static JobStore jobStore;
47+
48+
private static ITrigger trigger;
49+
50+
private static IJobDetail jobDetail;
51+
52+
private static TimeZoneInfo expectedTimeZone;
53+
54+
private static JobKey jobKey = new JobKey("test");
55+
56+
private static CronTriggerImpl retrievedCronTrigger;
57+
58+
private static DateTimeOffset expectedNextFireTime;
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1-
using Machine.Specifications;
1+
using System;
2+
3+
using Machine.Specifications;
24
namespace Quartz.Impl.MongoDB.Tests
35
{
4-
using System;
5-
using System.Collections.Specialized;
6-
using System.Diagnostics;
76
using System.Linq;
8-
using System.Threading;
9-
10-
using Common.Logging.Simple;
117

128
using Quartz.Spi;
139

14-
public class TriggerSpecs
10+
public class DailyIntervalTriggerSpecs
1511
{
1612
public class When_a_daily_interval_trigger_has_been_stored_in_the_mongo_db
1713
{
1814
private Establish context = () =>
1915
{
2016
jobStore = new JobStore();
2117
jobStore.ClearAllSchedulingData();
18+
19+
germanTimeZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
2220
trigger = TriggerBuilder.Create()
2321
.ForJob(new JobKey("test"))
24-
.WithDailyTimeIntervalSchedule(x => x.OnEveryDay().StartingDailyAt(new TimeOfDay(10, 10)))
22+
.WithDailyTimeIntervalSchedule(x => x.InTimeZone(germanTimeZone).OnEveryDay().StartingDailyAt(new TimeOfDay(10, 10)))
2523
.Build();
2624
jobDetail = JobBuilder.Create<TestJob>().WithIdentity("test").Build();
2725
};
@@ -34,19 +32,19 @@ public class When_a_daily_interval_trigger_has_been_stored_in_the_mongo_db
3432
triggersForJob.Count.ShouldEqual(1);
3533
};
3634

35+
private It should_retrieve_the_correct_time_zone = () =>
36+
{
37+
var trigger = (IDailyTimeIntervalTrigger)jobStore.GetTriggersForJob(new JobKey("test")).Single();
38+
trigger.TimeZone.ShouldEqual(germanTimeZone);
39+
};
40+
3741
private static JobStore jobStore;
3842

3943
private static ITrigger trigger;
4044

4145
private static IJobDetail jobDetail;
42-
}
43-
}
4446

45-
public class TestJob: IJob
46-
{
47-
public void Execute(IJobExecutionContext context)
48-
{
49-
throw new NotImplementedException();
47+
private static TimeZoneInfo germanTimeZone;
5048
}
5149
}
5250
}

src/Quartz.Impl.MongoDB.Tests/Quartz.Impl.MongoDB.Tests.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@
5555
<Reference Include="System.Xml" />
5656
</ItemGroup>
5757
<ItemGroup>
58-
<Compile Include="TriggerSpecs.cs" />
58+
<Compile Include="CronTriggerSpecs.cs" />
59+
<Compile Include="DailyIntervalTriggerSpecs.cs" />
5960
<Compile Include="Properties\AssemblyInfo.cs" />
61+
<Compile Include="TestJob.cs" />
6062
</ItemGroup>
6163
<ItemGroup>
6264
<None Include="App.config" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
namespace Quartz.Impl.MongoDB.Tests
4+
{
5+
public class TestJob: IJob
6+
{
7+
public void Execute(IJobExecutionContext context)
8+
{
9+
throw new NotImplementedException();
10+
}
11+
}
12+
}

src/Quartz.Impl.MongoDB/JobStore.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
using System.Text;
2828
using System.Threading;
2929

30+
using AutoScout24.SMP.BackgroundServices.SmpJobs.Infrastructure.Quartz;
31+
3032
using Common.Logging;
3133

3234
using Quartz.Collection;
@@ -165,6 +167,7 @@ static JobStore()
165167
cm.AutoMap();
166168
cm.MapField("nextFireTimeUtc");
167169
cm.MapField("previousFireTimeUtc");
170+
cm.MapField(x => x.TimeZone).SetSerializer(new TimeZoneInfoSerializer());
168171
cm.SetIgnoreExtraElements(true);
169172
});
170173

@@ -174,6 +177,7 @@ static JobStore()
174177
cm.MapField("complete");
175178
cm.MapField("nextFireTimeUtc");
176179
cm.MapField("previousFireTimeUtc");
180+
cm.MapField(x => x.TimeZone).SetSerializer(new TimeZoneInfoSerializer());
177181
cm.SetIgnoreExtraElements(true);
178182
});
179183

src/Quartz.Impl.MongoDB/Quartz.Impl.MongoDB.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<Compile Include="IdOrKeyConvention.cs" />
6969
<Compile Include="Properties\AssemblyInfo.cs" />
7070
<Compile Include="SetSerializer.cs" />
71+
<Compile Include="TimeZoneInfoSerializer.cs" />
7172
<Compile Include="TriggerKeySerializer.cs" />
7273
</ItemGroup>
7374
<ItemGroup>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
3+
using MongoDB.Bson.IO;
4+
using MongoDB.Bson.Serialization;
5+
6+
namespace AutoScout24.SMP.BackgroundServices.SmpJobs.Infrastructure.Quartz
7+
{
8+
public class TimeZoneInfoSerializer : IBsonSerializer
9+
{
10+
public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
11+
{
12+
return Deserialize(bsonReader);
13+
}
14+
15+
public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
16+
{
17+
return Deserialize(bsonReader);
18+
}
19+
20+
private static object Deserialize(BsonReader bsonReader)
21+
{
22+
var timeZoneId = bsonReader.ReadString();
23+
return TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
24+
}
25+
26+
public IBsonSerializationOptions GetDefaultSerializationOptions()
27+
{
28+
return null;
29+
}
30+
31+
public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
32+
{
33+
var timeZoneInfo = (TimeZoneInfo)value;
34+
bsonWriter.WriteString(timeZoneInfo.Id);
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)