diff --git a/Spring.Net.sln b/Spring.Net.sln index ece8552e..2be5bc59 100644 --- a/Spring.Net.sln +++ b/Spring.Net.sln @@ -65,16 +65,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Testing.Microsoft.Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Messaging.Ems", "src\Spring\Spring.Messaging.Ems\Spring.Messaging.Ems.csproj", "{900E3839-301E-48B1-BAEB-B6645620ACFF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz2", "src\Spring\Spring.Scheduling.Quartz2\Spring.Scheduling.Quartz2.csproj", "{E823D54C-CE82-4868-929F-5F95A999F123}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz3", "src\Spring\Spring.Scheduling.Quartz3\Spring.Scheduling.Quartz3.csproj", "{E823D54C-CE82-4868-929F-5F95A999F123}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz2.Tests", "test\Spring\Spring.Scheduling.Quartz2.Tests\Spring.Scheduling.Quartz2.Tests.csproj", "{247787CF-ECE1-4675-8B42-7DF4329A4891}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz3.Integration.Tests", "test\Spring\Spring.Scheduling.Quartz3.Integration.Tests\Spring.Scheduling.Quartz3.Integration.Tests.csproj", "{8CF0F34A-CC93-4D87-AE14-A2DEEF072F26}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz3.Tests", "test\Spring\Spring.Scheduling.Quartz3.Tests\Spring.Scheduling.Quartz3.Tests.csproj", "{247787CF-ECE1-4675-8B42-7DF4329A4891}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Messaging.Ems.Integration.Tests", "test\Spring\Spring.Messaging.Ems.Integration.Tests\Spring.Messaging.Ems.Integration.Tests.csproj", "{FA934E92-C8C2-428A-BE2A-26818F17A787}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Messaging.Nms.Integration.Tests", "test\Spring\Spring.Messaging.Nms.Integration.Tests\Spring.Messaging.Nms.Integration.Tests.csproj", "{E5323AC8-137E-4EF7-BC62-3BD6FC0576CD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Scheduling.Quartz2.Integration.Tests", "test\Spring\Spring.Scheduling.Quartz2.Integration.Tests\Spring.Scheduling.Quartz2.Integration.Tests.csproj", "{8CF0F34A-CC93-4D87-AE14-A2DEEF072F26}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Web.Conversation.NHibernate5", "src\Spring\Spring.Web.Conversation.NHibernate5\Spring.Web.Conversation.NHibernate5.csproj", "{CF375928-B6D5-485C-B04D-2BC41D9DBF1E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Web.Conversation.NHibernate5.Tests", "test\Spring\Spring.Web.Conversation.NHibernate5.Tests\Spring.Web.Conversation.NHibernate5.Tests.csproj", "{C57B05EA-FD1A-40EC-BB60-D2E45AB1A86A}" diff --git a/Spring.Net.sln.DotSettings b/Spring.Net.sln.DotSettings index d591379e..191cf932 100644 --- a/Spring.Net.sln.DotSettings +++ b/Spring.Net.sln.DotSettings @@ -1,4 +1,8 @@  + Required + Required + Required + Required License /* * Copyright 2018 the original author or authors. @@ -15,6 +19,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> diff --git a/Spring.build b/Spring.build index 96c3ef66..091f7c11 100644 --- a/Spring.build +++ b/Spring.build @@ -417,6 +417,7 @@ Commandline Examples: + @@ -1071,9 +1072,9 @@ Commandline Examples: - - - + + + @@ -1277,7 +1278,7 @@ Commandline Examples: - + @@ -1298,7 +1299,7 @@ Commandline Examples: - + diff --git a/changelog.txt b/changelog.txt index f0a9f9ff..675019d6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,7 @@ Release Notes - Spring.NET - Version 3.0.0 Breaking Changes * .NET 4.5.2 is the lowest full framework supported +* Tranasaction definitions no longer have EnterpriseServicesInteropOption, it was replaced by TransactionScopeAsyncFlowOption New Feature Highlights diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.build b/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.build deleted file mode 100644 index a3813a83..00000000 --- a/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.build +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.sln b/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.sln index f3e47874..6558c076 100644 --- a/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.sln +++ b/examples/Spring/Spring.Scheduling.Quartz.Example/Spring.Scheduling.Quartz.Example.sln @@ -5,6 +5,14 @@ VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Scheduling.Quartz.Example.2010", "src\Spring.Scheduling.Quartz.Example.csproj", "{0C0D8C65-90DE-4914-9940-4C684C54971B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Scheduling.Quartz3", "..\..\..\src\Spring\Spring.Scheduling.Quartz3\Spring.Scheduling.Quartz3.csproj", "{E397E260-643A-4929-8979-3483BF0C77CB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core", "..\..\..\src\Spring\Spring.Core\Spring.Core.csproj", "{7BF79668-CD22-461B-BF82-5571E3E1119E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Data", "..\..\..\src\Spring\Spring.Data\Spring.Data.csproj", "{7FBD7BF1-B978-4DBC-BDBC-B8B20865E96D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Aop", "..\..\..\src\Spring\Spring.Aop\Spring.Aop.csproj", "{6905DB1E-B4B7-4B5A-9E6F-72881BB6C98D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +23,22 @@ Global {0C0D8C65-90DE-4914-9940-4C684C54971B}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C0D8C65-90DE-4914-9940-4C684C54971B}.Release|Any CPU.ActiveCfg = Release|Any CPU {0C0D8C65-90DE-4914-9940-4C684C54971B}.Release|Any CPU.Build.0 = Release|Any CPU + {E397E260-643A-4929-8979-3483BF0C77CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E397E260-643A-4929-8979-3483BF0C77CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E397E260-643A-4929-8979-3483BF0C77CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E397E260-643A-4929-8979-3483BF0C77CB}.Release|Any CPU.Build.0 = Release|Any CPU + {7BF79668-CD22-461B-BF82-5571E3E1119E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BF79668-CD22-461B-BF82-5571E3E1119E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BF79668-CD22-461B-BF82-5571E3E1119E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BF79668-CD22-461B-BF82-5571E3E1119E}.Release|Any CPU.Build.0 = Release|Any CPU + {7FBD7BF1-B978-4DBC-BDBC-B8B20865E96D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FBD7BF1-B978-4DBC-BDBC-B8B20865E96D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FBD7BF1-B978-4DBC-BDBC-B8B20865E96D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FBD7BF1-B978-4DBC-BDBC-B8B20865E96D}.Release|Any CPU.Build.0 = Release|Any CPU + {6905DB1E-B4B7-4B5A-9E6F-72881BB6C98D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6905DB1E-B4B7-4B5A-9E6F-72881BB6C98D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6905DB1E-B4B7-4B5A-9E6F-72881BB6C98D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6905DB1E-B4B7-4B5A-9E6F-72881BB6C98D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/src/ExampleJob.cs b/examples/Spring/Spring.Scheduling.Quartz.Example/src/ExampleJob.cs index 141a2606..27121b3b 100644 --- a/examples/Spring/Spring.Scheduling.Quartz.Example/src/ExampleJob.cs +++ b/examples/Spring/Spring.Scheduling.Quartz.Example/src/ExampleJob.cs @@ -1,34 +1,31 @@ using System; - +using System.Threading.Tasks; using Quartz; namespace Spring.Scheduling.Quartz.Example { - /// - /// Example job. - /// + /// + /// Example job. + /// public class ExampleJob : QuartzJobObject { - private string userName; - /// - /// Simple property that can be injected. - /// + /// + /// Simple property that can be injected. + /// public string UserName { - set { userName = value; } + set => userName = value; } - /// - /// Execute. - /// - /// - protected override void ExecuteInternal(IJobExecutionContext context) + /// + protected override Task ExecuteInternal(IJobExecutionContext context) { - Console.WriteLine("{0}: ExecuteInternal called, user name: {1}, next fire time {2}", - DateTime.Now, userName, context.NextFireTimeUtc.Value.ToLocalTime()); - } + Console.WriteLine( + $"{DateTime.Now}: ExecuteInternal called, user name: {userName}, next fire time {context.NextFireTimeUtc?.ToLocalTime()}"); + return Task.FromResult(true); + } } -} +} \ No newline at end of file diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/src/Spring.Scheduling.Quartz.Example.csproj b/examples/Spring/Spring.Scheduling.Quartz.Example/src/Spring.Scheduling.Quartz.Example.csproj index e1f512fc..074494ef 100644 --- a/examples/Spring/Spring.Scheduling.Quartz.Example/src/Spring.Scheduling.Quartz.Example.csproj +++ b/examples/Spring/Spring.Scheduling.Quartz.Example/src/Spring.Scheduling.Quartz.Example.csproj @@ -3,19 +3,13 @@ net452 Exe - - - ..\..\..\..\build\$(Configuration)\Spring.Core\$(TargetFramework)\Spring.Core.dll - - - ..\..\..\..\build\$(Configuration)\Spring.Scheduling.Quartz2\$(TargetFramework)\Spring.Scheduling.Quartz2.dll - - - + + + \ No newline at end of file diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/src/project.json b/examples/Spring/Spring.Scheduling.Quartz.Example/src/project.json deleted file mode 100644 index ca901796..00000000 Binary files a/examples/Spring/Spring.Scheduling.Quartz.Example/src/project.json and /dev/null differ diff --git a/examples/Spring/Spring.Scheduling.Quartz.Example/src/spring-objects.xml b/examples/Spring/Spring.Scheduling.Quartz.Example/src/spring-objects.xml index 3bcb80ed..99c37490 100644 --- a/examples/Spring/Spring.Scheduling.Quartz.Example/src/spring-objects.xml +++ b/examples/Spring/Spring.Scheduling.Quartz.Example/src/spring-objects.xml @@ -2,7 +2,7 @@ - + @@ -17,20 +17,20 @@ - + - + - + @@ -40,13 +40,13 @@ - + - + diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 370c4ca5..5be198d9 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -44,7 +44,11 @@ - + + + + + Full diff --git a/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs b/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs index f5329377..5887a772 100644 --- a/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs +++ b/src/Spring/Spring.Aop/Aspects/RetryAdvice.cs @@ -16,18 +16,18 @@ * limitations under the License. */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using System.Threading; - -using AopAlliance.Intercept; - -using Common.Logging; - -using Spring.Core.TypeConversion; +#endregion + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Threading; + +using AopAlliance.Intercept; + +using Common.Logging; + +using Spring.Core.TypeConversion; using Spring.Expressions; namespace Spring.Aspects @@ -40,22 +40,22 @@ namespace Spring.Aspects /// /// /// - /// Mark Pollack + /// Mark Pollack [Serializable] public class RetryAdvice : AbstractExceptionHandlerAdvice - { - /// - ///The type of the callback that is called for delaying retries. - /// - public delegate void SleepHandler(TimeSpan duration); - - private static readonly ILog log; - private static readonly TimeSpanConverter timeSpanConverter; - + { + /// + ///The type of the callback that is called for delaying retries. + /// + public delegate void SleepHandler(TimeSpan duration); + + private static readonly ILog log; + private static readonly TimeSpanConverter timeSpanConverter; + static RetryAdvice() - { - log = LogManager.GetLogger(typeof(RetryAdvice)); - timeSpanConverter = new TimeSpanConverter(); + { + log = LogManager.GetLogger(typeof(RetryAdvice)); + timeSpanConverter = new TimeSpanConverter(); } #region Fields @@ -112,19 +112,20 @@ namespace Spring.Aspects #endregion - /// - /// Creates a new RetryAdvice instance, using for delaying retries + /// + /// Creates a new RetryAdvice instance, using for delaying retries /// - public RetryAdvice() :this(new SleepHandler(Thread.Sleep)) - { - } - - /// - /// Creates a new RetryAdvice instance, using any arbitrary callback for delaying retries - /// - public RetryAdvice(SleepHandler sleepHandler) - { - this.sleepHandler = sleepHandler; + public RetryAdvice() + :this(new SleepHandler(Thread.Sleep)) + { + } + + /// + /// Creates a new RetryAdvice instance, using any arbitrary callback for delaying retries + /// + public RetryAdvice(SleepHandler sleepHandler) + { + this.sleepHandler = sleepHandler; } #region IMethodInterceptor implementation @@ -211,19 +212,19 @@ namespace Spring.Aspects IExpression expression = Expression.Parse(handler.DelayRateExpression); object result = expression.GetValue(null, callContextDictionary); decimal d = decimal.Parse(result.ToString()); - decimal rounded = decimal.Round(d*1000,0); + decimal rounded = decimal.Round(d*1000,0); TimeSpan duration = TimeSpan.FromMilliseconds(decimal.ToDouble(rounded)); sleepHandler(duration); } catch (InvalidCastException e) { - log.Warn("Was not able to cast expression to decimal [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); + log.Warn("Was not able to cast expression to decimal [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); sleepHandler(new TimeSpan(0,0,1)); } catch (Exception e) { - log.Warn("Was not able to evaluate rate expression [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); - sleepHandler(new TimeSpan(0,0,1)); + log.Warn("Was not able to evaluate rate expression [" + handler.DelayRateExpression + "]. Sleeping for 1 second", e); + sleepHandler(new TimeSpan(0,0,1)); } } } @@ -341,18 +342,18 @@ namespace Spring.Aspects RegexOptions options = ((RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline) | RegexOptions.IgnoreCase); Regex reg = new Regex(regexString, options); return reg.Match(actionExpressionString); - } - - /// - /// Override in case you need to initialized non-serialized fields on deserialization. - /// - protected override void OnDeserialization(object sender) - { - base.OnDeserialization(sender); - if (retryExpression != null) - { - this.AfterPropertiesSet(); - } + } + + /// + /// Override in case you need to initialized non-serialized fields on deserialization. + /// + protected override void OnDeserialization(object sender) + { + base.OnDeserialization(sender); + if (retryExpression != null) + { + this.AfterPropertiesSet(); + } } } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs index b0e497a4..eb2a4a44 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/NamespaceParserRegistry.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright © 2002-2011 the original author or authors. * @@ -16,10 +14,6 @@ * limitations under the License. */ -#endregion - -#region Imports - using System; using System.Collections; using System.Collections.Specialized; @@ -30,8 +24,6 @@ using Spring.Core.IO; using Spring.Objects.Factory.Config; using Spring.Util; -#endregion - namespace Spring.Objects.Factory.Xml { /// @@ -72,31 +64,38 @@ namespace Spring.Objects.Factory.Xml /// private const string ConfigParsersSectionName = "spring/parsers"; - #region Fields - private static IDictionary parsers; private readonly static IDictionary wellknownNamespaceParserTypeNames; private static XmlSchemaSet schemas; - #endregion - /// /// Creates a new instance of the NamespaceParserRegistry class. /// static NamespaceParserRegistry() { wellknownNamespaceParserTypeNames = new CaseInsensitiveHashtable(); - wellknownNamespaceParserTypeNames["http://www.springframework.net/tx"] = "Spring.Transaction.Config.TxNamespaceParser, Spring.Data"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/aop"] = "Spring.Aop.Config.AopNamespaceParser, Spring.Aop"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/context"] = "Spring.Context.Config.ContextNamespaceParser, Spring.Core"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/db"] = "Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/database"] = "Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/remoting"] = "Spring.Remoting.Config.RemotingNamespaceParser, Spring.Services"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/wcf"] = "Spring.ServiceModel.Config.WcfNamespaceParser, Spring.Services"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/nms"] = "Spring.Messaging.Nms.Config.NmsNamespaceParser, Spring.Messaging.Nms"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/ems"] = "Spring.Messaging.Ems.Config.EmsNamespaceParser, Spring.Messaging.Ems"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/validation"] = "Spring.Validation.Config.ValidationNamespaceParser, Spring.Core"; - wellknownNamespaceParserTypeNames["http://www.springframework.net/nvelocity"] = "Spring.Template.Velocity.Config.TemplateNamespaceParser, Spring.Template.Velocity"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/tx"] = + "Spring.Transaction.Config.TxNamespaceParser, Spring.Data"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/aop"] = + "Spring.Aop.Config.AopNamespaceParser, Spring.Aop"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/context"] = + "Spring.Context.Config.ContextNamespaceParser, Spring.Core"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/db"] = + "Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/database"] = + "Spring.Data.Config.DatabaseNamespaceParser, Spring.Data"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/remoting"] = + "Spring.Remoting.Config.RemotingNamespaceParser, Spring.Services"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/wcf"] = + "Spring.ServiceModel.Config.WcfNamespaceParser, Spring.Services"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/nms"] = + "Spring.Messaging.Nms.Config.NmsNamespaceParser, Spring.Messaging.Nms"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/ems"] = + "Spring.Messaging.Ems.Config.EmsNamespaceParser, Spring.Messaging.Ems"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/validation"] = + "Spring.Validation.Config.ValidationNamespaceParser, Spring.Core"; + wellknownNamespaceParserTypeNames["http://www.springframework.net/nvelocity"] = + "Spring.Template.Velocity.Config.TemplateNamespaceParser, Spring.Template.Velocity"; Reset(); } @@ -109,7 +108,7 @@ namespace Spring.Objects.Factory.Xml { parsers = new HybridDictionary(); schemas = new XmlSchemaSet(); - schemas.XmlResolver = new XmlResourceUrlResolver(); + schemas.XmlResolver = new XmlResourceUrlResolver(); RegisterParser(new ObjectsNamespaceParser()); // register custom config parsers @@ -126,7 +125,7 @@ namespace Spring.Objects.Factory.Xml if (wellknownNamespaceParserTypeNames.Contains(namespaceUri)) { - string parserTypeName = (string)wellknownNamespaceParserTypeNames[namespaceUri]; + string parserTypeName = (string) wellknownNamespaceParserTypeNames[namespaceUri]; // assume, that all Spring.XXX assemblies have same version + public key // get the ", Version=x.x.x.x, Culture=neutral, PublicKeyToken=65e474d141e25e07" part of Spring.Core and append it string name = typeof(NamespaceParserRegistry).Assembly.GetName().Name; @@ -138,6 +137,7 @@ namespace Spring.Objects.Factory.Xml RegisterParser(parserType); return true; } + return false; } @@ -151,6 +151,7 @@ namespace Spring.Objects.Factory.Xml { return "assembly://" + schemaLocationAssemblyHint.Assembly.FullName + schemaLocation; } + return schemaLocation; } @@ -166,21 +167,22 @@ namespace Spring.Objects.Factory.Xml /// public static INamespaceParser GetParser(string namespaceURI) { - INamespaceParser parser = (INamespaceParser)parsers[namespaceURI]; + INamespaceParser parser = (INamespaceParser) parsers[namespaceURI]; if (parser == null) { bool ok = RegisterWellknownNamespaceParserType(namespaceURI); if (ok) { - parser = (INamespaceParser)parsers[namespaceURI]; - + parser = (INamespaceParser) parsers[namespaceURI]; + //work-around for SPRNET-1277 where we're inconsistent re: exposing /db or /database as the final namespace element if (parser == null && namespaceURI == "http://www.springframework.net/db") { - parser = (INamespaceParser)parsers["http://www.springframework.net/database"]; + parser = (INamespaceParser) parsers["http://www.springframework.net/database"]; } } } + return parser; } @@ -250,7 +252,7 @@ namespace Spring.Objects.Factory.Xml if ((typeof(INamespaceParser)).IsAssignableFrom(parserType)) { - np = (INamespaceParser)ObjectUtils.InstantiateType(parserType); + np = (INamespaceParser) ObjectUtils.InstantiateType(parserType); } // TODO (EE): workaround to enable smooth transition between 1.x and 2.0 style namespace handling else if (typeof(IObjectDefinitionParser).IsAssignableFrom(parserType)) @@ -264,28 +266,31 @@ namespace Spring.Objects.Factory.Xml throw new ArgumentNullException( "Either default or an explicit namespace value must be specified for a configuration parser."); } + if (StringUtils.IsNullOrEmpty(namespaceUri)) { namespaceUri = defaults.Namespace; } + if (StringUtils.IsNullOrEmpty(schemaLocation)) { schemaLocation = defaults.SchemaLocation; if (defaults.SchemaLocationAssemblyHint != null) { - schemaLocation = GetAssemblySchemaLocation(defaults.SchemaLocationAssemblyHint, schemaLocation); + schemaLocation = + GetAssemblySchemaLocation(defaults.SchemaLocationAssemblyHint, schemaLocation); } } } - IObjectDefinitionParser odParser = (IObjectDefinitionParser)ObjectUtils.InstantiateType(parserType); + IObjectDefinitionParser odParser = (IObjectDefinitionParser) ObjectUtils.InstantiateType(parserType); np = new ObjectDefinitionParserNamespaceParser(odParser); } else { throw new ArgumentException( - string.Format("The [{0}] Type must implement the INamespaceParser interface.", parserType.Name) - , "parserType"); + string.Format("The [{0}] Type must implement the INamespaceParser interface.", parserType.Name) + , "parserType"); } RegisterParser(np, namespaceUri, schemaLocation); @@ -345,10 +350,12 @@ namespace Spring.Objects.Factory.Xml throw new ArgumentNullException( "Either default or an explicit namespace value must be specified for a configuration parser."); } + if (StringUtils.IsNullOrEmpty(namespaceUri)) { namespaceUri = defaults.Namespace; } + if (StringUtils.IsNullOrEmpty(schemaLocation)) { schemaLocation = defaults.SchemaLocation; @@ -364,14 +371,14 @@ namespace Spring.Objects.Factory.Xml // register parser lock (parsers.SyncRoot) - lock (schemas) + lock (schemas) + { + parsers[namespaceUri] = parser; + if (StringUtils.HasText(schemaLocation) && !schemas.Contains(namespaceUri)) { - parsers[namespaceUri] = parser; - if (StringUtils.HasText(schemaLocation) && !schemas.Contains(namespaceUri)) - { - RegisterSchema(namespaceUri, schemaLocation); - } + RegisterSchema(namespaceUri, schemaLocation); } + } } /// @@ -410,13 +417,12 @@ namespace Spring.Objects.Factory.Xml object[] attrs = parserType.GetCustomAttributes(typeof(NamespaceParserAttribute), true); if (attrs.Length > 0) { - return (NamespaceParserAttribute)attrs[0]; + return (NamespaceParserAttribute) attrs[0]; } + return null; } - #region ObjectDefinitionParserNamespaceParser Utility class - /// /// Adapts the interface to . /// Only for smooth transition between 1.x and 2.0 style namespace handling, will be dropped for 2.0 @@ -440,12 +446,11 @@ namespace Spring.Objects.Factory.Xml return odParser.ParseElement(element, parserContext); } - public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, ParserContext parserContext) + public ObjectDefinitionHolder Decorate(XmlNode node, ObjectDefinitionHolder definition, + ParserContext parserContext) { return null; } } - - #endregion } } \ No newline at end of file diff --git a/src/Spring/Spring.Data.NHibernate5/Data/NHibernate/HibernateTxScopeTransactionManager.cs b/src/Spring/Spring.Data.NHibernate5/Data/NHibernate/HibernateTxScopeTransactionManager.cs index 73b09e8d..384addb6 100644 --- a/src/Spring/Spring.Data.NHibernate5/Data/NHibernate/HibernateTxScopeTransactionManager.cs +++ b/src/Spring/Spring.Data.NHibernate5/Data/NHibernate/HibernateTxScopeTransactionManager.cs @@ -463,7 +463,7 @@ namespace Spring.Data.NHibernate TransactionScopeOption txScopeOption = CreateTransactionScopeOptions(definition); TransactionOptions txOptions = CreateTransactionOptions(definition); - txObject.TxScopeAdapter.CreateTransactionScope(txScopeOption, txOptions, definition.EnterpriseServicesInteropOption); + txObject.TxScopeAdapter.CreateTransactionScope(txScopeOption, txOptions, definition.AsyncFlowOption); } diff --git a/src/Spring/Spring.Data.NHibernate5/Spring.Data.NHibernate5.csproj b/src/Spring/Spring.Data.NHibernate5/Spring.Data.NHibernate5.csproj index 317973d6..7638a906 100644 --- a/src/Spring/Spring.Data.NHibernate5/Spring.Data.NHibernate5.csproj +++ b/src/Spring/Spring.Data.NHibernate5/Spring.Data.NHibernate5.csproj @@ -2,6 +2,7 @@ netstandard2.0;net461 Interfaces and classes that provide NHibernate 5 support in Spring.Net + Spring.Data.NHibernate 0618 diff --git a/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs b/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs index e93f879f..3c8d3e41 100644 --- a/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs +++ b/src/Spring/Spring.Data/Data/Core/TxScopeTransactionManager.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright 2007 the original author or authors. * @@ -16,8 +14,6 @@ * limitations under the License. */ -#endregion - using System; using System.Transactions; using Spring.Data.Support; @@ -54,8 +50,6 @@ namespace Spring.Data.Core this.txAdapter = txAdapter; } - #region IInitializingObject Members - /// /// No-op initialization /// @@ -64,8 +58,6 @@ namespace Spring.Data.Core // placeholder for more advanced configurations. } - #endregion - protected override object DoGetTransaction() { PromotableTxScopeTransactionObject txObject = new PromotableTxScopeTransactionObject(); @@ -74,20 +66,21 @@ namespace Spring.Data.Core { txObject.TxScopeAdapter = txAdapter; } + return txObject; } protected override bool IsExistingTransaction(object transaction) { PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)transaction; - return txObject.TxScopeAdapter.IsExistingTransaction; + (PromotableTxScopeTransactionObject) transaction; + return txObject.TxScopeAdapter.IsExistingTransaction; } - protected override void DoBegin(object transaction, Spring.Transaction.ITransactionDefinition definition) + protected override void DoBegin(object transaction, ITransactionDefinition definition) { PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)transaction; + (PromotableTxScopeTransactionObject) transaction; try { DoTxScopeBegin(txObject, definition); @@ -106,7 +99,7 @@ namespace Spring.Data.Core PromotableTxScopeTransactionObject txMgrStateObject = (PromotableTxScopeTransactionObject) transaction; return txMgrStateObject.TxScopeAdapter; } - + protected override void DoResume(object transaction, object suspendedResources) { } @@ -114,7 +107,7 @@ namespace Spring.Data.Core protected override void DoCommit(DefaultTransactionStatus status) { PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)status.Transaction; + (PromotableTxScopeTransactionObject) status.Transaction; try { txObject.TxScopeAdapter.Complete(); @@ -122,7 +115,8 @@ namespace Spring.Data.Core } catch (TransactionAbortedException ex) { - throw new UnexpectedRollbackException("Transaction unexpectedly rolled back (maybe due to a timeout)", ex); + throw new UnexpectedRollbackException("Transaction unexpectedly rolled back (maybe due to a timeout)", + ex); } catch (TransactionInDoubtException ex) { @@ -137,54 +131,53 @@ namespace Spring.Data.Core protected override void DoRollback(DefaultTransactionStatus status) { PromotableTxScopeTransactionObject txObject = - (PromotableTxScopeTransactionObject)status.Transaction; + (PromotableTxScopeTransactionObject) status.Transaction; try { - txObject.TxScopeAdapter.Dispose(); } catch (Exception e) { - throw new Spring.Transaction.TransactionSystemException("Failure on Transaction Scope rollback.", e); + throw new TransactionSystemException("Failure on Transaction Scope rollback.", e); } } - protected override void DoSetRollbackOnly(DefaultTransactionStatus status) { if (status.Debug) { log.Debug("Setting transaction rollback-only"); } + try { System.Transactions.Transaction.Current.Rollback(); - } catch (Exception ex) + } + catch (Exception ex) { throw new TransactionSystemException("Failure on System.Transactions.Transaction.Current.Rollback", ex); } } - protected override bool ShouldCommitOnGlobalRollbackOnly - { - get { return true; } - } + protected override bool ShouldCommitOnGlobalRollbackOnly => true; - private void DoTxScopeBegin(PromotableTxScopeTransactionObject txObject, - Spring.Transaction.ITransactionDefinition definition) + private void DoTxScopeBegin( + PromotableTxScopeTransactionObject txObject, + ITransactionDefinition definition) { - - TransactionScopeOption txScopeOption = CreateTransactionScopeOptions(definition); + TransactionScopeOption txScopeOption = CreateTransactionScopeOptions(definition); TransactionOptions txOptions = CreateTransactionOptions(definition); - txObject.TxScopeAdapter.CreateTransactionScope(txScopeOption, txOptions, definition.EnterpriseServicesInteropOption); - + txObject.TxScopeAdapter.CreateTransactionScope( + txScopeOption, + txOptions, + definition.AsyncFlowOption); } private static TransactionOptions CreateTransactionOptions(ITransactionDefinition definition) { TransactionOptions txOptions = new TransactionOptions(); - switch (definition.TransactionIsolationLevel ) + switch (definition.TransactionIsolationLevel) { case System.Data.IsolationLevel.Chaos: txOptions.IsolationLevel = IsolationLevel.Chaos; @@ -210,9 +203,10 @@ namespace Spring.Data.Core } if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT) - { + { txOptions.Timeout = new TimeSpan(0, 0, definition.TransactionTimeout); } + return txOptions; } @@ -233,10 +227,11 @@ namespace Spring.Data.Core } else { - throw new Spring.Transaction.TransactionSystemException("Transaction Propagation Behavior" + - definition.PropagationBehavior + - " not supported by TransactionScope. Use Required or RequiredNew"); + throw new TransactionSystemException("Transaction Propagation Behavior" + + definition.PropagationBehavior + + " not supported by TransactionScope. Use Required or RequiredNew"); } + return txScopeOption; } @@ -264,22 +259,16 @@ namespace Spring.Data.Core /// The transaction scope adapter. public ITransactionScopeAdapter TxScopeAdapter { - get { return txScopeAdapter; } - set { txScopeAdapter = value; } + get => txScopeAdapter; + set => txScopeAdapter = value; } - /// /// Return whether the transaction is internally marked as rollback-only. /// /// /// True of the transaction is marked as rollback-only. - public bool RollbackOnly - { - get { - return txScopeAdapter.RollbackOnly; - } - } + public bool RollbackOnly => txScopeAdapter.RollbackOnly; } } -} +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs b/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs index 9bf94e0a..cb59a5a7 100644 --- a/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/DefaultTransactionScopeAdapter.cs @@ -31,75 +31,45 @@ namespace Spring.Data.Support { private TransactionScope txScope; - /// - /// Call Complete() on the TransactionScope object created by this instance. - /// + /// public void Complete() { txScope.Complete(); } - /// - /// Call Disponse() on the TransactionScope object created by this instance. - /// + /// public void Dispose() { txScope.Dispose(); } + /// + public bool IsExistingTransaction => System.Transactions.Transaction.Current != null; - /// - /// Gets a value indicating whether there is a new transaction or an existing transaction. - /// - /// - /// true if this instance is existing transaction; otherwise, false. - /// - public bool IsExistingTransaction - { - get { - if (System.Transactions.Transaction.Current != null) - { - return true; - } - else - { - return false; - } - } - } - - /// - /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the - /// Transaction object) and therefore voting that the transaction will be aborted. - /// - /// true if rollback only; otherwise, false. + /// public bool RollbackOnly { get { - if (System.Transactions.Transaction.Current != null && - System.Transactions.Transaction.Current.TransactionInformation != null && - System.Transactions.Transaction.Current.TransactionInformation.Status == TransactionStatus.Aborted) + var transaction = System.Transactions.Transaction.Current; + if (transaction != null && + transaction.TransactionInformation != null && + transaction.TransactionInformation.Status == TransactionStatus.Aborted) { return true; } - else - { - return false; - } - } + + return false; + } } - /// - /// Creates the transaction scope. - /// - /// The tx scope option. - /// The tx options. - /// The interop option. - public void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, - EnterpriseServicesInteropOption interopOption) + /// + public void CreateTransactionScope( + TransactionScopeOption txScopeOption, + TransactionOptions txOptions, + TransactionScopeAsyncFlowOption asyncFlowOption) { - txScope = new TransactionScope(txScopeOption, txOptions, interopOption); + txScope = new TransactionScope(txScopeOption, txOptions, asyncFlowOption); } } -} +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs b/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs index 5baa2970..9e55a473 100644 --- a/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs +++ b/src/Spring/Spring.Data/Data/Support/ITransactionScopeAdapter.cs @@ -35,21 +35,22 @@ namespace Spring.Data.Support /// /// The tx scope option. /// The tx options. - /// The interop option. - void CreateTransactionScope(TransactionScopeOption txScopeOption, TransactionOptions txOptions, EnterpriseServicesInteropOption interopOption); + /// The async flow option. + void CreateTransactionScope( + TransactionScopeOption txScopeOption, + TransactionOptions txOptions, + TransactionScopeAsyncFlowOption asyncFlowOption); /// /// Call Complete() on the TransactionScope object created by this instance. /// void Complete(); - /// - /// Call Disponse() on the TransactionScope object created by this instance. + /// Call Dispose() on the TransactionScope object created by this instance. /// void Dispose(); - /// /// Gets a value indicating whether there is a new transaction or an existing transaction. /// @@ -58,13 +59,11 @@ namespace Spring.Data.Support /// bool IsExistingTransaction { get; } - /// /// Gets a value indicating whether rollback only has been called (i.e. Rollback() on the /// Transaction object) and therefore voting that the transaction will be aborted. /// /// true if rollback only; otherwise, false. bool RollbackOnly { get; } - } - -} + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs b/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs index fb1505ad..ab35760a 100644 --- a/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs +++ b/src/Spring/Spring.Data/Transaction/ITransactionDefinition.cs @@ -111,9 +111,9 @@ namespace Spring.Transaction string Name { get; } /// - /// Gets the enterprise services interop option. + /// Gets the async flow option. /// - /// The enterprise services interop option. - System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption { get;} + /// The async flow option. + System.Transactions.TransactionScopeAsyncFlowOption AsyncFlowOption { get;} } } diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs b/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs index 0706e753..b5b0bb85 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/AttributesTransactionAttributeSource.cs @@ -89,7 +89,7 @@ namespace Spring.Transaction.Interceptor rbta.TransactionIsolationLevel = ta.IsolationLevel; rbta.ReadOnly = ta.ReadOnly; rbta.TransactionTimeout = ta.Timeout; - rbta.EnterpriseServicesInteropOption = ta.EnterpriseServicesInteropOption; + rbta.AsyncFlowOption = ta.AsyncFlowOption; Type[] rbf = ta.RollbackFor; diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs index d63a68b5..45a43c1d 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/DefaultTransactionAttribute.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright 2002-2010 the original author or authors. * @@ -16,83 +14,83 @@ * limitations under the License. */ -#endregion - using System; using Spring.Transaction.Support; namespace Spring.Transaction.Interceptor { - /// - /// Transaction attribute approach to rolling back on all exceptions, no other - /// exceptions by default. - /// - /// Rod Johnson - /// Griffin Caprio (.NET) - public class DefaultTransactionAttribute : DefaultTransactionDefinition, ITransactionAttribute - { - /// - /// Prefix for rollback-on-exception rules in description strings. - /// - public static readonly string ROLLBACK_RULE_PREFIX = "-"; + /// + /// Transaction attribute approach to rolling back on all exceptions, no other + /// exceptions by default. + /// + /// Rod Johnson + /// Griffin Caprio (.NET) + public class DefaultTransactionAttribute : DefaultTransactionDefinition, ITransactionAttribute + { + /// + /// Prefix for rollback-on-exception rules in description strings. + /// + public static readonly string ROLLBACK_RULE_PREFIX = "-"; - /// - /// Prefix for commit-on-exception rules in description strings. - /// - public static readonly string COMMIT_RULE_PREFIX = "+"; + /// + /// Prefix for commit-on-exception rules in description strings. + /// + public static readonly string COMMIT_RULE_PREFIX = "+"; - /// - /// Creates a new instance of the - /// - /// class. - /// - public DefaultTransactionAttribute() {} + /// + /// Creates a new instance of the + /// + /// class. + /// + public DefaultTransactionAttribute() + { + } - /// - /// Creates a new instance of the - /// - /// class, setting the propagation behavior to the supplied value. - /// - /// - /// The desired transaction propagation behaviour. - /// - public DefaultTransactionAttribute( TransactionPropagation propagationBehavior ) - : base (propagationBehavior) {} + /// + /// Creates a new instance of the + /// + /// class, setting the propagation behavior to the supplied value. + /// + /// + /// The desired transaction propagation behaviour. + /// + public DefaultTransactionAttribute(TransactionPropagation propagationBehavior) + : base(propagationBehavior) + { + } - #region ITransactionAttribute Members - /// - /// Decides if rollback is required for the supplied . - /// - /// - ///

