Skip to content

Commit

Permalink
Start OWIN adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
mausch committed Jun 29, 2015
1 parent 29286ae commit c0b1bc8
Show file tree
Hide file tree
Showing 11 changed files with 671 additions and 1 deletion.
6 changes: 6 additions & 0 deletions QuartzNetWebConsole.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApp", "SampleApp\Samp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuartzNetWebConsole.Web", "QuartzNetWebConsole.Web\QuartzNetWebConsole.Web.csproj", "{1F666487-F60B-4C8D-B632-58B24C37FEC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApp.Owin", "SampleApp.Owin\SampleApp.Owin.csproj", "{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -46,6 +48,10 @@ Global
{1F666487-F60B-4C8D-B632-58B24C37FEC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F666487-F60B-4C8D-B632-58B24C37FEC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F666487-F60B-4C8D-B632-58B24C37FEC1}.Release|Any CPU.Build.0 = Release|Any CPU
{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion QuartzNetWebConsole/Controllers/LogController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static Response Execute(Uri url) {
public static KeyValuePair<string, Func<IEnumerable<LogEntry>, PaginationInfo, string, XDocument>> GetView(IEnumerable<string> qs) {
if (qs.Contains("rss"))
return Helpers.KV("application/rss+xml", RSSView);
return Helpers.KV((string)null, XHTMLView);
return Helpers.KV("text/html", XHTMLView);
}

public static readonly Func<IEnumerable<LogEntry>, PaginationInfo, string, XDocument> XHTMLView =
Expand Down
84 changes: 84 additions & 0 deletions QuartzNetWebConsole/Setup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Quartz;
using QuartzNetWebConsole.Utils;

namespace QuartzNetWebConsole {
public static class Setup {
Expand Down Expand Up @@ -37,5 +42,84 @@ public static ILogger Logger {
static Setup() {
Scheduler = () => { throw new Exception("Define QuartzNetWebConsole.Setup.Scheduler"); };
}

private static Uri GetOwinUri(this IDictionary<string, object> env) {
var headers = (IDictionary<string, string[]>)env["owin.RequestHeaders"];
var scheme = (string)env["owin.RequestScheme"];
var hostAndPort = headers["Host"].First().Split(':');
var host = hostAndPort[0];
var port = hostAndPort.Length > 1 ? int.Parse(hostAndPort[1]) : (scheme == Uri.UriSchemeHttp ? 80 : 443);
var path = (string)env["owin.RequestPathBase"] + (string)env["owin.RequestPath"];
var query = (string)env["owin.RequestQueryString"];

var uriBuilder = new UriBuilder(scheme: scheme, host: host, portNumber: port) {
Path = path,
Query = query,
};

return uriBuilder.Uri;
}

private static Stream GetOwinResponseBody(this IDictionary<string, object> env) {
return (Stream) env["owin.ResponseBody"];
}

private static IDictionary<string, string[]> GetOwinResponseHeaders(this IDictionary<string, object> env) {
return (IDictionary<string, string[]>) env["owin.ResponseHeaders"];
}

private static void SetOwinContentType(this IDictionary<string, object> env, string contentType) {
if (string.IsNullOrEmpty(contentType))
return;
env.GetOwinResponseHeaders()["Content-Type"] = new [] {contentType};
}

private static void SetOwinContentLength(this IDictionary<string, object> env, long length) {
env.GetOwinResponseHeaders()["Content-Length"] = new[] { length.ToString() };
}

private static void SetOwinStatusCode(this IDictionary<string, object> env, int statusCode) {
env["owin.ResponseStatusCode"] = statusCode;
}

public delegate Task AppFunc(IDictionary<string, object> env);

private static AppFunc EvaluateResponse(Response response) {
return env => response.Match(
content: async x => {
env.SetOwinContentType(x.ContentType);
env.SetOwinContentLength(x.Content.Length);
var sw = new StreamWriter(env.GetOwinResponseBody());
await sw.WriteAsync(x.Content);
await sw.FlushAsync();
},
xdoc: async x => {
env.SetOwinContentType(x.ContentType);
var content = x.Content.ToString();
env.SetOwinContentLength(content.Length);
var sw = new StreamWriter(env.GetOwinResponseBody());
await sw.WriteAsync(content);
await sw.FlushAsync();
},
redirect: async x => {
env.SetOwinStatusCode(302);
env.GetOwinResponseHeaders()["Location"] = new [] {x.Location};
await Task.Yield();
});
}

public static Func<AppFunc, AppFunc> Owin(Func<IScheduler> scheduler) {
Setup.Scheduler = scheduler;
return app => env => {
var uri = env.GetOwinUri();
var response =
Routing.Routes
.Where(x => uri.AbsolutePath.Split('.')[0].EndsWith(x.Key, StringComparison.InvariantCultureIgnoreCase))
.Select(r => r.Value(uri))
.Select(EvaluateResponse)
.FirstOrDefault();
return response == null ? app(env) : response(env);
};
}
}
}
6 changes: 6 additions & 0 deletions SampleApp.Owin/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
15 changes: 15 additions & 0 deletions SampleApp.Owin/HelloJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Threading;
using Quartz;

namespace SampleApp {
/// <summary>
/// A sample dummy job
/// </summary>
[DisallowConcurrentExecution]
public class HelloJob : IJob {
public void Execute(IJobExecutionContext context) {
Thread.Sleep(5000);
}
}
}
50 changes: 50 additions & 0 deletions SampleApp.Owin/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using Microsoft.Owin.Hosting;
using Owin;
using Quartz;
using Quartz.Impl;

namespace SampleApp.Owin {
class Program {
static void Start(IAppBuilder app) {

// First, initialize Quartz.NET as usual. In this sample app I'll configure Quartz.NET by code.
var schedulerFactory = new StdSchedulerFactory();
var scheduler = schedulerFactory.GetScheduler();
scheduler.Start();

// I'll add some global listeners
//scheduler.ListenerManager.AddJobListener(new GlobalJobListener());
//scheduler.ListenerManager.AddTriggerListener(new GlobalTriggerListener());

// A sample trigger and job
var trigger = TriggerBuilder.Create()
.WithIdentity("myTrigger")
.WithSchedule(DailyTimeIntervalScheduleBuilder.Create()
.WithIntervalInSeconds(6))
.StartNow()
.Build();
var job = new JobDetailImpl("myJob", null, typeof(HelloJob));
scheduler.ScheduleJob(job, trigger);

// A cron trigger and job
var cron = TriggerBuilder.Create()
.WithIdentity("myCronTrigger")
.ForJob(job.Key)
.WithCronSchedule("0/10 * * * * ?") // every 10 seconds
.Build();

scheduler.ScheduleJob(cron);

// A dummy calendar
//scheduler.AddCalendar("myCalendar", new DummyCalendar { Description = "dummy calendar" }, false, false);

app.Use(QuartzNetWebConsole.Setup.Owin(() => scheduler));
}

private static void Main(string[] args) {
using (WebApp.Start("http://localhost:12345", Start))
Console.ReadLine();
}
}
}
36 changes: 36 additions & 0 deletions SampleApp.Owin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SampleApp.Owin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SampleApp.Owin")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("29510bce-2fc0-41b8-b16a-716ed60f8f97")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
104 changes: 104 additions & 0 deletions SampleApp.Owin/SampleApp.Owin.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{76153C2F-C591-417B-A9D9-38E7A2DFF5F3}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SampleApp.Owin</RootNamespace>
<AssemblyName>SampleApp.Owin</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging">
<HintPath>..\packages\Common.Logging.3.0.0\lib\net40\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="Common.Logging.Core">
<HintPath>..\packages\Common.Logging.Core.3.0.0\lib\net40\Common.Logging.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Hosting">
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
</Reference>
<Reference Include="Owin">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Quartz">
<HintPath>..\packages\Quartz.2.3.2\lib\net40\Quartz.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="HelloJob.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="job_scheduling_data_2_0.xsd">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\QuartzNetWebConsole.Views\QuartzNetWebConsole.Views.vbproj">
<Project>{7961ab01-1549-4340-8d3d-f0da43b8c84f}</Project>
<Name>QuartzNetWebConsole.Views</Name>
</ProjectReference>
<ProjectReference Include="..\QuartzNetWebConsole\QuartzNetWebConsole.csproj">
<Project>{72a7a322-38dd-47dd-8948-6ed6e2f9dc5d}</Project>
<Name>QuartzNetWebConsole</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Loading

0 comments on commit c0b1bc8

Please sign in to comment.