├── src ├── Processing.Activities │ ├── Retrieve │ │ ├── RetrieveLog.cs │ │ ├── RetrieveArguments.cs │ │ └── RetrieveActivity.cs │ ├── Validate │ │ ├── ValidateArguments.cs │ │ └── ValidateActivity.cs │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Processing.Activities.csproj ├── Client │ ├── App.config │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Client.csproj │ └── Program.cs ├── Processing.Contracts │ ├── RoutingSlipCreated.cs │ ├── ContentNotFound.cs │ ├── RequestRejected.cs │ ├── ContentRetrieved.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Processing.Contracts.csproj ├── TrackingService │ ├── RoutingSlipStateSagaMap.cs │ ├── RoutingSlipMetricsConsumer.cs │ ├── RoutingSlipActivityConsumer.cs │ ├── App.config │ ├── RoutingSlipMetrics.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── packages.config │ ├── TrackingService.cs │ ├── SQLiteSessionFactoryProvider.cs │ ├── SingleConnectionSessionFactory.cs │ └── TrackingService.csproj ├── Tracking │ ├── packages.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RoutingSlipState.cs │ ├── RoutingSlipStateMachine.cs │ └── Tracking.csproj ├── ProcessingService │ ├── App.config │ ├── packages.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ActivityService.cs │ └── ProcessingService.csproj └── Sample-Courier.sln ├── .gitignore └── alpha_prerelease.cmd /src/Processing.Activities/Retrieve/RetrieveLog.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Activities.Retrieve 2 | { 3 | public interface RetrieveLog 4 | { 5 | /// 6 | /// The path where the content was saved 7 | /// 8 | string LocalFilePath { get; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Client/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Processing.Activities/Retrieve/RetrieveArguments.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Activities.Retrieve 2 | { 3 | using System; 4 | 5 | 6 | public interface RetrieveArguments 7 | { 8 | /// 9 | /// The requestId for eventing 10 | /// 11 | Guid RequestId { get; } 12 | 13 | /// 14 | /// The address of the content to retrieve 15 | /// 16 | Uri Address { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Processing.Contracts/RoutingSlipCreated.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Contracts 2 | { 3 | using System; 4 | 5 | 6 | public interface RoutingSlipCreated 7 | { 8 | /// 9 | /// The tracking number of the routing slip 10 | /// 11 | Guid TrackingNumber { get; } 12 | 13 | /// 14 | /// The time the routing slip was created 15 | /// 16 | DateTime Timestamp { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Processing.Activities/Validate/ValidateArguments.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Activities.Validate 2 | { 3 | using System; 4 | 5 | 6 | public interface ValidateArguments 7 | { 8 | /// 9 | /// The requestId for this activity argument 10 | /// 11 | Guid RequestId { get; } 12 | 13 | /// 14 | /// The address of the resource to retrieve 15 | /// 16 | Uri Address { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/TrackingService/RoutingSlipStateSagaMap.cs: -------------------------------------------------------------------------------- 1 | namespace TrackingService 2 | { 3 | using MassTransit.NHibernateIntegration; 4 | using Tracking; 5 | 6 | 7 | public class RoutingSlipStateSagaMap : 8 | SagaClassMapping 9 | { 10 | public RoutingSlipStateSagaMap() 11 | { 12 | Property(x => x.State); 13 | 14 | Property(x => x.CreateTime); 15 | Property(x => x.StartTime); 16 | Property(x => x.EndTime); 17 | Property(x => x.Duration); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build_output/* 2 | build_artifacts/* 3 | *.suo 4 | *.user 5 | packages 6 | *.dotCover 7 | 8 | Gemfile.lock 9 | 10 | *.ncrunch* 11 | 12 | src/logs/* 13 | 14 | .idea 15 | 16 | bin 17 | obj 18 | _ReSharper* 19 | src/Samples/HeavyLoad/logs 20 | 21 | *.csproj.user 22 | *.resharper.user 23 | *.resharper 24 | *.ReSharper 25 | *.cache 26 | *~ 27 | *.swp 28 | *.bak 29 | *.orig 30 | 31 | NuGet.exe 32 | 33 | packages 34 | 35 | TestResult.xml 36 | submit.xml 37 | tests/* 38 | SolutionVersion.cs 39 | src/SolutionVersion.cs 40 | tests 41 | doc/build/* 42 | 43 | # osx noise 44 | .DS_Store 45 | NuGet.Exe 46 | 47 | nuspecs/ 48 | -------------------------------------------------------------------------------- /src/Processing.Contracts/ContentNotFound.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Contracts 2 | { 3 | using System; 4 | 5 | 6 | public interface ContentNotFound 7 | { 8 | /// 9 | /// The timestamp that the event occurred 10 | /// 11 | DateTime Timestamp { get; } 12 | 13 | /// 14 | /// The source address from which the image was retrieved 15 | /// 16 | Uri Address { get; } 17 | 18 | /// 19 | /// The reason why the image was not found 20 | /// 21 | string Reason { get; } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Processing.Activities/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /alpha_prerelease.cmd: -------------------------------------------------------------------------------- 1 | @copy ..\masstransit\build_output\net-4.5\masstransit.dll src\packages\MassTransit.3.0.11-beta\lib\net45 2 | @copy ..\masstransit\build_output\net-4.5\masstransit.xml src\packages\MassTransit.3.0.11-beta\lib\net45 3 | @copy ..\masstransit\build_output\net-4.5\masstransit.pdb src\packages\MassTransit.3.0.11-beta\lib\net45 4 | @copy ..\masstransit\build_output\net-4.5\transports\rabbitmq\masstransit.RabbitMqTransport.* src\packages\MassTransit.RabbitMQ.3.0.11-beta\lib\net45 5 | @copy ..\masstransit\build_artifacts\MassTransit.3.0.11-beta.nupkg src\packages\MassTransit.3.0.11-beta 6 | @copy ..\masstransit\build_artifacts\MassTransit.RabbitMQ.3.0.11-beta.nupkg src\packages\MassTransit.RabbitMQ.3.0.11-beta 7 | -------------------------------------------------------------------------------- /src/TrackingService/RoutingSlipMetricsConsumer.cs: -------------------------------------------------------------------------------- 1 | namespace TrackingService 2 | { 3 | using System.Threading.Tasks; 4 | using MassTransit; 5 | using MassTransit.Courier.Contracts; 6 | 7 | 8 | public class RoutingSlipMetricsConsumer : 9 | IConsumer 10 | { 11 | readonly RoutingSlipMetrics _metrics; 12 | 13 | public RoutingSlipMetricsConsumer(RoutingSlipMetrics metrics) 14 | { 15 | _metrics = metrics; 16 | } 17 | 18 | public async Task Consume(ConsumeContext context) 19 | { 20 | _metrics.AddComplete(context.Message.Duration); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tracking/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/ProcessingService/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/TrackingService/RoutingSlipActivityConsumer.cs: -------------------------------------------------------------------------------- 1 | namespace TrackingService 2 | { 3 | using System; 4 | using System.Threading.Tasks; 5 | using MassTransit; 6 | using MassTransit.Courier.Contracts; 7 | 8 | 9 | public class RoutingSlipActivityConsumer : 10 | IConsumer 11 | { 12 | readonly string _activityName; 13 | readonly RoutingSlipMetrics _metrics; 14 | 15 | public RoutingSlipActivityConsumer(RoutingSlipMetrics metrics, string activityName) 16 | { 17 | _metrics = metrics; 18 | _activityName = activityName; 19 | } 20 | 21 | public async Task Consume(ConsumeContext context) 22 | { 23 | if (context.Message.ActivityName.Equals(_activityName, StringComparison.OrdinalIgnoreCase)) 24 | _metrics.AddComplete(context.Message.Duration); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/TrackingService/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Processing.Contracts/RequestRejected.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Contracts 2 | { 3 | using System; 4 | 5 | /// 6 | /// Published when a request is rejected 7 | /// 8 | public interface RequestRejected 9 | { 10 | /// 11 | /// The requestId 12 | /// 13 | Guid RequestId { get; } 14 | 15 | /// 16 | /// The tracking number of the routing slip 17 | /// 18 | Guid TrackingNumber { get; } 19 | 20 | /// 21 | /// When the event was produced 22 | /// 23 | DateTime Timestamp { get; } 24 | 25 | /// 26 | /// The code assigned to the rejection 27 | /// 28 | int ReasonCode { get; } 29 | 30 | /// 31 | /// A displayable version of the rejection reason 32 | /// 33 | string ReasonText { get; } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Processing.Contracts/ContentRetrieved.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Contracts 2 | { 3 | using System; 4 | 5 | 6 | public interface ContentRetrieved 7 | { 8 | /// 9 | /// When the content was retrieved 10 | /// 11 | DateTime Timestamp { get; } 12 | 13 | /// 14 | /// The content address 15 | /// 16 | Uri Address { get; } 17 | 18 | /// 19 | /// The local URI for the content 20 | /// 21 | Uri LocalAddress { get; } 22 | 23 | /// 24 | /// The local path of the content 25 | /// 26 | string LocalPath { get; } 27 | 28 | /// 29 | /// The length of the content 30 | /// 31 | long Length { get; } 32 | 33 | /// 34 | /// The content type 35 | /// 36 | string ContentType { get; } 37 | } 38 | } -------------------------------------------------------------------------------- /src/Client/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ProcessingService/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/TrackingService/RoutingSlipMetrics.cs: -------------------------------------------------------------------------------- 1 | namespace TrackingService 2 | { 3 | using System; 4 | using System.Collections.Concurrent; 5 | using System.Linq; 6 | using System.Threading; 7 | 8 | 9 | public class RoutingSlipMetrics 10 | { 11 | readonly ConcurrentBag _durations; 12 | long _completedCount; 13 | readonly string _description; 14 | 15 | public RoutingSlipMetrics(string description) 16 | { 17 | _description = description; 18 | _completedCount = 0; 19 | _durations = new ConcurrentBag(); 20 | } 21 | 22 | public void AddComplete(TimeSpan duration) 23 | { 24 | long count = Interlocked.Increment(ref _completedCount); 25 | _durations.Add(duration); 26 | 27 | if (count % 100 == 0) 28 | Snapshot(); 29 | } 30 | 31 | public void Snapshot() 32 | { 33 | TimeSpan[] snapshot = _durations.ToArray(); 34 | double averageDuration = snapshot.Average(x => x.TotalMilliseconds); 35 | 36 | Console.WriteLine("{0} {2} Completed, {1:F0}ms (average)", snapshot.Length, averageDuration, _description); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/ProcessingService/Program.cs: -------------------------------------------------------------------------------- 1 | namespace ProcessingService 2 | { 3 | using System.IO; 4 | using System.Text; 5 | using log4net.Config; 6 | using MassTransit.Log4NetIntegration.Logging; 7 | using Topshelf; 8 | using Topshelf.Logging; 9 | 10 | 11 | class Program 12 | { 13 | static int Main(string[] args) 14 | { 15 | ConfigureLogger(); 16 | 17 | // Topshelf to use Log4Net 18 | Log4NetLogWriterFactory.Use(); 19 | 20 | // MassTransit to use Log4Net 21 | Log4NetLogger.Use(); 22 | 23 | return (int)HostFactory.Run(x => x.Service()); 24 | } 25 | 26 | static void ConfigureLogger() 27 | { 28 | const string logConfig = @" 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | "; 40 | 41 | using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(logConfig))) 42 | { 43 | XmlConfigurator.Configure(stream); 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/TrackingService/Program.cs: -------------------------------------------------------------------------------- 1 | namespace TrackingService 2 | { 3 | using System.IO; 4 | using System.Text; 5 | using log4net.Config; 6 | using MassTransit.Log4NetIntegration.Logging; 7 | using Topshelf; 8 | using Topshelf.Logging; 9 | 10 | 11 | class Program 12 | { 13 | static int Main(string[] args) 14 | { 15 | ConfigureLogger(); 16 | 17 | // Topshelf to use Log4Net 18 | Log4NetLogWriterFactory.Use(); 19 | 20 | // MassTransit to use Log4Net 21 | Log4NetLogger.Use(); 22 | 23 | return (int)HostFactory.Run(x => x.Service()); 24 | } 25 | 26 | static void ConfigureLogger() 27 | { 28 | const string logConfig = @" 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | "; 43 | 44 | using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(logConfig))) 45 | { 46 | XmlConfigurator.Configure(stream); 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/Client/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Client")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("Client")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4788de84-2efc-4d3a-8d34-411a4ba70007")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Tracking/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Tracking")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("Tracking")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f2314c08-3529-4426-99be-f830976ee0b1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/TrackingService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TrackingService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("TrackingService")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3aa36d96-d4a5-4240-8d28-d9ee0492f982")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/ProcessingService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ProcessingService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("ProcessingService")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f2a2fcb9-556f-4bd0-af66-460e867cb3f2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Tracking/RoutingSlipState.cs: -------------------------------------------------------------------------------- 1 | namespace Tracking 2 | { 3 | using System; 4 | using Automatonymous; 5 | 6 | 7 | public class RoutingSlipState : 8 | SagaStateMachineInstance 9 | { 10 | protected RoutingSlipState() 11 | { 12 | } 13 | 14 | public RoutingSlipState(Guid correlationId) 15 | { 16 | CorrelationId = correlationId; 17 | } 18 | 19 | /// 20 | /// The state of the saga 21 | /// 22 | public int State { get; set; } 23 | 24 | /// 25 | /// When the routing slip was started 26 | /// 27 | public DateTime? StartTime { get; set; } 28 | 29 | /// 30 | /// When the routing slip was completed 31 | /// 32 | public DateTime? EndTime { get; set; } 33 | 34 | /// 35 | /// The total duration of the routing slip 36 | /// 37 | public TimeSpan? Duration { get; set; } 38 | 39 | /// 40 | /// When the routing slip was created 41 | /// 42 | public DateTime? CreateTime { get; set; } 43 | 44 | /// 45 | /// The fault summary is an exception summary for the faulted routing slip 46 | /// 47 | public string FaultSummary { get; set; } 48 | 49 | /// 50 | /// This maps to the tracking number of the routing slip 51 | /// 52 | public Guid CorrelationId { get; set; } 53 | } 54 | } -------------------------------------------------------------------------------- /src/Processing.Contracts/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Processing.Contracts")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("Processing.Contracts")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1c83157f-b65e-4a6c-85b8-5aae860005dd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Processing.Activities/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Processing.Activities")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("RelayHealth")] 12 | [assembly: AssemblyProduct("Processing.Activities")] 13 | [assembly: AssemblyCopyright("Copyright © RelayHealth 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d886ddc6-4d14-4ec9-b6d2-159bfd56c156")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/TrackingService/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Processing.Activities/Validate/ValidateActivity.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Activities.Validate 2 | { 3 | using System; 4 | using System.Threading.Tasks; 5 | using Contracts; 6 | using MassTransit.Courier; 7 | using MassTransit.Logging; 8 | 9 | 10 | /// 11 | /// Validates the address of the request to ensure it isn't an unacceptable domain 12 | /// 13 | public class ValidateActivity : 14 | ExecuteActivity 15 | { 16 | static readonly ILog _log = Logger.Get(); 17 | 18 | public async Task Execute(ExecuteContext context) 19 | { 20 | try 21 | { 22 | Uri address = context.Arguments.Address; 23 | if (address == null) 24 | { 25 | await context.Publish(new 26 | { 27 | context.Arguments.RequestId, 28 | context.TrackingNumber, 29 | Timestamp = DateTime.UtcNow, 30 | ReasonCode = 500, 31 | ReasonText = "The address was not specified", 32 | }); 33 | 34 | return context.Terminate(); 35 | } 36 | 37 | if (address.Host.EndsWith("microsoft.com", StringComparison.OrdinalIgnoreCase)) 38 | { 39 | await context.Publish(new 40 | { 41 | context.Arguments.RequestId, 42 | context.TrackingNumber, 43 | Timestamp = DateTime.UtcNow, 44 | ReasonCode = 403, 45 | ReasonText = "The host specified is forbidden: " + address.Host, 46 | }); 47 | 48 | return context.Terminate(); 49 | } 50 | 51 | if (_log.IsInfoEnabled) 52 | { 53 | _log.InfoFormat("Validated Request {0} for address {1}", context.Arguments.RequestId, 54 | context.Arguments.Address); 55 | } 56 | 57 | return context.Completed(); 58 | } 59 | catch (Exception ex) 60 | { 61 | Console.WriteLine(ex); 62 | throw; 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/Processing.Contracts/Processing.Contracts.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {79175983-7A1A-42DC-880B-F098312C4281} 8 | Library 9 | Properties 10 | Processing.Contracts 11 | Processing.Contracts 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 52 | -------------------------------------------------------------------------------- /src/ProcessingService/ActivityService.cs: -------------------------------------------------------------------------------- 1 | using GreenPipes; 2 | 3 | namespace ProcessingService 4 | { 5 | using System; 6 | using System.Configuration; 7 | using System.Threading; 8 | using MassTransit; 9 | using MassTransit.Courier; 10 | using MassTransit.Courier.Factories; 11 | using MassTransit.RabbitMqTransport; 12 | using MassTransit.Util; 13 | using Processing.Activities.Retrieve; 14 | using Processing.Activities.Validate; 15 | using Topshelf; 16 | using Topshelf.Logging; 17 | 18 | 19 | class ActivityService : 20 | ServiceControl 21 | { 22 | readonly LogWriter _log = HostLogger.Get(); 23 | 24 | IBusControl _busControl; 25 | 26 | public bool Start(HostControl hostControl) 27 | { 28 | int workerThreads; 29 | int completionPortThreads; 30 | ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads); 31 | Console.WriteLine("Min: {0}", workerThreads); 32 | 33 | ThreadPool.SetMinThreads(200, completionPortThreads); 34 | 35 | _log.Info("Creating bus..."); 36 | 37 | _busControl = Bus.Factory.CreateUsingRabbitMq(x => 38 | { 39 | IRabbitMqHost host = x.Host(new Uri(ConfigurationManager.AppSettings["RabbitMQHost"]), h => 40 | { 41 | h.Username("guest"); 42 | h.Password("guest"); 43 | }); 44 | 45 | x.ReceiveEndpoint(host, ConfigurationManager.AppSettings["ValidateActivityQueue"], e => 46 | { 47 | e.PrefetchCount = 100; 48 | e.ExecuteActivityHost( 49 | DefaultConstructorExecuteActivityFactory.ExecuteFactory, c => c.UseRetry(r => r.Immediate(5))); 50 | }); 51 | 52 | string compQueue = ConfigurationManager.AppSettings["CompensateRetrieveActivityQueue"]; 53 | 54 | Uri compAddress = new Uri(string.Concat(ConfigurationManager.AppSettings["RabbitMQHost"], compQueue)); 55 | 56 | x.ReceiveEndpoint(host, ConfigurationManager.AppSettings["RetrieveActivityQueue"], e => 57 | { 58 | e.PrefetchCount = 100; 59 | e.ExecuteActivityHost(compAddress, c=> c.UseRetry(r => r.Immediate(5))); 60 | }); 61 | 62 | x.ReceiveEndpoint(host, ConfigurationManager.AppSettings["CompensateRetrieveActivityQueue"], 63 | e => e.CompensateActivityHost(c => c.UseRetry(r => r.Immediate(5)))); 64 | }); 65 | 66 | _log.Info("Starting bus..."); 67 | 68 | TaskUtil.Await(() => _busControl.StartAsync()); 69 | 70 | return true; 71 | } 72 | 73 | public bool Stop(HostControl hostControl) 74 | { 75 | _log.Info("Stopping bus..."); 76 | 77 | _busControl?.Stop(); 78 | 79 | return true; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /src/TrackingService/TrackingService.cs: -------------------------------------------------------------------------------- 1 | 2 | namespace TrackingService 3 | { 4 | using System; 5 | using System.Configuration; 6 | using GreenPipes; 7 | using MassTransit; 8 | using MassTransit.NHibernateIntegration.Saga; 9 | using MassTransit.RabbitMqTransport; 10 | using MassTransit.Saga; 11 | using MassTransit.Util; 12 | using NHibernate; 13 | using Topshelf; 14 | using Topshelf.Logging; 15 | using Tracking; 16 | 17 | 18 | class TrackingService : 19 | ServiceControl 20 | { 21 | readonly LogWriter _log = HostLogger.Get(); 22 | RoutingSlipMetrics _activityMetrics; 23 | 24 | IBusControl _busControl; 25 | RoutingSlipStateMachine _machine; 26 | RoutingSlipMetrics _metrics; 27 | SQLiteSessionFactoryProvider _provider; 28 | ISagaRepository _repository; 29 | ISessionFactory _sessionFactory; 30 | 31 | public bool Start(HostControl hostControl) 32 | { 33 | _log.Info("Creating bus..."); 34 | 35 | _metrics = new RoutingSlipMetrics("Routing Slip"); 36 | _activityMetrics = new RoutingSlipMetrics("Validate Activity"); 37 | 38 | _machine = new RoutingSlipStateMachine(); 39 | _provider = new SQLiteSessionFactoryProvider(false, typeof(RoutingSlipStateSagaMap)); 40 | _sessionFactory = _provider.GetSessionFactory(); 41 | 42 | _repository = new NHibernateSagaRepository(_sessionFactory); 43 | 44 | _busControl = Bus.Factory.CreateUsingRabbitMq(x => 45 | { 46 | IRabbitMqHost host = x.Host(new Uri(ConfigurationManager.AppSettings["RabbitMQHost"]), h => 47 | { 48 | h.Username("guest"); 49 | h.Password("guest"); 50 | }); 51 | 52 | x.ReceiveEndpoint(host, "routing_slip_metrics", e => 53 | { 54 | e.PrefetchCount = 100; 55 | e.UseRetry(r => r.None()); 56 | e.Consumer(() => new RoutingSlipMetricsConsumer(_metrics)); 57 | }); 58 | 59 | x.ReceiveEndpoint(host, "routing_slip_activity_metrics", e => 60 | { 61 | e.PrefetchCount = 100; 62 | e.UseRetry(r => r.None()); 63 | e.Consumer(() => new RoutingSlipActivityConsumer(_activityMetrics, "Validate")); 64 | }); 65 | 66 | x.ReceiveEndpoint(host, "routing_slip_state", e => 67 | { 68 | e.PrefetchCount = 8; 69 | e.UseConcurrencyLimit(1); 70 | e.StateMachineSaga(_machine, _repository); 71 | }); 72 | }); 73 | 74 | _log.Info("Starting bus..."); 75 | 76 | TaskUtil.Await(() => _busControl.StartAsync()); 77 | 78 | return true; 79 | } 80 | 81 | public bool Stop(HostControl hostControl) 82 | { 83 | _log.Info("Stopping bus..."); 84 | 85 | _busControl?.Stop(); 86 | 87 | return true; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/Sample-Courier.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProcessingService", "ProcessingService\ProcessingService.csproj", "{5243967D-8497-4118-B658-562A9E39390E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Processing.Activities", "Processing.Activities\Processing.Activities.csproj", "{373CBED9-B86D-4905-BAED-6C0C67C89F49}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tracking", "Tracking\Tracking.csproj", "{BEABD42E-9313-4721-A300-3CEE00720F98}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrackingService", "TrackingService\TrackingService.csproj", "{BADD6487-6537-4D68-902D-F69A9C6C98B3}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Processing.Contracts", "Processing.Contracts\Processing.Contracts.csproj", "{79175983-7A1A-42DC-880B-F098312C4281}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{8BFA7C9B-F99F-44F3-9533-F1D2150B4042}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {5243967D-8497-4118-B658-562A9E39390E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {5243967D-8497-4118-B658-562A9E39390E}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {5243967D-8497-4118-B658-562A9E39390E}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {5243967D-8497-4118-B658-562A9E39390E}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {373CBED9-B86D-4905-BAED-6C0C67C89F49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {373CBED9-B86D-4905-BAED-6C0C67C89F49}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {373CBED9-B86D-4905-BAED-6C0C67C89F49}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {373CBED9-B86D-4905-BAED-6C0C67C89F49}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {BEABD42E-9313-4721-A300-3CEE00720F98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {BEABD42E-9313-4721-A300-3CEE00720F98}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {BEABD42E-9313-4721-A300-3CEE00720F98}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {BEABD42E-9313-4721-A300-3CEE00720F98}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {BADD6487-6537-4D68-902D-F69A9C6C98B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {BADD6487-6537-4D68-902D-F69A9C6C98B3}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {BADD6487-6537-4D68-902D-F69A9C6C98B3}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {BADD6487-6537-4D68-902D-F69A9C6C98B3}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {79175983-7A1A-42DC-880B-F098312C4281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {79175983-7A1A-42DC-880B-F098312C4281}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {79175983-7A1A-42DC-880B-F098312C4281}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {79175983-7A1A-42DC-880B-F098312C4281}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {8BFA7C9B-F99F-44F3-9533-F1D2150B4042}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {8BFA7C9B-F99F-44F3-9533-F1D2150B4042}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {8BFA7C9B-F99F-44F3-9533-F1D2150B4042}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {8BFA7C9B-F99F-44F3-9533-F1D2150B4042}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /src/Tracking/RoutingSlipStateMachine.cs: -------------------------------------------------------------------------------- 1 | namespace Tracking 2 | { 3 | using System; 4 | using System.Linq; 5 | using Automatonymous; 6 | using MassTransit.Courier.Contracts; 7 | using Processing.Contracts; 8 | 9 | 10 | /// 11 | /// This state machine observes the events of a routing slip, and captures the state 12 | /// of the routing slip from execution to completion/failure. 13 | /// 14 | public class RoutingSlipStateMachine : 15 | MassTransitStateMachine 16 | { 17 | public RoutingSlipStateMachine() 18 | { 19 | InstanceState(x => x.State, Executing, Completed, Faulted, CompensationFailed); 20 | 21 | Event(() => SlipCreated, x => x.CorrelateById(context => context.Message.TrackingNumber)); 22 | Event(() => SlipCompleted, x => x.CorrelateById(context => context.Message.TrackingNumber)); 23 | Event(() => SlipFaulted, x => x.CorrelateById(context => context.Message.TrackingNumber)); 24 | Event(() => SlipCompensationFailed, x => x.CorrelateById(context => context.Message.TrackingNumber)); 25 | 26 | // Events can arrive out of order, so we want to make sure that all observed events can created 27 | // the state machine instance 28 | Initially( 29 | When(SlipCreated) 30 | .Then(HandleRoutingSlipCreated) 31 | .TransitionTo(Executing), 32 | When(SlipCompleted) 33 | .Then(HandleRoutingSlipCompleted) 34 | .TransitionTo(Completed), 35 | When(SlipFaulted) 36 | .Then(HandleRoutingSlipFaulted) 37 | .TransitionTo(Faulted), 38 | When(SlipCompensationFailed) 39 | .TransitionTo(CompensationFailed)); 40 | 41 | // during any state, we can handle any of the events, to transition or capture previously 42 | // missed data. 43 | DuringAny( 44 | When(SlipCreated) 45 | .Then(context => context.Instance.CreateTime = context.Data.Timestamp), 46 | When(SlipCompleted) 47 | .Then(HandleRoutingSlipCompleted) 48 | .TransitionTo(Completed), 49 | When(SlipFaulted) 50 | .Then(HandleRoutingSlipFaulted) 51 | .TransitionTo(Faulted), 52 | When(SlipCompensationFailed) 53 | .TransitionTo(CompensationFailed)); 54 | } 55 | 56 | 57 | public State Executing { get; private set; } 58 | public State Completed { get; private set; } 59 | public State Faulted { get; private set; } 60 | public State CompensationFailed { get; private set; } 61 | 62 | public Event SlipCreated { get; private set; } 63 | public Event SlipCompleted { get; private set; } 64 | public Event SlipFaulted { get; private set; } 65 | public Event SlipCompensationFailed { get; private set; } 66 | 67 | static void HandleRoutingSlipCreated(BehaviorContext context) 68 | { 69 | context.Instance.CreateTime = context.Data.Timestamp; 70 | } 71 | 72 | static void HandleRoutingSlipCompleted(BehaviorContext context) 73 | { 74 | context.Instance.EndTime = context.Data.Timestamp; 75 | context.Instance.Duration = context.Data.Duration; 76 | } 77 | 78 | static void HandleRoutingSlipFaulted(BehaviorContext context) 79 | { 80 | context.Instance.EndTime = context.Data.Timestamp; 81 | context.Instance.Duration = context.Data.Duration; 82 | 83 | string faultSummary = string.Join(", ", 84 | context.Data.ActivityExceptions.Select(x => string.Format("{0}: {1}", x.Name, x.ExceptionInfo.Message))); 85 | 86 | context.Instance.FaultSummary = faultSummary; 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /src/Processing.Activities/Processing.Activities.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {373CBED9-B86D-4905-BAED-6C0C67C89F49} 8 | Library 9 | Properties 10 | Processing.Activities 11 | Processing.Activities 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\GreenPipes.2.1.1\lib\net452\GreenPipes.dll 36 | True 37 | 38 | 39 | ..\packages\MassTransit.5.1.2\lib\net452\MassTransit.dll 40 | True 41 | 42 | 43 | 44 | ..\packages\NewId.3.0.1\lib\net452\NewId.dll 45 | 46 | 47 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 48 | True 49 | 50 | 51 | ..\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll 52 | 53 | 54 | 55 | 56 | 57 | 58 | ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll 59 | True 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {79175983-7A1A-42DC-880B-F098312C4281} 73 | Processing.Contracts 74 | 75 | 76 | 77 | 78 | 79 | 80 | 87 | -------------------------------------------------------------------------------- /src/Tracking/Tracking.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BEABD42E-9313-4721-A300-3CEE00720F98} 8 | Library 9 | Properties 10 | Tracking 11 | Tracking 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | ..\packages\Automatonymous.4.1.1\lib\net452\Automatonymous.dll 36 | True 37 | 38 | 39 | ..\packages\GreenPipes.2.1.1\lib\net452\GreenPipes.dll 40 | True 41 | 42 | 43 | ..\packages\MassTransit.5.1.2\lib\net452\MassTransit.dll 44 | True 45 | 46 | 47 | ..\packages\MassTransit.Automatonymous.5.1.2\lib\net452\MassTransit.AutomatonymousIntegration.dll 48 | True 49 | 50 | 51 | 52 | ..\packages\NewId.3.0.1\lib\net452\NewId.dll 53 | 54 | 55 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 56 | True 57 | 58 | 59 | ..\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll 60 | 61 | 62 | 63 | 64 | 65 | 66 | ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll 67 | True 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | {79175983-7A1A-42DC-880B-F098312C4281} 79 | Processing.Contracts 80 | 81 | 82 | 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /src/Processing.Activities/Retrieve/RetrieveActivity.cs: -------------------------------------------------------------------------------- 1 | namespace Processing.Activities.Retrieve 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Net.Http; 6 | using System.Threading.Tasks; 7 | using Contracts; 8 | using MassTransit; 9 | using MassTransit.Courier; 10 | using MassTransit.Logging; 11 | 12 | 13 | public class RetrieveActivity : 14 | Activity 15 | { 16 | static readonly ILog _log = Logger.Get(); 17 | 18 | public async Task Execute(ExecuteContext context) 19 | { 20 | var sourceAddress = context.Arguments.Address; 21 | 22 | _log.DebugFormat("Retrieve Content: {0}", sourceAddress); 23 | 24 | try 25 | { 26 | using (var client = new HttpClient()) 27 | { 28 | HttpResponseMessage response = await client.GetAsync(sourceAddress); 29 | if (response.IsSuccessStatusCode) 30 | { 31 | var localFileName = GetLocalFileName(response, sourceAddress); 32 | 33 | _log.DebugFormat("Success, copying to local file: {0}", localFileName); 34 | 35 | using (FileStream stream = File.Create(localFileName, 4096, FileOptions.Asynchronous)) 36 | { 37 | await response.Content.CopyToAsync(stream); 38 | stream.Close(); 39 | 40 | var fileInfo = new FileInfo(localFileName); 41 | var localAddress = new Uri(fileInfo.FullName); 42 | 43 | _log.DebugFormat("Completed, length = {0}", fileInfo.Length); 44 | 45 | await context.Publish(new 46 | { 47 | Timestamp = DateTime.UtcNow, 48 | Address = sourceAddress, 49 | LocalPath = fileInfo.FullName, 50 | LocalAddress = localAddress, 51 | Length = fileInfo.Length, 52 | ContentType = response.Content.Headers.ContentType.ToString(), 53 | }); 54 | 55 | return context.Completed(new Log(fileInfo.FullName)); 56 | } 57 | } 58 | 59 | string message = string.Format("Server returned a response status code: {0} ({1})", 60 | (int)response.StatusCode, response.StatusCode); 61 | 62 | _log.ErrorFormat("Failed to retrieve image: {0}", message); 63 | await context.Publish(new 64 | { 65 | Timestamp = DateTime.UtcNow, 66 | Address = sourceAddress, 67 | Reason = message, 68 | }); 69 | 70 | return context.Completed(); 71 | } 72 | } 73 | catch (HttpRequestException exception) 74 | { 75 | _log.Error("Exception from HttpClient", exception.InnerException); 76 | 77 | throw; 78 | } 79 | } 80 | 81 | static string GetLocalFileName(HttpResponseMessage response, Uri sourceAddress) 82 | { 83 | string localFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "content"); 84 | 85 | Directory.CreateDirectory(localFilePath); 86 | 87 | string localFileName = Path.GetFullPath(Path.Combine(localFilePath, NewId.NextGuid().ToString())); 88 | Uri contentLocation = response.Content.Headers.ContentLocation ?? sourceAddress; 89 | if (response.Content.Headers.ContentDisposition != null && 90 | Path.HasExtension(response.Content.Headers.ContentDisposition.FileName)) 91 | localFileName += Path.GetExtension(response.Content.Headers.ContentDisposition.FileName); 92 | else if (Path.HasExtension(contentLocation.AbsoluteUri)) 93 | localFileName += Path.GetExtension(contentLocation.AbsoluteUri); 94 | return localFileName; 95 | } 96 | 97 | public async Task Compensate(CompensateContext context) 98 | { 99 | if (_log.IsErrorEnabled) 100 | _log.ErrorFormat("Removing local file: {0}", context.Log.LocalFilePath); 101 | 102 | return context.Compensated(); 103 | } 104 | 105 | 106 | class Log : 107 | RetrieveLog 108 | { 109 | public Log(string localFilePath) 110 | { 111 | LocalFilePath = localFilePath; 112 | } 113 | 114 | public string LocalFilePath { get; private set; } 115 | } 116 | } 117 | } -------------------------------------------------------------------------------- /src/TrackingService/SQLiteSessionFactoryProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2014 Chris Patterson, Dru Sellers, Travis Smith, et. al. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | // this file except in compliance with the License. You may obtain a copy of the 5 | // License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software distributed 10 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | // specific language governing permissions and limitations under the License. 13 | namespace TrackingService 14 | { 15 | using System; 16 | using System.Data; 17 | using System.Data.Common; 18 | using System.Data.SQLite; 19 | using MassTransit.NHibernateIntegration; 20 | using NHibernate; 21 | using NHibernate.Cache; 22 | using NHibernate.Cfg; 23 | using NHibernate.Cfg.Loquacious; 24 | using NHibernate.Dialect; 25 | using NHibernate.Tool.hbm2ddl; 26 | 27 | /// 28 | /// Creates a session factory that works with SQLite, by default in memory, for testing purposes 29 | /// 30 | public class SQLiteSessionFactoryProvider : 31 | NHibernateSessionFactoryProvider, 32 | IDisposable 33 | { 34 | const string InMemoryConnectionString = "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1;"; 35 | bool _disposed; 36 | ISessionFactory _innerSessionFactory; 37 | SQLiteConnection _openConnection; 38 | SingleConnectionSessionFactory _sessionFactory; 39 | 40 | public SQLiteSessionFactoryProvider(string connectionString, params Type[] mappedTypes) 41 | : base(mappedTypes, x => Integrate(x, connectionString, false)) 42 | { 43 | } 44 | 45 | public SQLiteSessionFactoryProvider(params Type[] mappedTypes) 46 | : this(false, mappedTypes) 47 | { 48 | } 49 | 50 | public SQLiteSessionFactoryProvider(bool logToConsole, params Type[] mappedTypes) 51 | : base(mappedTypes, x => Integrate(x, null, logToConsole)) 52 | { 53 | Configuration.SetProperty(NHibernate.Cfg.Environment.UseSecondLevelCache, "true"); 54 | Configuration.SetProperty(NHibernate.Cfg.Environment.UseQueryCache, "true"); 55 | Configuration.SetProperty(NHibernate.Cfg.Environment.CacheProvider, typeof(HashtableCacheProvider).AssemblyQualifiedName); 56 | } 57 | 58 | public void Dispose() 59 | { 60 | Dispose(true); 61 | GC.SuppressFinalize(this); 62 | } 63 | 64 | ~SQLiteSessionFactoryProvider() 65 | { 66 | Dispose(false); 67 | } 68 | 69 | void Dispose(bool disposing) 70 | { 71 | if (_disposed) 72 | return; 73 | 74 | if (disposing) 75 | { 76 | if (_openConnection != null) 77 | { 78 | _openConnection.Close(); 79 | _openConnection.Dispose(); 80 | } 81 | } 82 | 83 | _disposed = true; 84 | } 85 | 86 | public override ISessionFactory GetSessionFactory() 87 | { 88 | string connectionString = Configuration.Properties[NHibernate.Cfg.Environment.ConnectionString]; 89 | _openConnection = new SQLiteConnection(connectionString); 90 | _openConnection.Open(); 91 | 92 | BuildSchema(Configuration, _openConnection); 93 | 94 | _innerSessionFactory = base.GetSessionFactory(); 95 | _innerSessionFactory.WithOptions().Connection(_openConnection).OpenSession(); 96 | 97 | _sessionFactory = new SingleConnectionSessionFactory(_innerSessionFactory, _openConnection); 98 | 99 | return _sessionFactory; 100 | } 101 | 102 | static void BuildSchema(Configuration config, DbConnection connection) 103 | { 104 | new SchemaExport(config).Execute(true, true, false, connection, null); 105 | } 106 | 107 | static void Integrate(IDbIntegrationConfigurationProperties db, string connectionString, bool logToConsole) 108 | { 109 | db.Dialect(); //This is a custom dialect 110 | 111 | db.ConnectionString = connectionString ?? InMemoryConnectionString; 112 | db.BatchSize = 100; 113 | db.IsolationLevel = IsolationLevel.Serializable; 114 | db.LogSqlInConsole = logToConsole; 115 | db.LogFormattedSql = logToConsole; 116 | db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote; 117 | 118 | // Do not use this property with real DB as it will modify schema 119 | db.SchemaAction = SchemaAutoAction.Update; 120 | 121 | //Disable comments until this issue is resolved 122 | // https://groups.google.com/forum/?fromgroups=#!topic/nhusers/xJ675yG2uhY 123 | //properties.AutoCommentSql = true; 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/Client/Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8BFA7C9B-F99F-44F3-9533-F1D2150B4042} 8 | Exe 9 | Properties 10 | Client 11 | Client 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\GreenPipes.2.1.1\lib\net452\GreenPipes.dll 38 | True 39 | 40 | 41 | ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll 42 | 43 | 44 | ..\packages\MassTransit.5.1.2\lib\net452\MassTransit.dll 45 | True 46 | 47 | 48 | ..\packages\MassTransit.Log4Net.5.1.2\lib\net452\MassTransit.Log4NetIntegration.dll 49 | True 50 | 51 | 52 | ..\packages\MassTransit.RabbitMQ.5.1.2\lib\net452\MassTransit.RabbitMqTransport.dll 53 | True 54 | 55 | 56 | ..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net40\Microsoft.Diagnostics.Tracing.EventSource.dll 57 | 58 | 59 | ..\packages\NewId.3.0.1\lib\net452\NewId.dll 60 | 61 | 62 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 63 | True 64 | 65 | 66 | ..\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll 67 | 68 | 69 | ..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll 70 | 71 | 72 | 73 | 74 | 75 | 76 | ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll 77 | True 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | {79175983-7A1A-42DC-880B-F098312C4281} 96 | Processing.Contracts 97 | 98 | 99 | 100 | 107 | -------------------------------------------------------------------------------- /src/Client/Program.cs: -------------------------------------------------------------------------------- 1 | namespace Client 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Configuration; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using log4net.Config; 11 | using MassTransit; 12 | using MassTransit.Courier; 13 | using MassTransit.Courier.Contracts; 14 | using MassTransit.Log4NetIntegration.Logging; 15 | using MassTransit.RabbitMqTransport; 16 | using MassTransit.Util; 17 | using Processing.Contracts; 18 | 19 | 20 | class Program 21 | { 22 | static IRabbitMqHost _host; 23 | 24 | static void Main() 25 | { 26 | ConfigureLogger(); 27 | 28 | // MassTransit to use Log4Net 29 | Log4NetLogger.Use(); 30 | 31 | 32 | IBusControl busControl = CreateBus(); 33 | 34 | TaskUtil.Await(() => busControl.StartAsync()); 35 | 36 | Uri hostAddress = busControl.Address.GetHostSettings().HostAddress; 37 | 38 | string validateQueueName = ConfigurationManager.AppSettings["ValidateActivityQueue"]; 39 | Uri validateAddress = new Uri(string.Concat(hostAddress, validateQueueName)); 40 | 41 | string retrieveQueueName = ConfigurationManager.AppSettings["RetrieveActivityQueue"]; 42 | Uri retrieveAddress = new Uri(string.Concat(hostAddress, retrieveQueueName)); 43 | 44 | 45 | try 46 | { 47 | for (;;) 48 | { 49 | Console.Write("Enter an address (quit exits): "); 50 | string requestAddress = Console.ReadLine(); 51 | if (requestAddress == "quit") 52 | break; 53 | 54 | if (string.IsNullOrEmpty(requestAddress)) 55 | requestAddress = "http://www.microsoft.com/index.html"; 56 | 57 | int limit = 1; 58 | 59 | if (requestAddress.All(x => char.IsDigit(x) || char.IsPunctuation(x))) 60 | { 61 | string[] values = requestAddress.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries); 62 | requestAddress = values[0]; 63 | if (values.Length > 1) 64 | { 65 | limit = int.Parse(values[1]); 66 | Console.WriteLine("Sending {0}", limit); 67 | } 68 | } 69 | 70 | switch (requestAddress) 71 | { 72 | case "0": 73 | requestAddress = "http://www.microsoft.com/index.html"; 74 | break; 75 | case "1": 76 | requestAddress = "http://i.imgur.com/Iroma7d.png"; 77 | break; 78 | case "2": 79 | requestAddress = "http://i.imgur.com/NK8eZUe.jpg"; 80 | break; 81 | } 82 | 83 | Uri requestUri; 84 | try 85 | { 86 | requestUri = new Uri(requestAddress); 87 | } 88 | catch (UriFormatException) 89 | { 90 | Console.WriteLine("The URL entered is invalid: " + requestAddress); 91 | continue; 92 | } 93 | 94 | IEnumerable tasks = Enumerable.Range(0, limit).Select(x => Task.Run(async () => 95 | { 96 | var builder = new RoutingSlipBuilder(NewId.NextGuid()); 97 | 98 | builder.AddActivity("Validate", validateAddress); 99 | builder.AddActivity("Retrieve", retrieveAddress); 100 | 101 | builder.SetVariables(new 102 | { 103 | RequestId = NewId.NextGuid(), 104 | Address = requestUri, 105 | }); 106 | 107 | RoutingSlip routingSlip = builder.Build(); 108 | 109 | await busControl.Publish(new 110 | { 111 | TrackingNumber = routingSlip.TrackingNumber, 112 | Timestamp = routingSlip.CreateTimestamp, 113 | }); 114 | 115 | await busControl.Execute(routingSlip); 116 | })); 117 | 118 | Task.WaitAll(tasks.ToArray()); 119 | } 120 | } 121 | catch (Exception ex) 122 | { 123 | Console.WriteLine("Exception!!! OMG!!! {0}", ex); 124 | Console.ReadLine(); 125 | } 126 | finally 127 | { 128 | busControl.Stop(); 129 | } 130 | } 131 | 132 | 133 | static IBusControl CreateBus() 134 | { 135 | return Bus.Factory.CreateUsingRabbitMq(x => 136 | { 137 | _host = x.Host(new Uri(ConfigurationManager.AppSettings["RabbitMQHost"]), h => 138 | { 139 | h.Username("guest"); 140 | h.Password("guest"); 141 | }); 142 | }); 143 | } 144 | 145 | static void ConfigureLogger() 146 | { 147 | const string logConfig = @" 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | "; 159 | 160 | using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(logConfig))) 161 | { 162 | XmlConfigurator.Configure(stream); 163 | } 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /src/TrackingService/SingleConnectionSessionFactory.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2007-2012 Chris Patterson, Dru Sellers, Travis Smith, et. al. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | // this file except in compliance with the License. You may obtain a copy of the 5 | // License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software distributed 10 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | // specific language governing permissions and limitations under the License. 13 | namespace TrackingService 14 | { 15 | using System; 16 | using System.Data.Common; 17 | using System.Collections.Generic; 18 | using System.Threading; 19 | using System.Threading.Tasks; 20 | using NHibernate; 21 | using NHibernate.Engine; 22 | using NHibernate.Metadata; 23 | using NHibernate.Stat; 24 | 25 | class SingleConnectionSessionFactory : 26 | ISessionFactory 27 | { 28 | readonly ISessionFactory _inner; 29 | readonly DbConnection _liveConnection; 30 | 31 | public SingleConnectionSessionFactory(ISessionFactory inner, DbConnection liveConnection) 32 | { 33 | _inner = inner; 34 | _liveConnection = liveConnection; 35 | } 36 | 37 | public void Dispose() => _inner.Dispose(); 38 | 39 | public ISession OpenSession(DbConnection conn) => _inner.WithOptions().Connection(_liveConnection).OpenSession(); 40 | 41 | public Task CloseAsync(CancellationToken cancellationToken = new CancellationToken()) => 42 | _inner.CloseAsync(cancellationToken); 43 | 44 | public Task EvictAsync(Type persistentClass, CancellationToken cancellationToken = new CancellationToken()) => 45 | _inner.EvictAsync(persistentClass, cancellationToken); 46 | 47 | public Task EvictAsync(Type persistentClass, object id, CancellationToken cancellationToken = new CancellationToken()) => 48 | _inner.EvictAsync(persistentClass, id, cancellationToken); 49 | 50 | public Task EvictEntityAsync(string entityName, CancellationToken cancellationToken = new CancellationToken()) => 51 | _inner.EvictEntityAsync(entityName, cancellationToken); 52 | 53 | public Task EvictEntityAsync(string entityName, object id, CancellationToken cancellationToken = new CancellationToken()) => 54 | _inner.EvictEntityAsync(entityName, id, cancellationToken); 55 | 56 | public Task EvictCollectionAsync(string roleName, CancellationToken cancellationToken = new CancellationToken()) => 57 | _inner.EvictCollectionAsync(roleName, cancellationToken); 58 | 59 | public Task EvictCollectionAsync(string roleName, object id, CancellationToken cancellationToken = new CancellationToken()) => 60 | _inner.EvictCollectionAsync(roleName, id, cancellationToken); 61 | 62 | public Task EvictQueriesAsync(CancellationToken cancellationToken = new CancellationToken()) => 63 | _inner.EvictQueriesAsync(cancellationToken); 64 | 65 | public Task EvictQueriesAsync(string cacheRegion, CancellationToken cancellationToken = new CancellationToken()) => 66 | _inner.EvictQueriesAsync(cacheRegion, cancellationToken); 67 | 68 | public ISessionBuilder WithOptions() => _inner.WithOptions(); 69 | 70 | public ISession OpenSession(IInterceptor sessionLocalInterceptor) => 71 | _inner.WithOptions().Connection(_liveConnection).Interceptor(sessionLocalInterceptor).OpenSession(); 72 | 73 | public ISession OpenSession(DbConnection conn, IInterceptor sessionLocalInterceptor) => 74 | _inner.WithOptions().Connection(_liveConnection).Interceptor(sessionLocalInterceptor).OpenSession(); 75 | 76 | public ISession OpenSession() => _inner.WithOptions().Connection(_liveConnection).OpenSession(); 77 | 78 | public IStatelessSessionBuilder WithStatelessOptions() 79 | { 80 | throw new NotImplementedException(); 81 | } 82 | 83 | public IClassMetadata GetClassMetadata(Type persistentClass) => 84 | _inner.GetClassMetadata(persistentClass); 85 | 86 | public IClassMetadata GetClassMetadata(string entityName) => 87 | _inner.GetClassMetadata(entityName); 88 | 89 | public ICollectionMetadata GetCollectionMetadata(string roleName) => 90 | _inner.GetCollectionMetadata(roleName); 91 | 92 | public IDictionary GetAllClassMetadata() => 93 | _inner.GetAllClassMetadata(); 94 | 95 | public IDictionary GetAllCollectionMetadata() => 96 | _inner.GetAllCollectionMetadata(); 97 | 98 | public void Close() => _inner.Close(); 99 | 100 | public void Evict(Type persistentClass) => _inner.Evict(persistentClass); 101 | 102 | public void Evict(Type persistentClass, object id) => _inner.Evict(persistentClass, id); 103 | 104 | public void EvictEntity(string entityName) => _inner.EvictEntity(entityName); 105 | 106 | public void EvictEntity(string entityName, object id) => _inner.EvictEntity(entityName, id); 107 | 108 | public void EvictCollection(string roleName) => _inner.EvictCollection(roleName); 109 | 110 | public void EvictCollection(string roleName, object id) => _inner.EvictCollection(roleName, id); 111 | 112 | public void EvictQueries() => _inner.EvictQueries(); 113 | 114 | public void EvictQueries(string cacheRegion) => _inner.EvictQueries(cacheRegion); 115 | 116 | public IStatelessSession OpenStatelessSession() => _inner.OpenStatelessSession(); 117 | 118 | public IStatelessSession OpenStatelessSession(DbConnection connection) => 119 | _inner.OpenStatelessSession(connection); 120 | 121 | public FilterDefinition GetFilterDefinition(string filterName) => 122 | _inner.GetFilterDefinition(filterName); 123 | 124 | public ISession GetCurrentSession() => _inner.GetCurrentSession(); 125 | 126 | public IStatistics Statistics => _inner.Statistics; 127 | 128 | public bool IsClosed => _inner.IsClosed; 129 | 130 | public ICollection DefinedFilterNames => _inner.DefinedFilterNames; 131 | } 132 | } -------------------------------------------------------------------------------- /src/ProcessingService/ProcessingService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5243967D-8497-4118-B658-562A9E39390E} 8 | Exe 9 | Properties 10 | ProcessingService 11 | ProcessingService 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\GreenPipes.2.1.1\lib\net452\GreenPipes.dll 38 | True 39 | 40 | 41 | ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll 42 | 43 | 44 | ..\packages\MassTransit.5.1.2\lib\net452\MassTransit.dll 45 | True 46 | 47 | 48 | ..\packages\MassTransit.Log4Net.5.1.2\lib\net452\MassTransit.Log4NetIntegration.dll 49 | True 50 | 51 | 52 | ..\packages\MassTransit.RabbitMQ.5.1.2\lib\net452\MassTransit.RabbitMqTransport.dll 53 | True 54 | 55 | 56 | 57 | ..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net40\Microsoft.Diagnostics.Tracing.EventSource.dll 58 | 59 | 60 | ..\packages\NewId.3.0.1\lib\net452\NewId.dll 61 | 62 | 63 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 64 | True 65 | 66 | 67 | ..\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll 68 | 69 | 70 | ..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll 79 | True 80 | 81 | 82 | 83 | ..\packages\Topshelf.4.0.4\lib\net452\Topshelf.dll 84 | True 85 | 86 | 87 | ..\packages\Topshelf.Log4Net.4.0.4\lib\net452\Topshelf.Log4Net.dll 88 | True 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | {373CBED9-B86D-4905-BAED-6C0C67C89F49} 103 | Processing.Activities 104 | 105 | 106 | 107 | 114 | -------------------------------------------------------------------------------- /src/TrackingService/TrackingService.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BADD6487-6537-4D68-902D-F69A9C6C98B3} 8 | Exe 9 | Properties 10 | TrackingService 11 | TrackingService 12 | v4.6.2 13 | 512 14 | 15 | 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | TrackingService.Program 37 | 38 | 39 | 40 | ..\packages\Antlr3.Runtime.3.5.1\lib\net40-client\Antlr3.Runtime.dll 41 | True 42 | 43 | 44 | ..\packages\Automatonymous.4.1.1\lib\net452\Automatonymous.dll 45 | True 46 | 47 | 48 | ..\packages\Automatonymous.NHibernate.4.1.1\lib\net461\Automatonymous.NHibernateIntegration.dll 49 | True 50 | 51 | 52 | ..\packages\GreenPipes.2.1.1\lib\net452\GreenPipes.dll 53 | True 54 | 55 | 56 | ..\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll 57 | True 58 | 59 | 60 | ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll 61 | 62 | 63 | ..\packages\MassTransit.5.1.2\lib\net452\MassTransit.dll 64 | True 65 | 66 | 67 | ..\packages\MassTransit.Automatonymous.5.1.2\lib\net452\MassTransit.AutomatonymousIntegration.dll 68 | True 69 | 70 | 71 | ..\packages\MassTransit.Log4Net.5.1.2\lib\net452\MassTransit.Log4NetIntegration.dll 72 | True 73 | 74 | 75 | ..\packages\MassTransit.NHibernate.5.1.2\lib\net461\MassTransit.NHibernateIntegration.dll 76 | True 77 | 78 | 79 | ..\packages\MassTransit.RabbitMQ.5.1.2\lib\net452\MassTransit.RabbitMqTransport.dll 80 | True 81 | 82 | 83 | 84 | ..\packages\Microsoft.Diagnostics.Tracing.EventSource.Redist.1.1.28\lib\net40\Microsoft.Diagnostics.Tracing.EventSource.dll 85 | 86 | 87 | ..\packages\NewId.3.0.1\lib\net452\NewId.dll 88 | 89 | 90 | ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll 91 | True 92 | 93 | 94 | ..\packages\Newtonsoft.Json.Bson.1.0.1\lib\net45\Newtonsoft.Json.Bson.dll 95 | 96 | 97 | ..\packages\NHibernate.5.1.2\lib\net461\NHibernate.dll 98 | True 99 | 100 | 101 | ..\packages\RabbitMQ.Client.5.0.1\lib\net451\RabbitMQ.Client.dll 102 | 103 | 104 | ..\packages\Remotion.Linq.2.1.2\lib\net45\Remotion.Linq.dll 105 | True 106 | 107 | 108 | ..\packages\Remotion.Linq.EagerFetching.2.1.0\lib\net45\Remotion.Linq.EagerFetching.dll 109 | True 110 | 111 | 112 | 113 | 114 | 115 | 116 | ..\packages\System.Data.SQLite.Core.1.0.106.0\lib\net451\System.Data.SQLite.dll 117 | 118 | 119 | 120 | 121 | ..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll 122 | True 123 | 124 | 125 | 126 | ..\packages\Topshelf.4.0.4\lib\net452\Topshelf.dll 127 | True 128 | 129 | 130 | ..\packages\Topshelf.Log4Net.4.0.4\lib\net452\Topshelf.Log4Net.dll 131 | True 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | {beabd42e-9313-4721-a300-3cee00720f98} 148 | Tracking 149 | 150 | 151 | 152 | 153 | Designer 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 162 | 163 | 164 | 165 | 172 | --------------------------------------------------------------------------------