- /// The default behavior is to rollback on any exception. - /// Consistent with 's behavior. - ///

- ///
- /// The to evaluate. - /// True if the exception causes a rollback, false otherwise. - public virtual bool RollbackOn(Exception exception) - { - return ( true ); - } - #endregion + /// + /// Decides if rollback is required for the supplied . + /// + /// + ///

+ /// The default behavior is to rollback on any exception. + /// Consistent with 's behavior. + ///

+ ///
+ /// The to evaluate. + /// True if the exception causes a rollback, false otherwise. + public virtual bool RollbackOn(Exception exception) + { + return (true); + } - /// - /// Return a description of this transaction attribute. - /// - /// - ///

- /// The format matches the one used by the - /// , - /// to be able to feed any result into a - /// instance's properties. - ///

- ///
- public override string ToString() - { - string result = DefinitionDescription; - result += "," + ROLLBACK_RULE_PREFIX + "System.Exception"; - return result; - } - } -} + /// + /// Return a description of this transaction attribute. + /// + /// + ///

+ /// The format matches the one used by the + /// , + /// to be able to feed any result into a + /// instance's properties. + ///

+ ///
+ public override string ToString() + { + string result = DefinitionDescription; + result += "," + ROLLBACK_RULE_PREFIX + "System.Exception"; + return result; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs b/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs index df064af7..2f5498a0 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/DelegatingTransactionAttributeWithName.cs @@ -30,8 +30,8 @@ namespace Spring.Transaction.Interceptor ///
public class DelegatingTransactionAttributeWithName : ITransactionAttribute { - private ITransactionAttribute targetAttribute; - private string joinpointIdentification; + private readonly ITransactionAttribute targetAttribute; + private readonly string joinpointIdentification; /// /// Initializes a new instance of the class. @@ -61,10 +61,7 @@ namespace Spring.Transaction.Interceptor /// . /// /// - public TransactionPropagation PropagationBehavior - { - get { return targetAttribute.PropagationBehavior; } - } + public TransactionPropagation PropagationBehavior => targetAttribute.PropagationBehavior; /// /// Return the isolation level of type . @@ -82,75 +79,19 @@ namespace Spring.Transaction.Interceptor /// . ///

/// - public IsolationLevel TransactionIsolationLevel - { - get { return targetAttribute.TransactionIsolationLevel; } - } + public IsolationLevel TransactionIsolationLevel => targetAttribute.TransactionIsolationLevel; - /// - /// Return the transaction timeout. - /// - /// - /// - ///

- /// Must return a number of seconds, or -1. - /// Only makes sense in combination with - /// and - /// . - /// Note that a transaction manager that does not support timeouts will - /// throw an exception when given any other timeout than -1. - ///

- ///
- public int TransactionTimeout - { - get { return targetAttribute.TransactionTimeout; } - } + /// + public int TransactionTimeout => targetAttribute.TransactionTimeout; - /// - /// Get whether to optimize as read-only transaction. - /// - /// - /// - ///

- /// This just serves as hint for the actual transaction subsystem, - /// it will not necessarily cause failure of write accesses. - ///

- ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// A transaction manager that cannot interpret the read-only hint - /// will not throw an exception when given ReadOnly=true. - ///

- ///
- public bool ReadOnly - { - get { return targetAttribute.ReadOnly; } - } + /// + public bool ReadOnly => targetAttribute.ReadOnly; - /// - /// Return the name of this transaction. - /// - /// - /// - /// The exposed name will be the fully - /// qualified type name + "." method name + assembly (by default). - /// - public string Name - { - get { return joinpointIdentification; } - } + /// + public string Name => joinpointIdentification; - /// - /// Gets the enterprise services interop option. - /// - /// The enterprise services interop option. - public EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return targetAttribute.EnterpriseServicesInteropOption; } - } + /// + public TransactionScopeAsyncFlowOption AsyncFlowOption => targetAttribute.AsyncFlowOption; /// /// Return a description of this transaction attribute. diff --git a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs index 9d0c7db6..4fc2d358 100644 --- a/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs +++ b/src/Spring/Spring.Data/Transaction/Interceptor/TransactionAttribute.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright © 2002-2011 the original author or authors. * @@ -16,30 +14,23 @@ * limitations under the License. */ -#endregion - -#region Imports - using System; using System.Data; using Spring.Transaction.Support; - -#endregion - namespace Spring.Transaction.Interceptor { - /// - /// .NET Attribute for describing transactional behavior of methods in a class. - /// - /// This attribute type is generally directly comparable - /// to Spring's class and - /// in fact will + /// + /// .NET Attribute for describing transactional behavior of methods in a class. + /// + /// This attribute type is generally directly comparable + /// to Spring's class and + /// in fact will /// directly convert the data to a /// so that Spring's transaction support code does not have to know about /// attributes. If no rules are relevant to the exception it will be treaded /// like DefaultTransactionAttribute, (rolling back on all exceptions). - /// + /// /// The default property values are TransactionPropagation.Required, IsolationLevel.ReadCommitted, /// DefaultTransactionDefinition.TIMEOUT_DEFAULT (can be changed, by default is the default /// value of the underlying transaction subsystem) @@ -47,32 +38,27 @@ namespace Spring.Transaction.Interceptor /// types. /// /// - /// Mark Pollack (.NET) - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, - Inherited = true)] + /// Mark Pollack (.NET) + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, + Inherited = true)] [Serializable] - public class TransactionAttribute : Attribute - { - #region Fields + public class TransactionAttribute : Attribute + { private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; private IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted; private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; private bool _readOnly = false; private Type[] _rollbackTypes = Type.EmptyTypes; private Type[] _noRollbackTypes = Type.EmptyTypes; - private System.Transactions.EnterpriseServicesInteropOption _esInteropOption = - System.Transactions.EnterpriseServicesInteropOption.Automatic; - #endregion + private System.Transactions.TransactionScopeAsyncFlowOption _asyncFlowOption = System.Transactions.TransactionScopeAsyncFlowOption.Enabled; - #region Constructor (s) - /// - /// Initializes a new instance of the class. + /// + /// Initializes a new instance of the class. /// - public TransactionAttribute() - { - - } + public TransactionAttribute() + { + } /// /// Initializes a new instance of the class. @@ -89,7 +75,7 @@ namespace Spring.Transaction.Interceptor /// The transaction propagation. /// The isolation level. public TransactionAttribute(TransactionPropagation transactionPropagation, - IsolationLevel isolationLevel) : this(transactionPropagation) + IsolationLevel isolationLevel) : this(transactionPropagation) { _isolationLevel = isolationLevel; } @@ -103,51 +89,41 @@ namespace Spring.Transaction.Interceptor _isolationLevel = isolationLevel; } - #endregion - - #region Properties - /// /// Gets the transaction propagation. /// /// Defaults to TransactionPropagation.Required /// The transaction propagation. - public TransactionPropagation TransactionPropagation - { - get { return _transactionPropagation; } - } + public TransactionPropagation TransactionPropagation => _transactionPropagation; /// /// Gets the isolation level. /// /// Defaults to IsolationLevel.Unspecified /// The isolation level. - public IsolationLevel IsolationLevel - { - get { return _isolationLevel; } - } + public IsolationLevel IsolationLevel => _isolationLevel; /// /// Gets or sets the timeout. /// /// Defaults to the default timeout of the underlying transaction system. /// The timeout. - public int Timeout - { - get { return _timeout; } - set { _timeout = value; } - } + public int Timeout + { + get => _timeout; + set => _timeout = value; + } /// /// Gets or sets a value indicating whether the transaction is readonly. /// /// Defaults to false /// true if read-only; otherwise, false. - public bool ReadOnly - { - get { return _readOnly; } - set { _readOnly = value; } - } + public bool ReadOnly + { + get => _readOnly; + set => _readOnly = value; + } /// /// Gets or sets the zero or more exception types which @@ -157,11 +133,11 @@ namespace Spring.Transaction.Interceptor /// This is the preferred way to construct a rollback rule, /// matching the exception class and subclasses. /// The rollback types. - public Type[] RollbackFor - { - get { return _rollbackTypes; } - set { _rollbackTypes = value; } - } + public Type[] RollbackFor + { + get => _rollbackTypes; + set => _rollbackTypes = value; + } /// /// Gets or sets zero or more exceptions types which @@ -171,27 +147,20 @@ namespace Spring.Transaction.Interceptor /// This is the preferred way to construct a rollback rule, /// matching the exception type. /// The no rollback for. - public Type[] NoRollbackFor - { - get { return _noRollbackTypes; } - set { _noRollbackTypes = value; } - } + public Type[] NoRollbackFor + { + get => _noRollbackTypes; + set => _noRollbackTypes = value; + } /// - /// Gets or sets the enterprise services interop option. + /// Gets the async flow option. /// - /// The enterprise services interop option. - public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return _esInteropOption;} - set { _esInteropOption = value; } - } - - #endregion - - #region Methods - - #endregion - - } -} + /// The async flow option. + public System.Transactions.TransactionScopeAsyncFlowOption AsyncFlowOption + { + get => _asyncFlowOption; + set => _asyncFlowOption = value; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs index 972c4017..8a242330 100644 --- a/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs +++ b/src/Spring/Spring.Data/Transaction/Support/DefaultTransactionDefinition.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright 2002-2010 the original author or authors. * @@ -16,174 +14,170 @@ * limitations under the License. */ -#endregion - using System; -using System.Data; using System.Text; +using System.Transactions; namespace Spring.Transaction.Support { - /// - /// Default implementation of the - /// interface, offering object-style configuration and sensible default values. - /// - /// - ///

- /// Base class for both and - /// . - ///

- ///
- /// Juergen Hoeller - /// Griffin Caprio (.NET) - /// Mark Pollack (.NET) - [Serializable] - public class DefaultTransactionDefinition : ITransactionDefinition - { - /// - /// Prefix for Propagation settings. - /// - public static readonly string PROPAGATION_CONSTANT_PREFIX = "PROPAGATION"; + /// + /// Default implementation of the + /// interface, offering object-style configuration and sensible default values. + /// + /// + ///

+ /// Base class for both and + /// . + ///

+ ///
+ /// Juergen Hoeller + /// Griffin Caprio (.NET) + /// Mark Pollack (.NET) + [Serializable] + public class DefaultTransactionDefinition : ITransactionDefinition + { + /// + /// Prefix for Propagation settings. + /// + public static readonly string PROPAGATION_CONSTANT_PREFIX = "PROPAGATION"; - /// - /// Prefix for IsolationLevel settings. - /// - public static readonly string ISOLATION_CONSTANT_PREFIX = "ISOLATION"; + /// + /// Prefix for IsolationLevel settings. + /// + public static readonly string ISOLATION_CONSTANT_PREFIX = "ISOLATION"; - /// - /// Prefix for transaction timeout values in description strings. - /// - public static readonly string TIMEOUT_PREFIX = "timeout_"; + /// + /// Prefix for transaction timeout values in description strings. + /// + public static readonly string TIMEOUT_PREFIX = "timeout_"; - /// - /// Marker for read-only transactions in description strings. - /// - public static readonly string READ_ONLY_MARKER = "readOnly"; + /// + /// Marker for read-only transactions in description strings. + /// + public static readonly string READ_ONLY_MARKER = "readOnly"; - /// - /// The default transaction timeout. - /// - public const int TIMEOUT_DEFAULT = -1; + /// + /// The default transaction timeout. + /// + public const int TIMEOUT_DEFAULT = -1; - //TODO Refactoring to sync with Spring 2.0 for nt/enums for various default values. - - private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; - private IsolationLevel _transactionIsolationLevel = IsolationLevel.ReadCommitted; - private int _timeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - private bool _readOnly = false; + //TODO Refactoring to sync with Spring 2.0 for nt/enums for various default values. + + private TransactionPropagation _transactionPropagation = TransactionPropagation.Required; + private System.Data.IsolationLevel _transactionIsolationLevel = System.Data.IsolationLevel.ReadCommitted; + private int _timeout = TIMEOUT_DEFAULT; + private bool _readOnly = false; private string _name = null; - private System.Transactions.EnterpriseServicesInteropOption _esInteropOption; - - /// + private System.Transactions.TransactionScopeAsyncFlowOption _asyncFlowOption = TransactionScopeAsyncFlowOption.Enabled; + + /// /// Creates a new instance of the /// class. - /// - public DefaultTransactionDefinition() {} + /// + public DefaultTransactionDefinition() + { + } - /// + /// /// Creates a new instance of the /// class /// with the supplied /// behaviour. - /// - /// - /// The desired behavior. - /// - public DefaultTransactionDefinition( TransactionPropagation transactionPropagation ) - { - _transactionPropagation = transactionPropagation; - } - - #region ITransactionDefinition Members + /// + /// + /// The desired behavior. + /// + public DefaultTransactionDefinition(TransactionPropagation transactionPropagation) + { + _transactionPropagation = transactionPropagation; + } // TODO change method name to same as type returned (TransactionPropagation) - - - /// - /// Gets / Sets the propagation - /// behavior. - /// - public TransactionPropagation PropagationBehavior - { - get { return _transactionPropagation; } - set { _transactionPropagation = value; } - } - + /// + /// Gets / Sets the propagation + /// behavior. + /// + public TransactionPropagation PropagationBehavior + { + get => _transactionPropagation; + set => _transactionPropagation = value; + } // TODO change method name to same as type returned (TransactionPropagation) - - /// - /// Return the isolation level of type . - /// - /// - ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// Note that a transaction manager that does not support custom isolation levels - /// will throw an exception when given any other level than - /// . - ///

- ///
- public IsolationLevel TransactionIsolationLevel - { - get { return _transactionIsolationLevel; } - set { _transactionIsolationLevel = value; } - } + /// + /// Return the isolation level of type . + /// + /// + ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// Note that a transaction manager that does not support custom isolation levels + /// will throw an exception when given any other level than + /// . + ///

+ ///
+ public System.Data.IsolationLevel TransactionIsolationLevel + { + get => _transactionIsolationLevel; + set => _transactionIsolationLevel = value; + } - /// - /// Return the transaction timeout. - /// - /// - ///

- /// Must return a number of seconds, or -1. - /// Only makes sense in combination with - /// and - /// . - /// Note that a transaction manager that does not support timeouts will - /// throw an exception when given any other timeout than -1. - ///

- ///
- public int TransactionTimeout - { - get { return _timeout; } - set - { - if ( value < DefaultTransactionDefinition.TIMEOUT_DEFAULT ) - { - throw new ArgumentException( "Timeout must be a positive integer or DefaultTransactionDefinition.TIMEOUT_DEFAULT" ); - } - _timeout = value; - } - } - - /// - /// Get whether to optimize as read-only transaction. - /// - /// - ///

- /// This just serves as hint for the actual transaction subsystem, - /// it will not necessarily cause failure of write accesses. - ///

- ///

- /// Only makes sense in combination with - /// and - /// . - ///

- ///

- /// A transaction manager that cannot interpret the read-only hint - /// will not throw an exception when given ReadOnly=true. - ///

- ///
- public bool ReadOnly - { - get { return _readOnly; } - set { _readOnly = value; } - } + /// + /// Return the transaction timeout. + /// + /// + ///

+ /// Must return a number of seconds, or -1. + /// Only makes sense in combination with + /// and + /// . + /// Note that a transaction manager that does not support timeouts will + /// throw an exception when given any other timeout than -1. + ///

+ ///
+ public int TransactionTimeout + { + get => _timeout; + set + { + if (value < TIMEOUT_DEFAULT) + { + throw new ArgumentException( + "Timeout must be a positive integer or DefaultTransactionDefinition.TIMEOUT_DEFAULT"); + } + + _timeout = value; + } + } + + /// + /// Get whether to optimize as read-only transaction. + /// + /// + ///

+ /// This just serves as hint for the actual transaction subsystem, + /// it will not necessarily cause failure of write accesses. + ///

+ ///

+ /// Only makes sense in combination with + /// and + /// . + ///

+ ///

+ /// A transaction manager that cannot interpret the read-only hint + /// will not throw an exception when given ReadOnly=true. + ///

+ ///
+ public bool ReadOnly + { + get => _readOnly; + set => _readOnly = value; + } /// /// Return the name of this transaction. Can be null. @@ -195,89 +189,86 @@ namespace Spring.Transaction.Support /// declarative transactions, the exposed name will be the fully /// qualified type name + "." method name + assembly (by default). /// - public string Name - { - get { return _name; } - set { _name = value;} - } - - /// - /// Gets the enterprise services interop option. - /// - /// The enterprise services interop option. - public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption + public string Name { - get { return _esInteropOption; } - set { _esInteropOption = value; } + get => _name; + set => _name = value; } - #endregion + /// + public System.Transactions.TransactionScopeAsyncFlowOption AsyncFlowOption + { + get => _asyncFlowOption; + set => _asyncFlowOption = value; + } - /// + /// /// An override of the default method. - /// - /// The to compare to. - /// True if the objects are equal. - public override bool Equals(object obj) - { - return ( obj is ITransactionDefinition ) && ToString().Equals( obj.ToString() ); - } + /// + /// The to compare to. + /// True if the objects are equal. + public override bool Equals(object obj) + { + return (obj is ITransactionDefinition) && ToString().Equals(obj.ToString()); + } - /// + /// /// An override of the default method that returns the /// hashcode of the /// /// property. - /// - /// - /// The hashcode of the - /// - /// property. + /// + /// + /// The hashcode of the + /// + /// property. /// - public override int GetHashCode() - { - return ToString().GetHashCode(); - } + public override int GetHashCode() + { + return ToString().GetHashCode(); + } - /// - /// An override of the default method that returns a string - /// representation of the - /// - /// property. - /// + /// + /// An override of the default method that returns a string + /// representation of the + /// + /// property. + /// /// /// A string representation of the /// /// property. /// - public override string ToString() - { - return DefinitionDescription; - } + public override string ToString() + { + return DefinitionDescription; + } - /// - /// Returns a representation of the - /// - /// property. - /// - protected string DefinitionDescription - { - get - { - StringBuilder builder = new StringBuilder(); - builder.Append( PROPAGATION_CONSTANT_PREFIX +"_" + PropagationBehavior ); - builder.Append( "," ); - builder.Append( ISOLATION_CONSTANT_PREFIX + "_" +TransactionIsolationLevel ); - if ( TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT ) - { - builder.Append( ",timeout_" + _timeout ); - } - if ( ReadOnly ) - { - builder.Append( ",readOnly" ); - } - return builder.ToString(); - } - } - } -} + /// + /// Returns a representation of the + /// + /// property. + /// + protected string DefinitionDescription + { + get + { + StringBuilder builder = new StringBuilder(); + builder.Append(PROPAGATION_CONSTANT_PREFIX + "_" + PropagationBehavior); + builder.Append(","); + builder.Append(ISOLATION_CONSTANT_PREFIX + "_" + TransactionIsolationLevel); + if (TransactionTimeout != TIMEOUT_DEFAULT) + { + builder.Append(",timeout_" + _timeout); + } + + if (ReadOnly) + { + builder.Append(",readOnly"); + } + + return builder.ToString(); + } + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/AdaptableJobFactory.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/AdaptableJobFactory.cs deleted file mode 100644 index 8c9245b9..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/AdaptableJobFactory.cs +++ /dev/null @@ -1,121 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ -using System; -using System.Threading; - -using Quartz; -using Quartz.Spi; -using Quartz.Util; - -namespace Spring.Scheduling.Quartz -{ - /// - /// JobFactory implementation that supports - /// objects as well as standard Quartz instances. - /// - /// Juergen Hoeller - /// Marko Lahma (.NET) - /// - /// - public class AdaptableJobFactory : IJobFactory - { - /// - /// Called by the scheduler at the time of the trigger firing, in order to - /// produce a instance on which to call Execute. - /// - /// - /// It should be extremely rare for this method to throw an exception - - /// basically only the the case where there is no way at all to instantiate - /// and prepare the Job for execution. When the exception is thrown, the - /// Scheduler will move all triggers associated with the Job into the - /// state, which will require human - /// intervention (e.g. an application restart after fixing whatever - /// configuration problem led to the issue wih instantiating the Job. - /// - /// The TriggerFiredBundle from which the - /// and other info relating to the trigger firing can be obtained. - /// The scheduler instance. - /// the newly instantiated Job - /// SchedulerException if there is a problem instantiating the Job. - public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) - { - try - { - object jobObject = CreateJobInstance(bundle); - return AdaptJob(jobObject); - } - catch (Exception ex) - { - throw new SchedulerException("Job instantiation failed", ex); - } - } - - /// - /// Allows the the job factory to destroy/cleanup the job if needed. - /// - public virtual void ReturnJob(IJob job) - { - - } - - /// - /// Create an instance of the specified job class. - ///

- /// Can be overridden to post-process the job instance. - ///

- ///
- /// - /// The TriggerFiredBundle from which the JobDetail - /// and other info relating to the trigger firing can be obtained. - /// - /// The job instance. - protected virtual object CreateJobInstance(TriggerFiredBundle bundle) - { - return ObjectUtils.InstantiateType(bundle.JobDetail.JobType); - } - - /// - /// Adapt the given job object to the Quartz Job interface. - /// - /// - /// The default implementation supports straight Quartz Jobs - /// as well as Runnables, which get wrapped in a DelegatingJob. - /// - /// - /// The original instance of the specified job class. - /// - /// The adapted Quartz Job instance. - /// - protected virtual IJob AdaptJob(object jobObject) - { - if (jobObject is IJob) - { - return (IJob)jobObject; - } - if (jobObject is ThreadStart) - { - return new DelegatingJob((ThreadStart)jobObject); - } - if (jobObject is IThreadRunnable) - { - return new DelegatingJob(((IThreadRunnable)jobObject).Run); - } - - string message = string.Format("Unable to execute job class [{0}]: only [IJob] and [ThreadStart] supported.", jobObject.GetType().FullName); - throw new ArgumentException(message); - } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/IJobDetailAwareTrigger.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/IJobDetailAwareTrigger.cs deleted file mode 100644 index c4593234..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/IJobDetailAwareTrigger.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ - -using Quartz; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Interface to be implemented by Quartz Triggers that are aware - /// of the JobDetail object that they are associated with. - /// - /// - ///

- /// SchedulerFactoryObject will auto-detect Triggers that implement this - /// interface and register them for the respective JobDetail accordingly. - ///

- /// - ///

- /// The alternative is to configure a Trigger for a Job name and group: - /// This involves the need to register the JobDetail object separately - /// with SchedulerFactoryObject. - ///

- ///
- /// Juergen Hoeller - /// - /// - public interface IJobDetailAwareTrigger - { - /// - /// Return the JobDetail that this Trigger is associated with. - /// - /// The associated JobDetail, or null if none - IJobDetail JobDetail { get; } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ISchedulerContextAware.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ISchedulerContextAware.cs deleted file mode 100644 index 35c6422c..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ISchedulerContextAware.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ -using Quartz; -using Quartz.Spi; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Callback interface to be implemented by Spring-managed - /// Quartz artifacts that need access to the SchedulerContext - /// (without having natural access to it). - /// - /// - /// Currently only supported for custom JobFactory implementations - /// that are passed in via Spring's SchedulerFactoryObject. - /// - /// Juergen Hoeller - /// - /// - public interface ISchedulerContextAware - { - /// - /// Set the SchedulerContext of the current Quartz Scheduler. - /// - /// - SchedulerContext SchedulerContext { set; } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/JobDetailObject.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/JobDetailObject.cs deleted file mode 100644 index 9ab40e6c..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/JobDetailObject.cs +++ /dev/null @@ -1,220 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ -using System; -using System.Collections; -using Quartz; -using Quartz.Impl; -using Spring.Context; -using Spring.Objects.Factory; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Convenience subclass of Quartz' JobDetail class that eases properties based - /// usage. - /// - /// - /// itself is already a object but lacks - /// sensible defaults. This class uses the Spring object name as job name, - /// and the Quartz default group ("DEFAULT") as job group if not specified. - /// - /// Juergen Hoeller - /// - /// - public class JobDetailObject : JobDetailImpl, IObjectNameAware, IApplicationContextAware, IInitializingObject - { - private Type actualJobType; - private string objectName; - private IApplicationContext applicationContext; - private string applicationContextJobDataKey; - - /// - /// Overridden to support any job class, to allow a custom JobFactory - /// to adapt the given job class to the Quartz Job interface. - /// - /// - public override Type JobType - { - get { return (actualJobType ?? base.JobType); } - - set - { - if (value != null && !typeof (IJob).IsAssignableFrom(value)) - { - base.JobType = typeof (DelegatingJob); - actualJobType = value; - } - else - { - base.JobType = value; - } - } - } - - /// - /// Register objects in the JobDataMap via a given Map. - /// - /// - /// These objects will be available to this Job only, - /// in contrast to objects in the SchedulerContext. - ///

- /// Note: When using persistent Jobs whose JobDetail will be kept in the - /// database, do not put Spring-managed objects or an ApplicationContext - /// reference into the JobDataMap but rather into the SchedulerContext. - ///

- ///
- /// - public virtual IDictionary JobDataAsMap - { - set - { - if (value == null) - { - throw new ArgumentException("Value cannot be null", "value"); - } - - foreach (DictionaryEntry entry in value) - { - JobDataMap.Put((string) entry.Key, entry.Value); - } - } - } - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// The name of the object in the factory. - /// - /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - /// - public virtual string ObjectName - { - set { objectName = value; } - } - - /// - /// Gets or sets the that this - /// object runs in. - /// - /// - /// - ///

- /// Normally this call will be used to initialize the object. - ///

- ///

- /// Invoked after population of normal object properties but before an - /// init callback such as - /// 's - /// - /// or a custom init-method. Invoked after the setting of any - /// 's - /// - /// property. - ///

- ///
- /// - /// In the case of application context initialization errors. - /// - /// - /// If thrown by any application context methods. - /// - /// - public virtual IApplicationContext ApplicationContext - { - set { applicationContext = value; } - get { return applicationContext; } - } - - /// - /// Set the key of an IApplicationContext reference to expose in the JobDataMap, - /// for example "applicationContext". Default is none. - /// Only applicable when running in a Spring ApplicationContext. - /// - /// - ///

- /// In case of a QuartzJobObject, the reference will be applied to the Job - /// instance as object property. An "applicationContext" attribute will correspond - /// to a "setApplicationContext" method in that scenario. - ///

- ///

- /// Note that ObjectFactory callback interfaces like IApplicationContextAware - /// are not automatically applied to Quartz Job instances, because Quartz - /// itself is responsible for the lifecycle of its Jobs. - ///

- ///

- /// Note: When using persistent job stores where JobDetail contents will - /// be kept in the database, do not put an IApplicationContext reference into - /// the JobDataMap but rather into the SchedulerContext. - ///

- ///
- /// - /// - public virtual string ApplicationContextJobDataKey - { - set { applicationContextJobDataKey = value; } - } - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public virtual void AfterPropertiesSet() - { - if (Name == null) - { - Name = objectName; - } - if (Group == null) - { - Group = SchedulerConstants.DefaultGroup; - } - if (applicationContextJobDataKey != null) - { - if (applicationContext == null) - { - throw new ArgumentException("JobDetailObject needs to be set up in an IApplicationContext " + - "to be able to handle an 'applicationContextJobDataKey'"); - } - JobDataMap.Put(applicationContextJobDataKey, applicationContext); - } - } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs deleted file mode 100644 index 8b1062af..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs +++ /dev/null @@ -1,160 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ - -using Common.Logging; -using Quartz; -using Quartz.Spi; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Quartz ThreadPool adapter that delegates to a Spring-managed - /// TaskExecutor instance, specified on SchedulerFactoryObject. - /// - /// Juergen Hoeller - /// - public class LocalTaskExecutorThreadPool : IThreadPool - { - /// - /// Logger available to subclasses. - /// - private readonly ILog logger; - - private ITaskExecutor taskExecutor; - - /// - /// Initializes a new instance of the class. - /// - public LocalTaskExecutorThreadPool() - { - logger = LogManager.GetLogger(GetType()); - } - - /// - /// Logger instance. - /// - protected ILog Logger - { - get { return logger; } - } - - /// - /// Gets the size of the pool. - /// - /// The size of the pool. - public virtual int PoolSize - { - get { return - 1; } - } - - /// - /// Inform the of the Scheduler instance's Id, - /// prior to initialize being invoked. - /// - public string InstanceId - { - set { } - } - - /// - /// Inform the of the Scheduler instance's name, - /// prior to initialize being invoked. - /// - public string InstanceName - { - set { } - } - - /// - /// Called by the QuartzScheduler before the is - /// used, in order to give the it a chance to Initialize. - /// - public virtual void Initialize() - { - // Absolutely needs thread-bound TaskExecutor to Initialize. - taskExecutor = SchedulerFactoryObject.ConfigTimeTaskExecutor; - if (taskExecutor == null) - { - throw new SchedulerConfigException("No local TaskExecutor found for configuration - " + - "'taskExecutor' property must be set on SchedulerFactoryObject"); - } - } - - /// - /// Called by the QuartzScheduler to inform the - /// that it should free up all of it's resources because the scheduler is - /// shutting down. - /// - /// - public virtual void Shutdown(bool waitForJobsToComplete) - { - } - - - /// - /// Execute the given in the next - /// available . - /// - /// - /// - /// - /// The implementation of this interface should not throw exceptions unless - /// there is a serious problem (i.e. a serious misconfiguration). If there - /// are no available threads, rather it should either queue the Runnable, or - /// block until a thread is available, depending on the desired strategy. - /// - public virtual bool RunInThread(IThreadRunnable runnable) - { - if (runnable == null) - { - return false; - } - try - { - taskExecutor.Execute(runnable.Run); - return true; - } - catch (TaskRejectedException ex) - { - logger.Error("Task has been rejected by TaskExecutor", ex); - return false; - } - } - - /// - /// Determines the number of threads that are currently available in in - /// the pool. Useful for determining the number of times - /// can be called before returning - /// false. - /// - /// - /// the number of currently available threads - /// - /// - /// The implementation of this method should block until there is at - /// least one available thread. - /// - public virtual int BlockForAvailableThreads() - { - // The present implementation always returns 1, making Quartz (1.6) - // always schedule any tasks that it feels like scheduling. - // This could be made smarter for specific TaskExecutors, - // for example calling getMaximumPoolSize() - getActiveCount() - // on a java.util.concurrent.ThreadPoolExecutor. - return 1; - } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs deleted file mode 100644 index e9cc7b4c..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs +++ /dev/null @@ -1,292 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ - -using System; - -using Quartz; -using Quartz.Impl; -using Spring.Objects.Factory; -using Spring.Objects.Factory.Config; -using Spring.Objects.Support; - -namespace Spring.Scheduling.Quartz -{ - /// - /// IFactoryObject that exposes a JobDetail object that delegates job execution - /// to a specified (static or non-static) method. Avoids the need to implement - /// a one-line Quartz Job that just invokes an existing service method. - /// - /// - ///

- /// Derived from ArgumentConverting MethodInvoker to share common properties and behavior - /// with MethodInvokingFactoryObject. - ///

- ///

- /// Supports both concurrently running jobs and non-currently running - /// ones through the "concurrent" property. Jobs created by this - /// MethodInvokingJobDetailFactoryObject are by default volatile and durable - /// (according to Quartz terminology). - ///

- ///

NOTE: JobDetails created via this FactoryObject are not - /// serializable and thus not suitable for persistent job stores. - /// You need to implement your own Quartz Job as a thin wrapper for each case - /// where you want a persistent job to delegate to a specific service method. - ///

- ///
- /// Juergen Hoeller - /// Alef Arendsen - /// - /// - public class MethodInvokingJobDetailFactoryObject : ArgumentConvertingMethodInvoker, - IObjectFactoryAware, - IFactoryObject, - IObjectNameAware, - IInitializingObject - { - private string name; - private string group; - private bool concurrent = true; - private string[] jobListenerNames; - private string targetObjectName; - private string objectName; - private JobDetailImpl jobDetail; - private IObjectFactory objectFactory; - - /// - /// Initializes a new instance of the class. - /// - public MethodInvokingJobDetailFactoryObject() - { - group = SchedulerConstants.DefaultGroup; - } - - - /// - /// Set the name of the job. - /// Default is the object name of this FactoryObject. - /// - /// - public virtual string Name - { - set { name = value; } - } - - /// - /// Set the group of the job. - /// Default is the default group of the Scheduler. - /// - /// - /// - public virtual string Group - { - set { group = value; } - } - - /// - /// Specify whether or not multiple jobs should be run in a concurrent - /// fashion. The behavior when one does not want concurrent jobs to be - /// executed is realized through adding the attribute. - /// More information on stateful versus stateless jobs can be found - /// here. - ///

- /// The default setting is to run jobs concurrently. - ///

- ///
- public virtual bool Concurrent - { - set { concurrent = value; } - } - - /// - /// Gets the job detail. - /// - /// The job detail. - protected IJobDetail JobDetail - { - get { return jobDetail; } - } - - /// - /// Set a list of JobListener names for this job, referring to - /// non-global JobListeners registered with the Scheduler. - /// - /// - /// A JobListener name always refers to the name returned - /// by the JobListener implementation. - /// - /// - /// - public virtual string[] JobListenerNames - { - set { jobListenerNames = value; } - } - - /// - /// Set the name of the object in the object factory that created this object. - /// - /// The name of the object in the factory. - /// - /// Invoked after population of normal object properties but before an init - /// callback like 's - /// - /// method or a custom init-method. - /// - public virtual string ObjectName - { - set { objectName = value; } - } - - /// - /// Set the name of the target object in the Spring object factory. - /// - /// - /// This is an alternative to specifying TargetObject - /// allowing for non-singleton objects to be invoked. Note that specified - /// "TargetObject" and "TargetType" values will - /// override the corresponding effect of this "TargetObjectName" setting - ///(i.e. statically pre-define the object type or even the target object). - /// - public string TargetObjectName - { - set { targetObjectName = value; } - } - - /// - /// Sets the object factory. - /// - /// The object factory. - public IObjectFactory ObjectFactory - { - set { objectFactory = value; } - } - - /// - /// Return an instance (possibly shared or independent) of the object - /// managed by this factory. - /// - /// - /// An instance (possibly shared or independent) of the object managed by - /// this factory. - /// - /// - /// - /// If this method is being called in the context of an enclosing IoC container and - /// returns , the IoC container will consider this factory - /// object as not being fully initialized and throw a corresponding (and most - /// probably fatal) exception. - /// - /// - public virtual object GetObject() - { - return jobDetail; - } - - /// - /// Return the of object that this - /// creates, or - /// if not known in advance. - /// - /// - public virtual Type ObjectType - { - get - { - if (targetObjectName != null) - { - if (objectFactory == null) - { - throw new InvalidOperationException("ObjectFactory must be set when using 'TargetObjectName'"); - } - return objectFactory.GetType(targetObjectName); - } - return typeof(IJobDetail); - } - } - - /// - /// Is the object managed by this factory a singleton or a prototype? - /// - /// - public virtual bool IsSingleton - { - get { return true; } - } - - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public virtual void AfterPropertiesSet() - { - Prepare(); - - // Use specific name if given, else fall back to object name. - string jobDetailName = name ?? objectName; - - // Consider the concurrent flag to choose between stateful and stateless job. - Type jobType = (concurrent ? typeof (MethodInvokingJob) : typeof (StatefulMethodInvokingJob)); - - // Build JobDetail instance. - jobDetail = new JobDetailImpl(jobDetailName, group, jobType); - jobDetail.JobDataMap.Put("methodInvoker", this); - jobDetail.Durable = true; - - // job listeners through configuration are no longer supported - if (jobListenerNames != null && jobListenerNames.Length > 0) - { - throw new InvalidOperationException("Non-global IJobListeners not supported on Quartz 2 - " + - "manually register a Matcher against the Quartz ListenerManager instead"); - } - - PostProcessJobDetail(jobDetail); - } - - /// - /// Callback for post-processing the JobDetail to be exposed by this FactoryObject. - ///

- /// The default implementation is empty. Can be overridden in subclasses. - ///

- ///
- /// the JobDetail prepared by this FactoryObject - protected virtual void PostProcessJobDetail(IJobDetail detail) - { - } - - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/QuartzJobObject.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/QuartzJobObject.cs deleted file mode 100644 index 7340781a..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/QuartzJobObject.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ -using Quartz; - -using Spring.Objects; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Simple implementation of the Quartz Job interface, applying the - /// passed-in JobDataMap and also the SchedulerContext as object property - /// values. This is appropriate because a new Job instance will be created - /// for each execution. JobDataMap entries will override SchedulerContext - /// entries with the same keys. - /// - /// - ///

- /// For example, let's assume that the JobDataMap contains a key - /// "myParam" with value "5": The Job implementation can then expose - /// a object property "myParam" of type int to receive such a value, - /// i.e. a method "setMyParam(int)". This will also work for complex - /// types like business objects etc. - ///

- /// - ///

- /// Note: The QuartzJobObject class itself only implements the standard - /// Quartz IJob interface. Let your subclass explicitly implement the - /// Quartz IStatefulJob interface to mark your concrete job object as stateful. - ///

- ///
- /// Juergen Hoeller - /// - /// - /// - /// - /// - /// - /// - public abstract class QuartzJobObject : IJob - { - /// - /// This implementation applies the passed-in job data map as object property - /// values, and delegates to ExecuteInternal afterwards. - /// - /// - public void Execute(IJobExecutionContext context) - { - try - { - ObjectWrapper bw = new ObjectWrapper(this); - MutablePropertyValues pvs = new MutablePropertyValues(); - pvs.AddAll(context.Scheduler.Context); - pvs.AddAll(context.MergedJobDataMap); - bw.SetPropertyValues(pvs, true); - } - catch (SchedulerException ex) - { - throw new JobExecutionException(ex); - } - ExecuteInternal(context); - } - - /// - /// Execute the actual job. The job data map will already have been - /// applied as object property values by execute. The contract is - /// exactly the same as for the standard Quartz execute method. - /// - /// - protected abstract void ExecuteInternal(IJobExecutionContext context); - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleThreadPoolTaskExecutor.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleThreadPoolTaskExecutor.cs deleted file mode 100644 index b1cd9f67..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleThreadPoolTaskExecutor.cs +++ /dev/null @@ -1,127 +0,0 @@ -/* -* Copyright 2002-2010 the original author or authors. -* -* Licensed 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. -*/ -using System; -using System.Threading; - -using Quartz; -using Quartz.Simpl; -using Spring.Objects.Factory; - -namespace Spring.Scheduling.Quartz -{ - /// - /// Subclass of Quartz's SimpleThreadPool that implements Spring's - /// TaskExecutor interface and listens to Spring lifecycle callbacks. - /// - /// Juergen Hoeller - /// - /// - /// - public class SimpleThreadPoolTaskExecutor : SimpleThreadPool, ISchedulingTaskExecutor, IInitializingObject, IDisposable - { - private bool waitForJobsToCompleteOnShutdown = false; - - /// - /// Set whether to wait for running jobs to complete on Shutdown. - /// Default is "false". - /// - /// - /// true if [wait for jobs to complete on shutdown]; otherwise, false. - /// - /// - public virtual bool WaitForJobsToCompleteOnShutdown - { - set { waitForJobsToCompleteOnShutdown = value; } - } - - /// - /// Invoked by an - /// after it has injected all of an object's dependencies. - /// - /// - ///

- /// This method allows the object instance to perform the kind of - /// initialization only possible when all of it's dependencies have - /// been injected (set), and to throw an appropriate exception in the - /// event of misconfiguration. - ///

- ///

- /// Please do consult the class level documentation for the - /// interface for a - /// description of exactly when this method is invoked. In - /// particular, it is worth noting that the - /// - /// and - /// callbacks will have been invoked prior to this method being - /// called. - ///

- ///
- /// - /// In the event of misconfiguration (such as the failure to set a - /// required property) or if initialization fails. - /// - public virtual void AfterPropertiesSet() - { - Initialize(); - } - - /// - /// Executes the specified task. - /// - /// The task. - public virtual void Execute(ThreadStart task) - { - if (task == null) - { - throw new ArgumentException("Runnable must not be null", "task"); - } - if (!RunInThread(new ThreadRunnableDelegate(task))) - { - throw new SchedulingException("Quartz SimpleThreadPool already shut down"); - } - } - - /// This task executor prefers short-lived work units. - public virtual bool PrefersShortLivedTasks - { - get { return true; } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public virtual void Dispose() - { - Shutdown(waitForJobsToCompleteOnShutdown); - } - - internal class ThreadRunnableDelegate : IThreadRunnable - { - private ThreadStart ts; - - - public ThreadRunnableDelegate(ThreadStart ts) - { - this.ts = ts; - } - - public void Run() - { - ts.Invoke(); - } - } - } -} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/TaskRejectedException.cs b/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/TaskRejectedException.cs deleted file mode 100644 index 4ac25434..00000000 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/TaskRejectedException.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Spring.Scheduling -{ - /// - /// Summary description for TaskRejectedException. - /// - public class TaskRejectedException : ApplicationException - { - } -} diff --git a/src/Spring/Spring.Scheduling.Quartz2/AssemblyInfo.cs b/src/Spring/Spring.Scheduling.Quartz3/AssemblyInfo.cs similarity index 96% rename from src/Spring/Spring.Scheduling.Quartz2/AssemblyInfo.cs rename to src/Spring/Spring.Scheduling.Quartz3/AssemblyInfo.cs index 33f45b2a..21c5617e 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/AssemblyInfo.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/AssemblyInfo.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright © 2002-2011 the original author or authors. * @@ -16,8 +14,6 @@ * limitations under the License. */ -#endregion - using System.Reflection; using System.Runtime.InteropServices; diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/AdaptableJobFactory.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/AdaptableJobFactory.cs new file mode 100644 index 00000000..28df74f9 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/AdaptableJobFactory.cs @@ -0,0 +1,129 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using System; +using System.Threading; +using System.Threading.Tasks; +using Quartz; +using Quartz.Spi; +using Quartz.Util; + +namespace Spring.Scheduling.Quartz +{ + /// + /// JobFactory implementation that supports + /// objects as well as standard Quartz instances. + /// + /// Juergen Hoeller + /// Marko Lahma (.NET) + /// + /// + public class AdaptableJobFactory : IJobFactory + { + /// + /// Called by the scheduler at the time of the trigger firing, in order to + /// produce a instance on which to call Execute. + /// + /// + /// It should be extremely rare for this method to throw an exception - + /// basically only the the case where there is no way at all to instantiate + /// and prepare the Job for execution. When the exception is thrown, the + /// Scheduler will move all triggers associated with the Job into the + /// state, which will require human + /// intervention (e.g. an application restart after fixing whatever + /// configuration problem led to the issue wih instantiating the Job. + /// + /// The TriggerFiredBundle from which the + /// and other info relating to the trigger firing can be obtained. + /// The scheduler instance. + /// the newly instantiated Job + /// SchedulerException if there is a problem instantiating the Job. + public virtual IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) + { + try + { + object jobObject = CreateJobInstance(bundle); + return AdaptJob(jobObject); + } + catch (Exception ex) + { + throw new SchedulerException("Job instantiation failed", ex); + } + } + + /// + /// Allows the the job factory to destroy/cleanup the job if needed. + /// + public virtual void ReturnJob(IJob job) + { + } + + /// + /// Create an instance of the specified job class. + ///

+ /// Can be overridden to post-process the job instance. + ///

+ ///
+ /// + /// The TriggerFiredBundle from which the JobDetail + /// and other info relating to the trigger firing can be obtained. + /// + /// The job instance. + protected virtual object CreateJobInstance(TriggerFiredBundle bundle) + { + return ObjectUtils.InstantiateType(bundle.JobDetail.JobType); + } + + /// + /// Adapt the given job object to the Quartz Job interface. + /// + /// + /// The default implementation supports straight Quartz Jobs + /// as well as Runnables, which get wrapped in a DelegatingJob. + /// + /// + /// The original instance of the specified job class. + /// + /// The adapted Quartz Job instance. + /// + protected virtual IJob AdaptJob(object jobObject) + { + if (jobObject is IJob job) + { + return job; + } + + if (jobObject is ThreadStart start) + { + return new DelegatingJob(start); + } + + if (jobObject is IThreadRunnable threadRunnable) + { + return new DelegatingJob(() => threadRunnable.Run().ConfigureAwait(false).GetAwaiter().GetResult()); + } + + if (jobObject is Func func) + { + return new DelegatingJob(() => func().ConfigureAwait(false).GetAwaiter().GetResult()); + } + + string message = + $"Unable to execute job class [{jobObject.GetType().FullName}]: only [IJob] and [ThreadStart] supported."; + throw new ArgumentException(message); + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/CronTriggerObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/CronTriggerObject.cs similarity index 56% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/CronTriggerObject.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/CronTriggerObject.cs index e4d16921..a4623c6d 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/CronTriggerObject.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/CronTriggerObject.cs @@ -17,7 +17,6 @@ using System; using System.Collections; using System.Reflection; - using Quartz; using Quartz.Impl.Triggers; using Spring.Objects.Factory; @@ -25,69 +24,73 @@ using Spring.Util; namespace Spring.Scheduling.Quartz { - /// - /// Convenience subclass of Quartz's CronTrigger type, making property based - /// usage easier. - /// - /// - ///

- /// CronTrigger itself is already property based but lacks sensible defaults. - /// This class uses the Spring object name as job name, the Quartz default group - /// ("DEFAULT") as job group, the current time as start time, and indefinite - /// repetition, if not specified. - ///

- ///

- /// This class will also register the trigger with the job name and group of - /// a given . This allows - /// to automatically register a trigger for the corresponding JobDetail, - /// instead of registering the JobDetail separately. - ///

- ///
- /// Juergen Hoeller + /// + /// Convenience subclass of Quartz's CronTrigger type, making property based + /// usage easier. + /// + /// + ///

+ /// CronTrigger itself is already property based but lacks sensible defaults. + /// This class uses the Spring object name as job name, the Quartz default group + /// ("DEFAULT") as job group, the current time as start time, and indefinite + /// repetition, if not specified. + ///

+ ///

+ /// This class will also register the trigger with the job name and group of + /// a given . This allows + /// to automatically register a trigger for the corresponding JobDetail, + /// instead of registering the JobDetail separately. + ///

+ ///
+ /// Juergen Hoeller /// /// /// /// - /// - /// - public class CronTriggerObject : CronTriggerImpl, IJobDetailAwareTrigger, IObjectNameAware, IInitializingObject - { - private readonly Constants constants = new Constants(typeof(MisfireInstruction.CronTrigger), typeof(MisfireInstruction)); + /// + /// + public class CronTriggerObject : CronTriggerImpl, IJobDetailAwareTrigger, IObjectNameAware, IInitializingObject + { + private readonly Constants constants = new Constants( + typeof(MisfireInstruction.CronTrigger), + typeof(MisfireInstruction) + ); + private IJobDetail jobDetail; - private string objectName; - private TimeSpan startDelay; + private string objectName; + private TimeSpan startDelay; - /// - /// Register objects in the JobDataMap via a given Map. - /// - /// - /// These objects will be available to this Trigger only, - /// in contrast to objects in the JobDetail's data map. - /// - /// - public virtual IDictionary JobDataAsMap - { - set - { - foreach (DictionaryEntry entry in value) - { - JobDataMap.Put((string) entry.Key, entry.Value); - } - } - } + /// + /// Register objects in the JobDataMap via a given Map. + /// + /// + /// These objects will be available to this Trigger only, + /// in contrast to objects in the JobDetail's data map. + /// + /// + public virtual IDictionary JobDataAsMap + { + set + { + foreach (DictionaryEntry entry in value) + { + JobDataMap.Put((string) entry.Key, entry.Value); + } + } + } - /// - /// Set the misfire instruction via the name of the corresponding - /// constant in the CronTrigger class. + /// + /// Set the misfire instruction via the name of the corresponding + /// constant in the CronTrigger class. /// Default is . - /// + /// /// /// /// - public virtual string MisfireInstructionName - { - set { MisfireInstruction = constants.AsNumber(value); } - } + public virtual string MisfireInstructionName + { + set => MisfireInstruction = constants.AsNumber(value); + } /// /// Set the name of the object in the object factory that created this object. @@ -101,25 +104,25 @@ namespace Spring.Scheduling.Quartz /// method or a custom init-method. ///

/// - public virtual string ObjectName - { - set { objectName = value; } - } + public virtual string ObjectName + { + set => objectName = value; + } - /// - /// Set the JobDetail that this trigger should be associated with. - /// - /// - /// This is typically used with a object reference if the JobDetail - /// is a Spring-managed object. Alternatively, the trigger can also - /// be associated with a job by name and group. - /// - /// - public virtual IJobDetail JobDetail - { - get { return jobDetail; } - set { jobDetail = value; } - } + /// + /// Set the JobDetail that this trigger should be associated with. + /// + /// + /// This is typically used with a object reference if the JobDetail + /// is a Spring-managed object. Alternatively, the trigger can also + /// be associated with a job by name and group. + /// + /// + public virtual IJobDetail JobDetail + { + get => jobDetail; + set => jobDetail = value; + } /// /// Set the start delay as . @@ -136,17 +139,17 @@ namespace Spring.Scheduling.Quartz /// /// /// the start delay, as object. - public TimeSpan StartDelay + public TimeSpan StartDelay { set - { - AssertUtils.State(value >= TimeSpan.Zero, "Start delay cannot be negative."); - startDelay = value; - } - get { return startDelay; } + { + AssertUtils.State(value >= TimeSpan.Zero, "Start delay cannot be negative."); + startDelay = value; + } + get => startDelay; } - /// + /// /// Invoked by an /// after it has injected all of an object's dependencies. /// @@ -172,31 +175,35 @@ namespace Spring.Scheduling.Quartz /// In the event of misconfiguration (such as the failure to set a /// required property) or if initialization fails. /// - public virtual void AfterPropertiesSet() - { + public virtual void AfterPropertiesSet() + { if (StartTimeUtc == DateTimeOffset.MinValue) { StartTimeUtc = DateTimeOffset.UtcNow; } + if (StartDelay > TimeSpan.Zero) { StartTimeUtc = DateTime.UtcNow.Add(startDelay); } - if (Name == null) - { - Name = objectName; - } - if (Group == null) - { + + if (Name == null) + { + Name = objectName; + } + + if (Group == null) + { Group = SchedulerConstants.DefaultGroup; - } - if (jobDetail != null) - { - JobName = jobDetail.Key.Name; - JobGroup = jobDetail.Key.Group; - } - } - } + } + + if (jobDetail != null) + { + JobName = jobDetail.Key.Name; + JobGroup = jobDetail.Key.Group; + } + } + } /// /// Helper class to map constant names to their values. @@ -222,7 +229,7 @@ namespace Spring.Scheduling.Quartz } // not found - throw new Exception(string.Format("Unknown field '{0}'", field)); + throw new Exception($"Unknown field '{field}'"); } } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/DelegatingJob.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/DelegatingJob.cs similarity index 53% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/DelegatingJob.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/DelegatingJob.cs index e43dce6c..07a44e04 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/DelegatingJob.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/DelegatingJob.cs @@ -13,59 +13,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using System.Threading; - +using System.Threading.Tasks; using Quartz; - using Spring.Util; namespace Spring.Scheduling.Quartz { - /// - /// Simple Quartz IJob adapter that delegates to a + /// + /// Simple Quartz IJob adapter that delegates to a /// given instance. /// /// - /// Typically used in combination with property injection on the - /// Runnable instance, receiving parameters from the Quartz JobDataMap - /// that way instead of via the JobExecutionContext. + /// Typically used in combination with property injection on the + /// Runnable instance, receiving parameters from the Quartz JobDataMap + /// that way instead of via the JobExecutionContext. /// - /// Juergen Hoeller - /// Marko Lahma (.NET) - /// - /// - public class DelegatingJob : IJob - { + /// Juergen Hoeller + /// Marko Lahma (.NET) + /// + /// + public class DelegatingJob : IJob + { private readonly ThreadStart delegateInstance; - /// - /// Return the wrapped Runnable implementation. + /// + /// Create a new DelegatingJob. /// - /// The delegate. - public virtual ThreadStart Delegate - { - get { return delegateInstance; } - } - - /// - /// Create a new DelegatingJob. - /// - /// - /// The Runnable implementation to delegate to. - /// + /// + /// The Runnable implementation to delegate to. + /// public DelegatingJob(ThreadStart delegateInstance) - { + { AssertUtils.ArgumentNotNull(delegateInstance, "delegateInstance", "Delegate must not be null"); - this.delegateInstance = delegateInstance; - } + this.delegateInstance = delegateInstance; + } - - /// + /// /// Delegates execution to the underlying ThreadStart. - /// - public virtual void Execute(IJobExecutionContext context) - { + /// + public virtual Task Execute(IJobExecutionContext context) + { delegateInstance.Invoke(); - } - } + return Task.FromResult(true); + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IJobDetailAwareTrigger.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IJobDetailAwareTrigger.cs new file mode 100644 index 00000000..f083085d --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IJobDetailAwareTrigger.cs @@ -0,0 +1,48 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using Quartz; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Interface to be implemented by Quartz Triggers that are aware + /// of the JobDetail object that they are associated with. + /// + /// + ///

+ /// SchedulerFactoryObject will auto-detect Triggers that implement this + /// interface and register them for the respective JobDetail accordingly. + ///

+ /// + ///

+ /// The alternative is to configure a Trigger for a Job name and group: + /// This involves the need to register the JobDetail object separately + /// with SchedulerFactoryObject. + ///

+ ///
+ /// Juergen Hoeller + /// + /// + public interface IJobDetailAwareTrigger + { + /// + /// Return the JobDetail that this Trigger is associated with. + /// + /// The associated JobDetail, or null if none + IJobDetail JobDetail { get; } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ISchedulerContextAware.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ISchedulerContextAware.cs new file mode 100644 index 00000000..fa4742d6 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ISchedulerContextAware.cs @@ -0,0 +1,42 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using Quartz; +using Quartz.Spi; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Callback interface to be implemented by Spring-managed + /// Quartz artifacts that need access to the SchedulerContext + /// (without having natural access to it). + /// + /// + /// Currently only supported for custom JobFactory implementations + /// that are passed in via Spring's SchedulerFactoryObject. + /// + /// Juergen Hoeller + /// + /// + public interface ISchedulerContextAware + { + /// + /// Set the SchedulerContext of the current Quartz Scheduler. + /// + /// + SchedulerContext SchedulerContext { set; } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ISchedulingTaskExecutor.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ISchedulingTaskExecutor.cs similarity index 100% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ISchedulingTaskExecutor.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ISchedulingTaskExecutor.cs diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ITaskExecutor.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ITaskExecutor.cs similarity index 75% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ITaskExecutor.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ITaskExecutor.cs index 93952687..c59eee19 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/ITaskExecutor.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/ITaskExecutor.cs @@ -18,14 +18,14 @@ using System.Threading; namespace Spring.Scheduling { - /// - /// - /// - public interface ITaskExecutor - { - /// - /// Executes this instance. - /// - void Execute(ThreadStart runnable); - } -} + /// + /// + /// + public interface ITaskExecutor + { + /// + /// Executes this instance. + /// + void Execute(ThreadStart runnable); + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IThreadRunnable.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IThreadRunnable.cs new file mode 100644 index 00000000..93b2377c --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/IThreadRunnable.cs @@ -0,0 +1,33 @@ +#region License +// /* +// * Copyright 2018 the original author or authors. +// * +// * Licensed 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. +// */ +#endregion + +using System.Threading.Tasks; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Adapter interface as Quartz no longer has this interface. + /// + public interface IThreadRunnable + { + /// + /// Runs thread runnable. + /// + Task Run(); + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobDetailObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobDetailObject.cs new file mode 100644 index 00000000..9cc9be26 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobDetailObject.cs @@ -0,0 +1,224 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using System; +using System.Collections; +using Quartz; +using Quartz.Impl; +using Spring.Context; +using Spring.Objects.Factory; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Convenience subclass of Quartz' JobDetail class that eases properties based + /// usage. + /// + /// + /// itself is already a object but lacks + /// sensible defaults. This class uses the Spring object name as job name, + /// and the Quartz default group ("DEFAULT") as job group if not specified. + /// + /// Juergen Hoeller + /// + /// + public class JobDetailObject : JobDetailImpl, IObjectNameAware, IApplicationContextAware, IInitializingObject + { + private Type actualJobType; + private string objectName; + private IApplicationContext applicationContext; + private string applicationContextJobDataKey; + + /// + /// Overridden to support any job class, to allow a custom JobFactory + /// to adapt the given job class to the Quartz Job interface. + /// + /// + public override Type JobType + { + get => actualJobType ?? base.JobType; + + set + { + if (value != null && !typeof(IJob).IsAssignableFrom(value)) + { + base.JobType = typeof(DelegatingJob); + actualJobType = value; + } + else + { + base.JobType = value; + } + } + } + + /// + /// Register objects in the JobDataMap via a given Map. + /// + /// + /// These objects will be available to this Job only, + /// in contrast to objects in the SchedulerContext. + ///

+ /// Note: When using persistent Jobs whose JobDetail will be kept in the + /// database, do not put Spring-managed objects or an ApplicationContext + /// reference into the JobDataMap but rather into the SchedulerContext. + ///

+ ///
+ /// + public virtual IDictionary JobDataAsMap + { + set + { + if (value == null) + { + throw new ArgumentException("Value cannot be null", "value"); + } + + foreach (DictionaryEntry entry in value) + { + JobDataMap.Put((string) entry.Key, entry.Value); + } + } + } + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// The name of the object in the factory. + /// + /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + /// + public virtual string ObjectName + { + set => objectName = value; + } + + /// + /// Gets or sets the that this + /// object runs in. + /// + /// + /// + ///

+ /// Normally this call will be used to initialize the object. + ///

+ ///

+ /// Invoked after population of normal object properties but before an + /// init callback such as + /// 's + /// + /// or a custom init-method. Invoked after the setting of any + /// 's + /// + /// property. + ///

+ ///
+ /// + /// In the case of application context initialization errors. + /// + /// + /// If thrown by any application context methods. + /// + /// + public virtual IApplicationContext ApplicationContext + { + set => applicationContext = value; + get => applicationContext; + } + + /// + /// Set the key of an IApplicationContext reference to expose in the JobDataMap, + /// for example "applicationContext". Default is none. + /// Only applicable when running in a Spring ApplicationContext. + /// + /// + ///

+ /// In case of a QuartzJobObject, the reference will be applied to the Job + /// instance as object property. An "applicationContext" attribute will correspond + /// to a "setApplicationContext" method in that scenario. + ///

+ ///

+ /// Note that ObjectFactory callback interfaces like IApplicationContextAware + /// are not automatically applied to Quartz Job instances, because Quartz + /// itself is responsible for the lifecycle of its Jobs. + ///

+ ///

+ /// Note: When using persistent job stores where JobDetail contents will + /// be kept in the database, do not put an IApplicationContext reference into + /// the JobDataMap but rather into the SchedulerContext. + ///

+ ///
+ /// + /// + public virtual string ApplicationContextJobDataKey + { + set => applicationContextJobDataKey = value; + } + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public virtual void AfterPropertiesSet() + { + if (Name == null) + { + Name = objectName; + } + + if (Group == null) + { + Group = SchedulerConstants.DefaultGroup; + } + + if (applicationContextJobDataKey != null) + { + if (applicationContext == null) + { + throw new ArgumentException("JobDetailObject needs to be set up in an IApplicationContext " + + "to be able to handle an 'applicationContextJobDataKey'"); + } + + JobDataMap.Put(applicationContextJobDataKey, applicationContext); + } + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/JobMethodInvocationFailedException.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobMethodInvocationFailedException.cs similarity index 90% rename from src/Spring/Spring.Scheduling.Quartz2/JobMethodInvocationFailedException.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobMethodInvocationFailedException.cs index 140da946..648dfb7f 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/JobMethodInvocationFailedException.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/JobMethodInvocationFailedException.cs @@ -15,7 +15,6 @@ */ using System; - using Spring.Objects.Support; namespace Spring.Scheduling.Quartz @@ -35,12 +34,9 @@ namespace Spring.Scheduling.Quartz /// the MethodInvoker used for reflective invocation /// the root cause (as thrown from the target method) public JobMethodInvocationFailedException(MethodInvoker methodInvoker, Exception cause) : - base("Invocation of method '" + methodInvoker.TargetMethod + - "' on target class [" + methodInvoker.TargetType + "] failed", cause) + base("Invocation of method '" + methodInvoker.TargetMethod + + "' on target class [" + methodInvoker.TargetType + "] failed", cause) { - } - } -} - +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalDataSourceJobStore.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalDataSourceJobStore.cs similarity index 89% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalDataSourceJobStore.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalDataSourceJobStore.cs index bec9799e..c3cd83bf 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/LocalDataSourceJobStore.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalDataSourceJobStore.cs @@ -14,10 +14,10 @@ * limitations under the License. */ +using System.Data.Common; using Quartz; using Quartz.Impl.AdoJobStore; using Quartz.Util; - using Spring.Data.Support; namespace Spring.Scheduling.Quartz @@ -48,7 +48,7 @@ namespace Spring.Scheduling.Quartz /// /// ///
- public const string TX_DATA_SOURCE_PREFIX = "springTxDataSource."; + public const string TxDataSourcePrefix = "springTxDataSource."; private Data.Common.IDbProvider dbProvider; @@ -58,12 +58,12 @@ namespace Spring.Scheduling.Quartz /// The name of the instance. public override string InstanceName { - get { return base.InstanceName; } + get => base.InstanceName; set { // use to catch property setting base.InstanceName = value; - DataSource = TX_DATA_SOURCE_PREFIX + InstanceName; + DataSource = TxDataSourcePrefix + InstanceName; // Register transactional ConnectionProvider for Quartz. // Absolutely needs thread-bound DataSource to initialize. dbProvider = SchedulerFactoryObject.ConfigTimeDbProvider; @@ -72,10 +72,10 @@ namespace Spring.Scheduling.Quartz throw new SchedulerConfigException( "No db provider found for configuration - " + "'DbProvider' property must be set on SchedulerFactoryObject"); - } - DBConnectionManager.Instance.AddConnectionProvider( - TX_DATA_SOURCE_PREFIX + InstanceName, new SpringDbProviderAdapter(dbProvider)); + } + DBConnectionManager.Instance.AddConnectionProvider( + TxDataSourcePrefix + InstanceName, new SpringDbProviderAdapter(dbProvider)); } } @@ -86,7 +86,7 @@ namespace Spring.Scheduling.Quartz protected override ConnectionAndTransactionHolder GetNonManagedTXConnection() { ConnectionTxPair pair = ConnectionUtils.DoGetConnection(dbProvider); - return new ConnectionAndTransactionHolder(pair.Connection, pair.Transaction); + return new ConnectionAndTransactionHolder((DbConnection) pair.Connection, (DbTransaction) pair.Transaction); } /// @@ -99,4 +99,4 @@ namespace Spring.Scheduling.Quartz ConnectionUtils.DisposeConnection(connectionAndTransactionHolder.Connection, dbProvider); } } -} +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs new file mode 100644 index 00000000..1ac44cba --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/LocalTaskExecutorThreadPool.cs @@ -0,0 +1,111 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using System; +using System.Threading.Tasks; +using Common.Logging; +using Quartz; +using Quartz.Spi; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Quartz ThreadPool adapter that delegates to a Spring-managed + /// TaskExecutor instance, specified on SchedulerFactoryObject. + /// + /// Juergen Hoeller + /// + public class LocalTaskExecutorThreadPool : IThreadPool + { + private ITaskExecutor taskExecutor; + + /// + /// Initializes a new instance of the class. + /// + public LocalTaskExecutorThreadPool() + { + Logger = LogManager.GetLogger(GetType()); + } + + /// + /// Logger instance. + /// + protected ILog Logger { get; } + + /// + public virtual int PoolSize => -1; + + /// + public string InstanceId + { + set { } + } + + /// + public string InstanceName + { + set { } + } + + /// + public virtual void Initialize() + { + // Absolutely needs thread-bound TaskExecutor to Initialize. + taskExecutor = SchedulerFactoryObject.ConfigTimeTaskExecutor; + if (taskExecutor == null) + { + throw new SchedulerConfigException("No local TaskExecutor found for configuration - " + + "'taskExecutor' property must be set on SchedulerFactoryObject"); + } + } + + /// + public virtual void Shutdown(bool waitForJobsToComplete) + { + } + + /// + public virtual bool RunInThread(Func runnable) + { + if (runnable == null) + { + return false; + } + + try + { + taskExecutor.Execute(() => runnable().ConfigureAwait(false).GetAwaiter().GetResult()); + return true; + } + catch (TaskRejectedException ex) + { + Logger.Error("Task has been rejected by TaskExecutor", ex); + return false; + } + } + + /// + public virtual int BlockForAvailableThreads() + { + // The present implementation always returns 1, making Quartz (1.6) + // always schedule any tasks that it feels like scheduling. + // This could be made smarter for specific TaskExecutors, + // for example calling getMaximumPoolSize() - getActiveCount() + // on a java.util.concurrent.ThreadPoolExecutor. + return 1; + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJob.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJob.cs similarity index 84% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJob.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJob.cs index 5e080385..aefe1de1 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingJob.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJob.cs @@ -16,11 +16,9 @@ using System; using System.Reflection; - +using System.Threading.Tasks; using Common.Logging; - using Quartz; - using Spring.Objects.Support; namespace Spring.Scheduling.Quartz @@ -42,28 +40,23 @@ namespace Spring.Scheduling.Quartz { set { - if (value == null) - { - throw new ArgumentException("Method invoker cannot be null", "value"); - } - methodInvoker = value; + methodInvoker = value ?? throw new ArgumentException("Method invoker cannot be null", nameof(value)); errorMessage = - string.Format("Could not invoke method '{0}' on target object [{1}]", methodInvoker.TargetMethod, - methodInvoker.TargetObject); + $"Could not invoke method '{methodInvoker.TargetMethod}' on target object [{methodInvoker.TargetObject}]"; } } - /// /// Invoke the method via the MethodInvoker. /// /// - protected override void ExecuteInternal(IJobExecutionContext context) + protected override Task ExecuteInternal(IJobExecutionContext context) { if (methodInvoker == null) { throw new JobExecutionException("Could not execute job when method invoker is null"); } + try { context.Result = methodInvoker.Invoke(); @@ -76,15 +69,17 @@ namespace Spring.Scheduling.Quartz // -> JobExecutionException, to be logged at info level by Quartz throw ex.GetBaseException(); } + // -> "unhandled exception", to be logged at error level by Quartz throw new JobMethodInvocationFailedException(methodInvoker, ex.GetBaseException()); } catch (Exception ex) { // -> "unhandled exception", to be logged at error level by Quartz - throw new JobMethodInvocationFailedException(methodInvoker, ex.GetBaseException()); + throw new JobMethodInvocationFailedException(methodInvoker, ex.GetBaseException()); } + + return Task.FromResult(true); } } - -} +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs new file mode 100644 index 00000000..b0766105 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingJobDetailFactoryObject.cs @@ -0,0 +1,284 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using System; +using Quartz; +using Quartz.Impl; +using Spring.Objects.Factory; +using Spring.Objects.Factory.Config; +using Spring.Objects.Support; + +namespace Spring.Scheduling.Quartz +{ + /// + /// IFactoryObject that exposes a JobDetail object that delegates job execution + /// to a specified (static or non-static) method. Avoids the need to implement + /// a one-line Quartz Job that just invokes an existing service method. + /// + /// + ///

+ /// Derived from ArgumentConverting MethodInvoker to share common properties and behavior + /// with MethodInvokingFactoryObject. + ///

+ ///

+ /// Supports both concurrently running jobs and non-currently running + /// ones through the "concurrent" property. Jobs created by this + /// MethodInvokingJobDetailFactoryObject are by default volatile and durable + /// (according to Quartz terminology). + ///

+ ///

NOTE: JobDetails created via this FactoryObject are not + /// serializable and thus not suitable for persistent job stores. + /// You need to implement your own Quartz Job as a thin wrapper for each case + /// where you want a persistent job to delegate to a specific service method. + ///

+ ///
+ /// Juergen Hoeller + /// Alef Arendsen + /// + /// + public class MethodInvokingJobDetailFactoryObject : ArgumentConvertingMethodInvoker, + IObjectFactoryAware, + IFactoryObject, + IObjectNameAware, + IInitializingObject + { + private string name; + private string group; + private bool concurrent = true; + private string[] jobListenerNames; + private string targetObjectName; + private string objectName; + private JobDetailImpl jobDetail; + private IObjectFactory objectFactory; + + /// + /// Initializes a new instance of the class. + /// + public MethodInvokingJobDetailFactoryObject() + { + group = SchedulerConstants.DefaultGroup; + } + + /// + /// Set the name of the job. + /// Default is the object name of this FactoryObject. + /// + /// + public virtual string Name + { + set => name = value; + } + + /// + /// Set the group of the job. + /// Default is the default group of the Scheduler. + /// + /// + /// + public virtual string Group + { + set => group = value; + } + + /// + /// Specify whether or not multiple jobs should be run in a concurrent + /// fashion. The behavior when one does not want concurrent jobs to be + /// executed is realized through adding the attribute. + /// More information on stateful versus stateless jobs can be found + /// here. + ///

+ /// The default setting is to run jobs concurrently. + ///

+ ///
+ public virtual bool Concurrent + { + set => concurrent = value; + } + + /// + /// Gets the job detail. + /// + /// The job detail. + protected IJobDetail JobDetail => jobDetail; + + /// + /// Set a list of JobListener names for this job, referring to + /// non-global JobListeners registered with the Scheduler. + /// + /// + /// A JobListener name always refers to the name returned + /// by the JobListener implementation. + /// + /// + /// + public virtual string[] JobListenerNames + { + set => jobListenerNames = value; + } + + /// + /// Set the name of the object in the object factory that created this object. + /// + /// The name of the object in the factory. + /// + /// Invoked after population of normal object properties but before an init + /// callback like 's + /// + /// method or a custom init-method. + /// + public virtual string ObjectName + { + set => objectName = value; + } + + /// + /// Set the name of the target object in the Spring object factory. + /// + /// + /// This is an alternative to specifying TargetObject + /// allowing for non-singleton objects to be invoked. Note that specified + /// "TargetObject" and "TargetType" values will + /// override the corresponding effect of this "TargetObjectName" setting + ///(i.e. statically pre-define the object type or even the target object). + /// + public string TargetObjectName + { + set => targetObjectName = value; + } + + /// + /// Sets the object factory. + /// + /// The object factory. + public IObjectFactory ObjectFactory + { + set => objectFactory = value; + } + + /// + /// Return an instance (possibly shared or independent) of the object + /// managed by this factory. + /// + /// + /// An instance (possibly shared or independent) of the object managed by + /// this factory. + /// + /// + /// + /// If this method is being called in the context of an enclosing IoC container and + /// returns , the IoC container will consider this factory + /// object as not being fully initialized and throw a corresponding (and most + /// probably fatal) exception. + /// + /// + public virtual object GetObject() + { + return jobDetail; + } + + /// + /// Return the of object that this + /// creates, or + /// if not known in advance. + /// + /// + public virtual Type ObjectType + { + get + { + if (targetObjectName != null) + { + if (objectFactory == null) + { + throw new InvalidOperationException("ObjectFactory must be set when using 'TargetObjectName'"); + } + + return objectFactory.GetType(targetObjectName); + } + + return typeof(IJobDetail); + } + } + + /// + /// Is the object managed by this factory a singleton or a prototype? + /// + /// + public virtual bool IsSingleton => true; + + /// + /// Invoked by an + /// after it has injected all of an object's dependencies. + /// + /// + ///

+ /// This method allows the object instance to perform the kind of + /// initialization only possible when all of it's dependencies have + /// been injected (set), and to throw an appropriate exception in the + /// event of misconfiguration. + ///

+ ///

+ /// Please do consult the class level documentation for the + /// interface for a + /// description of exactly when this method is invoked. In + /// particular, it is worth noting that the + /// + /// and + /// callbacks will have been invoked prior to this method being + /// called. + ///

+ ///
+ /// + /// In the event of misconfiguration (such as the failure to set a + /// required property) or if initialization fails. + /// + public virtual void AfterPropertiesSet() + { + Prepare(); + + // Use specific name if given, else fall back to object name. + string jobDetailName = name ?? objectName; + + // Consider the concurrent flag to choose between stateful and stateless job. + Type jobType = (concurrent ? typeof(MethodInvokingJob) : typeof(StatefulMethodInvokingJob)); + + // Build JobDetail instance. + jobDetail = new JobDetailImpl(jobDetailName, group, jobType); + jobDetail.JobDataMap.Put("methodInvoker", this); + jobDetail.Durable = true; + + // job listeners through configuration are no longer supported + if (jobListenerNames != null && jobListenerNames.Length > 0) + { + throw new InvalidOperationException("Non-global IJobListeners not supported on Quartz 2 - " + + "manually register a Matcher against the Quartz ListenerManager instead"); + } + + PostProcessJobDetail(jobDetail); + } + + /// + /// Callback for post-processing the JobDetail to be exposed by this FactoryObject. + ///

+ /// The default implementation is empty. Can be overridden in subclasses. + ///

+ ///
+ /// the JobDetail prepared by this FactoryObject + protected virtual void PostProcessJobDetail(IJobDetail detail) + { + } + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingRunnable.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingRunnable.cs similarity index 80% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingRunnable.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingRunnable.cs index e60635cb..a462a2e5 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/MethodInvokingRunnable.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/MethodInvokingRunnable.cs @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using System; using System.Reflection; - +using System.Threading.Tasks; using Common.Logging; - -using Quartz; - using Spring.Objects.Factory; using Spring.Objects.Support; @@ -34,19 +32,6 @@ namespace Spring.Scheduling.Quartz /// Derives from ArgumentConvertingMethodInvoker, inheriting common /// configuration properties from MethodInvoker. ///

- /// - ///

- /// Useful to generically encapsulate a method invocation as timer task for - /// java.util.Timer, in combination with a DelegatingTimerTask adapter. - /// Can also be used with JDK 1.5's java.util.concurrent.Executor - /// abstraction, which works with plain Runnables. - ///

- ///

- /// Extended by Spring's MethodInvokingTimerTaskFactoryObject adapter - /// for TimerTask. Note that you can populate a - /// ScheduledTimerTask object with a plain MethodInvokingRunnable instance - /// as well, which will automatically get wrapped with a DelegatingTimerTask. - ///

/// /// Juergen Hoeller /// @@ -69,19 +54,14 @@ namespace Spring.Scheduling.Quartz /// /// Logger instance. /// - protected ILog Logger - { - get { return logger; } - } + protected ILog Logger => logger; /// /// Gets the invocation failure message. /// /// The invocation failure message. - protected virtual string InvocationFailureMessage - { - get { return string.Format("Invocation of method '{0}' on target object [{1}] failed", TargetMethod, TargetObject); } - } + protected virtual string InvocationFailureMessage => + $"Invocation of method '{TargetMethod}' on target object [{TargetObject}] failed"; /// /// Invoked by an @@ -118,7 +98,7 @@ namespace Spring.Scheduling.Quartz /// This method has to be implemented in order that starting of the thread causes the object's /// run method to be called in that separately executing thread. /// - public virtual void Run() + public virtual Task Run() { try { @@ -134,6 +114,8 @@ namespace Spring.Scheduling.Quartz logger.Error(InvocationFailureMessage, ex); // Do not throw exception, else the main loop of the Timer will stop! } + + return Task.FromResult(true); } } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/QuartzJobObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/QuartzJobObject.cs new file mode 100644 index 00000000..a79ce7b0 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/QuartzJobObject.cs @@ -0,0 +1,86 @@ +/* +* Copyright 2002-2010 the original author or authors. +* +* Licensed 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. +*/ + +using System.Threading.Tasks; +using Quartz; +using Spring.Objects; + +namespace Spring.Scheduling.Quartz +{ + /// + /// Simple implementation of the Quartz Job interface, applying the + /// passed-in JobDataMap and also the SchedulerContext as object property + /// values. This is appropriate because a new Job instance will be created + /// for each execution. JobDataMap entries will override SchedulerContext + /// entries with the same keys. + /// + /// + ///

+ /// For example, let's assume that the JobDataMap contains a key + /// "myParam" with value "5": The Job implementation can then expose + /// a object property "myParam" of type int to receive such a value, + /// i.e. a method "setMyParam(int)". This will also work for complex + /// types like business objects etc. + ///

+ /// + ///

+ /// Note: The QuartzJobObject class itself only implements the standard + /// Quartz IJob interface. Let your subclass explicitly implement the + /// Quartz IStatefulJob interface to mark your concrete job object as stateful. + ///

+ ///
+ /// Juergen Hoeller + /// + /// + /// + /// + /// + /// + /// + public abstract class QuartzJobObject : IJob + { + /// + /// This implementation applies the passed-in job data map as object property + /// values, and delegates to ExecuteInternal afterwards. + /// + /// + public Task Execute(IJobExecutionContext context) + { + try + { + ObjectWrapper bw = new ObjectWrapper(this); + MutablePropertyValues pvs = new MutablePropertyValues(); + pvs.AddAll(context.Scheduler.Context); + pvs.AddAll(context.MergedJobDataMap); + bw.SetPropertyValues(pvs, true); + } + catch (SchedulerException ex) + { + throw new JobExecutionException(ex); + } + + return ExecuteInternal(context); + } + + /// + /// Execute the actual job. The job data map will already have been + /// applied as object property values by execute. The contract is + /// exactly the same as for the standard Quartz execute method. + /// + /// + protected abstract Task ExecuteInternal(IJobExecutionContext context); + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessor.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessor.cs similarity index 83% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessor.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessor.cs index e6290307..b7000b86 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessor.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessor.cs @@ -14,16 +14,14 @@ * limitations under the License. */ - using System; using System.Collections; using System.Collections.Generic; +using System.Threading.Tasks; using Common.Logging; - using Quartz; using Quartz.Simpl; using Quartz.Xml; - using Spring.Collections; using Spring.Context; using Spring.Core.IO; @@ -48,6 +46,7 @@ namespace Spring.Scheduling.Quartz /// Logger instance. ///
private readonly ILog logger; + private bool overwriteExistingJobs; private string[] jobSchedulingDataLocations; @@ -63,6 +62,7 @@ namespace Spring.Scheduling.Quartz private ITriggerListener[] triggerListeners; private IPlatformTransactionManager transactionManager; + /// /// Resource loader instance for sub-classes /// @@ -83,10 +83,9 @@ namespace Spring.Scheduling.Quartz ///
public virtual bool OverwriteExistingJobs { - set { overwriteExistingJobs = value; } + set => overwriteExistingJobs = value; } - /// /// Set the locations of Quartz job definition XML files that follow the /// "job_scheduling_data_1_5" XSD. Can be specified to automatically @@ -96,7 +95,7 @@ namespace Spring.Scheduling.Quartz /// public virtual string[] JobSchedulingDataLocations { - set { jobSchedulingDataLocations = value; } + set => jobSchedulingDataLocations = value; } /// @@ -108,7 +107,7 @@ namespace Spring.Scheduling.Quartz /// public virtual string JobSchedulingDataLocation { - set { jobSchedulingDataLocations = new string[] {value}; } + set => jobSchedulingDataLocations = new string[] {value}; } /// @@ -125,12 +124,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IJobDetail[] JobDetails { - set - { - // Use modifiable ArrayList here, to allow for further adding of - // JobDetail objects during autodetection of JobDetailAwareTriggers. - jobDetails = new List(value); - } + set => jobDetails = new List(value); } /// @@ -142,7 +136,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IDictionary Calendars { - set { calendars = value; } + set => calendars = value; } /// @@ -162,7 +156,7 @@ namespace Spring.Scheduling.Quartz /// public virtual ITrigger[] Triggers { - set { triggers = new ArrayList(value); } + set => triggers = new ArrayList(value); } /// @@ -170,7 +164,7 @@ namespace Spring.Scheduling.Quartz /// public virtual ISchedulerListener[] SchedulerListeners { - set { schedulerListeners = value; } + set => schedulerListeners = value; } /// @@ -179,7 +173,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IJobListener[] GlobalJobListeners { - set { globalJobListeners = value; } + set => globalJobListeners = value; } /// @@ -190,20 +184,18 @@ namespace Spring.Scheduling.Quartz /// public virtual IJobListener[] JobListeners { - set { jobListeners = value; } + set => jobListeners = value; } - /// /// Specify global Quartz TriggerListeners to be registered with the Scheduler. /// Such TriggerListeners will apply to all Triggers in the Scheduler. /// public virtual ITriggerListener[] GlobalTriggerListeners { - set { globalTriggerListeners = value; } + set => globalTriggerListeners = value; } - /// /// Specify named Quartz TriggerListeners to be registered with the Scheduler. /// Such TriggerListeners will only apply to Triggers that explicitly activate @@ -212,10 +204,9 @@ namespace Spring.Scheduling.Quartz /// public virtual ITriggerListener[] TriggerListeners { - set { triggerListeners = value; } + set => triggerListeners = value; } - /// /// Set the transaction manager to be used for registering jobs and triggers /// that are defined by this SchedulerFactoryObject. Default is none; setting @@ -223,7 +214,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IPlatformTransactionManager TransactionManager { - set { transactionManager = value; } + set => transactionManager = value; } /// @@ -250,30 +241,28 @@ namespace Spring.Scheduling.Quartz /// /// Logger instance. /// - protected ILog Logger - { - get { return logger; } - } + protected ILog Logger => logger; /// /// Register jobs and triggers (within a transaction, if possible). /// - protected virtual void RegisterJobsAndTriggers() + protected virtual async Task RegisterJobsAndTriggers() { ITransactionStatus transactionStatus = null; if (transactionManager != null) { transactionStatus = transactionManager.GetTransaction(new DefaultTransactionDefinition()); } + try { if (jobSchedulingDataLocations != null) { - XMLSchedulingDataProcessor dataProcessor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper()); + var dataProcessor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper()); dataProcessor.OverWriteExistingData = overwriteExistingJobs; foreach (string location in jobSchedulingDataLocations) { - dataProcessor.ProcessFileAndScheduleJobs(location, GetScheduler()); + await dataProcessor.ProcessFileAndScheduleJobs(location, GetScheduler()).ConfigureAwait(false); } } @@ -282,7 +271,7 @@ namespace Spring.Scheduling.Quartz { foreach (IJobDetail jobDetail in jobDetails) { - AddJobToScheduler(jobDetail); + await AddJobToScheduler(jobDetail).ConfigureAwait(false); } } else @@ -298,7 +287,7 @@ namespace Spring.Scheduling.Quartz { string calendarName = (string) entry.Key; ICalendar calendar = (ICalendar) entry.Value; - GetScheduler().AddCalendar(calendarName, calendar, true, true); + await GetScheduler().AddCalendar(calendarName, calendar, true, true).ConfigureAwait(false); } } @@ -307,11 +296,10 @@ namespace Spring.Scheduling.Quartz { foreach (ITrigger trigger in triggers) { - AddTriggerToScheduler(trigger); + await AddTriggerToScheduler(trigger).ConfigureAwait(false); } } } - catch (Exception ex) { if (transactionStatus != null) @@ -326,10 +314,12 @@ namespace Spring.Scheduling.Quartz throw; } } + if (ex is SchedulerException) { throw; } + throw new SchedulerException("Registration of jobs and triggers failed: " + ex.Message); } @@ -345,17 +335,16 @@ namespace Spring.Scheduling.Quartz /// /// the job to add /// true if the job was actually added, false if it already existed before - private bool AddJobToScheduler(IJobDetail jobDetail) + private async Task AddJobToScheduler(IJobDetail jobDetail) { - if (overwriteExistingJobs || GetScheduler().GetJobDetail(jobDetail.Key) == null) + if (overwriteExistingJobs + || await GetScheduler().GetJobDetail(jobDetail.Key).ConfigureAwait(false) == null) { - GetScheduler().AddJob(jobDetail, true, true); + await GetScheduler().AddJob(jobDetail, true, true).ConfigureAwait(false); return true; } - else - { - return false; - } + + return false; } /// @@ -364,45 +353,48 @@ namespace Spring.Scheduling.Quartz /// /// the trigger to add /// true if the trigger was actually added, false if it already existed before - private bool AddTriggerToScheduler(ITrigger trigger) + private async Task AddTriggerToScheduler(ITrigger trigger) { - bool triggerExists = (GetScheduler().GetTrigger(trigger.Key) != null); - if (!triggerExists || this.overwriteExistingJobs) + bool triggerExists = await GetScheduler().GetTrigger(trigger.Key).ConfigureAwait(false) != null; + if (!triggerExists || overwriteExistingJobs) { // Check if the Trigger is aware of an associated JobDetail. - if (trigger is IJobDetailAwareTrigger) + if (trigger is IJobDetailAwareTrigger awareTrigger) { - IJobDetail jobDetail = ((IJobDetailAwareTrigger) trigger).JobDetail; + IJobDetail jobDetail = awareTrigger.JobDetail; // Automatically register the JobDetail too. - if (!jobDetails.Contains(jobDetail) && AddJobToScheduler(jobDetail)) + if (!jobDetails.Contains(jobDetail) + && await AddJobToScheduler(jobDetail).ConfigureAwait(false)) { jobDetails.Add(jobDetail); } } + if (!triggerExists) { try { - GetScheduler().ScheduleJob(trigger); + await GetScheduler().ScheduleJob(trigger).ConfigureAwait(false); } catch (ObjectAlreadyExistsException ex) { if (logger.IsDebugEnabled) { logger.Debug( - "Unexpectedly found existing trigger, assumably due to cluster race condition: " + - ex.Message + " - can safely be ignored"); + $"Unexpectedly found existing trigger, assumably due to cluster race condition: {ex.Message} - can safely be ignored"); } + if (overwriteExistingJobs) { - GetScheduler().RescheduleJob(trigger.Key, trigger); + await GetScheduler().RescheduleJob(trigger.Key, trigger).ConfigureAwait(false); } } } else { - GetScheduler().RescheduleJob(trigger.Key, trigger); + await GetScheduler().RescheduleJob(trigger.Key, trigger).ConfigureAwait(false); } + return true; } else @@ -411,7 +403,6 @@ namespace Spring.Scheduling.Quartz } } - /// /// Register all specified listeners with the Scheduler. /// @@ -424,6 +415,7 @@ namespace Spring.Scheduling.Quartz GetScheduler().ListenerManager.AddSchedulerListener(schedulerListeners[i]); } } + if (globalJobListeners != null) { foreach (IJobListener jobListener in globalJobListeners) @@ -431,11 +423,13 @@ namespace Spring.Scheduling.Quartz GetScheduler().ListenerManager.AddJobListener(jobListener); } } + if (jobListeners != null && jobListeners.Length > 0) { - throw new InvalidOperationException("Non-global JobListeners not supported on Quartz 2 - " + - "manually register a Matcher against the Quartz ListenerManager instead"); + throw new InvalidOperationException("Non-global JobListeners not supported on Quartz 2 - " + + "manually register a Matcher against the Quartz ListenerManager instead"); } + if (globalTriggerListeners != null) { foreach (ITriggerListener triggerListener in globalTriggerListeners) @@ -443,10 +437,11 @@ namespace Spring.Scheduling.Quartz GetScheduler().ListenerManager.AddTriggerListener(triggerListener); } } + if (triggerListeners != null && triggerListeners.Length > 0) { throw new InvalidOperationException("Non-global TriggerListeners not supported on Quartz 2 - " + - "manually register a Matcher against the Quartz ListenerManager instead"); + "manually register a Matcher against the Quartz ListenerManager instead"); } } diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessorObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessorObject.cs similarity index 90% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessorObject.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessorObject.cs index 80ece13a..1da2cfa0 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerAccessorObject.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerAccessorObject.cs @@ -15,10 +15,8 @@ */ using System; -using System.Collections.Generic; using Quartz; using Quartz.Impl; - using Spring.Objects.Factory; namespace Spring.Scheduling.Quartz @@ -50,7 +48,7 @@ namespace Spring.Scheduling.Quartz /// public string SchedulerName { - set { schedulerName = value; } + set => schedulerName = value; } /// @@ -58,7 +56,7 @@ namespace Spring.Scheduling.Quartz /// protected IScheduler Scheduler { - set { scheduler = value; } + set => scheduler = value; } /// @@ -75,10 +73,9 @@ namespace Spring.Scheduling.Quartz /// public IObjectFactory ObjectFactory { - set { objectFactory = value; } + set => objectFactory = value; } - /// /// Invoked by an /// after it has injected all of an object's dependencies. @@ -118,8 +115,9 @@ namespace Spring.Scheduling.Quartz throw new InvalidOperationException("No Scheduler specified"); } } + RegisterListeners(); - RegisterJobsAndTriggers(); + RegisterJobsAndTriggers().ConfigureAwait(false).GetAwaiter().GetResult(); } /// @@ -129,26 +127,27 @@ namespace Spring.Scheduling.Quartz /// protected virtual IScheduler FindScheduler(string schedulerName) { - if (objectFactory is IListableObjectFactory) + if (objectFactory is IListableObjectFactory lbf) { - IListableObjectFactory lbf = (IListableObjectFactory) objectFactory; - IEnumerable objectNames = lbf.GetObjectNamesForType(typeof(IScheduler)); + var objectNames = lbf.GetObjectNamesForType(typeof(IScheduler)); foreach (string objectName in objectNames) { - IScheduler schedulerObject = (IScheduler)lbf.GetObject(objectName); + IScheduler schedulerObject = (IScheduler) lbf.GetObject(objectName); if (schedulerName.Equals(schedulerObject.SchedulerName)) { return schedulerObject; } } } - IScheduler schedulerInRepo = SchedulerRepository.Instance.Lookup(schedulerName); + + IScheduler schedulerInRepo = SchedulerRepository.Instance.Lookup(schedulerName) + .ConfigureAwait(false).GetAwaiter().GetResult(); if (schedulerInRepo == null) { throw new InvalidOperationException("No Scheduler named '" + schedulerName + "' found"); } + return schedulerInRepo; } - } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerFactoryObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerFactoryObject.cs similarity index 90% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerFactoryObject.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerFactoryObject.cs index b68e8ebc..75da6c9e 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulerFactoryObject.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulerFactoryObject.cs @@ -19,13 +19,12 @@ using System.Collections; using System.Collections.Specialized; using System.IO; using System.Linq; - +using System.Threading.Tasks; using Quartz; using Quartz.Impl; using Quartz.Simpl; using Quartz.Spi; using Quartz.Util; - using Spring.Context; using Spring.Context.Events; using Spring.Core.IO; @@ -81,18 +80,16 @@ namespace Spring.Scheduling.Quartz /// /// Default thread count to be set to thread pool. /// - public const int DEFAULT_THREAD_COUNT = 10; + public const int DefaultThreadCount = 10; /// /// Property name for thread count in thread pool. /// - public const string PROP_THREAD_COUNT = "quartz.threadPool.threadCount"; + public const string PropThreadCount = "quartz.threadPool.threadCount"; - [ThreadStatic] - private static IDbProvider configTimeDbProvider; + [ThreadStatic] private static IDbProvider configTimeDbProvider; - [ThreadStatic] - private static ITaskExecutor configTimeTaskExecutor; + [ThreadStatic] private static ITaskExecutor configTimeTaskExecutor; /// /// Return the IDbProvider for the currently configured Quartz Scheduler, @@ -105,10 +102,7 @@ namespace Spring.Scheduling.Quartz /// /// /// - public static IDbProvider ConfigTimeDbProvider - { - get { return configTimeDbProvider; } - } + public static IDbProvider ConfigTimeDbProvider => configTimeDbProvider; /// /// Return the TaskExecutor for the currently configured Quartz Scheduler, @@ -119,10 +113,7 @@ namespace Spring.Scheduling.Quartz /// Scheduler, and reset immediately afterwards. It is thus only available /// during configuration. /// - public static ITaskExecutor ConfigTimeTaskExecutor - { - get { return configTimeTaskExecutor; } - } + public static ITaskExecutor ConfigTimeTaskExecutor => configTimeTaskExecutor; private IApplicationContext applicationContext; private string applicationContextSchedulerContextKey; @@ -146,7 +137,7 @@ namespace Spring.Scheduling.Quartz /// public SchedulerFactoryObject() { - schedulerFactoryType = typeof (StdSchedulerFactory); + schedulerFactoryType = typeof(StdSchedulerFactory); } /// @@ -165,10 +156,11 @@ namespace Spring.Scheduling.Quartz { set { - if (value == null || !typeof (ISchedulerFactory).IsAssignableFrom(value)) + if (value == null || !typeof(ISchedulerFactory).IsAssignableFrom(value)) { throw new ArgumentException("schedulerFactoryType must implement [Quartz.ISchedulerFactory]"); } + schedulerFactoryType = value; } } @@ -182,7 +174,7 @@ namespace Spring.Scheduling.Quartz /// public virtual string SchedulerName { - set { schedulerName = value; } + set => schedulerName = value; } /// @@ -196,7 +188,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IResource ConfigLocation { - set { configLocation = value; } + set => configLocation = value; } /// @@ -209,7 +201,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IDictionary QuartzProperties { - set { quartzProperties = value; } + set => quartzProperties = value; } /// @@ -225,7 +217,7 @@ namespace Spring.Scheduling.Quartz /// public virtual ITaskExecutor TaskExecutor { - set { taskExecutor = value; } + set => taskExecutor = value; } /// @@ -244,7 +236,7 @@ namespace Spring.Scheduling.Quartz /// public virtual IDictionary SchedulerContextAsMap { - set { schedulerContextMap = value; } + set => schedulerContextMap = value; } /// @@ -275,7 +267,7 @@ namespace Spring.Scheduling.Quartz /// public virtual string ApplicationContextSchedulerContextKey { - set { applicationContextSchedulerContextKey = value; } + set => applicationContextSchedulerContextKey = value; } /// @@ -317,7 +309,7 @@ namespace Spring.Scheduling.Quartz /// public virtual bool ExposeSchedulerInRepository { - set { exposeSchedulerInRepository = value; } + set => exposeSchedulerInRepository = value; } /// @@ -326,7 +318,7 @@ namespace Spring.Scheduling.Quartz /// public virtual bool AutoStartup { - set { autoStartup = value; } + set => autoStartup = value; } /// @@ -340,7 +332,7 @@ namespace Spring.Scheduling.Quartz /// public virtual TimeSpan StartupDelay { - set { startupDelay = value; } + set => startupDelay = value; } /// @@ -353,7 +345,7 @@ namespace Spring.Scheduling.Quartz /// public virtual bool WaitForJobsToCompleteOnShutdown { - set { waitForJobsToCompleteOnShutdown = value; } + set => waitForJobsToCompleteOnShutdown = value; } /// @@ -377,7 +369,7 @@ namespace Spring.Scheduling.Quartz /// public IDbProvider DbProvider { - set { dbProvider = value; } + set => dbProvider = value; } /// @@ -422,12 +414,11 @@ namespace Spring.Scheduling.Quartz return false; } } + return false; } } - #region IApplicationContextAware Members - /// /// Sets the that this /// object runs in. @@ -457,13 +448,9 @@ namespace Spring.Scheduling.Quartz /// public virtual IApplicationContext ApplicationContext { - set { applicationContext = value; } + set => applicationContext = value; } - #endregion - - #region IDisposable Members - /// /// Shut down the Quartz scheduler on object factory Shutdown, /// stopping all scheduled jobs. @@ -471,11 +458,9 @@ namespace Spring.Scheduling.Quartz public virtual void Dispose() { Logger.Info("Shutting down Quartz Scheduler"); - scheduler.Shutdown(waitForJobsToCompleteOnShutdown); + scheduler.Shutdown(waitForJobsToCompleteOnShutdown).ConfigureAwait(false).GetAwaiter().GetResult(); } - #endregion - /// /// Template method that determines the Scheduler to operate on. /// To be implemented by subclasses. @@ -486,8 +471,6 @@ namespace Spring.Scheduling.Quartz return scheduler; } - #region IFactoryObject Members - /// /// Return an instance (possibly shared or independent) of the object /// managed by this factory. @@ -515,28 +498,18 @@ namespace Spring.Scheduling.Quartz /// if not known in advance. /// /// - public virtual Type ObjectType - { - get { return (scheduler != null) ? scheduler.GetType() : typeof (IScheduler); } - } + public virtual Type ObjectType => (scheduler != null) ? scheduler.GetType() : typeof(IScheduler); /// /// Is the object managed by this factory a singleton or a prototype? /// /// - public virtual bool IsSingleton - { - get { return true; } - } - - #endregion + public virtual bool IsSingleton => true; //--------------------------------------------------------------------- // Implementation of IInitializingObject interface //--------------------------------------------------------------------- - #region IInitializingObject Members - /// /// Invoked by an /// after it has injected all of an object's dependencies. @@ -575,6 +548,7 @@ namespace Spring.Scheduling.Quartz // Make given TaskExecutor available for SchedulerFactory configuration. configTimeTaskExecutor = taskExecutor; } + if (dbProvider != null) { // Make given db provider available for SchedulerFactory configuration. @@ -600,6 +574,7 @@ namespace Spring.Scheduling.Quartz { ((ISchedulerContextAware) jobFactory).SchedulerContext = scheduler.Context; } + scheduler.JobFactory = jobFactory; } } @@ -609,6 +584,7 @@ namespace Spring.Scheduling.Quartz { configTimeTaskExecutor = null; } + if (dbProvider != null) { configTimeDbProvider = null; @@ -616,11 +592,9 @@ namespace Spring.Scheduling.Quartz } RegisterListeners(); - RegisterJobsAndTriggers(); + RegisterJobsAndTriggers().ConfigureAwait(false).GetAwaiter().GetResult(); } - #endregion - /// /// Load and/or apply Quartz properties to the given SchedulerFactory. /// @@ -632,11 +606,14 @@ namespace Spring.Scheduling.Quartz if (configLocation != null || quartzProperties != null || schedulerName != null || taskExecutor != null || dbProvider != null) { - throw new ArgumentException("StdSchedulerFactory required for applying Quartz properties: " + schedulerFactory); + throw new ArgumentException("StdSchedulerFactory required for applying Quartz properties: " + + schedulerFactory); } + // Otherwise assume that no initialization is necessary... return; } + NameValueCollection mergedProps = new NameValueCollection(); // Set necessary default properties here, as Quartz will not apply @@ -644,12 +621,13 @@ namespace Spring.Scheduling.Quartz if (taskExecutor != null) { mergedProps[StdSchedulerFactory.PropertyThreadPoolType] = - typeof (LocalTaskExecutorThreadPool).AssemblyQualifiedName; + typeof(LocalTaskExecutorThreadPool).AssemblyQualifiedName; } else { - mergedProps.Set(StdSchedulerFactory.PropertyThreadPoolType, typeof (SimpleThreadPool).AssemblyQualifiedName); - mergedProps[PROP_THREAD_COUNT] = Convert.ToString(DEFAULT_THREAD_COUNT); + mergedProps.Set(StdSchedulerFactory.PropertyThreadPoolType, + typeof(DefaultThreadPool).AssemblyQualifiedName); + mergedProps[PropThreadCount] = Convert.ToString(DefaultThreadCount); } if (configLocation != null) @@ -658,6 +636,7 @@ namespace Spring.Scheduling.Quartz { Logger.Info("Loading Quartz config from [" + configLocation + "]"); } + using (StreamReader sr = new StreamReader(configLocation.InputStream)) { string line; @@ -680,7 +659,8 @@ namespace Spring.Scheduling.Quartz if (dbProvider != null) { - mergedProps[StdSchedulerFactory.PropertyJobStoreType] = typeof (LocalDataSourceJobStore).AssemblyQualifiedName; + mergedProps[StdSchedulerFactory.PropertyJobStoreType] = + typeof(LocalDataSourceJobStore).AssemblyQualifiedName; } // Make sure to set the scheduler name as configured in the Spring configuration. @@ -724,21 +704,25 @@ namespace Spring.Scheduling.Quartz SchedulerRepository repository = SchedulerRepository.Instance; lock (repository) { - IScheduler existingScheduler = (schedulerName != null ? repository.Lookup(schedulerName) : null); - IScheduler newScheduler = schedulerFactory.GetScheduler(); + IScheduler existingScheduler = schedulerName != null + ? repository.Lookup(schedulerName).ConfigureAwait(false).GetAwaiter().GetResult() + : null; + + IScheduler newScheduler = + schedulerFactory.GetScheduler().ConfigureAwait(false).GetAwaiter().GetResult(); if (newScheduler == existingScheduler) { throw new InvalidOperationException( - string.Format( - "Active Scheduler of name '{0}' already registered in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!", - schedulerName)); + $"Active Scheduler of name '{schedulerName}' already registered in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!"); } + if (!exposeSchedulerInRepository) { // Need to explicitly remove it if not intended for exposure, // since Quartz shares the Scheduler instance by default! SchedulerRepository.Instance.Remove(newScheduler.SchedulerName); } + return newScheduler; } } @@ -752,7 +736,8 @@ namespace Spring.Scheduling.Quartz // Put specified objects into Scheduler context. if (schedulerContextMap != null) { - var dictionary = schedulerContextMap.Cast().ToDictionary(entry => entry.Key.ToString(), entry => entry.Value); + var dictionary = schedulerContextMap.Cast() + .ToDictionary(entry => entry.Key.ToString(), entry => entry.Value); scheduler.Context.PutAll(dictionary); } @@ -764,6 +749,7 @@ namespace Spring.Scheduling.Quartz throw new SystemException("SchedulerFactoryObject needs to be set up in an IApplicationContext " + "to be able to handle an 'applicationContextSchedulerContextKey'"); } + scheduler.Context.Put(applicationContextSchedulerContextKey, applicationContext); } } @@ -773,21 +759,23 @@ namespace Spring.Scheduling.Quartz /// /// the Scheduler to start /// the time span to wait before starting - /// the Scheduler asynchronously - protected virtual void StartScheduler(IScheduler sched, TimeSpan startDelay) + /// the Scheduler asynchronously + protected virtual async Task StartScheduler(IScheduler sched, TimeSpan startDelay) { if (startDelay.TotalSeconds <= 0) { Logger.Info("Starting Quartz Scheduler now"); - sched.Start(); + await sched.Start().ConfigureAwait(false); } else { if (Logger.IsInfoEnabled) { - Logger.InfoFormat("Will start Quartz Scheduler [{0}] in {1} seconds", sched.SchedulerName, startDelay); + Logger.InfoFormat("Will start Quartz Scheduler [{0}] in {1} seconds", sched.SchedulerName, + startDelay); } - sched.StartDelayed(startDelay); + + await sched.StartDelayed(startDelay).ConfigureAwait(false); } } @@ -798,13 +786,13 @@ namespace Spring.Scheduling.Quartz /// /// Starts this instance. /// - public virtual void Start() + public virtual async Task Start() { if (scheduler != null) { try { - scheduler.Start(); + await scheduler.Start().ConfigureAwait(false); } catch (SchedulerException ex) { @@ -816,13 +804,13 @@ namespace Spring.Scheduling.Quartz /// /// Stops this instance. /// - public virtual void Stop() + public virtual async Task Stop() { if (scheduler != null) { try { - scheduler.Standby(); + await scheduler.Standby().ConfigureAwait(false); } catch (SchedulerException ex) { @@ -841,7 +829,7 @@ namespace Spring.Scheduling.Quartz { try { - StartScheduler(scheduler, startupDelay); + StartScheduler(scheduler, startupDelay).ConfigureAwait(false).GetAwaiter().GetResult(); } catch (SchedulerException ex) { diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulingException.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulingException.cs similarity index 59% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulingException.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulingException.cs index eb12e030..c70afc77 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SchedulingException.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SchedulingException.cs @@ -2,26 +2,26 @@ using System; namespace Spring.Scheduling.Quartz { - /// - /// Generic scheduling exception. - /// - public class SchedulingException : Exception - { + /// + /// Generic scheduling exception. + /// + public class SchedulingException : Exception + { /// /// Initializes a new instance of the class. /// /// The message. - public SchedulingException(string message) : base(message) - { - } + public SchedulingException(string message) : base(message) + { + } /// /// Initializes a new instance of the class. /// /// The message. /// The original exception. - public SchedulingException(string message, Exception ex) : base(message, ex) - { - } - } + public SchedulingException(string message, Exception ex) : base(message, ex) + { + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleTriggerObject.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SimpleTriggerObject.cs similarity index 51% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleTriggerObject.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SimpleTriggerObject.cs index 9c78fcab..8817cce8 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SimpleTriggerObject.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SimpleTriggerObject.cs @@ -13,50 +13,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using System; using System.Collections; - using Quartz; using Quartz.Impl.Triggers; - using Spring.Objects.Factory; using Spring.Util; namespace Spring.Scheduling.Quartz { - /// - /// Convenience subclass of Quartz's - /// class, making properties based usage easier. - /// - /// - ///

- /// SimpleTrigger itself is already a PONO but lacks sensible defaults. - /// This class uses the Spring object name as job name, the Quartz default group - /// ("DEFAULT") as job group, the current time as start time, and indefinite - /// repetition, if not specified. - ///

- /// - ///

- /// This class will also register the trigger with the job name and group of - /// a given . This allows - /// to automatically register a trigger for the corresponding JobDetail, - /// instead of registering the JobDetail separately. - ///

+ /// + /// Convenience subclass of Quartz's + /// class, making properties based usage easier. + /// + /// + ///

+ /// SimpleTrigger itself is already a PONO but lacks sensible defaults. + /// This class uses the Spring object name as job name, the Quartz default group + /// ("DEFAULT") as job group, the current time as start time, and indefinite + /// repetition, if not specified. + ///

+ /// + ///

+ /// This class will also register the trigger with the job name and group of + /// a given . This allows + /// to automatically register a trigger for the corresponding JobDetail, + /// instead of registering the JobDetail separately. + ///

///
- /// Juergen Hoeller - /// + /// Juergen Hoeller + /// /// /// /// - /// - /// - /// - public class SimpleTriggerObject : SimpleTriggerImpl, IJobDetailAwareTrigger, IObjectNameAware, IInitializingObject - { - private TimeSpan startDelay = TimeSpan.Zero; - private IJobDetail jobDetail; - private string objectName; - private readonly Constants constants = new Constants(typeof(MisfireInstruction.SimpleTrigger), typeof(MisfireInstruction)); + /// + /// + /// + public class SimpleTriggerObject : SimpleTriggerImpl, IJobDetailAwareTrigger, IObjectNameAware, IInitializingObject + { + private TimeSpan startDelay = TimeSpan.Zero; + private IJobDetail jobDetail; + private string objectName; + + private readonly Constants constants = + new Constants(typeof(MisfireInstruction.SimpleTrigger), typeof(MisfireInstruction)); /// /// Initializes a new instance of the class. @@ -66,62 +67,62 @@ namespace Spring.Scheduling.Quartz RepeatCount = RepeatIndefinitely; } - /// - /// Register objects in the JobDataMap via a given Map. - ///

- /// These objects will be available to this Trigger only, - /// in contrast to objects in the JobDetail's data map. - ///

- ///
- /// - public virtual IDictionary JobDataAsMap - { - set - { - foreach (DictionaryEntry entry in value) - { + /// + /// Register objects in the JobDataMap via a given Map. + ///

+ /// These objects will be available to this Trigger only, + /// in contrast to objects in the JobDetail's data map. + ///

+ ///
+ /// + public virtual IDictionary JobDataAsMap + { + set + { + foreach (DictionaryEntry entry in value) + { JobDataMap.Put((string) entry.Key, entry.Value); - } - } - } + } + } + } - /// - /// Set the misfire instruction via the name of the corresponding - /// constant in the SimpleTrigger class. + /// + /// Set the misfire instruction via the name of the corresponding + /// constant in the SimpleTrigger class. /// Default is . - /// + /// /// /// /// /// /// /// - public virtual string MisfireInstructionName - { - set { MisfireInstruction = constants.AsNumber(value); } - } + public virtual string MisfireInstructionName + { + set => MisfireInstruction = constants.AsNumber(value); + } - /// - /// Set the delay before starting the job for the first time. - /// The given time span will be added to the current - /// time to calculate the start time. Default is . - /// - /// - /// This delay will just be applied if no custom start time was - /// specified. However, in typical usage within a Spring context, - /// the start time will be the container startup time anyway. - /// Specifying a relative delay is appropriate in that case. - /// - /// - public virtual TimeSpan StartDelay - { + /// + /// Set the delay before starting the job for the first time. + /// The given time span will be added to the current + /// time to calculate the start time. Default is . + /// + /// + /// This delay will just be applied if no custom start time was + /// specified. However, in typical usage within a Spring context, + /// the start time will be the container startup time anyway. + /// Specifying a relative delay is appropriate in that case. + /// + /// + public virtual TimeSpan StartDelay + { set { AssertUtils.State(value >= TimeSpan.Zero, "Start delay cannot be negative."); startDelay = value; } - get { return startDelay; } - } + get => startDelay; + } /// /// Set the name of the object in the object factory that created this object. @@ -135,25 +136,24 @@ namespace Spring.Scheduling.Quartz /// method or a custom init-method. ///

/// - public virtual string ObjectName - { - set { objectName = value; } - } - - /// - /// Set the JobDetail that this trigger should be associated with. - ///

- /// This is typically used with a object reference if the JobDetail - /// is a Spring-managed object. Alternatively, the trigger can also - /// be associated with a job by name and group. - ///

- ///
- public virtual IJobDetail JobDetail - { - get { return jobDetail; } - set { jobDetail = value; } - } + public virtual string ObjectName + { + set => objectName = value; + } + /// + /// Set the JobDetail that this trigger should be associated with. + ///

+ /// This is typically used with a object reference if the JobDetail + /// is a Spring-managed object. Alternatively, the trigger can also + /// be associated with a job by name and group. + ///

+ ///
+ public virtual IJobDetail JobDetail + { + get => jobDetail; + set => jobDetail = value; + } /// /// Invoked by an @@ -181,30 +181,33 @@ namespace Spring.Scheduling.Quartz /// In the event of misconfiguration (such as the failure to set a /// required property) or if initialization fails. /// - public virtual void AfterPropertiesSet() - { + public virtual void AfterPropertiesSet() + { if (StartTimeUtc == DateTimeOffset.MinValue) { StartTimeUtc = DateTimeOffset.UtcNow; } + if (StartDelay > TimeSpan.Zero) { StartTimeUtc = DateTime.UtcNow.Add(startDelay); } - if (Name == null) - { - Name = objectName; - } - if (Group == null) - { + if (Name == null) + { + Name = objectName; + } + + if (Group == null) + { Group = SchedulerConstants.DefaultGroup; - } - if (jobDetail != null) - { - JobName = jobDetail.Key.Name; - JobGroup = jobDetail.Key.Group; - } - } - } + } + + if (jobDetail != null) + { + JobName = jobDetail.Key.Name; + JobGroup = jobDetail.Key.Group; + } + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringDbProviderAdapter.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringDbProviderAdapter.cs similarity index 73% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringDbProviderAdapter.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringDbProviderAdapter.cs index d9bc8b0c..b5c2bd1f 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringDbProviderAdapter.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringDbProviderAdapter.cs @@ -1,4 +1,4 @@ - /* +/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,11 +16,10 @@ using System; using System.Data; +using System.Data.Common; using System.Reflection; - using Quartz.Impl.AdoJobStore.Common; - -using IDbMetadata=Spring.Data.Common.IDbMetadata; +using IDbMetadata = Spring.Data.Common.IDbMetadata; namespace Spring.Scheduling.Quartz { @@ -48,16 +47,15 @@ namespace Spring.Scheduling.Quartz /// public void Initialize() { - } /// /// Creates the command. /// /// - public IDbCommand CreateCommand() + public DbCommand CreateCommand() { - return dbProvider.CreateCommand(); + return (DbCommand) dbProvider.CreateCommand(); } /// @@ -73,9 +71,9 @@ namespace Spring.Scheduling.Quartz /// Creates the connection. /// /// - public IDbConnection CreateConnection() + public DbConnection CreateConnection() { - return dbProvider.CreateConnection(); + return (DbConnection) dbProvider.CreateConnection(); } /// @@ -101,18 +99,15 @@ namespace Spring.Scheduling.Quartz /// The connection string. public string ConnectionString { - get { return dbProvider.ConnectionString; } - set { dbProvider.ConnectionString = value; } + get => dbProvider.ConnectionString; + set => dbProvider.ConnectionString = value; } /// /// Gets the metadata. /// /// The metadata. - public DbMetadata Metadata - { - get { return metadata; } - } + public DbMetadata Metadata => metadata; } /// @@ -149,7 +144,6 @@ namespace Spring.Scheduling.Quartz // use standard binary type dbTypeBinary = DbType.Binary; } - } /// @@ -158,8 +152,8 @@ namespace Spring.Scheduling.Quartz /// The name of the product. public override string ProductName { - get { return metadata.ProductName; } - set { throw new NotSupportedException(); } + get => metadata.ProductName; + set => throw new NotSupportedException(); } /// @@ -168,8 +162,8 @@ namespace Spring.Scheduling.Quartz /// The type of the connection. public override Type ConnectionType { - get { return metadata.ConnectionType; } - set { throw new NotSupportedException(); } + get => metadata.ConnectionType; + set => throw new NotSupportedException(); } /// @@ -178,8 +172,8 @@ namespace Spring.Scheduling.Quartz /// The type of the command. public override Type CommandType { - get { return metadata.CommandType; } - set { throw new NotSupportedException(); } + get => metadata.CommandType; + set => throw new NotSupportedException(); } /// @@ -188,28 +182,8 @@ namespace Spring.Scheduling.Quartz /// The type of the parameter. public override Type ParameterType { - get { return metadata.ParameterType; } - set { throw new NotSupportedException(); } - } - - /// - /// Gets or sets the type of the command builder. - /// - /// The type of the command builder. - public override Type CommandBuilderType - { - get { return metadata.CommandBuilderType; } - set { throw new NotSupportedException(); } - } - - /// - /// Gets or sets the command builder derive parameters method. - /// - /// The command builder derive parameters method. - public override MethodInfo CommandBuilderDeriveParametersMethod - { - get { return metadata.CommandBuilderDeriveParametersMethod; } - set { throw new NotSupportedException(); } + get => metadata.ParameterType; + set => throw new NotSupportedException(); } /// @@ -218,8 +192,8 @@ namespace Spring.Scheduling.Quartz /// The parameter name prefix. public override string ParameterNamePrefix { - get { return metadata.ParameterNamePrefix; } - set { throw new NotSupportedException(); } + get => metadata.ParameterNamePrefix; + set => throw new NotSupportedException(); } /// @@ -228,8 +202,8 @@ namespace Spring.Scheduling.Quartz /// The type of the exception. public override Type ExceptionType { - get { return metadata.ExceptionType; } - set { throw new NotSupportedException(); } + get => metadata.ExceptionType; + set => throw new NotSupportedException(); } /// @@ -238,8 +212,8 @@ namespace Spring.Scheduling.Quartz /// true if [bind by name]; otherwise, false. public override bool BindByName { - get { return metadata.BindByName; } - set { throw new NotSupportedException(); } + get => metadata.BindByName; + set => throw new NotSupportedException(); } /// @@ -248,8 +222,8 @@ namespace Spring.Scheduling.Quartz /// The type of the parameter db. public override Type ParameterDbType { - get { return metadata.ParameterDbType; } - set { throw new NotSupportedException(); } + get => metadata.ParameterDbType; + set => throw new NotSupportedException(); } /// @@ -258,8 +232,8 @@ namespace Spring.Scheduling.Quartz /// The parameter db type property. public override PropertyInfo ParameterDbTypeProperty { - get { return metadata.ParameterDbTypeProperty; } - set { throw new NotSupportedException(); } + get => metadata.ParameterDbTypeProperty; + set => throw new NotSupportedException(); } /// @@ -268,18 +242,15 @@ namespace Spring.Scheduling.Quartz /// The parameter is nullable property. public override PropertyInfo ParameterIsNullableProperty { - get { return metadata.ParameterIsNullableProperty; } - set { throw new NotSupportedException(); } + get => metadata.ParameterIsNullableProperty; + set => throw new NotSupportedException(); } /// /// Gets the type of the db binary. /// /// The type of the db binary. - public override Enum DbBinaryType - { - get { return dbTypeBinary; } - } + public override Enum DbBinaryType => dbTypeBinary; /// /// Gets or sets a value indicating whether [use parameter name prefix in parameter collection]. @@ -289,9 +260,8 @@ namespace Spring.Scheduling.Quartz /// public override bool UseParameterNamePrefixInParameterCollection { - get { return metadata.UseParameterNamePrefixInParameterCollection; } - set { throw new NotSupportedException(); } + get => metadata.UseParameterNamePrefixInParameterCollection; + set => throw new NotSupportedException(); } } - } \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringObjectJobFactory.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringObjectJobFactory.cs similarity index 97% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringObjectJobFactory.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringObjectJobFactory.cs index 87efe3e3..b30174d5 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/SpringObjectJobFactory.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/SpringObjectJobFactory.cs @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + using Quartz; using Quartz.Spi; using Spring.Objects; @@ -50,7 +51,7 @@ namespace Spring.Scheduling.Quartz /// public virtual string[] IgnoredUnknownProperties { - set { ignoredUnknownProperties = value; } + set => ignoredUnknownProperties = value; } /// @@ -60,10 +61,9 @@ namespace Spring.Scheduling.Quartz /// public virtual SchedulerContext SchedulerContext { - set { schedulerContext = value; } + set => schedulerContext = value; } - /// /// Create the job instance, populating it with property values taken /// from the scheduler context, job data map and trigger data map. @@ -78,6 +78,7 @@ namespace Spring.Scheduling.Quartz { pvs.AddAll(schedulerContext); } + pvs.AddAll(bundle.JobDetail.JobDataMap); pvs.AddAll(bundle.Trigger.JobDataMap); if (ignoredUnknownProperties != null) @@ -90,6 +91,7 @@ namespace Spring.Scheduling.Quartz pvs.Remove(propName); } } + ow.SetPropertyValues(pvs); } else @@ -97,6 +99,7 @@ namespace Spring.Scheduling.Quartz ow.SetPropertyValues(pvs, true); } } + return ow.WrappedInstance; } diff --git a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/StatefulMethodInvokingJob.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/StatefulMethodInvokingJob.cs similarity index 99% rename from src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/StatefulMethodInvokingJob.cs rename to src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/StatefulMethodInvokingJob.cs index 6885337f..c39842b5 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Scheduling/Quartz/StatefulMethodInvokingJob.cs +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/Quartz/StatefulMethodInvokingJob.cs @@ -30,4 +30,4 @@ namespace Spring.Scheduling.Quartz // No implementation, just an addition of the tag interface StatefulJob // in order to allow stateful method invoking jobs. } -} +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz3/Scheduling/TaskRejectedException.cs b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/TaskRejectedException.cs new file mode 100644 index 00000000..cf9adf77 --- /dev/null +++ b/src/Spring/Spring.Scheduling.Quartz3/Scheduling/TaskRejectedException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Spring.Scheduling +{ + /// + /// Summary description for TaskRejectedException. + /// + public class TaskRejectedException : ApplicationException + { + } +} \ No newline at end of file diff --git a/src/Spring/Spring.Scheduling.Quartz2/Spring.Scheduling.Quartz2.csproj b/src/Spring/Spring.Scheduling.Quartz3/Spring.Scheduling.Quartz3.csproj similarity index 73% rename from src/Spring/Spring.Scheduling.Quartz2/Spring.Scheduling.Quartz2.csproj rename to src/Spring/Spring.Scheduling.Quartz3/Spring.Scheduling.Quartz3.csproj index 4c046dc6..84540539 100644 --- a/src/Spring/Spring.Scheduling.Quartz2/Spring.Scheduling.Quartz2.csproj +++ b/src/Spring/Spring.Scheduling.Quartz3/Spring.Scheduling.Quartz3.csproj @@ -1,14 +1,14 @@  - net452 - Spring.NET Integration with the Quartz Scheduling Library 2.x + netstandard2.0;$(TargetFullFrameworkVersion) + Spring.NET Integration with the Quartz Scheduling Library 3.x - + diff --git a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs index 949e70ec..18e2b853 100644 --- a/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs +++ b/test/Spring/Spring.Data.Tests/Data/Core/TxScopeTransactionManagerTests.cs @@ -63,7 +63,7 @@ namespace Spring.Data.Core TransactionOptions txOptions = new TransactionOptions(); txOptions.IsolationLevel = IsolationLevel.ReadCommitted; - txAdapter.CreateTransactionScope(TransactionScopeOption.Required, txOptions, EnterpriseServicesInteropOption.None); + txAdapter.CreateTransactionScope(TransactionScopeOption.Required, txOptions, TransactionScopeAsyncFlowOption.Enabled); txAdapter.Complete(); txAdapter.Dispose(); } @@ -103,7 +103,7 @@ namespace Spring.Data.Core } Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active"); - A.CallTo(() => txAdapter.CreateTransactionScope(TransactionScopeOption.Required, txOptions, EnterpriseServicesInteropOption.None)).MustHaveHappenedOnceExactly(); + A.CallTo(() => txAdapter.CreateTransactionScope(TransactionScopeOption.Required, txOptions, TransactionScopeAsyncFlowOption.Enabled)).MustHaveHappenedOnceExactly(); A.CallTo(() => txAdapter.Dispose()).MustHaveHappenedOnceExactly(); } @@ -151,7 +151,7 @@ namespace Spring.Data.Core return null; }); - A.CallTo(() => txAdapter.CreateTransactionScope(TransactionScopeOption.RequiresNew, txOptions, EnterpriseServicesInteropOption.None)).MustHaveHappenedTwiceExactly(); + A.CallTo(() => txAdapter.CreateTransactionScope(TransactionScopeOption.RequiresNew, txOptions, TransactionScopeAsyncFlowOption.Enabled)).MustHaveHappenedTwiceExactly(); A.CallTo(() => txAdapter.Dispose()).MustHaveHappenedTwiceExactly(); A.CallTo(() => txAdapter.Complete()).MustHaveHappenedOnceExactly(); } diff --git a/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs b/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs index ea14389c..f9bff15c 100644 --- a/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs +++ b/test/Spring/Spring.Data.Tests/Data/TestObjectMgr.cs @@ -1,5 +1,3 @@ -#region License - /* * Copyright © 2002-2011 the original author or authors. * @@ -16,47 +14,31 @@ * limitations under the License. */ -#endregion - -#region Imports - using System; +using System.Transactions; using Common.Logging; using Spring.Objects; using Spring.Transaction; using Spring.Transaction.Interceptor; using Spring.Transaction.Support; -using IsolationLevel=System.Data.IsolationLevel; - -#endregion +using IsolationLevel = System.Data.IsolationLevel; namespace Spring.Data { - /// - /// Group together multiple ITestObjectDao operations. - /// - /// Mark Pollack (.NET) - public class TestObjectMgr : ITestObjectMgr - { - #region Fields - + /// + /// Group together multiple ITestObjectDao operations. + /// + /// Mark Pollack (.NET) + public class TestObjectMgr : ITestObjectMgr + { private static readonly ILog LOG = LogManager.GetLogger(typeof(TestObjectMgr)); - #endregion - #region Constructor (s) - /// - /// Initializes a new instance of the class. + /// + /// Initializes a new instance of the class. /// - public TestObjectMgr() - { - - } - - #endregion - - - - #region Methods + public TestObjectMgr() + { + } [Transaction()] public void SaveTwoTestObjects(TestObject to1, TestObject to2) @@ -65,14 +47,12 @@ namespace Spring.Data } [Transaction(TransactionPropagation.Required, IsolationLevel.Unspecified, Timeout = 50, - RollbackFor = new Type[]{typeof(ArgumentNullException)}, - ReadOnly = false, - EnterpriseServicesInteropOption = System.Transactions.EnterpriseServicesInteropOption.Automatic, - NoRollbackFor = new Type[] { typeof(ArithmeticException), typeof(NotSupportedException) })] - public void DeleteTwoTestObjects(string name1, string name2) + RollbackFor = new Type[] {typeof(ArgumentNullException)}, + ReadOnly = false, + AsyncFlowOption = TransactionScopeAsyncFlowOption.Enabled, + NoRollbackFor = new Type[] {typeof(ArithmeticException), typeof(NotSupportedException)})] + public void DeleteTwoTestObjects(string name1, string name2) { } - - #endregion - } -} + } +} \ No newline at end of file diff --git a/test/Spring/Spring.Data.Tests/Transaction/CommonTypes.cs b/test/Spring/Spring.Data.Tests/Transaction/CommonTypes.cs index bc91fd63..477048c9 100644 --- a/test/Spring/Spring.Data.Tests/Transaction/CommonTypes.cs +++ b/test/Spring/Spring.Data.Tests/Transaction/CommonTypes.cs @@ -5,49 +5,17 @@ namespace Spring.Transaction { public class MockTxnDefinition : ITransactionDefinition { - private int _transactionTimeout = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - private TransactionPropagation _transactionPropagation = TransactionPropagation.NotSupported; - private bool _readOnly = false; - private string _name = null; - private System.Transactions.EnterpriseServicesInteropOption _esInteropOption; + public bool ReadOnly { get; set; } - #region ITransactionDefinition Members + public int TransactionTimeout { get; set; } = DefaultTransactionDefinition.TIMEOUT_DEFAULT; - public bool ReadOnly - { - get { return _readOnly; } - set { _readOnly = value; } - } + public IsolationLevel TransactionIsolationLevel => IsolationLevel.Unspecified; - public int TransactionTimeout - { - get { return _transactionTimeout; } - set { _transactionTimeout = value; } - } + public TransactionPropagation PropagationBehavior { get; set; } = TransactionPropagation.NotSupported; - public IsolationLevel TransactionIsolationLevel - { - get { return IsolationLevel.Unspecified; } - } + public string Name { get; } = null; - public TransactionPropagation PropagationBehavior - { - get { return _transactionPropagation; } - set { _transactionPropagation = value; } - } - - public string Name - { - get { return _name; } - } - - public System.Transactions.EnterpriseServicesInteropOption EnterpriseServicesInteropOption - { - get { return _esInteropOption; } - set { _esInteropOption = value; } - } - - #endregion + public System.Transactions.TransactionScopeAsyncFlowOption AsyncFlowOption { get; set; } } public class MockTxnPlatformMgrAbstract : AbstractPlatformTransactionManager @@ -68,32 +36,18 @@ namespace Spring.Transaction _isExistingTransaction = true; } - public object Transaction - { - get { return _transaction; } - } + public object Transaction => _transaction; public bool Savepoints { - set { _useSavepointForNestedTransaction = value; } + set => _useSavepointForNestedTransaction = value; } - public int DoBeginCallCount - { - get { return _doBeginCalls; } - } + public int DoBeginCallCount => _doBeginCalls; - public int DoGetTransactionCallCount - { - get { return _doGetTxnCalls; } - } + public int DoGetTransactionCallCount => _doGetTxnCalls; - public int IsExistingTransactionCallCount - { - get { return _isExistingTxnCalls; } - } - - #region AbstractPlatformTransactionManager Impls + public int IsExistingTransactionCallCount => _isExistingTxnCalls; protected override void DoResume(object transaction, object suspendedResources) { @@ -144,7 +98,5 @@ namespace Spring.Transaction { return _useSavepointForNestedTransaction; } - - #endregion } } \ No newline at end of file diff --git a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml b/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml deleted file mode 100644 index 49a88834..00000000 --- a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/App.config b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/App.config similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/App.config rename to test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/App.config diff --git a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs similarity index 76% rename from test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs index 02dcc54a..0d7ad57e 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.cs @@ -1,7 +1,7 @@ #region License /* - * Copyright © 2002-2007 the original author or authors. + * Copyright � 2002-2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,32 +21,32 @@ #region Imports using System.Threading; - using NUnit.Framework; using Spring.Context; using Spring.Context.Support; #endregion + namespace Spring.Scheduling.Quartz.Integration.Tests { [TestFixture] - public class LocalDataSourceJobStoreTest + public class LocalDataSourceJobStoreTest { private IApplicationContext ctx; [SetUp] public void SetUp() { - ctx = new XmlApplicationContext("assembly://Spring.Scheduling.Quartz2.Integration.Tests/Spring.Scheduling.Quartz/LocalDataSourceJobStoreTest.xml"); + ctx = new XmlApplicationContext( + "assembly://Spring.Scheduling.Quartz3.Integration.Tests/Spring.Scheduling.Quartz/LocalDataSourceJobStoreTest.xml"); } [Test] - [Ignore("Appveyor problems")] + [Explicit("Appveyor problems")] public void TestLocalDataSourceJobStore() { // sleep 20 seconds Thread.Sleep(20000); } - } } \ No newline at end of file diff --git a/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml new file mode 100644 index 00000000..de7bd6be --- /dev/null +++ b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/LocalDataSourceJobStoreTest.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/TestJob.cs b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/TestJob.cs similarity index 69% rename from test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/TestJob.cs rename to test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/TestJob.cs index 4e4c784b..356a65e4 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Scheduling/Quartz/TestJob.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Scheduling/Quartz/TestJob.cs @@ -1,14 +1,15 @@ using System; - +using System.Threading.Tasks; using Quartz; namespace Spring.Scheduling.Quartz.Integration.Tests { public class TestJob : IJob { - public void Execute(IJobExecutionContext context) + public Task Execute(IJobExecutionContext context) { Console.WriteLine("Executing Execute!"); + return Task.FromResult(true); } public void DoIt() diff --git a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Spring.Scheduling.Quartz2.Integration.Tests.csproj b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Spring.Scheduling.Quartz3.Integration.Tests.csproj similarity index 87% rename from test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Spring.Scheduling.Quartz2.Integration.Tests.csproj rename to test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Spring.Scheduling.Quartz3.Integration.Tests.csproj index 2758f42c..87bb9c0b 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Integration.Tests/Spring.Scheduling.Quartz2.Integration.Tests.csproj +++ b/test/Spring/Spring.Scheduling.Quartz3.Integration.Tests/Spring.Scheduling.Quartz3.Integration.Tests.csproj @@ -1,11 +1,11 @@  - net452 + netcoreapp2.1;$(TargetFullFrameworkVersion) - + diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/App.config b/test/Spring/Spring.Scheduling.Quartz3.Tests/App.config similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/App.config rename to test/Spring/Spring.Scheduling.Quartz3.Tests/App.config diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/QuartzCompilerOptionsTests.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/QuartzCompilerOptionsTests.cs similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/QuartzCompilerOptionsTests.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/QuartzCompilerOptionsTests.cs diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs similarity index 99% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs index bf5d8248..29f022e9 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/AdaptableJobFactoryTest.cs @@ -19,7 +19,6 @@ using System; using NUnit.Framework; using Quartz; -using Quartz.Job; using Quartz.Spi; namespace Spring.Scheduling.Quartz diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs similarity index 99% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs index c84c3a94..aa06b2a6 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/CronTriggerObjectTest.cs @@ -22,8 +22,6 @@ using NUnit.Framework; using Quartz; using Quartz.Impl; -using Quartz.Job; - namespace Spring.Scheduling.Quartz { diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/JobDetailObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/JobDetailObjectTest.cs similarity index 99% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/JobDetailObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/JobDetailObjectTest.cs index e4f5e843..98a03818 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/JobDetailObjectTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/JobDetailObjectTest.cs @@ -20,7 +20,6 @@ using System.Collections; using NUnit.Framework; using Quartz; -using Quartz.Job; using Spring.Context.Support; diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/MethodInvokingJobDetailFactoryObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/MethodInvokingJobDetailFactoryObjectTest.cs similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/MethodInvokingJobDetailFactoryObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/MethodInvokingJobDetailFactoryObjectTest.cs diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs similarity index 96% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs index da4676a3..8cba1189 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/MethodInvokingJobTest.cs @@ -24,7 +24,6 @@ using NUnit.Framework; using Quartz; using Quartz.Impl; using Quartz.Impl.Triggers; -using Quartz.Job; using Quartz.Spi; using Spring.Objects.Support; @@ -151,7 +150,15 @@ namespace Spring.Scheduling.Quartz { IJobDetail jd = new JobDetailImpl("jobName", "jobGroup", typeof(NoOpJob)); IOperableTrigger trigger = new SimpleTriggerImpl("triggerName", "triggerGroup"); - TriggerFiredBundle retValue = new TriggerFiredBundle(jd, trigger, null, false, null, null, null, null); + TriggerFiredBundle retValue = new TriggerFiredBundle( + jd, + trigger, + null, + false, + DateTimeOffset.UtcNow, + null, + null, + null); return retValue; } diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/QuartzSupportTests.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/QuartzSupportTests.cs similarity index 82% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/QuartzSupportTests.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/QuartzSupportTests.cs index 57b7df0a..9f6c4228 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/QuartzSupportTests.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/QuartzSupportTests.cs @@ -17,7 +17,7 @@ using System; using System.Collections; using System.Threading; - +using System.Threading.Tasks; using FakeItEasy; using NUnit.Framework; @@ -46,18 +46,18 @@ namespace Spring.Scheduling.Quartz /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObject() + public async Task TestSchedulerFactoryObject() { - DoTestSchedulerFactoryObject(false, false); + await DoTestSchedulerFactoryObject(false, false); } /// /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObjectWithExplicitJobDetail() + public async Task TestSchedulerFactoryObjectWithExplicitJobDetail() { - DoTestSchedulerFactoryObject(true, false); + await DoTestSchedulerFactoryObject(true, false); } /// @@ -65,12 +65,12 @@ namespace Spring.Scheduling.Quartz /// [Test] [Ignore("Requires change to MethodInvoker for overriding target object and type")] - public void TestSchedulerFactoryObjectWithPrototypeJob() + public async Task TestSchedulerFactoryObjectWithPrototypeJob() { - DoTestSchedulerFactoryObject(false, true); + await DoTestSchedulerFactoryObject(false, true); } - private void DoTestSchedulerFactoryObject(bool explicitJobDetail, bool prototypeJob) + private async Task DoTestSchedulerFactoryObject(bool explicitJobDetail, bool prototypeJob) { TestObject tb = new TestObject("tb", 99); JobDetailObject jobDetail0 = new JobDetailObject(); @@ -116,8 +116,8 @@ namespace Spring.Scheduling.Quartz IScheduler scheduler = A.Fake(); A.CallTo(() => scheduler.Context).Returns(new SchedulerContext()); - A.CallTo(() => scheduler.GetTrigger(A._)).Returns(null); - A.CallTo(() => scheduler.GetJobDetail(A._)).Returns(null); + A.CallTo(() => scheduler.GetTrigger(A._, A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetJobDetail(A._, A._)).Returns(Task.FromResult(null)); SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); schedulerFactoryObject.JobFactory = null; @@ -132,42 +132,42 @@ namespace Spring.Scheduling.Quartz try { schedulerFactoryObject.AfterPropertiesSet(); - schedulerFactoryObject.Start(); + await schedulerFactoryObject.Start(); } finally { schedulerFactoryObject.Dispose(); } - A.CallTo(() => scheduler.ScheduleJob(trigger0)).MustHaveHappened(); - A.CallTo(() => scheduler.ScheduleJob(trigger1)).MustHaveHappened(); + A.CallTo(() => scheduler.ScheduleJob(trigger0, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.ScheduleJob(trigger1, A._)).MustHaveHappened(); - A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); - A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail0, true, true, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail0, true, true, A._)).MustHaveHappened(); - A.CallTo(() => scheduler.Start()).MustHaveHappened(); - A.CallTo(() => scheduler.Shutdown(false)).MustHaveHappened(); + A.CallTo(() => scheduler.Start(A._)).MustHaveHappened(); + A.CallTo(() => scheduler.Shutdown(false, A._)).MustHaveHappened(); } /// /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObjectWithExistingJobs() + public async Task TestSchedulerFactoryObjectWithExistingJobs() { - DoTestSchedulerFactoryObjectWithExistingJobs(false); + await DoTestSchedulerFactoryObjectWithExistingJobs(false); } /// /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObjectWithOverwriteExistingJobs() + public async Task TestSchedulerFactoryObjectWithOverwriteExistingJobs() { - DoTestSchedulerFactoryObjectWithExistingJobs(true); + await DoTestSchedulerFactoryObjectWithExistingJobs(true); } - private void DoTestSchedulerFactoryObjectWithExistingJobs(bool overwrite) + private async Task DoTestSchedulerFactoryObjectWithExistingJobs(bool overwrite) { TestObject tb = new TestObject("tb", 99); JobDetailObject jobDetail0 = new JobDetailObject(); @@ -202,13 +202,13 @@ namespace Spring.Scheduling.Quartz IScheduler scheduler = A.Fake(); A.CallTo(() => scheduler.Context).Returns(new SchedulerContext()); - A.CallTo(() => scheduler.GetJobDetail(A._)).Returns(null); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup))).Returns(null); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup))).Returns(new SimpleTriggerImpl()); + A.CallTo(() => scheduler.GetJobDetail(A._, A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup), A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), A._)).Returns(Task.FromResult(new SimpleTriggerImpl())); if (overwrite) { - A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), trigger1)).Returns(DateTime.UtcNow); + A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), trigger1, A._)).Returns(DateTime.UtcNow); } SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); @@ -224,38 +224,38 @@ namespace Spring.Scheduling.Quartz try { schedulerFactoryObject.AfterPropertiesSet(); - schedulerFactoryObject.Start(); + await schedulerFactoryObject.Start(); } finally { schedulerFactoryObject.Dispose(); } - A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); - A.CallTo(() => scheduler.ScheduleJob(trigger0)).MustHaveHappened(); - A.CallTo(() => scheduler.Start()).MustHaveHappened(); - A.CallTo(() => scheduler.Shutdown(false)).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail0, true, true, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.ScheduleJob(trigger0, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.Start(A._)).MustHaveHappened(); + A.CallTo(() => scheduler.Shutdown(false, A._)).MustHaveHappened(); } /// /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObjectWithExistingJobsAndRaceCondition() + public async Task TestSchedulerFactoryObjectWithExistingJobsAndRaceCondition() { - DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(false); + await DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(false); } /// /// Executes parametrized test. /// [Test] - public void TestSchedulerFactoryObjectWithOverwriteExistingJobsAndRaceCondition() + public async Task TestSchedulerFactoryObjectWithOverwriteExistingJobsAndRaceCondition() { - DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(true); + await DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(true); } - private void DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(bool overwrite) + private async Task DoTestSchedulerFactoryObjectWithExistingJobsAndRaceCondition(bool overwrite) { TestObject tb = new TestObject("tb", 99); JobDetailObject jobDetail0 = new JobDetailObject(); @@ -290,24 +290,24 @@ namespace Spring.Scheduling.Quartz IScheduler scheduler = A.Fake(); A.CallTo(() => scheduler.Context).Returns(new SchedulerContext()); - A.CallTo(() => scheduler.GetJobDetail(A._)).Returns(null); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup))).Returns(null); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup))).Returns(new SimpleTriggerImpl()); + A.CallTo(() => scheduler.GetJobDetail(A._, A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup), A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), A._)).Returns(Task.FromResult(new SimpleTriggerImpl())); if (overwrite) { - scheduler.AddJob(jobDetail1, true); - A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), trigger1)).Returns(DateTime.UtcNow); + await scheduler.AddJob(jobDetail1, true); + A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), trigger1, A._)).Returns(DateTime.UtcNow); } - A.CallTo(() => scheduler.ScheduleJob(trigger0)).Throws(new ObjectAlreadyExistsException("")); + A.CallTo(() => scheduler.ScheduleJob(trigger0, A._)).Throws(new ObjectAlreadyExistsException("")); if (overwrite) { - A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup), trigger0)).Returns(DateTime.UtcNow); + A.CallTo(() => scheduler.RescheduleJob(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup), trigger0, A._)).Returns(DateTime.UtcNow); } - scheduler.Start(); - scheduler.Shutdown(false); + await scheduler.Start(); + await scheduler.Shutdown(false); SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); @@ -323,14 +323,14 @@ namespace Spring.Scheduling.Quartz try { schedulerFactoryObject.AfterPropertiesSet(); - schedulerFactoryObject.Start(); + await schedulerFactoryObject.Start(); } finally { schedulerFactoryObject.Dispose(); } - A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail0, true, true, A._)).MustHaveHappened(); } @@ -417,7 +417,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerFactoryObjectWithPlainQuartzObjects() + public async Task TestSchedulerFactoryObjectWithPlainQuartzObjects() { IJobFactory jobFactory = new AdaptableJobFactory(); @@ -456,8 +456,8 @@ namespace Spring.Scheduling.Quartz trigger1.RepeatInterval = TimeSpan.FromMilliseconds(20); IScheduler scheduler = A.Fake(); - A.CallTo(() => scheduler.GetTrigger(A._)).Returns(null); - A.CallTo(() => scheduler.GetJobDetail(A._)).Returns(null); + A.CallTo(() => scheduler.GetTrigger(A._, A._)).Returns(Task.FromResult(null)); + A.CallTo(() => scheduler.GetJobDetail(A._, A._)).Returns(Task.FromResult(null)); SchedulerFactoryObject schedulerFactoryObject = new TestSchedulerFactoryObject(scheduler); @@ -467,7 +467,7 @@ namespace Spring.Scheduling.Quartz try { schedulerFactoryObject.AfterPropertiesSet(); - schedulerFactoryObject.Start(); + await schedulerFactoryObject.Start(); } finally { @@ -479,18 +479,18 @@ namespace Spring.Scheduling.Quartz .WhenArgumentsMatch(x => x.Get(0) == jobFactory) .MustHaveHappened(); - A.CallTo(() => scheduler.AddJob(jobDetail0, true, true)).MustHaveHappened(); - A.CallTo(() => scheduler.AddJob(jobDetail1, true, true)).MustHaveHappened(); - A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob0", SchedulerConstants.DefaultGroup))).MustHaveHappened(); - A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob1", SchedulerConstants.DefaultGroup))).MustHaveHappened(); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup))).MustHaveHappened(); - A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup))).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail0, true, true, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.AddJob(jobDetail1, true, true, A._)).MustHaveHappened(); + A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob0", SchedulerConstants.DefaultGroup), A._)).MustHaveHappened(); + A.CallTo(() => scheduler.GetJobDetail(new JobKey("myJob1", SchedulerConstants.DefaultGroup), A._)).MustHaveHappened(); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger0", SchedulerConstants.DefaultGroup), A._)).MustHaveHappened(); + A.CallTo(() => scheduler.GetTrigger(new TriggerKey("myTrigger1", SchedulerConstants.DefaultGroup), A._)).MustHaveHappened(); } /// /// [Test] - public void TestSchedulerFactoryObjectWithApplicationContext() + public async Task TestSchedulerFactoryObjectWithApplicationContext() { TestObject tb = new TestObject("tb", 99); StaticApplicationContext ac = new StaticApplicationContext(); @@ -509,7 +509,7 @@ namespace Spring.Scheduling.Quartz try { schedulerFactoryObject.AfterPropertiesSet(); - schedulerFactoryObject.Start(); + await schedulerFactoryObject.Start(); IScheduler returnedScheduler = (IScheduler) schedulerFactoryObject.GetObject(); Assert.AreEqual(tb, returnedScheduler.Context["testObject"]); Assert.AreEqual(ac, returnedScheduler.Context["appCtx"]); @@ -545,7 +545,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithTaskExecutor() + public async Task TestSchedulerWithTaskExecutor() { CountingTaskExecutor taskExecutor = new CountingTaskExecutor(); DummyJob.count = 0; @@ -567,7 +567,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.IsTrue(DummyJob.count > 0); @@ -579,7 +579,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithRunnable() + public async Task TestSchedulerWithRunnable() { DummyRunnable.count = 0; @@ -599,7 +599,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); DummyRunnable.runEvent.WaitOne(500); Assert.IsTrue(DummyRunnable.count > 0); @@ -610,7 +610,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithQuartzJobObject() + public async Task TestSchedulerWithQuartzJobObject() { DummyJob.param = 0; DummyJob.count = 0; @@ -632,7 +632,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.AreEqual(10, DummyJobObject.param); @@ -644,7 +644,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithSpringObjectJobFactory() + public async Task TestSchedulerWithSpringObjectJobFactory() { DummyJob.param = 0; DummyJob.count = 0; @@ -668,7 +668,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.AreEqual(10, DummyJob.param); @@ -717,7 +717,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithSpringObjectJobFactoryAndRunnable() + public async Task TestSchedulerWithSpringObjectJobFactoryAndRunnable() { DummyRunnable.param = 0; DummyRunnable.count = 0; @@ -740,7 +740,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.AreEqual(10, DummyRunnable.param); @@ -752,7 +752,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithSpringObjectJobFactoryAndQuartzJobObject() + public async Task TestSchedulerWithSpringObjectJobFactoryAndQuartzJobObject() { DummyJobObject.param = 0; DummyJobObject.count = 0; @@ -775,7 +775,7 @@ namespace Spring.Scheduling.Quartz factoryObject.Triggers = new ITrigger[] {trigger}; factoryObject.JobDetails = new IJobDetail[] {jobDetail}; factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.AreEqual(10, DummyJobObject.param); @@ -788,7 +788,7 @@ namespace Spring.Scheduling.Quartz /// /// [Test] - public void TestSchedulerWithSpringObjectJobFactoryAndJobSchedulingData() + public async Task TestSchedulerWithSpringObjectJobFactoryAndJobSchedulingData() { DummyJob.param = 0; DummyJob.count = 0; @@ -798,7 +798,7 @@ namespace Spring.Scheduling.Quartz factoryObject.JobSchedulingDataLocation = "job-scheduling-data.xml"; // TODO bean.ResourceLoader = (new FileSystemResourceLoader()); factoryObject.AfterPropertiesSet(); - factoryObject.Start(); + await factoryObject.Start(); Thread.Sleep(500); Assert.AreEqual(10, DummyJob.param); @@ -924,145 +924,14 @@ namespace Spring.Scheduling.Quartz /// Tests how scheduler is exposed to application context. /// [Test] - public void TestSchedulerRepositoryExposure() + public async Task TestSchedulerRepositoryExposure() { XmlApplicationContext ctx = new XmlApplicationContext("schedulerRepositoryExposure.xml"); - Assert.AreSame(SchedulerRepository.Instance.Lookup("myScheduler"), ctx.GetObject("scheduler")); + var expected = await SchedulerRepository.Instance.Lookup("myScheduler"); + Assert.AreSame(expected, ctx.GetObject("scheduler")); ctx.Dispose(); } - private class TestSchedulerListener : ISchedulerListener - { - public void JobScheduled(ITrigger trigger) - { - } - - public void JobUnscheduled(TriggerKey triggerKey) - { - } - - public void TriggerFinalized(ITrigger trigger) - { - } - - public void TriggerPaused(TriggerKey triggerKey) - { - } - - public void TriggersPaused(string triggerGroup) - { - } - - public void TriggerResumed(TriggerKey triggerKey) - { - } - - public void TriggersResumed(string triggerGroup) - { - } - - public void JobAdded(IJobDetail jobDetail) - { - } - - public void JobDeleted(JobKey jobKey) - { - } - - public void JobPaused(JobKey jobKey) - { - } - - public void JobsPaused(string jobGroup) - { - } - - public void JobResumed(JobKey jobKey) - { - } - - public void JobsResumed(string jobGroup) - { - } - - public void SchedulerError(string msg, SchedulerException cause) - { - } - - public void SchedulerInStandbyMode() - { - } - - public void SchedulerStarted() - { - } - - public void SchedulerStarting() - { - - } - - public void SchedulerShutdown() - { - } - - public void SchedulerShuttingdown() - { - } - - public void SchedulingDataCleared() - { - } - } - - private class TestJobListener : IJobListener - { - public string Name - { - get { return null; } - } - - public void JobToBeExecuted(IJobExecutionContext context) - { - } - - public void JobExecutionVetoed(IJobExecutionContext context) - { - } - - public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException) - { - } - } - - - private class TestTriggerListener : ITriggerListener - { - public string Name - { - get { return null; } - } - - public void TriggerFired(ITrigger trigger, IJobExecutionContext context) - { - } - - public bool VetoJobExecution(ITrigger trigger, IJobExecutionContext context) - { - return false; - } - - public void TriggerMisfired(ITrigger trigger) - { - } - - public void TriggerComplete(ITrigger trigger, IJobExecutionContext context, - SchedulerInstruction triggerInstructionCode) - { - } - } - - /// /// Simple task executor that tracks invocation count. /// @@ -1107,9 +976,10 @@ namespace Spring.Scheduling.Quartz /// applied as object property values by execute. The contract is /// exactly the same as for the standard Quartz execute method. /// - protected override void ExecuteInternal(IJobExecutionContext jobExecutionContext) + protected override Task ExecuteInternal(IJobExecutionContext jobExecutionContext) { count++; + return Task.FromResult(true); } } @@ -1125,10 +995,11 @@ namespace Spring.Scheduling.Quartz /// /// Runs thread runnable. /// - public void Run() + public Task Run() { count++; runEvent.Set(); + return Task.FromResult(true); } } } @@ -1158,9 +1029,10 @@ namespace Spring.Scheduling.Quartz /// Executes this job instance. /// /// - public void Execute(IJobExecutionContext jobExecutionContext) + public Task Execute(IJobExecutionContext jobExecutionContext) { count++; + return Task.FromResult(true); } } diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/QuartzTestObject.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/QuartzTestObject.cs similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/QuartzTestObject.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/QuartzTestObject.cs diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs similarity index 87% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs index e8fe1607..e53815ee 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SchedulerFactoryObjectTest.cs @@ -21,7 +21,8 @@ using System.Collections.Specialized; using System.IO; using System.Reflection; using System.Text; - +using System.Threading; +using System.Threading.Tasks; using FakeItEasy; using NUnit.Framework; @@ -87,7 +88,7 @@ namespace Spring.Scheduling.Quartz factory.AutoStartup = false; factory.AfterPropertiesSet(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.Start()).MustNotHaveHappened(); + A.CallTo(() => TestSchedulerFactory.MockScheduler.Start(A._)).MustNotHaveHappened(); } /// @@ -106,7 +107,7 @@ namespace Spring.Scheduling.Quartz factory.AfterPropertiesSet(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.AddCalendar(calendarName, cal, true, true)).MustHaveHappened(); + A.CallTo(() => TestSchedulerFactory.MockScheduler.AddCalendar(calendarName, cal, true, true, A._)).MustHaveHappened(); } /// @@ -122,7 +123,7 @@ namespace Spring.Scheduling.Quartz SimpleTriggerImpl trigger = new SimpleTriggerImpl(TRIGGER_NAME, TRIGGER_GROUP); factory.Triggers = new ITrigger[] { trigger }; - A.CallTo(() => TestSchedulerFactory.MockScheduler.GetTrigger(new TriggerKey(TRIGGER_NAME, TRIGGER_GROUP))).Returns(trigger); + A.CallTo(() => TestSchedulerFactory.MockScheduler.GetTrigger(new TriggerKey(TRIGGER_NAME, TRIGGER_GROUP), A._)).Returns(trigger); factory.AfterPropertiesSet(); } @@ -134,7 +135,7 @@ namespace Spring.Scheduling.Quartz public void TestAfterPropertiesSet_Trigger_TriggerDoesntExist() { InitForAfterPropertiesSetTest(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.GetTrigger(A._)).Returns(null); + A.CallTo(() => TestSchedulerFactory.MockScheduler.GetTrigger(A._, A._)).Returns(Task.FromResult(null)); const string TRIGGER_NAME = "trigName"; const string TRIGGER_GROUP = "trigGroup"; @@ -143,7 +144,7 @@ namespace Spring.Scheduling.Quartz factory.AfterPropertiesSet(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.ScheduleJob(trigger)).MustHaveHappened(); + A.CallTo(() => TestSchedulerFactory.MockScheduler.ScheduleJob(trigger, A._)).MustHaveHappened(); } @@ -159,38 +160,38 @@ namespace Spring.Scheduling.Quartz /// Tests AfterPropertiesSet behavior. /// [Test] - public void TestStart() + public async Task TestStart() { factory.SchedulerFactoryType = typeof(TestSchedulerFactory); factory.AutoStartup = false; factory.AfterPropertiesSet(); - factory.Start(); + await factory.Start(); A.CallTo(TestSchedulerFactory.MockScheduler) .Where(x => x.Method.Name.Equals("set_JobFactory")) .WhenArgumentsMatch(x => x.Get(0) != null) .MustHaveHappened(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.Start()).MustHaveHappened(); + A.CallTo(() => TestSchedulerFactory.MockScheduler.Start(A._)).MustHaveHappened(); } /// /// Tests AfterPropertiesSet behavior. /// [Test] - public void TestStop() + public async Task TestStop() { factory.SchedulerFactoryType = typeof(TestSchedulerFactory); factory.AutoStartup = false; factory.AfterPropertiesSet(); - factory.Stop(); + await factory.Stop(); A.CallTo(TestSchedulerFactory.MockScheduler) .Where(x => x.Method.Name.Equals("set_JobFactory")) .WhenArgumentsMatch(x => x.Get(0) != null) .MustHaveHappened(); - A.CallTo(() => TestSchedulerFactory.MockScheduler.Standby()).MustHaveHappened(); + A.CallTo(() => TestSchedulerFactory.MockScheduler.Standby(A._)).MustHaveHappened(); } /// @@ -284,34 +285,23 @@ ConnectionStringKey+ " = " + ConnectionStringValue + Environment.NewLine + /// /// The mocked scheduler. /// - public static IScheduler MockScheduler + public static IScheduler MockScheduler => mockScheduler; + + /// + public Task GetScheduler(CancellationToken _) { - get { return mockScheduler; } + return Task.FromResult(mockScheduler); } - /// - /// - /// - public IScheduler GetScheduler() + /// + public Task GetScheduler(string schedName, CancellationToken _) { - return mockScheduler; + return Task.FromResult(mockScheduler); } - /// - /// - /// - /// - public IScheduler GetScheduler(string schedName) - { - return mockScheduler; - } - - /// - /// - public ICollection AllSchedulers - { - get { return new List(); } - } + /// + public Task> GetAllSchedulers(CancellationToken _) + => Task.FromResult>(new List()); public static void Initialize() { @@ -326,21 +316,15 @@ ConnectionStringKey+ " = " + ConnectionStringValue + Environment.NewLine + { private NameValueCollection properties; - /// - /// Initializes the factory. - /// - /// + /// public override void Initialize(NameValueCollection props) { - this.properties = props; + properties = props; } /// /// Return propeties given to this factory at initialization time. /// - public NameValueCollection Properties - { - get { return properties; } - } + public NameValueCollection Properties => properties; } } diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs similarity index 99% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs index 3ed7af72..8bdcadef 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SimpleTriggerObjectTest.cs @@ -21,7 +21,6 @@ using System.Collections.Generic; using NUnit.Framework; using Quartz.Impl; -using Quartz.Job; namespace Spring.Scheduling.Quartz { diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs similarity index 92% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs index 543779a0..a3fc58e1 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/SpringObjectJobFactoryTest.cs @@ -15,12 +15,11 @@ */ using System.Collections.Generic; - +using System.Threading.Tasks; using NUnit.Framework; using Quartz; using Quartz.Impl.Triggers; -using Quartz.Job; using Quartz.Spi; namespace Spring.Scheduling.Quartz @@ -95,31 +94,28 @@ namespace Spring.Scheduling.Quartz } } + + public class NoOpJob : IJob + { + public Task Execute(IJobExecutionContext context) + { + return Task.FromResult(true); + } + } /// /// Test job object that has injectable properties /// public class InjectableJob : NoOpJob { - private int number; - private string foo; - /// /// Simple int property. /// - public int Number - { - get { return number; } - set { number = value; } - } + public int Number { get; set; } /// /// Simple string property. /// - public string Foo - { - get { return foo; } - set { foo = value; } - } + public string Foo { get; set; } } } diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TestMethodInvokingTask.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TestMethodInvokingTask.cs similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TestMethodInvokingTask.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TestMethodInvokingTask.cs diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TestUtil.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TestUtil.cs similarity index 96% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TestUtil.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TestUtil.cs index 7675ed13..459b2bef 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TestUtil.cs +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TestUtil.cs @@ -49,7 +49,7 @@ namespace Spring.Scheduling.Quartz public static TriggerFiredBundle CreateMinimalFiredBundleWithTypedJobDetail(Type jobType, IOperableTrigger trigger) { IJobDetail jd = new JobDetailImpl("jobName", "jobGroup", jobType); - TriggerFiredBundle bundle = new TriggerFiredBundle(jd, trigger, null, false, null, null, null, null); + TriggerFiredBundle bundle = new TriggerFiredBundle(jd, trigger, null, false, DateTimeOffset.UtcNow, null, null, null); return bundle; } } diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TriggerObjectTest.cs b/test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TriggerObjectTest.cs similarity index 100% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Scheduling/Quartz/TriggerObjectTest.cs rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Scheduling/Quartz/TriggerObjectTest.cs diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/Spring.Scheduling.Quartz2.Tests.csproj b/test/Spring/Spring.Scheduling.Quartz3.Tests/Spring.Scheduling.Quartz3.Tests.csproj similarity index 88% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/Spring.Scheduling.Quartz2.Tests.csproj rename to test/Spring/Spring.Scheduling.Quartz3.Tests/Spring.Scheduling.Quartz3.Tests.csproj index 458106ee..6901c20a 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/Spring.Scheduling.Quartz2.Tests.csproj +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/Spring.Scheduling.Quartz3.Tests.csproj @@ -1,10 +1,10 @@  - net452 + netcoreapp2.1;$(TargetFullFrameworkVersion) - + diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/job-scheduling-data.xml b/test/Spring/Spring.Scheduling.Quartz3.Tests/job-scheduling-data.xml similarity index 97% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/job-scheduling-data.xml rename to test/Spring/Spring.Scheduling.Quartz3.Tests/job-scheduling-data.xml index ad1f5336..42bedecc 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/job-scheduling-data.xml +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/job-scheduling-data.xml @@ -13,7 +13,7 @@ myJob myGroup - Spring.Scheduling.Quartz.DummyJob, Spring.Scheduling.Quartz2.Tests + Spring.Scheduling.Quartz.DummyJob, Spring.Scheduling.Quartz3.Tests true false diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml b/test/Spring/Spring.Scheduling.Quartz3.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml similarity index 81% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml rename to test/Spring/Spring.Scheduling.Quartz3.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml index 6a29387d..b9ee8e4a 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/multipleAnonymousMethodInvokingJobDetailFB.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> - + @@ -14,9 +14,9 @@ - + - + @@ -26,9 +26,9 @@ - + - + @@ -38,8 +38,8 @@ - + - + diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/multipleSchedulers.xml b/test/Spring/Spring.Scheduling.Quartz3.Tests/multipleSchedulers.xml similarity index 85% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/multipleSchedulers.xml rename to test/Spring/Spring.Scheduling.Quartz3.Tests/multipleSchedulers.xml index 495908d3..011fbff5 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/multipleSchedulers.xml +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/multipleSchedulers.xml @@ -5,11 +5,11 @@ xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> - + - + diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerAccessorObject.xml b/test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerAccessorObject.xml similarity index 81% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerAccessorObject.xml rename to test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerAccessorObject.xml index acb7c5ca..87a74cf5 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerAccessorObject.xml +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerAccessorObject.xml @@ -5,9 +5,9 @@ xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> - + - + @@ -18,9 +18,9 @@ - + - + @@ -29,10 +29,10 @@ - + - + @@ -41,8 +41,8 @@ - + - + diff --git a/test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerRepositoryExposure.xml b/test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerRepositoryExposure.xml similarity index 82% rename from test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerRepositoryExposure.xml rename to test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerRepositoryExposure.xml index 76b97387..1342c5d0 100644 --- a/test/Spring/Spring.Scheduling.Quartz2.Tests/schedulerRepositoryExposure.xml +++ b/test/Spring/Spring.Scheduling.Quartz3.Tests/schedulerRepositoryExposure.xml @@ -5,12 +5,12 @@ xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd"> - + - + @@ -21,10 +21,10 @@ - + - + @@ -33,9 +33,9 @@ - + - + @@ -45,8 +45,8 @@ - + - +