├── .gitignore ├── .hgignore ├── Framework ├── Library │ ├── Autofac │ │ ├── Autofac.License.txt │ │ ├── Autofac.XML │ │ └── Autofac.dll │ ├── Azure │ │ ├── Microsoft.WindowsAzure.ServiceRuntime.dll │ │ ├── Microsoft.WindowsAzure.ServiceRuntime.xml │ │ ├── Microsoft.WindowsAzure.StorageClient.dll │ │ ├── Microsoft.WindowsAzure.StorageClient.xml │ │ └── ReadMe.txt │ ├── NUnit │ │ ├── NUnit.License.txt │ │ └── nunit.framework.dll │ ├── ProtoBuf-net │ │ ├── protobuf-net.dll │ │ ├── protobuf-net.pdb │ │ └── protobuf-net.xml │ ├── Reactive │ │ ├── System.CoreEx.dll │ │ ├── System.CoreEx.xml │ │ ├── System.Reactive.dll │ │ └── System.Reactive.xml │ └── ServiceStack │ │ ├── ServiceStack.Text.dll │ │ └── ServiceStack.Text.pdb ├── Lokad.CQRS.5.1.ReSharper ├── Lokad.CQRS.6.0.ReSharper ├── Lokad.CQRS.sln ├── Lokad.Cqrs.Azure.Tests │ ├── BasicClientConfigurationTests.cs │ ├── Core.Envelope │ │ └── Play_all_for_ProtoBuf.cs │ ├── Core.Serialization │ │ ├── ProtoBufDataTests.cs │ │ ├── ProtoBufNativeTests.cs │ │ ├── ProtoBufXmlTests.cs │ │ └── ProtobufFixture.cs │ ├── Feature.AtomicStorage │ │ ├── Given_Azure_Configuration.cs │ │ └── When_DefaultAzureAtomicStorageStrategy_is_used.cs │ ├── Feature.StreamingStorage │ │ ├── HashingTests.cs │ │ └── Play_all_for_BlobStreaming.cs │ ├── Feature.TapeStorage │ │ ├── BlobTapeStorageTests.cs │ │ ├── DatabaseHelper.cs │ │ └── SqlTapeStorageTests.cs │ ├── Lokad.Cqrs.Azure.Tests.csproj │ ├── Performance_tests_for_reaction.cs │ ├── Performance_tests_for_throughput.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── SmokeTests.cs │ ├── Synthetic │ │ └── Run_all_Synthetic_tests_on_azure.cs │ └── app.config ├── Lokad.Cqrs.Azure │ ├── AzureSettingsProvider.cs │ ├── AzureStorage.cs │ ├── Build │ │ ├── AzureClientModule.cs │ │ ├── AzureStorageConfig.cs │ │ ├── AzureStorageConfigurationBuilder.cs │ │ └── Engine │ │ │ ├── AzureEngineModule.cs │ │ │ └── CqrsEngineRole.cs │ ├── Core.Envelope │ │ └── EnvelopeSerializerWithProtoBuf.cs │ ├── Core.Serialization │ │ └── DataSerializerWithProtoBuf.cs │ ├── ExtendCqrsClientBuilder.cs │ ├── ExtendCqrsEngineBuilder.cs │ ├── ExtendSerializationModule.cs │ ├── ExtendStorageModule.cs │ ├── Feature.AtomicStorage │ │ ├── AtomicStorageSerializerWithProtoBuf.cs │ │ ├── AzureAtomicEntityReader.cs │ │ ├── AzureAtomicEntityWriter.cs │ │ ├── AzureAtomicSingletonReader.cs │ │ ├── AzureAtomicSingletonWriter.cs │ │ └── AzureAtomicStorageFactory.cs │ ├── Feature.AzurePartition │ │ ├── AzurePartitionModule.cs │ │ ├── Inbox │ │ │ ├── AzurePartitionFactory.cs │ │ │ └── AzurePartitionInbox.cs │ │ ├── Sender │ │ │ └── AzureQueueWriterFactory.cs │ │ ├── StatelessAzureQueueReader.cs │ │ └── StatelessAzureQueueWriter.cs │ ├── Feature.StreamingStorage │ │ ├── BlobStorageUtil.cs │ │ ├── BlobStreamingContainer.cs │ │ ├── BlobStreamingItem.cs │ │ ├── BlobStreamingRoot.cs │ │ └── SuppressFlushForStream.cs │ ├── Feature.TapeStorage │ │ ├── BlobExtensions.cs │ │ ├── BlobRecordUtil.cs │ │ ├── BlobTapeStorageFactory.cs │ │ ├── BlobTapeStream.cs │ │ ├── PageBlobAppendStream.cs │ │ ├── PageBlobReadStream.cs │ │ ├── SqlTapeStorageFactory.cs │ │ └── SqlTapeStream.cs │ ├── IAzureStorageConfig.cs │ ├── Lokad.Cqrs.Azure.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── WipeAzureAccount.cs ├── Lokad.Cqrs.Portable.Tests │ ├── BasicEngineConfigurationTests.cs │ ├── Core.Directory │ │ ├── MessageDirectoryFixture.cs │ │ ├── Method_Invoker_tests.cs │ │ ├── When_activation_map_constrained_to_catch_all_consumer.cs │ │ ├── When_activations_constrained_to_handler_type_with_interface.cs │ │ ├── When_activations_constrained_to_handler_type_with_type.cs │ │ ├── When_activations_constrained_to_message_interface.cs │ │ ├── When_builder_is_available.cs │ │ └── When_there_are_no_catch_all_handlers.cs │ ├── Core.Envelope │ │ ├── Play_all_for_BinaryFormatter.cs │ │ ├── Play_all_for_DataContracts.cs │ │ ├── Play_all_for_Memory.cs │ │ └── Scenarios │ │ │ ├── DataSerializerWithBinaryFormatter.cs │ │ │ ├── EnvelopeSerializerWithBinaryFormatter.cs │ │ │ └── When_envelope_is_serialized.cs │ ├── Documentation_sample.cs │ ├── ExtendMaybe.cs │ ├── Feature.AtomicStorage │ │ ├── Atomic_storage_scenarios.cs │ │ ├── Engine_scenario_for_AtomicStorage_in_partition.cs │ │ ├── Engine_scenario_for_NuclearStorage_in_partition.cs │ │ ├── Engine_scenario_for_custom_view_domain.cs │ │ ├── Given_File_Configuration.cs │ │ ├── Given_Memory_Configuration.cs │ │ └── Syntax_verification.cs │ ├── Feature.StreamingStorage │ │ ├── Engine_scenario_for_streaming_storage.cs │ │ ├── Run_all_StreamingStorage_scenarios_for_Files.cs │ │ └── Scenarios │ │ │ ├── ITestStorage.cs │ │ │ ├── StorageItemFixture.cs │ │ │ ├── When_checking_item_in.cs │ │ │ ├── When_copying_items_in.cs │ │ │ ├── When_deleting_item_in.cs │ │ │ ├── When_listing_items_in.cs │ │ │ ├── When_reading_item_in.cs │ │ │ └── When_writing_item_in.cs │ ├── Feature.TapeStorage │ │ ├── FileTapeStorageTests.cs │ │ ├── MemoryTapeStorageTests.cs │ │ └── TapeStorageTests.cs │ ├── FiniteEngineScenario.cs │ ├── Given_MessageContext_Omitted.cs │ ├── Given_MessageContext_Specified.cs │ ├── Lokad.Cqrs.Portable.Tests.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Scenarios │ │ ├── 001-SimpleES │ │ │ ├── AccountAggregateReader.cs │ │ │ ├── AccountAggregateRepository.cs │ │ │ ├── AccountAggregateWriter.cs │ │ │ ├── AccountHandler.cs │ │ │ ├── Contracts │ │ │ │ ├── AccountCreated.cs │ │ │ │ ├── AddLogin.cs │ │ │ │ ├── CreateAccount.cs │ │ │ │ ├── LoginAdded.cs │ │ │ │ └── LoginIndex.cs │ │ │ ├── Definitions │ │ │ │ ├── Define.cs │ │ │ │ ├── IAccountCommand.cs │ │ │ │ └── IAccountEvent.cs │ │ │ ├── InMemoryEventStreamer.cs │ │ │ ├── RedirectToWhen.cs │ │ │ └── SimpleESTests.cs │ │ └── 002-Multiverse │ │ │ └── MultiverseTests.cs │ └── Synthetic │ │ ├── All_synthetic_scenarios.cs │ │ ├── Engine_scenario_for_permanent_failure.cs │ │ ├── Engine_scenario_for_transactional_commands.cs │ │ ├── Engine_scenario_for_transient_failure.cs │ │ ├── Given_duplicate_configuration.cs │ │ ├── Run_all_Synthetic_scenarios_in_memory.cs │ │ ├── Run_all_synthetic_scenarios_for_files.cs │ │ └── TransactionTester.cs ├── Lokad.Cqrs.Portable │ ├── Build │ │ ├── Client │ │ │ ├── CqrsClient.cs │ │ │ ├── CqrsClientBuilder.cs │ │ │ ├── FileClientModule.cs │ │ │ └── IAdvancedClientBuilder.cs │ │ └── Engine │ │ │ ├── AtomicRegistrationSource.cs │ │ │ ├── CqrsEngineBuilder.cs │ │ │ ├── CqrsEngineHost.cs │ │ │ ├── Events │ │ │ ├── EngineInitializationStarted.cs │ │ │ ├── EngineInitialized.cs │ │ │ ├── EngineStarted.cs │ │ │ └── EngineStopped.cs │ │ │ ├── FileModule.cs │ │ │ ├── IAdvancedEngineBuilder.cs │ │ │ ├── MemoryModule.cs │ │ │ └── StorageModule.cs │ ├── Core.Dispatch │ │ ├── ActionDispatcher.cs │ │ ├── DispatchMessagesToRoute.cs │ │ ├── DispatcherProcess.cs │ │ ├── Events │ │ │ ├── DispatchRecoveryFailed.cs │ │ │ ├── EnvelopeAckFailed.cs │ │ │ ├── EnvelopeAcked.cs │ │ │ ├── EnvelopeDispatchFailed.cs │ │ │ ├── EnvelopeDuplicateDiscarded.cs │ │ │ ├── EnvelopeQuarantined.cs │ │ │ └── EventHadNoConsumers.cs │ │ ├── IEnvelopeQuarantine.cs │ │ ├── ISingleThreadMessageDispatcher.cs │ │ ├── MemoryQuarantine.cs │ │ ├── MessageDuplicationManager.cs │ │ └── MessageDuplicationMemory.cs │ ├── Core.Envelope │ │ ├── EnvelopeAttributeContract.cs │ │ ├── EnvelopeAttributeTypeContract.cs │ │ ├── EnvelopeBuilder.cs │ │ ├── EnvelopeContract.cs │ │ ├── EnvelopeConvert.cs │ │ ├── EnvelopeHeaderContract.cs │ │ ├── EnvelopePrinter.cs │ │ ├── EnvelopeSerializerWithDataContracts.cs │ │ ├── EnvelopeStreamer.cs │ │ ├── MessageAttributeContract.cs │ │ ├── MessageAttributes.cs │ │ ├── MessageBuilder.cs │ │ └── MessageContract.cs │ ├── Core.Inbox │ │ ├── EnvelopeTransportContext.cs │ │ ├── Events │ │ │ ├── EnvelopeDeserializationFailed.cs │ │ │ ├── FailedToAccessStorage.cs │ │ │ └── FailedToReadMessage.cs │ │ ├── GetEnvelopeResult.cs │ │ ├── GetEnvelopeResultState.cs │ │ └── IPartitionInbox.cs │ ├── Core.Outbox │ │ ├── CommitActionEnlistment.cs │ │ ├── DefaultMessageSender.cs │ │ ├── EnvelopeSent.cs │ │ ├── IQueueWriter.cs │ │ ├── IQueueWriterFactory.cs │ │ ├── QueueWriterRegistry.cs │ │ └── SendMessageModule.cs │ ├── Core.Reactive │ │ ├── ImmediateConsoleObserver.cs │ │ ├── ImmediateEventsObserver.cs │ │ ├── ImmediateTracingObserver.cs │ │ └── SystemObserver.cs │ ├── Core.Serialization │ │ ├── ContractEvil.cs │ │ ├── DataSerializerWithDataContracts.cs │ │ └── SerializationContractRegistry.cs │ ├── Core │ │ └── FunqContainer.cs │ ├── Define.cs │ ├── EnvelopeReference.cs │ ├── Evil │ │ ├── AssemblyScanEvil.cs │ │ ├── DecayEvil.cs │ │ └── InvocationUtil.cs │ ├── Feature.AtomicStorage │ │ ├── AddOrUpdateHint.cs │ │ ├── AtomicStorageInitialization.cs │ │ ├── AtomicStorageInitialized.cs │ │ ├── AtomicStorageSerializerWithDataContracts.cs │ │ ├── AtomicStorageSerializerWithDelegates.cs │ │ ├── DefaultAtomicStorageStrategy.cs │ │ ├── DefaultAtomicStorageStrategyBuilder.cs │ │ ├── ExtendAtomicEntityReader.cs │ │ ├── ExtendAtomicEntityWriter.cs │ │ ├── ExtendAtomicSingletonReader.cs │ │ ├── ExtendAtomicSingletonWriter.cs │ │ ├── FileAtomicEntityContainer.cs │ │ ├── FileAtomicSingletonContainer.cs │ │ ├── FileAtomicStorageFactory.cs │ │ ├── IAtomicEntityReader.cs │ │ ├── IAtomicEntityWriter.cs │ │ ├── IAtomicSingletonReader.cs │ │ ├── IAtomicSingletonWriter.cs │ │ ├── IAtomicStorageFactory.cs │ │ ├── IAtomicStorageSerializer.cs │ │ ├── IAtomicStorageStrategy.cs │ │ ├── MemoryAtomicEntityContainer.cs │ │ ├── MemoryAtomicSingletonContainer.cs │ │ ├── MemoryAtomicStorageFactory.cs │ │ ├── MemoryAtomicStorageModule.cs │ │ ├── NuclearStorage.cs │ │ └── NuclearStorageExtensions.cs │ ├── Feature.DirectoryDispatch │ │ ├── AutofacDispatchStrategy.cs │ │ ├── Default │ │ │ ├── IConsume.cs │ │ │ ├── IConsumeMessage.cs │ │ │ └── IMessage.cs │ │ ├── DirectoryDispatchFactory.cs │ │ ├── DispatchCommandBatch.cs │ │ ├── DispatchDirectoryModule.cs │ │ ├── DispatchLifetimeScopeTags.cs │ │ ├── DispatchOneEvent.cs │ │ ├── DomainAssemblyScanner.cs │ │ ├── IMessageDispatchScope.cs │ │ ├── IMessageDispatchStrategy.cs │ │ ├── IMethodContextManager.cs │ │ ├── MessageActivationInfo.cs │ │ ├── MessageDirectoryBuilder.cs │ │ ├── MessageDirectoryFilter.cs │ │ ├── MessageMapping.cs │ │ ├── MethodContextManager.cs │ │ └── MethodInvokerHint.cs │ ├── Feature.FilePartition │ │ ├── FilePartitionInbox.cs │ │ ├── FilePartitionModule.cs │ │ ├── FileQueueWriter.cs │ │ ├── FileQueueWriterFactory.cs │ │ └── StatelessFileQueueReader.cs │ ├── Feature.MemoryPartition │ │ ├── MemoryAccount.cs │ │ ├── MemoryPartitionFactory.cs │ │ ├── MemoryPartitionInbox.cs │ │ ├── MemoryPartitionModule.cs │ │ ├── MemoryQueueWriter.cs │ │ └── MemoryQueueWriterFactory.cs │ ├── Feature.StreamingStorage │ │ ├── ExtendStreamingItem.cs │ │ ├── FileStreamingContainer.cs │ │ ├── FileStreamingItem.cs │ │ ├── IStreamingContainer.cs │ │ ├── IStreamingItem.cs │ │ ├── IStreamingRoot.cs │ │ ├── LocalStreamingInfo.cs │ │ ├── ReaderDelegate.cs │ │ ├── StreamingBaseException.cs │ │ ├── StreamingCondition.cs │ │ ├── StreamingConditionFailedException.cs │ │ ├── StreamingConditionType.cs │ │ ├── StreamingContainerNotFoundException.cs │ │ ├── StreamingErrors.cs │ │ ├── StreamingItemInfo.cs │ │ ├── StreamingItemIntegrityException.cs │ │ ├── StreamingItemNotFoundException.cs │ │ └── StreamingWriteOptions.cs │ ├── Feature.TapeStorage │ │ ├── FileTapeStorageFactory.cs │ │ ├── FileTapeStream.cs │ │ ├── ITapeStorageFactory.cs │ │ ├── ITapeStream.cs │ │ ├── MemoryTapeStorageFactory.cs │ │ ├── MemoryTapeStream.cs │ │ ├── TapeAppendCondition.cs │ │ ├── TapeAppendConditionException.cs │ │ ├── TapeRecord.cs │ │ └── TapeStorageInitilization.cs │ ├── FileStorage.cs │ ├── FileStorageConfig.cs │ ├── HideObjectMembersFromIntelliSense.cs │ ├── IDataSerializer.cs │ ├── IEngineProcess.cs │ ├── IEnvelopeSerializer.cs │ ├── IEnvelopeStreamer.cs │ ├── IMessageSender.cs │ ├── ISystemEvent.cs │ ├── ISystemObserver.cs │ ├── ImmutableAttribute.cs │ ├── ImmutableEnvelope.cs │ ├── ImmutableMessage.cs │ ├── Lokad.Cqrs.Portable.csproj │ ├── MemoryStorage.cs │ ├── MessageContext.cs │ ├── Optional.1.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── SharedKey.snk ├── do-path.cmd └── go.cmd ├── License.txt ├── Prototypes ├── 2011-05-24 Lmf conversion │ ├── LmfAdapter.sln │ ├── LmfAdapter │ │ ├── LmfAdapter.csproj │ │ ├── MessageAttributeBuilder.cs │ │ ├── MessageAttributeContract.cs │ │ ├── MessageAttributeTypeContract.cs │ │ ├── MessageAttributesContract.cs │ │ ├── MessageContext.cs │ │ ├── MessageHeader.cs │ │ ├── MessagePrinter.cs │ │ ├── MessageUtil.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── ProtoBufMessageSerializer.cs │ │ └── UnpackedMessage.cs │ └── protobuf-net.dll └── this folder you see not.txt ├── ReadMe.markdown └── Resource ├── Misc ├── Graphs.vsd └── Sheets.xlsx ├── _ReadMe.txt ├── lokad-cqrs.png └── nuget └── Lokad.CQRS.nuspec /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | bin 3 | *.user 4 | *.suo 5 | *.orig 6 | output 7 | publish 8 | packages 9 | _ReSharper.* 10 | *.Resharper 11 | *.Cache 12 | *.cache 13 | ~$* 14 | *~ 15 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | # Mercurial .hgignore file template by Abdullin.com 2 | # For syntax see: http://linux.die.net/man/5/hgignore 3 | # Source: http://bitbucket.org/abdullin/snippets/ 4 | 5 | # Visual Studio 6 | glob:*.user 7 | glob:*.suo 8 | glob:*.cache 9 | glob:_ReSharper.*/ 10 | relre:/obj/ 11 | relre:/bin/ 12 | 13 | # Subversion 14 | glob:.svn/ 15 | glob:_svn/ 16 | 17 | # Build structure 18 | relre:^Build/ 19 | 20 | # Misc 21 | glob:Thumbs.db 22 | glob:*.bak 23 | glob:*.log 24 | glob:Resource/ILMerge/ILMerge* 25 | glob:Features/NHibernate/Build/ 26 | glob:Framework/Build/ 27 | glob:*.build.csdef 28 | -------------------------------------------------------------------------------- /Framework/Library/Autofac/Autofac.License.txt: -------------------------------------------------------------------------------- 1 | Autofac IoC Container 2 | Copyright (c) 2007-2008 Autofac Contributors 3 | http://code.google.com/p/autofac/wiki/Contributing 4 | 5 | Other software included in this distribution is owned and 6 | licensed separately, see the included license files for details. 7 | 8 | Permission is hereby granted, free of charge, to any person 9 | obtaining a copy of this software and associated documentation 10 | files (the "Software"), to deal in the Software without 11 | restriction, including without limitation the rights to use, 12 | copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the 14 | Software is furnished to do so, subject to the following 15 | conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 22 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Framework/Library/Autofac/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/Autofac/Autofac.dll -------------------------------------------------------------------------------- /Framework/Library/Azure/Microsoft.WindowsAzure.ServiceRuntime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/Azure/Microsoft.WindowsAzure.ServiceRuntime.dll -------------------------------------------------------------------------------- /Framework/Library/Azure/Microsoft.WindowsAzure.StorageClient.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/Azure/Microsoft.WindowsAzure.StorageClient.dll -------------------------------------------------------------------------------- /Framework/Library/Azure/ReadMe.txt: -------------------------------------------------------------------------------- 1 | Version 1.2 -------------------------------------------------------------------------------- /Framework/Library/NUnit/NUnit.License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/NUnit/NUnit.License.txt -------------------------------------------------------------------------------- /Framework/Library/NUnit/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/NUnit/nunit.framework.dll -------------------------------------------------------------------------------- /Framework/Library/ProtoBuf-net/protobuf-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/ProtoBuf-net/protobuf-net.dll -------------------------------------------------------------------------------- /Framework/Library/ProtoBuf-net/protobuf-net.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/ProtoBuf-net/protobuf-net.pdb -------------------------------------------------------------------------------- /Framework/Library/Reactive/System.CoreEx.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/Reactive/System.CoreEx.dll -------------------------------------------------------------------------------- /Framework/Library/Reactive/System.Reactive.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/Reactive/System.Reactive.dll -------------------------------------------------------------------------------- /Framework/Library/ServiceStack/ServiceStack.Text.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/ServiceStack/ServiceStack.Text.dll -------------------------------------------------------------------------------- /Framework/Library/ServiceStack/ServiceStack.Text.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/Library/ServiceStack/ServiceStack.Text.pdb -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Core.Envelope/Play_all_for_ProtoBuf.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Core.Envelope.Scenarios; 9 | using NUnit.Framework; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | // ReSharper disable InconsistentNaming 14 | 15 | [TestFixture] 16 | public sealed class Play_all_for_ProtoBuf : When_envelope_is_serialized 17 | { 18 | readonly IEnvelopeStreamer _streamer = BuildStreamer(new EnvelopeSerializerWithProtoBuf()); 19 | 20 | protected override ImmutableEnvelope RoundtripViaSerializer(EnvelopeBuilder builder) 21 | { 22 | var bytes = _streamer.SaveEnvelopeData(builder.Build()); 23 | return _streamer.ReadAsEnvelopeData(bytes); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Feature.AtomicStorage/Given_Azure_Configuration.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using Lokad.Cqrs.Build; 10 | using Lokad.Cqrs.Build.Engine; 11 | using Microsoft.WindowsAzure; 12 | using NUnit.Framework; 13 | 14 | // ReSharper disable InconsistentNaming 15 | 16 | namespace Lokad.Cqrs.Feature.AtomicStorage 17 | { 18 | [TestFixture] 19 | public sealed class Given_Azure_Configuration : Atomic_storage_scenarios 20 | { 21 | protected override void EngineConfig(CqrsEngineBuilder b) 22 | { 23 | var account = AzureStorage.CreateConfigurationForDev(); 24 | WipeAzureAccount.Fast(s => s.StartsWith("test-"), account); 25 | 26 | b.Azure(m => 27 | { 28 | m.AddAzureProcess(account, new[] {"test-incoming"}, c => c.QueueVisibility(1)); 29 | m.AddAzureSender(account, "test-incoming", x => x.IdGeneratorForTests()); 30 | }); 31 | b.Storage(m => m.AtomicIsInAzure(account, DefaultWithCustomConfig)); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Feature.TapeStorage/DatabaseHelper.cs: -------------------------------------------------------------------------------- 1 | using System.Data.SqlClient; 2 | 3 | namespace Lokad.Cqrs.Feature.TapeStorage 4 | { 5 | public static class DatabaseHelper 6 | { 7 | public static void CreateDatabase(string connectionString) 8 | { 9 | var csb = new SqlConnectionStringBuilder(connectionString); 10 | var databaseName = csb.InitialCatalog; 11 | csb.InitialCatalog = "master"; 12 | 13 | using (var conn = new SqlConnection(csb.ConnectionString)) 14 | { 15 | conn.Open(); 16 | using (var command = conn.CreateCommand()) 17 | { 18 | command.CommandText = "CREATE DATABASE " + databaseName; 19 | command.ExecuteNonQuery(); 20 | } 21 | } 22 | } 23 | 24 | public static void DeleteDatabase(string connectionString) 25 | { 26 | var csb = new SqlConnectionStringBuilder(connectionString); 27 | var databaseName = csb.InitialCatalog; 28 | csb.InitialCatalog = "master"; 29 | 30 | using (var conn = new SqlConnection(csb.ConnectionString)) 31 | { 32 | conn.Open(); 33 | using (var command = conn.CreateCommand()) 34 | { 35 | command.CommandText = "DROP DATABASE " + databaseName; 36 | command.ExecuteNonQuery(); 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly : AssemblyTitle("CloudBus.Tests")] 16 | [assembly : AssemblyDescription("")] 17 | [assembly : AssemblyConfiguration("")] 18 | [assembly : AssemblyCompany("Microsoft")] 19 | [assembly : AssemblyProduct("CloudBus.Tests")] 20 | [assembly : AssemblyCopyright("Copyright © Microsoft 2010")] 21 | [assembly : AssemblyTrademark("")] 22 | [assembly : AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly : ComVisible(false)] 29 | 30 | // The following GUID is for the ID of the typelib if this project is exposed to COM 31 | 32 | [assembly : Guid("95d3779f-a138-48c6-9415-bf413705f087")] 33 | 34 | // Version information for an assembly consists of the following four values: 35 | // 36 | // Major Version 37 | // Minor Version 38 | // Build Number 39 | // Revision 40 | // 41 | // You can specify all the values or you can default the Build and Revision Numbers 42 | // by using the '*' as shown below: 43 | // [assembly: AssemblyVersion("1.0.*")] 44 | 45 | [assembly : AssemblyVersion("1.0.0.0")] 46 | [assembly : AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | <?xml version="1.0" encoding="utf-16"?> 7 | <SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 8 | <ConnectionString>Data Source=.\sqlexpress;Initial Catalog=testdb;Integrated Security=True;Pooling=false</ConnectionString> 9 | </SerializableConnectionString> 10 | Data Source=.\sqlexpress;Initial Catalog=testdb;Integrated Security=True;Pooling=false 11 | 12 | 13 | Cqrs_Tape_Storage 14 | 15 | 16 | UseDevelopmentStorage=true 17 | 18 | 19 | -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/Synthetic/Run_all_Synthetic_tests_on_azure.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Build.Engine; 9 | using Lokad.Cqrs.Synthetic; 10 | using Microsoft.WindowsAzure; 11 | using NUnit.Framework; 12 | 13 | // ReSharper disable InconsistentNaming 14 | 15 | namespace Lokad.Cqrs 16 | { 17 | [TestFixture] 18 | public sealed class Run_all_Synthetic_tests_on_azure : All_synthetic_scenarios 19 | { 20 | 21 | protected override void CurrentConfig(CqrsEngineBuilder b) 22 | { 23 | var dev = AzureStorage.CreateConfigurationForDev(); 24 | 25 | WipeAzureAccount.Fast(s => s.StartsWith("test-"), dev); 26 | b.Azure(m => 27 | { 28 | m.AddAzureProcess(dev, new[] {"test-incoming"}, c => 29 | { 30 | c.QueueVisibility(1); 31 | c.DispatchAsCommandBatch(); 32 | }); 33 | m.AddAzureSender(dev, "test-incoming", x => x.IdGeneratorForTests()); 34 | }); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | Cqrs_Tape_Storage 16 | 17 | 18 | UseDevelopmentStorage=true 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Build/AzureClientModule.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.ComponentModel; 10 | using Autofac; 11 | using Autofac.Core; 12 | using Lokad.Cqrs.Core; 13 | using Lokad.Cqrs.Core.Outbox; 14 | using Lokad.Cqrs.Feature.AzurePartition.Sender; 15 | 16 | namespace Lokad.Cqrs.Build 17 | { 18 | public sealed class AzureClientModule : HideObjectMembersFromIntelliSense, IModule 19 | { 20 | Action _modules = context => { }; 21 | 22 | 23 | 24 | 25 | public void AddAzureSender(IAzureStorageConfig config, string queueName, Action configure) 26 | { 27 | var module = new SendMessageModule((context, endpoint) => new AzureQueueWriterFactory(config, context.Resolve()), config.AccountName, queueName); 28 | configure(module); 29 | _modules += module.Configure; 30 | } 31 | 32 | 33 | 34 | public void AddAzureSender(IAzureStorageConfig config, string queueName) 35 | { 36 | AddAzureSender(config, queueName, m => { }); 37 | } 38 | 39 | [EditorBrowsable(EditorBrowsableState.Never)] 40 | public void Configure(IComponentRegistry container) 41 | { 42 | _modules(container); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Build/Engine/CqrsEngineRole.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | using Microsoft.WindowsAzure.ServiceRuntime; 12 | 13 | namespace Lokad.Cqrs.Build.Engine 14 | { 15 | public abstract class CqrsEngineRole : RoleEntryPoint 16 | { 17 | /// 18 | /// Implement in the inheriting class to configure the bus host. 19 | /// 20 | /// 21 | protected abstract CqrsEngineHost BuildHost(); 22 | 23 | CqrsEngineHost _host; 24 | readonly CancellationTokenSource _source = new CancellationTokenSource(); 25 | 26 | Task _task; 27 | 28 | public override bool OnStart() 29 | { 30 | // this is actually azure initialization; 31 | _host = BuildHost(); 32 | return base.OnStart(); 33 | } 34 | 35 | public override void Run() 36 | { 37 | _task = _host.Start(_source.Token); 38 | _source.Token.WaitHandle.WaitOne(); 39 | } 40 | 41 | public string InstanceName 42 | { 43 | get 44 | { 45 | return string.Format("{0}/{1}", 46 | RoleEnvironment.CurrentRoleInstance.Role.Name, 47 | RoleEnvironment.CurrentRoleInstance.Id); 48 | } 49 | } 50 | 51 | public override void OnStop() 52 | { 53 | _source.Cancel(true); 54 | 55 | _task.Wait(TimeSpan.FromSeconds(10)); 56 | _host.Dispose(); 57 | 58 | base.OnStop(); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Core.Envelope/EnvelopeSerializerWithProtoBuf.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using ProtoBuf; 3 | 4 | namespace Lokad.Cqrs.Core.Envelope 5 | { 6 | public sealed class EnvelopeSerializerWithProtoBuf : IEnvelopeSerializer 7 | { 8 | public void SerializeEnvelope(Stream stream, EnvelopeContract contract) 9 | { 10 | Serializer.Serialize(stream, contract); 11 | } 12 | 13 | public EnvelopeContract DeserializeEnvelope(Stream stream) 14 | { 15 | return Serializer.Deserialize(stream); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/ExtendCqrsClientBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Build; 3 | using Lokad.Cqrs.Build.Client; 4 | 5 | namespace Lokad.Cqrs 6 | { 7 | public static class ExtendCqrsClientBuilder 8 | { 9 | public static void Azure(this CqrsClientBuilder @this, Action config) 10 | { 11 | var module = new AzureClientModule(); 12 | config(module); 13 | @this.Advanced.RegisterModule(module); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/ExtendCqrsEngineBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Build.Engine; 3 | 4 | namespace Lokad.Cqrs 5 | { 6 | public static class ExtendCqrsEngineBuilder 7 | { 8 | public static void Azure(this CqrsEngineBuilder @this, Action config) 9 | { 10 | var module = new AzureEngineModule(); 11 | config(module); 12 | @this.Advanced.RegisterModule(module); 13 | } 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/ExtendSerializationModule.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Build.Client; 9 | using Lokad.Cqrs.Build.Engine; 10 | using Lokad.Cqrs.Core.Envelope; 11 | using Lokad.Cqrs.Core.Serialization; 12 | 13 | namespace Lokad.Cqrs 14 | { 15 | public static class ExtendSerializationModule 16 | { 17 | public static void UseProtoBufSerialization(this CqrsClientBuilder self) 18 | { 19 | self.Advanced.DataSerializer(t => new DataSerializerWithProtoBuf(t)); 20 | self.Advanced.EnvelopeSerializer(new EnvelopeSerializerWithProtoBuf()); 21 | } 22 | public static void UseProtoBufSerialization(this CqrsEngineBuilder self) 23 | { 24 | self.Advanced.CustomDataSerializer(t => new DataSerializerWithProtoBuf(t)); 25 | self.Advanced.CustomEnvelopeSerializer(new EnvelopeSerializerWithProtoBuf()); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/ExtendStorageModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Build.Engine; 3 | using Lokad.Cqrs.Feature.AtomicStorage; 4 | using Lokad.Cqrs.Feature.StreamingStorage; 5 | 6 | namespace Lokad.Cqrs 7 | { 8 | public static class ExtendStorageModule 9 | { 10 | public static void AtomicIsInAzure(this StorageModule self, IAzureStorageConfig storage, Action config) 11 | { 12 | var builder = new DefaultAtomicStorageStrategyBuilder(); 13 | config(builder); 14 | AtomicIsInAzure(self, storage, builder.Build()); 15 | } 16 | 17 | public static void AtomicIsInAzure(this StorageModule self, IAzureStorageConfig storage) 18 | { 19 | AtomicIsInAzure(self, storage, builder => { }); 20 | } 21 | 22 | public static void AtomicIsInAzure(this StorageModule self, IAzureStorageConfig storage, IAtomicStorageStrategy strategy) 23 | { 24 | self.AtomicIs(new AzureAtomicStorageFactory(strategy, storage)); 25 | } 26 | 27 | public static void StreamingIsInAzure(this StorageModule self, IAzureStorageConfig storage) 28 | { 29 | self.StreamingIs(new BlobStreamingRoot(storage.CreateBlobClient())); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Feature.AtomicStorage/AtomicStorageSerializerWithProtoBuf.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using ProtoBuf; 3 | 4 | namespace Lokad.Cqrs.Feature.AtomicStorage 5 | { 6 | public sealed class AtomicStorageSerializerWithProtoBuf : IAtomicStorageSerializer 7 | { 8 | public void Serialize(TView view, Stream stream) 9 | { 10 | Serializer.Serialize(stream, view); 11 | } 12 | 13 | public TView Deserialize(Stream stream) 14 | { 15 | return Serializer.Deserialize(stream); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Feature.AzurePartition/Sender/AzureQueueWriterFactory.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Collections.Concurrent; 9 | using Lokad.Cqrs.Core.Outbox; 10 | 11 | namespace Lokad.Cqrs.Feature.AzurePartition.Sender 12 | { 13 | public sealed class AzureQueueWriterFactory : IQueueWriterFactory 14 | { 15 | readonly IAzureStorageConfig _config; 16 | readonly IEnvelopeStreamer _streamer; 17 | 18 | readonly ConcurrentDictionary _writeQueues = 19 | new ConcurrentDictionary(); 20 | 21 | public AzureQueueWriterFactory( 22 | IAzureStorageConfig accounts, 23 | IEnvelopeStreamer streamer) 24 | { 25 | _config = accounts; 26 | _streamer = streamer; 27 | } 28 | 29 | public string Endpoint { get { return _config.AccountName; } } 30 | 31 | 32 | public IQueueWriter GetWriteQueue(string queueName) 33 | { 34 | return _writeQueues.GetOrAdd(queueName, name => 35 | { 36 | var queue = _config.CreateQueueClient().GetQueueReference(name); 37 | var container = _config.CreateBlobClient().GetContainerReference(name); 38 | var v = new StatelessAzureQueueWriter(_streamer, container, queue, name); 39 | v.Init(); 40 | return v; 41 | }); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Feature.StreamingStorage/BlobStreamingRoot.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Microsoft.WindowsAzure.StorageClient; 9 | 10 | namespace Lokad.Cqrs.Feature.StreamingStorage 11 | { 12 | /// 13 | /// Windows Azure implementation of storage 14 | /// 15 | public sealed class BlobStreamingRoot : IStreamingRoot 16 | { 17 | readonly CloudBlobClient _client; 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The client. 23 | public BlobStreamingRoot(CloudBlobClient client) 24 | { 25 | _client = client; 26 | } 27 | 28 | public IStreamingContainer GetContainer(string name) 29 | { 30 | return new BlobStreamingContainer(_client.GetBlobDirectoryReference(name)); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Feature.TapeStorage/BlobTapeStorageFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Configuration; 4 | using System.Linq; 5 | using Microsoft.WindowsAzure.StorageClient; 6 | 7 | namespace Lokad.Cqrs.Feature.TapeStorage 8 | { 9 | public class BlobTapeStorageFactory : ITapeStorageFactory 10 | { 11 | readonly CloudBlobClient _cloudBlobClient; 12 | readonly string _containerName; 13 | 14 | readonly ConcurrentDictionary _writers = 15 | new ConcurrentDictionary(); 16 | 17 | public BlobTapeStorageFactory(IAzureStorageConfig config, string containerName) 18 | { 19 | if (containerName.Any(Char.IsUpper)) 20 | throw new ArgumentException("All letters in a container name must be lowercase."); 21 | 22 | _cloudBlobClient = config.CreateBlobClient(); 23 | 24 | _containerName = containerName; 25 | } 26 | 27 | public ITapeStream GetOrCreateStream(string name) 28 | { 29 | if (name == null) 30 | throw new ArgumentNullException("name"); 31 | if (string.IsNullOrWhiteSpace("name")) 32 | throw new ArgumentException("Incorrect value.", "name"); 33 | 34 | return _writers.GetOrAdd( 35 | name, 36 | s => 37 | { 38 | var container = _cloudBlobClient.GetContainerReference(_containerName); 39 | return new BlobTapeStream(container, name); 40 | }); 41 | } 42 | 43 | public void InitializeForWriting() 44 | { 45 | var container = _cloudBlobClient.GetContainerReference(_containerName); 46 | container.CreateIfNotExist(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/IAzureStorageConfig.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Microsoft.WindowsAzure; 9 | using Microsoft.WindowsAzure.StorageClient; 10 | 11 | namespace Lokad.Cqrs 12 | { 13 | public interface IAzureStorageConfig 14 | { 15 | string AccountName { get; } 16 | 17 | CloudStorageAccount UnderlyingAccount { get; } 18 | 19 | CloudBlobClient CreateBlobClient(); 20 | CloudQueueClient CreateQueueClient(); 21 | CloudTableClient CreateTableClient(); 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Azure/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly : AssemblyTitle("Lokad.Cqrs.Azure")] 16 | [assembly : AssemblyDescription("")] 17 | [assembly : AssemblyConfiguration("")] 18 | [assembly : AssemblyCompany("Lokad SAS")] 19 | [assembly : AssemblyProduct("Lokad.Cqrs")] 20 | [assembly : AssemblyCopyright("Copyright © Lokad 2011")] 21 | [assembly : AssemblyTrademark("")] 22 | [assembly : AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly : ComVisible(false)] 29 | 30 | // The following GUID is for the ID of the typelib if this project is exposed to COM 31 | 32 | [assembly : Guid("0f1cc484-ef24-4b41-a4ef-207649194a94")] 33 | 34 | // Version information for an assembly consists of the following four values: 35 | // 36 | // Major Version 37 | // Minor Version 38 | // Build Number 39 | // Revision 40 | // 41 | // You can specify all the values or you can default the Build and Revision Numbers 42 | // by using the '*' as shown below: 43 | // [assembly: AssemblyVersion("1.0.*")] 44 | 45 | [assembly : AssemblyVersion("2.0.0.0")] 46 | [assembly : AssemblyFileVersion("2.0.0.0")] -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_activation_map_constrained_to_catch_all_consumer.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Feature.DirectoryDispatch; 9 | using NUnit.Framework; 10 | using System.Linq; 11 | 12 | namespace Lokad.Cqrs.Core.Directory 13 | { 14 | [TestFixture] 15 | public sealed class When_activation_map_constrained_to_catch_all_consumer : MessageDirectoryFixture 16 | { 17 | // ReSharper disable InconsistentNaming 18 | 19 | 20 | MessageActivationInfo[] Map { get; set; } 21 | 22 | 23 | 24 | [TestFixtureSetUp] 25 | public void FixtureSetUp() 26 | { 27 | Map = Builder.BuildActivationMap(mm => typeof(ListenToAll) == mm.Consumer); 28 | } 29 | 30 | [Test] 31 | public void Only_one_consumer_is_allowed() 32 | { 33 | CollectionAssert.AreEquivalent(new[] { typeof(ListenToAll) }, Map.SelectMany(c => c.AllConsumers).Distinct()); 34 | } 35 | 36 | 37 | [Test] 38 | public void All_messages_are_allowed() 39 | { 40 | CollectionAssert.AreEquivalent(TestMessageTypes, Map.Select(c => c.MessageType).Distinct()); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_activations_constrained_to_handler_type_with_interface.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Feature.DirectoryDispatch; 2 | using NUnit.Framework; 3 | using System.Linq; 4 | 5 | // ReSharper disable InconsistentNaming 6 | namespace Lokad.Cqrs.Core.Directory 7 | { 8 | [TestFixture] 9 | public sealed class When_activations_constrained_to_handler_type_with_interface : MessageDirectoryFixture 10 | { 11 | 12 | MessageActivationInfo[] Map { get; set; } 13 | 14 | [TestFixtureSetUp] 15 | public void FixtureSetUp() 16 | { 17 | Map = Builder.BuildActivationMap(mm => typeof(WhenSomethingGenericHappened) == mm.Consumer); 18 | } 19 | 20 | [Test] 21 | public void Only_derived_messages_are_allowed() 22 | { 23 | var expected = TestMessageTypes 24 | .Where(t => typeof (ISomethingHappenedEvent).IsAssignableFrom(t)) 25 | .ToArray(); 26 | 27 | CollectionAssert.AreEquivalent(expected, QueryAllMessageTypes(Map)); 28 | } 29 | 30 | [Test] 31 | public void Only_single_consumer_is_allowed() 32 | { 33 | var expected = new[] {typeof(WhenSomethingGenericHappened)}; 34 | CollectionAssert.AreEquivalent(expected, QueryDistinctConsumingTypes(Map)); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_activations_constrained_to_handler_type_with_type.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Feature.DirectoryDispatch; 2 | using NUnit.Framework; 3 | 4 | namespace Lokad.Cqrs.Core.Directory 5 | { 6 | [TestFixture] 7 | public sealed class When_activations_constrained_to_handler_type_with_type : MessageDirectoryFixture 8 | { 9 | // ReSharper disable InconsistentNaming 10 | MessageActivationInfo[] Map { get; set; } 11 | 12 | [TestFixtureSetUp] 13 | public void FixtureSetUp() 14 | { 15 | Map = Builder.BuildActivationMap(mm => typeof(WhenSomethingSpecificHappened) == mm.Consumer); 16 | } 17 | 18 | [Test] 19 | public void Only_single_consumer_is_allowed() 20 | { 21 | var expected = new[] { typeof(WhenSomethingSpecificHappened) }; 22 | CollectionAssert.AreEquivalent(expected, QueryDistinctConsumingTypes(Map)); 23 | } 24 | 25 | [Test] 26 | public void Only_specific_message_is_allowed() 27 | { 28 | var expected = new[] { typeof(SomethingSpecificHappenedEvent) }; 29 | CollectionAssert.AreEquivalent(expected, QueryAllMessageTypes(Map)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_activations_constrained_to_message_interface.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Lokad.Cqrs.Feature.DirectoryDispatch; 3 | using NUnit.Framework; 4 | // ReSharper disable InconsistentNaming 5 | namespace Lokad.Cqrs.Core.Directory 6 | { 7 | [TestFixture] 8 | public sealed class When_activations_constrained_to_message_interface : MessageDirectoryFixture 9 | { 10 | MessageActivationInfo[] Map { get; set; } 11 | 12 | [TestFixtureSetUp] 13 | public void FixtureSetUp() 14 | { 15 | Map = Builder.BuildActivationMap(mm => typeof(ISomethingHappenedEvent) == mm.Message); 16 | } 17 | 18 | [Test] 19 | public void Only_derived_messages_are_allowed() 20 | { 21 | var derivedMessages = TestMessageTypes 22 | .Where(t => typeof (ISomethingHappenedEvent).IsAssignableFrom(t)); 23 | 24 | CollectionAssert.IsSubsetOf(QueryAllMessageTypes(Map), derivedMessages); 25 | } 26 | 27 | [Test] 28 | public void Non_handled_derived_messages_are_prohibited() 29 | { 30 | CollectionAssert.DoesNotContain(QueryAllMessageTypes(Map), typeof(SomethingUnexpectedHandled)); 31 | } 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_builder_is_available.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NUnit.Framework; 3 | 4 | namespace Lokad.Cqrs.Core.Directory 5 | { 6 | [TestFixture] 7 | public sealed class When_builder_is_available : MessageDirectoryFixture 8 | { 9 | // ReSharper disable InconsistentNaming 10 | 11 | [Test] 12 | public void All_concrete_messages_discovered_for_serialization() 13 | { 14 | var expected = TestMessageTypes.Where(t => !t.IsAbstract).ToArray(); 15 | var enumerable = Mappings 16 | .Select(m => m.Message) 17 | .Where(m => !m.IsAbstract) 18 | .Distinct(); 19 | CollectionAssert.AreEquivalent(expected, enumerable); 20 | } 21 | 22 | [Test] 23 | public void Al_concrete_handlers_discovered_for_activation() 24 | { 25 | var expected = TestConsumerTypes.Where(t => !t.IsAbstract).ToArray(); 26 | var enumerable = Mappings 27 | .Select(m => m.Consumer) 28 | .Where(m => !m.IsAbstract) 29 | .Distinct(); 30 | CollectionAssert.AreEquivalent(expected, enumerable); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Directory/When_there_are_no_catch_all_handlers.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Feature.DirectoryDispatch; 9 | using NUnit.Framework; 10 | 11 | namespace Lokad.Cqrs.Core.Directory 12 | { 13 | [TestFixture] 14 | public sealed class When_there_are_no_catch_all_handlers : MessageDirectoryFixture 15 | { 16 | // ReSharper disable InconsistentNaming 17 | MessageActivationInfo[] Map { get; set; } 18 | 19 | [TestFixtureSetUp] 20 | public void FixtureSetUp() 21 | { 22 | Map = Builder.BuildActivationMap(mm => mm.Consumer != typeof (ListenToAll)); 23 | } 24 | 25 | [Test] 26 | public void Orphaned_messages_are_excluded() 27 | { 28 | CollectionAssert.DoesNotContain(QueryAllMessageTypes(Map), typeof (NonHandledCommand)); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Envelope/Play_all_for_BinaryFormatter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Core.Envelope.Scenarios; 9 | using NUnit.Framework; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [TestFixture] 14 | public sealed class Play_all_for_BinaryFormatter : When_envelope_is_serialized 15 | { 16 | readonly IEnvelopeStreamer _streamer = BuildStreamer(new EnvelopeSerializerWithBinaryFormatter()); 17 | protected override ImmutableEnvelope RoundtripViaSerializer(EnvelopeBuilder builder) 18 | { 19 | var bytes = _streamer.SaveEnvelopeData(builder.Build()); 20 | return _streamer.ReadAsEnvelopeData(bytes); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Envelope/Play_all_for_DataContracts.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Core.Envelope.Scenarios; 9 | using NUnit.Framework; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [TestFixture] 14 | public sealed class Play_all_for_DataContracts : When_envelope_is_serialized 15 | { 16 | readonly IEnvelopeStreamer _streamer = BuildStreamer(new EnvelopeSerializerWithDataContracts()); 17 | protected override ImmutableEnvelope RoundtripViaSerializer(EnvelopeBuilder builder) 18 | { 19 | var bytes = _streamer.SaveEnvelopeData(builder.Build()); 20 | return _streamer.ReadAsEnvelopeData(bytes); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Envelope/Play_all_for_Memory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Core.Envelope.Scenarios; 3 | using NUnit.Framework; 4 | using ServiceStack.Text; 5 | 6 | namespace Lokad.Cqrs.Core.Envelope 7 | { 8 | [TestFixture] 9 | public sealed class Play_all_for_Memory : When_envelope_is_serialized 10 | { 11 | protected override ImmutableEnvelope RoundtripViaSerializer(EnvelopeBuilder builder) 12 | { 13 | return builder.Build(); 14 | } 15 | } 16 | 17 | [TestFixture] 18 | public sealed class EnvelopePrinterTests 19 | { 20 | // ReSharper disable InconsistentNaming 21 | [Test] 22 | public void Test() 23 | { 24 | var b = new EnvelopeBuilder("GUID"); 25 | b.DelayBy(TimeSpan.FromSeconds(10)); 26 | b.AddString("Test"); 27 | b.AddItem(new { Cool = "1"}).AddAttribute("D2","D1"); 28 | 29 | Console.WriteLine(b.Build().PrintToString(o => o.Dump())); 30 | 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Envelope/Scenarios/DataSerializerWithBinaryFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization.Formatters.Binary; 4 | 5 | namespace Lokad.Cqrs.Core.Envelope.Scenarios 6 | { 7 | sealed class DataSerializerWithBinaryFormatter : IDataSerializer 8 | { 9 | static readonly BinaryFormatter Formatter = new BinaryFormatter(); 10 | 11 | public void Serialize(object instance, Stream destinationStream) 12 | { 13 | Formatter.Serialize(destinationStream, instance); 14 | } 15 | 16 | public object Deserialize(Stream sourceStream, Type type) 17 | { 18 | return Formatter.Deserialize(sourceStream); 19 | } 20 | 21 | public bool TryGetContractNameByType(Type messageType, out string contractName) 22 | { 23 | contractName = messageType.FullName; 24 | return true; 25 | } 26 | 27 | public bool TryGetContractTypeByName(string contractName, out Type contractType) 28 | { 29 | contractType = Type.GetType(contractName); 30 | return true; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Core.Envelope/Scenarios/EnvelopeSerializerWithBinaryFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.Serialization.Formatters.Binary; 3 | 4 | namespace Lokad.Cqrs.Core.Envelope.Scenarios 5 | { 6 | class EnvelopeSerializerWithBinaryFormatter : IEnvelopeSerializer 7 | { 8 | public void SerializeEnvelope(Stream stream, EnvelopeContract contract) 9 | { 10 | Formatter.Serialize(stream, contract); 11 | } 12 | 13 | 14 | public EnvelopeContract DeserializeEnvelope(Stream stream) 15 | { 16 | return (EnvelopeContract)Formatter.Deserialize(stream); 17 | } 18 | 19 | static readonly BinaryFormatter Formatter = new BinaryFormatter(); 20 | 21 | 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/ExtendMaybe.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using NUnit.Framework; 9 | 10 | namespace Lokad.Cqrs 11 | { 12 | /// 13 | /// Extends for the purposes of testing 14 | /// 15 | public static class ExtendMaybe 16 | { 17 | /// 18 | /// Checks that optional has value matching to the provided value in tests. 19 | /// 20 | /// The type of the value. 21 | /// The result. 22 | /// same instance for inlining 23 | public static void ShouldPass(this Optional result) 24 | { 25 | Assert.IsTrue(result.HasValue, "Maybe should have value"); 26 | return; 27 | } 28 | 29 | /// 30 | /// Checks that the optional does not have any value 31 | /// 32 | /// The type of the value. 33 | /// The maybe. 34 | /// same instance for inlining 35 | public static void ShouldFail(this Optional optional) 36 | { 37 | Assert.IsFalse(optional.HasValue, "Maybe should not have value"); 38 | return; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.AtomicStorage/Atomic_storage_scenarios.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Build.Engine; 2 | using NUnit.Framework; 3 | 4 | // ReSharper disable InconsistentNaming 5 | namespace Lokad.Cqrs.Feature.AtomicStorage 6 | { 7 | public abstract class Atomic_storage_scenarios 8 | { 9 | [Test] 10 | public void When_atomic_config_is_requested() 11 | { 12 | new Engine_scenario_for_AtomicStorage_in_partition() 13 | .TestConfiguration(EngineConfig); 14 | } 15 | 16 | 17 | [Test] 18 | public void When_nuclear_config_is_requested() 19 | { 20 | new Engine_scenario_for_NuclearStorage_in_partition() 21 | .TestConfiguration(EngineConfig); 22 | } 23 | 24 | [Test] 25 | public void When_custom_view_domain() 26 | { 27 | new Engine_scenario_for_custom_view_domain() 28 | .TestConfiguration(EngineConfig); 29 | } 30 | 31 | protected abstract void EngineConfig(CqrsEngineBuilder b); 32 | 33 | protected static void DefaultWithCustomConfig(DefaultAtomicStorageStrategyBuilder builder) 34 | { 35 | builder.WhereEntity(type => 36 | { 37 | if (typeof(Define.AtomicEntity).IsAssignableFrom(type)) 38 | return true; 39 | if (type.Name.Contains("CustomDomainView")) 40 | return true; 41 | return false; 42 | }); 43 | builder.FolderForEntity(type1 => "test-" +type1.Name.ToLowerInvariant()); 44 | builder.FolderForSingleton("test-singleton"); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.AtomicStorage/Given_File_Configuration.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Lokad.Cqrs.Build.Engine; 3 | using NUnit.Framework; 4 | 5 | namespace Lokad.Cqrs.Feature.AtomicStorage 6 | { 7 | [TestFixture] 8 | public sealed class Given_File_Configuration : Atomic_storage_scenarios 9 | { 10 | // ReSharper disable InconsistentNaming 11 | 12 | readonly string _path = Path.Combine(Directory.GetCurrentDirectory(), typeof (Given_File_Configuration).Name); 13 | [SetUp] 14 | public void SetUp() 15 | { 16 | if (Directory.Exists(_path)) 17 | { 18 | Directory.Delete(_path, true); 19 | } 20 | Directory.CreateDirectory(_path); 21 | } 22 | 23 | [TestFixtureTearDown] 24 | public void FixtureTearDown() 25 | { 26 | 27 | } 28 | 29 | protected override void EngineConfig(CqrsEngineBuilder b) 30 | { 31 | b.Storage(m => m.AtomicIsInFiles(_path, DefaultWithCustomConfig)); 32 | b.Memory(m => 33 | { 34 | m.AddMemoryProcess("azure-dev"); 35 | m.AddMemorySender("azure-dev", x => x.IdGeneratorForTests()); 36 | }); 37 | } 38 | 39 | } 40 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.AtomicStorage/Given_Memory_Configuration.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Lokad.Cqrs.Build.Engine; 9 | using NUnit.Framework; 10 | 11 | // ReSharper disable InconsistentNaming 12 | namespace Lokad.Cqrs.Feature.AtomicStorage 13 | { 14 | [TestFixture] 15 | public sealed class Given_Memory_Configuration : Atomic_storage_scenarios 16 | { 17 | 18 | protected override void EngineConfig(CqrsEngineBuilder config) 19 | { 20 | config.Memory(m => 21 | { 22 | m.AddMemoryProcess("do"); 23 | m.AddMemorySender("do", cb => cb.IdGeneratorForTests()); 24 | }); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.StreamingStorage/Scenarios/ITestStorage.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.StreamingStorage.Scenarios 9 | { 10 | public interface ITestStorage 11 | { 12 | IStreamingContainer GetContainer(string name); 13 | } 14 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.StreamingStorage/Scenarios/When_copying_items_in.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using NUnit.Framework; 10 | 11 | // ReSharper disable InconsistentNaming 12 | 13 | namespace Lokad.Cqrs.Feature.StreamingStorage.Scenarios 14 | { 15 | public abstract class When_copying_items_in : StorageItemFixture where T : ITestStorage, new() 16 | { 17 | [Test] 18 | public void Test() 19 | { 20 | TestContainer.Create(); 21 | 22 | var source = GetItem("source"); 23 | var target = GetItem("target"); 24 | 25 | Write(source, Guid.Empty); 26 | 27 | target.CopyFrom(source); 28 | 29 | ShouldHaveGuid(target, Guid.Empty); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.StreamingStorage/Scenarios/When_listing_items_in.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using System.Linq; 4 | 5 | namespace Lokad.Cqrs.Feature.StreamingStorage.Scenarios 6 | { 7 | public abstract class When_listing_items_in : 8 | StorageItemFixture where TStorage : ITestStorage, new() 9 | { 10 | [Test] 11 | public void Missing_container_throws_error() 12 | { 13 | ExpectContainerNotFound(() => TestContainer.ListItems()); 14 | } 15 | 16 | [Test] 17 | public void Existing_empty_container_returns_empty() 18 | { 19 | TestContainer.Create(); 20 | CollectionAssert.IsEmpty(TestContainer.ListItems()); 21 | } 22 | 23 | [Test] 24 | public void Existing_container_lists_items() 25 | { 26 | TestContainer.Create(); 27 | var newGuid = Guid.NewGuid(); 28 | Write(TestItem, newGuid); 29 | var first = TestContainer.ListItems().First(); 30 | 31 | ShouldHaveGuid(TestContainer.GetItem(first),newGuid); 32 | } 33 | 34 | 35 | } 36 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Feature.TapeStorage/MemoryTapeStorageTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Collections.Generic; 3 | using NUnit.Framework; 4 | 5 | namespace Lokad.Cqrs.Feature.TapeStorage 6 | { 7 | [TestFixture] 8 | public sealed class MemoryTapeStorageTests : TapeStorageTests 9 | { 10 | // ReSharper disable InconsistentNaming 11 | 12 | readonly ConcurrentDictionary> _storage = new ConcurrentDictionary>(); 13 | MemoryTapeStorageFactory _storageFactory; 14 | 15 | protected override void PrepareEnvironment() 16 | { 17 | } 18 | 19 | protected override ITapeStream InitializeAndGetTapeStorage() 20 | { 21 | _storageFactory = new MemoryTapeStorageFactory(_storage); 22 | 23 | 24 | const string name = "Memory"; 25 | return _storageFactory.GetOrCreateStream(name); 26 | } 27 | 28 | protected override void FreeResources() 29 | { 30 | _storageFactory = null; 31 | } 32 | 33 | protected override void TearDownEnvironment() 34 | { 35 | _storage.Clear(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly : AssemblyTitle("Lokad.Cqrs.Portable.Tests")] 16 | [assembly : AssemblyDescription("")] 17 | [assembly : AssemblyConfiguration("")] 18 | [assembly : AssemblyCompany("Microsoft")] 19 | [assembly : AssemblyProduct("Lokad.Cqrs.Portable.Tests")] 20 | [assembly : AssemblyCopyright("Copyright © Microsoft 2011")] 21 | [assembly : AssemblyTrademark("")] 22 | [assembly : AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly : ComVisible(false)] 29 | 30 | // The following GUID is for the ID of the typelib if this project is exposed to COM 31 | 32 | [assembly : Guid("ff55fd97-c930-4d93-82ad-ce21394f1794")] 33 | 34 | // Version information for an assembly consists of the following four values: 35 | // 36 | // Major Version 37 | // Minor Version 38 | // Build Number 39 | // Revision 40 | // 41 | // You can specify all the values or you can default the Build and Revision Numbers 42 | // by using the '*' as shown below: 43 | // [assembly: AssemblyVersion("1.0.*")] 44 | 45 | [assembly : AssemblyVersion("1.0.0.0")] 46 | [assembly : AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/AccountAggregateReader.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Scenarios.SimpleES.Contracts; 2 | 3 | namespace Lokad.Cqrs.Scenarios.SimpleES 4 | { 5 | public class AccountAggregateReader 6 | { 7 | public void When(AccountCreated created) 8 | { 9 | 10 | } 11 | 12 | public void When(LoginAdded added) 13 | { 14 | 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/AccountAggregateRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 4 | 5 | namespace Lokad.Cqrs.Scenarios.SimpleES 6 | { 7 | public sealed class AccountAggregateRepository 8 | { 9 | readonly InMemoryEventStreamer _streams; 10 | 11 | public AccountAggregateRepository(InMemoryEventStreamer streams) 12 | { 13 | _streams = streams; 14 | } 15 | 16 | 17 | public void Append(string key, Action update) 18 | { 19 | _streams.Append(key, before => 20 | { 21 | var obs = new Subject(); 22 | var ar = new AccountAggregateWriter(obs); 23 | var list = new List(); 24 | foreach (var @event in before) 25 | { 26 | ar.Apply(@event); 27 | } 28 | using (obs.Subscribe(list.Add)) 29 | { 30 | update(ar); 31 | } 32 | return list; 33 | }); 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/AccountAggregateWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Scenarios.SimpleES.Contracts; 3 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 4 | 5 | namespace Lokad.Cqrs.Scenarios.SimpleES 6 | { 7 | public sealed class AccountAggregateWriter : AccountAggregateReader 8 | { 9 | public void CreateAccount(string name) 10 | { 11 | Apply(new AccountCreated(name)); 12 | } 13 | 14 | public void AddLogin(string login, string password) 15 | { 16 | Apply(new LoginAdded(login, password)); 17 | } 18 | 19 | public void Apply(IAccountEvent e) 20 | { 21 | RedirectToWhen.Invoke(this, e); 22 | _observer.OnNext(e); 23 | } 24 | 25 | 26 | readonly IObserver _observer; 27 | 28 | public AccountAggregateWriter(IObserver observer) 29 | { 30 | _observer = observer; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/AccountHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Lokad.Cqrs.Feature.AtomicStorage; 3 | using Lokad.Cqrs.Scenarios.SimpleES.Contracts; 4 | 5 | namespace Lokad.Cqrs.Scenarios.SimpleES 6 | { 7 | public sealed class AccountHandler : 8 | Definitions.Define.Consumer,Definitions.Define.Consumer 9 | 10 | { 11 | readonly Func _context; 12 | readonly AccountAggregateRepository _repository; 13 | readonly NuclearStorage _storage; 14 | 15 | public AccountHandler(Func context, AccountAggregateRepository repository, NuclearStorage storage) 16 | { 17 | _context = context; 18 | _storage = storage; 19 | _repository = repository; 20 | } 21 | 22 | public void Consume(CreateAccount command) 23 | { 24 | _repository.Append(_context().AggregateId, aar => aar.CreateAccount(command.Name)); 25 | } 26 | 27 | public void Consume(AddLogin command) 28 | { 29 | _storage.UpdateSingleton(li => li.AddOrThrow(command.Username)); 30 | _repository.Append(_context().AggregateId, aar => aar.AddLogin(command.Username,command.Password)); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Contracts/AccountCreated.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 3 | 4 | namespace Lokad.Cqrs.Scenarios.SimpleES.Contracts 5 | { 6 | [DataContract] 7 | public sealed class AccountCreated : IAccountEvent 8 | { 9 | public readonly string Name; 10 | 11 | public AccountCreated(string name) 12 | { 13 | Name = name; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Contracts/AddLogin.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 3 | 4 | namespace Lokad.Cqrs.Scenarios.SimpleES.Contracts 5 | { 6 | [DataContract] 7 | public sealed class AddLogin : IAccountCommand 8 | { 9 | [DataMember] 10 | public readonly string Username; 11 | [DataMember] 12 | public readonly string Password; 13 | 14 | public AddLogin(string username, string password) 15 | { 16 | Username = username; 17 | Password = password; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Contracts/CreateAccount.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 3 | 4 | namespace Lokad.Cqrs.Scenarios.SimpleES.Contracts 5 | { 6 | [DataContract] 7 | public sealed class CreateAccount : IAccountCommand 8 | { 9 | [DataMember] 10 | public readonly string Name; 11 | 12 | public CreateAccount(string name) 13 | { 14 | Name = name; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Contracts/LoginAdded.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Lokad.Cqrs.Scenarios.SimpleES.Definitions; 3 | 4 | namespace Lokad.Cqrs.Scenarios.SimpleES.Contracts 5 | { 6 | [DataContract] 7 | public sealed class LoginAdded : IAccountEvent 8 | { 9 | [DataMember] 10 | public readonly string Login; 11 | [DataMember] 12 | public readonly string Password; 13 | 14 | public LoginAdded(string login, string password) 15 | { 16 | Login = login; 17 | Password = password; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Contracts/LoginIndex.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Lokad.Cqrs.Scenarios.SimpleES.Contracts 5 | { 6 | public sealed class LoginIndex 7 | { 8 | readonly HashSet _set = new HashSet(StringComparer.InvariantCultureIgnoreCase); 9 | 10 | public void AddOrThrow(string login) 11 | { 12 | if (!_set.Add(login)) 13 | throw new InvalidOperationException("Index already existed"); 14 | } 15 | public void Release(string login) 16 | { 17 | _set.Remove(login); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Definitions/Define.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Scenarios.SimpleES.Definitions 2 | { 3 | public static class Define 4 | { 5 | public interface ICommand 6 | { 7 | 8 | } 9 | 10 | public interface Consumer where T : ICommand 11 | { 12 | void Consume(T command); 13 | } 14 | 15 | public sealed class MyContext 16 | { 17 | public readonly string AggregateId; 18 | 19 | public MyContext(string aggregateId) 20 | { 21 | AggregateId = aggregateId; 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Definitions/IAccountCommand.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Scenarios.SimpleES.Definitions 2 | { 3 | public interface IAccountCommand : Define.ICommand 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/Definitions/IAccountEvent.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Scenarios.SimpleES.Definitions 2 | { 3 | public interface IAccountEvent : Define.ICommand 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/InMemoryEventStreamer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace Lokad.Cqrs.Scenarios.SimpleES 7 | { 8 | public sealed class InMemoryEventStreamer 9 | { 10 | // non serialized 11 | readonly ConcurrentDictionary> _streams = new ConcurrentDictionary>(); 12 | readonly IMessageSender _sender; 13 | public InMemoryEventStreamer(IMessageSender sender) 14 | { 15 | _sender = sender; 16 | } 17 | 18 | public void Append(string key, Func, IEnumerable> append) 19 | { 20 | _streams.AddOrUpdate(key, s => 21 | { 22 | var result = append(Enumerable.Empty()); 23 | 24 | // temporary 25 | foreach (var @event in result) 26 | { 27 | _sender.SendOne(@event, eb =>eb.AddString("EntityId", key)); 28 | } 29 | 30 | return new List(result); 31 | }, (s, list) => 32 | { 33 | var result = append(list); 34 | 35 | // temporary 36 | foreach (var @event in result) 37 | { 38 | _sender.SendOne(@event, eb => eb.AddString("EntityId", key)); 39 | } 40 | list.AddRange(result); 41 | return list; 42 | }); 43 | } 44 | 45 | } 46 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Scenarios/001-SimpleES/RedirectToWhen.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace Lokad.Cqrs.Scenarios.SimpleES 7 | { 8 | public static class RedirectToWhen 9 | { 10 | static readonly IDictionary _dict = typeof (T) 11 | .GetMethods() 12 | .Where(m => m.Name == "When") 13 | .Where(m => m.GetParameters().Length == 1) 14 | .ToDictionary(m => m.GetParameters().First().ParameterType, m => m); 15 | 16 | public static void Invoke(T instance, object argument) 17 | { 18 | _dict[argument.GetType()].Invoke(instance, new[] {argument}); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/All_synthetic_scenarios.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Build.Engine; 2 | using NUnit.Framework; 3 | 4 | namespace Lokad.Cqrs.Synthetic 5 | { 6 | public abstract class All_synthetic_scenarios 7 | { 8 | protected abstract void CurrentConfig(CqrsEngineBuilder config); 9 | [Test] 10 | public void Transient_failures_are_retried() 11 | { 12 | new Engine_scenario_for_transient_failure() 13 | .TestConfiguration(CurrentConfig); 14 | } 15 | 16 | [Test] 17 | public void Permanent_failure_is_quarantined() 18 | { 19 | new Engine_scenario_for_permanent_failure() 20 | .TestConfiguration(CurrentConfig); 21 | } 22 | 23 | [Test] 24 | public void Command_batches_work_with_transaction() 25 | { 26 | new Engine_scenario_for_transactional_commands() 27 | .TestConfiguration(CurrentConfig); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/Engine_scenario_for_permanent_failure.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Linq; 10 | using System.Runtime.Serialization; 11 | using Lokad.Cqrs.Build.Engine; 12 | using Lokad.Cqrs.Core.Dispatch.Events; 13 | using NUnit.Framework; 14 | 15 | // ReSharper disable InconsistentNaming 16 | 17 | namespace Lokad.Cqrs.Synthetic 18 | { 19 | public sealed class Engine_scenario_for_permanent_failure : FiniteEngineScenario 20 | { 21 | [DataContract] 22 | public sealed class Message : Define.Command {} 23 | 24 | public sealed class Handler : Define.Handle 25 | { 26 | public void Consume(Message message) 27 | { 28 | throw new NotImplementedException("Fail: try"); 29 | } 30 | } 31 | 32 | 33 | protected override void Configure(CqrsEngineBuilder b) 34 | { 35 | HandlerFailuresAreExpected = true; 36 | 37 | Enlist((observable, sender, arg3) => observable 38 | .OfType() 39 | .Subscribe(eq => 40 | { 41 | Assert.AreEqual("Fail: try", eq.LastException.Message); 42 | arg3.Cancel(); 43 | })); 44 | 45 | EnlistMessage(new Message()); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/Engine_scenario_for_transient_failure.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | using Lokad.Cqrs.Build.Engine; 11 | using Lokad.Cqrs.Feature.AtomicStorage; 12 | 13 | namespace Lokad.Cqrs.Synthetic 14 | { 15 | public sealed class Engine_scenario_for_transient_failure : FiniteEngineScenario 16 | { 17 | [DataContract] 18 | public sealed class Message : Define.Command {} 19 | 20 | 21 | public sealed class Handler : Define.Handle 22 | { 23 | readonly NuclearStorage _storage; 24 | readonly IMessageSender _sender; 25 | 26 | public Handler(NuclearStorage storage, IMessageSender sender) 27 | { 28 | _storage = storage; 29 | _sender = sender; 30 | } 31 | 32 | public void Consume(Message message) 33 | { 34 | var count = _storage.AddOrUpdateSingleton(() => 1, i => i + 1); 35 | if (count < 4) 36 | throw new InvalidOperationException("Fail"); 37 | 38 | _sender.SendOne(new Message(), cb => cb.AddString("finish")); 39 | } 40 | } 41 | 42 | protected override void Configure(CqrsEngineBuilder b) 43 | { 44 | HandlerFailuresAreExpected = true; 45 | 46 | EnlistMessage(new Message()); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/Run_all_Synthetic_scenarios_in_memory.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Build.Engine; 2 | using NUnit.Framework; 3 | 4 | namespace Lokad.Cqrs.Synthetic 5 | { 6 | [TestFixture] 7 | public sealed class Run_all_Synthetic_scenarios_in_memory : All_synthetic_scenarios 8 | { 9 | // ReSharper disable InconsistentNaming 10 | 11 | protected override void CurrentConfig(CqrsEngineBuilder config) 12 | { 13 | config.Memory(m => 14 | { 15 | m.AddMemoryProcess("do", x => x.DispatchAsCommandBatch()); 16 | m.AddMemorySender("do", cb => cb.IdGeneratorForTests()); 17 | }); 18 | } 19 | 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/Run_all_synthetic_scenarios_for_files.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Lokad.Cqrs.Build.Engine; 3 | using NUnit.Framework; 4 | 5 | namespace Lokad.Cqrs.Synthetic 6 | { 7 | [TestFixture] 8 | public sealed class Run_all_synthetic_scenarios_for_files : All_synthetic_scenarios 9 | { 10 | protected override void CurrentConfig(CqrsEngineBuilder config) 11 | { 12 | var currentDirectory = Directory.GetCurrentDirectory(); 13 | var bus = Path.Combine(currentDirectory, "test"); 14 | var dir = new DirectoryInfo(bus); 15 | if (dir.Exists) 16 | { 17 | dir.Delete(true); 18 | } 19 | var store = FileStorage.CreateConfig(bus, "file"); 20 | config.File(m => 21 | { 22 | m.AddFileProcess(store,"do", x => x.DispatchAsCommandBatch()); 23 | m.AddFileSender(store, "do", cb => cb.IdGeneratorForTests()); 24 | }); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable.Tests/Synthetic/TransactionTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | 4 | namespace Lokad.Cqrs.Synthetic 5 | { 6 | public sealed class TransactionTester : IEnlistmentNotification 7 | { 8 | public Action OnCommit = () => { }; 9 | public Action OnRollback = () => { }; 10 | 11 | 12 | public TransactionTester() 13 | { 14 | Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None); 15 | } 16 | 17 | public void Prepare(PreparingEnlistment preparingEnlistment) 18 | { 19 | preparingEnlistment.Prepared(); 20 | } 21 | 22 | public void Commit(Enlistment enlistment) 23 | { 24 | OnCommit(); 25 | enlistment.Done(); 26 | } 27 | 28 | public void Rollback(Enlistment enlistment) 29 | { 30 | OnRollback(); 31 | enlistment.Done(); 32 | } 33 | 34 | public void InDoubt(Enlistment enlistment) 35 | { 36 | enlistment.Done(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Client/CqrsClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | 4 | namespace Lokad.Cqrs.Build.Client 5 | { 6 | public sealed class CqrsClient : IDisposable 7 | { 8 | public ILifetimeScope Scope { get; private set; } 9 | 10 | public CqrsClient(ILifetimeScope scope) 11 | { 12 | Scope = scope; 13 | } 14 | 15 | public IMessageSender Sender 16 | { 17 | get 18 | { 19 | IMessageSender sender; 20 | if(Scope.TryResolve(out sender)) 21 | { 22 | return sender; 23 | } 24 | var message = string.Format("Failed to discover default {0}, have you added it to the system?", typeof(IMessageSender).Name); 25 | throw new InvalidOperationException(message); 26 | } 27 | } 28 | 29 | public TService Resolve() 30 | { 31 | return Scope.Resolve(); 32 | } 33 | 34 | public void Dispose() 35 | { 36 | Scope.Dispose(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Client/FileClientModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.IO; 4 | using Autofac; 5 | using Autofac.Core; 6 | using Lokad.Cqrs.Core.Outbox; 7 | using Lokad.Cqrs.Feature.FilePartition; 8 | 9 | namespace Lokad.Cqrs.Build.Engine 10 | { 11 | public sealed class FileClientModule : HideObjectMembersFromIntelliSense, IModule 12 | { 13 | Action _modules = context => { }; 14 | 15 | 16 | 17 | 18 | public void AddFileSender(FileStorageConfig config, string queueName, Action configure) 19 | { 20 | var module = new SendMessageModule((context, endpoint) => new FileQueueWriterFactory(config, context.Resolve()), config.AccountName, queueName); 21 | configure(module); 22 | _modules += module.Configure; 23 | } 24 | 25 | 26 | 27 | public void AddFileSender(FileStorageConfig config, string queueName) 28 | { 29 | AddFileSender(config, queueName, m => { }); 30 | } 31 | 32 | [EditorBrowsable(EditorBrowsableState.Never)] 33 | public void Configure(IComponentRegistry container) 34 | { 35 | _modules(container); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Engine/Events/EngineInitializationStarted.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Build.Engine.Events 9 | { 10 | public sealed class EngineInitializationStarted : ISystemEvent 11 | { 12 | public override string ToString() 13 | { 14 | return "Engine initializing"; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Engine/Events/EngineInitialized.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Build.Engine.Events 9 | { 10 | public sealed class EngineInitialized : ISystemEvent 11 | { 12 | public override string ToString() 13 | { 14 | return "Engine initialized"; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Engine/Events/EngineStarted.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Build.Engine.Events 9 | { 10 | public sealed class EngineStarted : ISystemEvent 11 | { 12 | public readonly string[] EngineProcesses; 13 | 14 | public EngineStarted(string[] engineProcesses) 15 | { 16 | EngineProcesses = engineProcesses; 17 | } 18 | 19 | public override string ToString() 20 | { 21 | return string.Format("Engine started: {0}", string.Join(",", EngineProcesses)); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Engine/Events/EngineStopped.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Build.Engine.Events 11 | { 12 | public sealed class EngineStopped : ISystemEvent 13 | { 14 | 15 | public TimeSpan Elapsed { get; private set; } 16 | 17 | public EngineStopped(TimeSpan elapsed) 18 | { 19 | Elapsed = elapsed; 20 | } 21 | 22 | public override string ToString() 23 | { 24 | return string.Format("Engine Stopped after {0} mins", Math.Round(Elapsed.TotalMinutes, 2)); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Build/Engine/IAdvancedEngineBuilder.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Generic; 10 | using Autofac; 11 | using Autofac.Core; 12 | using Lokad.Cqrs.Core.Outbox; 13 | 14 | namespace Lokad.Cqrs.Build.Engine 15 | { 16 | public interface IAdvancedEngineBuilder : IHideObjectMembersFromIntelliSense 17 | { 18 | void RegisterQueueWriterFactory(Func activator); 19 | void RegisterModule(IModule module); 20 | void ConfigureContainer(Action build); 21 | void RegisterObserver(IObserver observer); 22 | IList> Observers { get; } 23 | void CustomEnvelopeSerializer(IEnvelopeSerializer serializer); 24 | void CustomDataSerializer(Func serializer); 25 | } 26 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/ActionDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Core.Dispatch 4 | { 5 | public sealed class ActionDispatcher : ISingleThreadMessageDispatcher 6 | { 7 | readonly Action _dispatcher; 8 | public ActionDispatcher(Action dispatcher) 9 | { 10 | _dispatcher = dispatcher; 11 | } 12 | 13 | public void DispatchMessage(ImmutableEnvelope message) 14 | { 15 | _dispatcher(message); 16 | } 17 | 18 | public void Init() 19 | { 20 | 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/DispatchRecoveryFailed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Core.Dispatch.Events 4 | { 5 | public sealed class DispatchRecoveryFailed : ISystemEvent 6 | { 7 | public Exception DispatchException { get; private set; } 8 | public ImmutableEnvelope Envelope { get; private set; } 9 | public string QueueName { get; private set; } 10 | 11 | public DispatchRecoveryFailed(Exception exception, ImmutableEnvelope envelope, string queueName) 12 | { 13 | DispatchException = exception; 14 | Envelope = envelope; 15 | QueueName = queueName; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EnvelopeAckFailed.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Dispatch.Events 11 | { 12 | public sealed class EnvelopeAckFailed : ISystemEvent 13 | { 14 | public Exception Exception { get; private set; } 15 | public string EnvelopeId { get; private set; } 16 | public string QueueName { get; private set; } 17 | 18 | public EnvelopeAckFailed(Exception exception, string envelopeId, string queueName) 19 | { 20 | Exception = exception; 21 | EnvelopeId = envelopeId; 22 | QueueName = queueName; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return string.Format("Failed to ack '{0}' from '{1}': {2}", EnvelopeId, QueueName, Exception.Message); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EnvelopeAcked.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Lokad.Cqrs.Core.Dispatch.Events 5 | { 6 | public sealed class EnvelopeAcked : ISystemEvent 7 | { 8 | public string QueueName { get; private set; } 9 | public string EnvelopeId { get; private set; } 10 | public ICollection Attributes { get; private set; } 11 | 12 | public EnvelopeAcked(string queueName, string envelopeId, ICollection attributes) 13 | { 14 | QueueName = queueName; 15 | EnvelopeId = envelopeId; 16 | Attributes = attributes; 17 | } 18 | 19 | public override string ToString() 20 | { 21 | return string.Format("[{0}] acked at '{1}'", EnvelopeId, QueueName); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EnvelopeDispatchFailed.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Dispatch.Events 11 | { 12 | public sealed class EnvelopeDispatchFailed : ISystemEvent 13 | { 14 | public Exception Exception { get; private set; } 15 | public ImmutableEnvelope Envelope { get; private set; } 16 | public string QueueName { get; private set; } 17 | 18 | public EnvelopeDispatchFailed(ImmutableEnvelope envelope, string queueName, Exception exception) 19 | { 20 | Exception = exception; 21 | Envelope = envelope; 22 | QueueName = queueName; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return string.Format("Failed to consume {0} from '{1}': {2}", Envelope.EnvelopeId, QueueName, 28 | Exception.Message); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EnvelopeDuplicateDiscarded.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Core.Dispatch.Events 2 | { 3 | public sealed class EnvelopeDuplicateDiscarded : ISystemEvent 4 | { 5 | public string QueueName { get; private set; } 6 | public string EnvelopeId { get; private set; } 7 | 8 | public EnvelopeDuplicateDiscarded(string queueName, string envelopeId) 9 | { 10 | QueueName = queueName; 11 | EnvelopeId = envelopeId; 12 | } 13 | 14 | public override string ToString() 15 | { 16 | return string.Format("[{0}] duplicate discarded '{1}'", EnvelopeId, QueueName); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EnvelopeQuarantined.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Core.Dispatch.Events 4 | { 5 | public sealed class EnvelopeQuarantined : ISystemEvent 6 | { 7 | public Exception LastException { get; private set; } 8 | public ImmutableEnvelope Envelope { get; private set; } 9 | public string QueueName { get; private set; } 10 | 11 | public EnvelopeQuarantined(Exception lastException, ImmutableEnvelope envelope, string queueName) 12 | { 13 | LastException = lastException; 14 | Envelope = envelope; 15 | QueueName = queueName; 16 | } 17 | 18 | public override string ToString() 19 | { 20 | return string.Format("Quarantined '{0}' of '{1}'", Envelope.EnvelopeId, QueueName); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/Events/EventHadNoConsumers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Core.Dispatch.Events 4 | { 5 | public sealed class EventHadNoConsumers : ISystemEvent 6 | { 7 | public string EnvelopeId { get; private set; } 8 | public Type EventItemType { get; private set; } 9 | 10 | public EventHadNoConsumers(string envelopeId, Type eventItemType) 11 | { 12 | EnvelopeId = envelopeId; 13 | EventItemType = eventItemType; 14 | } 15 | 16 | public override string ToString() 17 | { 18 | return string.Format("Event '{0}' had no consumers {1}", EnvelopeId, EventItemType); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/ISingleThreadMessageDispatcher.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Dispatch 9 | { 10 | /// 11 | /// Generic message dispatch interface 12 | /// 13 | public interface ISingleThreadMessageDispatcher 14 | { 15 | /// 16 | /// Dispatches the message. 17 | /// 18 | /// The message. 19 | void DispatchMessage(ImmutableEnvelope message); 20 | /// 21 | /// Initializes this instance 22 | /// 23 | void Init(); 24 | } 25 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/MemoryQuarantine.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using Lokad.Cqrs.Core.Inbox; 4 | 5 | namespace Lokad.Cqrs.Core.Dispatch 6 | { 7 | public sealed class MemoryQuarantine : IEnvelopeQuarantine 8 | { 9 | readonly ConcurrentDictionary _failures = new ConcurrentDictionary(); 10 | 11 | public bool TryToQuarantine(EnvelopeTransportContext context, Exception ex) 12 | { 13 | var current = _failures.AddOrUpdate(context.Unpacked.EnvelopeId, s => 1, (s1, i) => i + 1); 14 | if (current < 4) 15 | { 16 | return false; 17 | } 18 | // accept and forget 19 | int forget; 20 | _failures.TryRemove(context.Unpacked.EnvelopeId, out forget); 21 | return true; 22 | } 23 | 24 | public void TryRelease(EnvelopeTransportContext context) 25 | { 26 | int value; 27 | _failures.TryRemove(context.Unpacked.EnvelopeId, out value); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/MessageDuplicationManager.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | 13 | namespace Lokad.Cqrs.Core.Dispatch 14 | { 15 | /// 16 | /// Shoud be registered as singleton, manages actual memories 17 | /// and performs cleanups in async 18 | /// 19 | public sealed class MessageDuplicationManager : IEngineProcess 20 | { 21 | readonly ConcurrentDictionary _memories = 22 | new ConcurrentDictionary(); 23 | 24 | public void Dispose() 25 | { 26 | } 27 | 28 | public void Initialize() 29 | { 30 | } 31 | 32 | public MessageDuplicationMemory GetOrAdd(DispatcherProcess dispatcher) 33 | { 34 | return _memories.GetOrAdd(dispatcher, s => new MessageDuplicationMemory()); 35 | } 36 | 37 | public Task Start(CancellationToken token) 38 | { 39 | return Task.Factory.StartNew(() => 40 | { 41 | while (!token.IsCancellationRequested) 42 | { 43 | foreach (var memory in _memories) 44 | { 45 | memory.Value.ForgetOlderThan(TimeSpan.FromMinutes(20)); 46 | } 47 | 48 | token.WaitHandle.WaitOne(TimeSpan.FromMinutes(5)); 49 | } 50 | }, token); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Dispatch/MessageDuplicationMemory.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Linq; 11 | 12 | namespace Lokad.Cqrs.Core.Dispatch 13 | { 14 | public sealed class MessageDuplicationMemory 15 | { 16 | readonly ConcurrentDictionary _memory = new ConcurrentDictionary(); 17 | 18 | public void Memorize(string memoryId) 19 | { 20 | _memory.TryAdd(memoryId, DateTime.UtcNow); 21 | } 22 | 23 | public bool DoWeRemember(string memoryId) 24 | { 25 | DateTime value; 26 | return _memory.TryGetValue(memoryId, out value); 27 | } 28 | 29 | public void ForgetOlderThan(TimeSpan older) 30 | { 31 | // suboptimal for now 32 | var deleteBefore = DateTime.UtcNow - older; 33 | var keys = _memory.ToArray() 34 | .Where(p => p.Value < deleteBefore) 35 | .Select(v => v.Key); 36 | 37 | foreach (var key in keys) 38 | { 39 | DateTime deleted; 40 | _memory.TryRemove(key, out deleted); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/EnvelopeAttributeContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [DataContract(Namespace = "Lokad.Cqrs.v2", Name = "EnvelopeAttribute"), Serializable] 14 | public sealed class EnvelopeAttributeContract 15 | { 16 | [DataMember(Order = 1)] 17 | public EnvelopeAttributeTypeContract Type { get; set; } 18 | 19 | [DataMember(Order = 2)] 20 | public string Name { get; set; } 21 | 22 | [DataMember(Order = 3)] 23 | public string Value { get; set; } 24 | } 25 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/EnvelopeAttributeTypeContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Envelope 9 | { 10 | public enum EnvelopeAttributeTypeContract 11 | { 12 | Undefined = 0, 13 | Sender = 2, 14 | CustomString = 4, 15 | } 16 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/EnvelopeContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [DataContract(Namespace = "Lokad.Cqrs.v2", Name = "Envelope"), Serializable] 14 | public sealed class EnvelopeContract 15 | { 16 | [DataMember(Order = 1)] public readonly string EnvelopeId; 17 | [DataMember(Order = 2)] public readonly EnvelopeAttributeContract[] EnvelopeAttributes; 18 | [DataMember(Order = 3)] public readonly MessageContract[] Messages; 19 | [DataMember(Order = 4)] public readonly DateTime DeliverOnUtc; 20 | [DataMember(Order = 5)] public readonly DateTime CreatedOnUtc; 21 | 22 | public EnvelopeContract(string envelopeId, EnvelopeAttributeContract[] envelopeAttributes, MessageContract[] messages, 23 | DateTime deliverOnUtc, DateTime createdOnUtc) 24 | { 25 | EnvelopeId = envelopeId; 26 | DeliverOnUtc = deliverOnUtc; 27 | EnvelopeAttributes = envelopeAttributes; 28 | Messages = messages; 29 | CreatedOnUtc = createdOnUtc; 30 | } 31 | 32 | // ReSharper disable UnusedMember.Local 33 | EnvelopeContract() 34 | // ReSharper restore UnusedMember.Local 35 | { 36 | Messages = NoMessages; 37 | EnvelopeAttributes = NoAttributes; 38 | } 39 | 40 | static readonly MessageContract[] NoMessages = new MessageContract[0]; 41 | static readonly EnvelopeAttributeContract[] NoAttributes = new EnvelopeAttributeContract[0]; 42 | } 43 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/EnvelopeHeaderContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.IO; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | public sealed class EnvelopeHeaderContract 14 | { 15 | public const int FixedSize = 20; 16 | 17 | public const int Schema2DataFormat = 2011021801; 18 | 19 | public readonly int MessageFormatVersion; 20 | public readonly long EnvelopeBytes; 21 | public readonly long CheckSum; 22 | 23 | public EnvelopeHeaderContract(int messageFormatVersion, long envelopeBytes, long checksum) 24 | { 25 | MessageFormatVersion = messageFormatVersion; 26 | EnvelopeBytes = envelopeBytes; 27 | CheckSum = checksum; 28 | } 29 | 30 | public static EnvelopeHeaderContract ReadHeader(byte[] buffer) 31 | { 32 | var magic = BitConverter.ToInt32(buffer, 0); 33 | var envelopeBytes = BitConverter.ToInt64(buffer, 4); 34 | var checkSum = BitConverter.ToInt64(buffer, 4 + 8); 35 | 36 | return new EnvelopeHeaderContract(magic, envelopeBytes, checkSum); 37 | } 38 | 39 | public void WriteToStream(MemoryStream stream) 40 | { 41 | stream.Write(BitConverter.GetBytes(MessageFormatVersion), 0, 4); 42 | stream.Write(BitConverter.GetBytes(EnvelopeBytes), 0, 8); 43 | stream.Write(BitConverter.GetBytes(CheckSum), 0, 8); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/EnvelopeSerializerWithDataContracts.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | using System.Runtime.Serialization; 10 | using System.Xml; 11 | 12 | namespace Lokad.Cqrs.Core.Envelope 13 | { 14 | public sealed class EnvelopeSerializerWithDataContracts : IEnvelopeSerializer 15 | { 16 | readonly DataContractSerializer _serializer; 17 | 18 | public EnvelopeSerializerWithDataContracts() 19 | { 20 | _serializer = new DataContractSerializer(typeof (EnvelopeContract)); 21 | } 22 | 23 | public void SerializeEnvelope(Stream stream, EnvelopeContract contract) 24 | { 25 | //using (var compressed = destination.Compress(true)) 26 | using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream, null, null, false)) 27 | { 28 | _serializer.WriteObject(writer, contract); 29 | } 30 | } 31 | 32 | public EnvelopeContract DeserializeEnvelope(Stream stream) 33 | { 34 | using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max)) 35 | { 36 | return (EnvelopeContract) _serializer.ReadObject(reader); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/MessageAttributeContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [DataContract(Namespace = "Lokad.Cqrs.v2", Name = "MessageAttribute"), Serializable] 14 | public sealed class MessageAttributeContract 15 | { 16 | [DataMember(Order = 2)] 17 | public string Name { get; set; } 18 | 19 | [DataMember(Order = 3)] 20 | public string Value { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/MessageAttributes.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Envelope 9 | { 10 | public static class MessageAttributes 11 | { 12 | public const string EnvelopeSender = "Sender"; 13 | } 14 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/MessageBuilder.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Generic; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | public sealed class MessageBuilder : HideObjectMembersFromIntelliSense 14 | { 15 | internal readonly IDictionary Attributes = new Dictionary(); 16 | public readonly Type MappedType; 17 | public readonly object Content; 18 | 19 | public MessageBuilder(Type mappedType, object content) 20 | { 21 | MappedType = mappedType; 22 | Content = content; 23 | } 24 | 25 | public void AddAttribute(string key, string value) 26 | { 27 | Attributes.Add(key, value); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Envelope/MessageContract.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Core.Envelope 12 | { 13 | [DataContract(Namespace = "Lokad.Cqrs.v2", Name = "Message"), Serializable] 14 | public sealed class MessageContract 15 | { 16 | [DataMember(Order = 1)] public readonly string ContractName; 17 | [DataMember(Order = 2)] public readonly long ContentSize; 18 | [DataMember(Order = 3)] public readonly long ContentPosition; 19 | [DataMember(Order = 4)] public readonly MessageAttributeContract[] Attributes; 20 | 21 | MessageContract() 22 | { 23 | Attributes = Empty; 24 | } 25 | 26 | public MessageContract(string contractName, long contentSize, long contentPosition, MessageAttributeContract[] attributes) 27 | { 28 | ContractName = contractName; 29 | ContentSize = contentSize; 30 | ContentPosition = contentPosition; 31 | Attributes = attributes; 32 | } 33 | 34 | static readonly MessageAttributeContract[] Empty = new MessageAttributeContract[0]; 35 | } 36 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/EnvelopeTransportContext.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Inbox 9 | { 10 | public sealed class EnvelopeTransportContext 11 | { 12 | public readonly object TransportMessage; 13 | public readonly ImmutableEnvelope Unpacked; 14 | public readonly string QueueName; 15 | 16 | public EnvelopeTransportContext(object transportMessage, ImmutableEnvelope unpacked, string queueName) 17 | { 18 | TransportMessage = transportMessage; 19 | QueueName = queueName; 20 | Unpacked = unpacked; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/Events/EnvelopeDeserializationFailed.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Inbox.Events 11 | { 12 | /// 13 | /// Raised when something goes wrong with the envelope deserialization (i.e.: unknown format or contract) 14 | /// 15 | public sealed class EnvelopeDeserializationFailed : ISystemEvent 16 | { 17 | public Exception Exception { get; private set; } 18 | public string QueueName { get; private set; } 19 | public string MessageId { get; private set; } 20 | 21 | public EnvelopeDeserializationFailed(Exception exception, string queueName, string messageId) 22 | { 23 | Exception = exception; 24 | QueueName = queueName; 25 | MessageId = messageId; 26 | } 27 | 28 | public override string ToString() 29 | { 30 | return string.Format("Failed to deserialize '{0}' from '{1}': {2}", MessageId, QueueName, Exception.Message); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/Events/FailedToAccessStorage.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Inbox.Events 11 | { 12 | public sealed class FailedToAccessStorage : ISystemEvent 13 | { 14 | public Exception Exception { get; private set; } 15 | public string QueueName { get; private set; } 16 | public string MessageId { get; private set; } 17 | 18 | public FailedToAccessStorage(Exception exception, string queueName, string messageId) 19 | { 20 | Exception = exception; 21 | QueueName = queueName; 22 | MessageId = messageId; 23 | } 24 | public override string ToString() 25 | { 26 | return string.Format("Failed to read '{0}' from '{1}': {2}", MessageId, QueueName, Exception.Message); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/Events/FailedToReadMessage.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Inbox.Events 11 | { 12 | public sealed class FailedToReadMessage : ISystemEvent 13 | { 14 | public Exception Exception { get; private set; } 15 | public string QueueName { get; private set; } 16 | 17 | public FailedToReadMessage(Exception exception, string queueName) 18 | { 19 | Exception = exception; 20 | QueueName = queueName; 21 | } 22 | 23 | public override string ToString() 24 | { 25 | return string.Format("Failed to read from '{0}': {1}", QueueName, Exception.Message); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/GetEnvelopeResult.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Inbox 11 | { 12 | public sealed class GetEnvelopeResult 13 | { 14 | public static readonly GetEnvelopeResult Empty = new GetEnvelopeResult(null, GetEnvelopeResultState.Empty); 15 | public static readonly GetEnvelopeResult Retry = new GetEnvelopeResult(null, GetEnvelopeResultState.Retry); 16 | public readonly GetEnvelopeResultState State; 17 | readonly EnvelopeTransportContext _envelope; 18 | 19 | GetEnvelopeResult(EnvelopeTransportContext envelope, GetEnvelopeResultState state) 20 | { 21 | _envelope = envelope; 22 | State = state; 23 | } 24 | 25 | 26 | public EnvelopeTransportContext Envelope 27 | { 28 | get 29 | { 30 | if (State != GetEnvelopeResultState.Success) 31 | throw new InvalidOperationException("State should be in success"); 32 | return _envelope; 33 | } 34 | } 35 | 36 | public static GetEnvelopeResult Success(EnvelopeTransportContext envelope) 37 | { 38 | return new GetEnvelopeResult(envelope, GetEnvelopeResultState.Success); 39 | } 40 | 41 | public static GetEnvelopeResult Error() 42 | { 43 | return new GetEnvelopeResult(null, GetEnvelopeResultState.Exception); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/GetEnvelopeResultState.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Inbox 9 | { 10 | public enum GetEnvelopeResultState 11 | { 12 | Success, 13 | Empty, 14 | Exception, 15 | Retry 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Inbox/IPartitionInbox.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Threading; 9 | 10 | namespace Lokad.Cqrs.Core.Inbox 11 | { 12 | public interface IPartitionInbox 13 | { 14 | void Init(); 15 | void AckMessage(EnvelopeTransportContext envelope); 16 | bool TakeMessage(CancellationToken token, out EnvelopeTransportContext context); 17 | void TryNotifyNack(EnvelopeTransportContext context); 18 | } 19 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Outbox/CommitActionEnlistment.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Transactions; 10 | 11 | namespace Lokad.Cqrs.Core.Outbox 12 | { 13 | sealed class CommitActionEnlistment : IEnlistmentNotification 14 | { 15 | readonly Action _commit; 16 | 17 | public CommitActionEnlistment(Action commit) 18 | { 19 | _commit = commit; 20 | } 21 | 22 | public void Prepare(PreparingEnlistment preparingEnlistment) 23 | { 24 | preparingEnlistment.Prepared(); 25 | } 26 | 27 | public void Commit(Enlistment enlistment) 28 | { 29 | _commit(); 30 | enlistment.Done(); 31 | } 32 | 33 | public void Rollback(Enlistment enlistment) 34 | { 35 | enlistment.Done(); 36 | } 37 | 38 | public void InDoubt(Enlistment enlistment) 39 | { 40 | enlistment.Done(); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Outbox/EnvelopeSent.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Outbox 9 | { 10 | public sealed class EnvelopeSent : ISystemEvent 11 | { 12 | public readonly string QueueName; 13 | public readonly string EnvelopeId; 14 | public readonly bool Transactional; 15 | public readonly string[] MappedTypes; 16 | 17 | public EnvelopeSent(string queueName, string envelopeId, bool transactional, string[] mappedTypes) 18 | { 19 | QueueName = queueName; 20 | EnvelopeId = envelopeId; 21 | Transactional = transactional; 22 | MappedTypes = mappedTypes; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | return string.Format("Sent {0}{1} to '{2}' as [{3}]", 28 | string.Join("+", MappedTypes), 29 | Transactional ? " +tx" : "", 30 | QueueName, 31 | EnvelopeId); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Outbox/IQueueWriter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Outbox 9 | { 10 | public interface IQueueWriter 11 | { 12 | string Name { get; } 13 | void PutMessage(ImmutableEnvelope envelope); 14 | } 15 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Outbox/IQueueWriterFactory.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Core.Outbox 9 | { 10 | public interface IQueueWriterFactory 11 | { 12 | string Endpoint { get; } 13 | IQueueWriter GetWriteQueue(string queueName); 14 | } 15 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Outbox/QueueWriterRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Diagnostics; 4 | 5 | namespace Lokad.Cqrs.Core.Outbox 6 | { 7 | public sealed class QueueWriterRegistry 8 | { 9 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] 10 | readonly ConcurrentDictionary _dictionary = new ConcurrentDictionary(); 11 | public void Add(IQueueWriterFactory factory) 12 | { 13 | if (!_dictionary.TryAdd(factory.Endpoint, factory)) 14 | { 15 | var message = string.Format("Failed to add {0}.{1}", factory.GetType().Name, factory.Endpoint); 16 | throw new InvalidOperationException(message); 17 | } 18 | } 19 | 20 | 21 | public IQueueWriterFactory GetOrAdd(string endpoint, Func factory) 22 | { 23 | return _dictionary.GetOrAdd(endpoint, factory); 24 | } 25 | 26 | public bool TryGet(string endpoint, out IQueueWriterFactory factory) 27 | { 28 | return _dictionary.TryGetValue(endpoint, out factory); 29 | } 30 | 31 | public override string ToString() 32 | { 33 | return string.Format("{0}[{1}], x{2:X8}", this.GetType().Name, _dictionary.Count, GetHashCode()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Reactive/ImmediateConsoleObserver.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Diagnostics; 10 | 11 | namespace Lokad.Cqrs.Core.Reactive 12 | { 13 | public sealed class ImmediateConsoleObserver : IObserver 14 | { 15 | readonly Stopwatch _watch = Stopwatch.StartNew(); 16 | 17 | public void OnNext(ISystemEvent value) 18 | { 19 | Console.WriteLine("[{0:0000000}]: {1}", _watch.ElapsedMilliseconds, value); 20 | } 21 | 22 | public void OnError(Exception error) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | 27 | public void OnCompleted() 28 | { 29 | Console.WriteLine("Completed"); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Reactive/ImmediateEventsObserver.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Reactive 11 | { 12 | public sealed class ImmediateEventsObserver : IObserver 13 | { 14 | public event Action Event = @event => { }; 15 | 16 | public void OnNext(ISystemEvent value) 17 | { 18 | Event(value); 19 | } 20 | 21 | public void OnError(Exception error) 22 | { 23 | //throw new NotImplementedException(); 24 | } 25 | 26 | public void OnCompleted() 27 | { 28 | Event = @event => { }; 29 | //throw new NotImplementedException(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Reactive/ImmediateTracingObserver.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Diagnostics; 10 | 11 | namespace Lokad.Cqrs.Core.Reactive 12 | { 13 | public sealed class ImmediateTracingObserver : IObserver, ISystemObserver 14 | { 15 | readonly DateTime _started = DateTime.UtcNow; 16 | 17 | public void OnNext(ISystemEvent value) 18 | { 19 | var diff = (DateTime.UtcNow - _started).TotalMilliseconds; 20 | Trace.WriteLine(string.Format("[{0:########}] {1}", diff, value)); 21 | Trace.Flush(); 22 | } 23 | 24 | public void OnError(Exception error) 25 | { 26 | Trace.WriteLine("!" + error.Message); 27 | } 28 | 29 | public void OnCompleted() 30 | { 31 | Trace.WriteLine("Observing completed"); 32 | } 33 | 34 | public void Notify(ISystemEvent @event) 35 | { 36 | OnNext(@event); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Reactive/SystemObserver.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Core.Reactive 11 | { 12 | public sealed class SystemObserver : ISystemObserver, IDisposable 13 | { 14 | readonly IObserver[] _observers; 15 | 16 | public SystemObserver(IObserver[] observers) 17 | { 18 | _observers = observers; 19 | } 20 | 21 | public void Notify(ISystemEvent @event) 22 | { 23 | foreach (var observer in _observers) 24 | { 25 | observer.OnNext(@event); 26 | } 27 | } 28 | 29 | public void Dispose() 30 | { 31 | foreach (var observer in _observers) 32 | { 33 | observer.OnCompleted(); 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core.Serialization/SerializationContractRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Lokad.Cqrs.Core.Serialization 5 | { 6 | public sealed class SerializationContractRegistry 7 | { 8 | readonly List _types = new List(); 9 | bool _readonly; 10 | readonly object _lock = new object(); 11 | public Type[] GetAndMakeReadOnly() 12 | { 13 | lock(_lock) 14 | { 15 | _readonly = true; 16 | } 17 | 18 | return _types.ToArray(); 19 | } 20 | 21 | public void AddRange(IEnumerable types) 22 | { 23 | lock(_lock) 24 | { 25 | if (_readonly) 26 | throw new InvalidOperationException("registry has already been read from. Make sure all regs are done before reading."); 27 | } 28 | _types.AddRange(types); 29 | 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Core/FunqContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Autofac.Core; 4 | 5 | namespace Lokad.Cqrs.Core 6 | { 7 | public static class FunqContainer 8 | { 9 | public static void Register(this IComponentRegistry registry, Func reg) 10 | { 11 | var builder = new ContainerBuilder(); 12 | builder.Register(reg).SingleInstance(); 13 | builder.Update(registry); 14 | } 15 | 16 | public static void Register(this IComponentRegistry registry, T instance) 17 | where T : class 18 | { 19 | var builder = new ContainerBuilder(); 20 | builder.RegisterInstance(instance); 21 | builder.Update(registry); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Define.cs: -------------------------------------------------------------------------------- 1 | using Lokad.Cqrs.Build.Client; 2 | using Lokad.Cqrs.Build.Engine; 3 | using Lokad.Cqrs.Feature.DirectoryDispatch.Default; 4 | 5 | namespace Lokad.Cqrs 6 | { 7 | /// 8 | /// Default implementations of the domain-specific interfaces 9 | /// 10 | public static class Define 11 | { 12 | public interface Event : IMessage 13 | { 14 | 15 | } 16 | public interface Command : IMessage 17 | { 18 | 19 | } 20 | 21 | public interface Subscribe : IConsume where TEvent : Event 22 | { 23 | 24 | } 25 | 26 | public interface Handle : IConsume where TCommand : Command 27 | { 28 | 29 | } 30 | 31 | public interface AtomicEntity 32 | { 33 | 34 | } 35 | public interface AtomicSingleton 36 | { 37 | 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/EnvelopeReference.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs 9 | { 10 | public sealed class EnvelopeReference 11 | { 12 | public readonly string EnvelopeId; 13 | public readonly string StorageReference; 14 | public readonly string StorageContainer; 15 | 16 | public EnvelopeReference(string envelopeId, string storageContainer, string storageReference) 17 | { 18 | EnvelopeId = envelopeId; 19 | StorageReference = storageReference; 20 | StorageContainer = storageContainer; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Evil/AssemblyScanEvil.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Reflection; 10 | 11 | namespace Lokad.Cqrs.Evil 12 | { 13 | /// 14 | /// One of these evil utility classes to filter out quickly some common non-user assemblies (this speeds assembly scans) 15 | /// 16 | public static class AssemblyScanEvil 17 | { 18 | /// 19 | /// Determines whether the specified assembly is user assembly. 20 | /// 21 | /// The assembly. 22 | /// 23 | /// true if specified assembly is probably a user assembly; otherwise, false. 24 | /// 25 | public static bool IsProbablyUserAssembly(Assembly assembly) 26 | { 27 | if (String.IsNullOrEmpty(assembly.FullName)) 28 | return false; 29 | 30 | if (assembly.IsDynamic) 31 | return false; 32 | 33 | var prefixes = new[] 34 | { 35 | "System", "Microsoft", "nunit", "JetBrains", "Autofac", "mscorlib", "ProtoBuf" 36 | }; 37 | 38 | foreach (var prefix in prefixes) 39 | { 40 | if (assembly.FullName.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase)) 41 | return false; 42 | } 43 | 44 | return true; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Evil/DecayEvil.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Evil 11 | { 12 | /// 13 | /// Helper to build decay functions 14 | /// 15 | public static class DecayEvil 16 | { 17 | /// 18 | /// Builds the exponential decay function that grows to as the argument grows 19 | /// 20 | /// The max interval. 21 | /// constructed function 22 | public static Func BuildExponentialDecay(TimeSpan maxInterval) 23 | { 24 | var seconds = maxInterval.TotalSeconds; 25 | return l => 26 | { 27 | if (l >= 31) 28 | { 29 | return maxInterval; 30 | } 31 | 32 | if (l == 0) 33 | { 34 | l += 1; 35 | } 36 | 37 | var foo = Math.Pow(2, (l - 1) / 5.0) / 64d * seconds; 38 | 39 | return TimeSpan.FromSeconds(foo); 40 | }; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Evil/InvocationUtil.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Reflection; 10 | 11 | namespace Lokad.Cqrs.Evil 12 | { 13 | /// 14 | /// Helper class for generating exceptions 15 | /// 16 | public static class InvocationUtil 17 | { 18 | static readonly MethodInfo InternalPreserveStackTraceMethod; 19 | 20 | static InvocationUtil() 21 | { 22 | InternalPreserveStackTraceMethod = typeof (Exception).GetMethod("InternalPreserveStackTrace", 23 | BindingFlags.Instance | BindingFlags.NonPublic); 24 | } 25 | 26 | /// 27 | /// Returns inner exception, while preserving the stack trace 28 | /// 29 | /// The target invocation exception to unwrap. 30 | /// inner exception 31 | public static Exception Inner(TargetInvocationException e) 32 | { 33 | if (e == null) throw new ArgumentNullException("e"); 34 | InternalPreserveStackTraceMethod.Invoke(e.InnerException, new object[0]); 35 | return e.InnerException; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/AddOrUpdateHint.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Feature.AtomicStorage 2 | { 3 | public enum AddOrUpdateHint 4 | { 5 | ProbablyExists, 6 | ProbablyDoesNotExist 7 | } 8 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/AtomicStorageInitialization.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | using System.Linq; 13 | 14 | namespace Lokad.Cqrs.Feature.AtomicStorage 15 | { 16 | public sealed class AtomicStorageInitialization : IEngineProcess 17 | { 18 | readonly IEnumerable _storage; 19 | readonly ISystemObserver _observer; 20 | 21 | public AtomicStorageInitialization(IEnumerable storage, ISystemObserver observer) 22 | { 23 | _storage = storage; 24 | _observer = observer; 25 | } 26 | 27 | public void Dispose() {} 28 | 29 | public void Initialize() 30 | { 31 | foreach (var atomicStorageFactory in _storage) 32 | { 33 | var folders = atomicStorageFactory.Initialize(); 34 | if (folders.Any()) 35 | { 36 | _observer.Notify(new AtomicStorageInitialized(folders.ToArray(), atomicStorageFactory.GetType())); 37 | } 38 | } 39 | } 40 | 41 | public Task Start(CancellationToken token) 42 | { 43 | // don't do anything 44 | return new Task(() => { }); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/AtomicStorageInitialized.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Feature.AtomicStorage 11 | { 12 | public sealed class AtomicStorageInitialized : ISystemEvent 13 | { 14 | public readonly string[] CreatedFolders; 15 | public readonly Type Storage; 16 | 17 | public AtomicStorageInitialized(string[] createdFolders, Type storage) 18 | { 19 | CreatedFolders = createdFolders; 20 | Storage = storage; 21 | } 22 | 23 | public override string ToString() 24 | { 25 | return string.Format("{1} created: {0}", string.Join(", ", CreatedFolders), Storage.Name); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/AtomicStorageSerializerWithDataContracts.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Lokad.Cqrs.Feature.AtomicStorage 5 | { 6 | public sealed class AtomicStorageSerializerWithDataContracts : IAtomicStorageSerializer 7 | { 8 | static class Cache 9 | { 10 | public static readonly DataContractSerializer Serializer = new DataContractSerializer(typeof(T)); 11 | } 12 | 13 | public void Serialize(TView view, Stream stream) 14 | { 15 | Cache.Serializer.WriteObject(stream, view); 16 | } 17 | 18 | public TView Deserialize(Stream stream) 19 | { 20 | return (TView) Cache.Serializer.ReadObject(stream); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/AtomicStorageSerializerWithDelegates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Lokad.Cqrs.Feature.AtomicStorage 5 | { 6 | public sealed class AtomicStorageSerializerWithDelegates : IAtomicStorageSerializer 7 | { 8 | readonly Action _serializer; 9 | readonly Func _deserializer; 10 | 11 | public AtomicStorageSerializerWithDelegates(Action serializer, Func deserializer) 12 | { 13 | _serializer = serializer; 14 | _deserializer = deserializer; 15 | } 16 | 17 | public void Serialize(TView view, Stream stream) 18 | { 19 | _serializer(view,typeof(TView), stream); 20 | } 21 | 22 | public TView Deserialize(Stream stream) 23 | { 24 | return (TView) _deserializer(typeof(TView),stream); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/ExtendAtomicEntityReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Feature.AtomicStorage 4 | { 5 | public static class ExtendAtomicEntityReader 6 | { 7 | public static Optional Get(this IAtomicEntityReader self, TKey key) 8 | { 9 | TEntity entity; 10 | if (self.TryGet(key, out entity)) 11 | { 12 | return entity; 13 | } 14 | return Optional.Empty; 15 | } 16 | 17 | public static TEntity Load(this IAtomicEntityReader self, TKey key) 18 | { 19 | TEntity entity; 20 | if (self.TryGet(key, out entity)) 21 | { 22 | return entity; 23 | } 24 | var txt = string.Format("Failed to load '{0}' with key '{1}'.", typeof(TEntity).Name, key); 25 | throw new InvalidOperationException(txt); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/ExtendAtomicSingletonReader.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.AtomicStorage 9 | { 10 | public static class ExtendAtomicSingletonReader 11 | { 12 | public static TView GetOrNew(this IAtomicSingletonReader reader) 13 | where TView : new() 14 | { 15 | TView view; 16 | if (reader.TryGet(out view)) 17 | { 18 | return view; 19 | } 20 | return new TView(); 21 | } 22 | 23 | public static Optional Get(this IAtomicSingletonReader reader) 24 | { 25 | TSingleton singleton; 26 | if (reader.TryGet(out singleton)) 27 | { 28 | return singleton; 29 | } 30 | return Optional.Empty; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicEntityReader.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | 9 | namespace Lokad.Cqrs.Feature.AtomicStorage 10 | { 11 | public interface IAtomicEntityReader 12 | //where TView : IAtomicEntity 13 | { 14 | /// 15 | /// Gets the view with the specified key. 16 | /// 17 | /// The key. 18 | /// The view. 19 | /// 20 | /// true, if it exists 21 | /// 22 | bool TryGet(TKey key, out TView view); 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicEntityWriter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Feature.AtomicStorage 11 | { 12 | /// 13 | /// View writer interface, used by the event handlers 14 | /// 15 | /// The type of the view. 16 | /// type of the key 17 | public interface IAtomicEntityWriter //where TEntity : IAtomicEntity 18 | { 19 | TEntity AddOrUpdate(TKey key, Func addFactory, Func update, AddOrUpdateHint hint = AddOrUpdateHint.ProbablyExists); 20 | bool TryDelete(TKey key); 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicSingletonReader.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | 9 | namespace Lokad.Cqrs.Feature.AtomicStorage 10 | { 11 | /// 12 | /// Strongly-typed reader for the view singletons. 13 | /// 14 | /// The type of the view. 15 | public interface IAtomicSingletonReader 16 | { 17 | /// 18 | /// Gets view singleton (if it's available). 19 | /// 20 | /// View singleton (if it's available) 21 | bool TryGet(out TSingleton singleton); 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicSingletonWriter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Feature.AtomicStorage 11 | { 12 | /// 13 | /// Strongly-typed view singleton writer 14 | /// 15 | /// The type of the view. 16 | public interface IAtomicSingletonWriter 17 | { 18 | TSingleton AddOrUpdate(Func addFactory, Func update, AddOrUpdateHint hint = AddOrUpdateHint.ProbablyExists); 19 | /// 20 | /// Deletes this view singleton. 21 | /// 22 | bool TryDelete(); 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicStorageFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Lokad.Cqrs.Feature.AtomicStorage 4 | { 5 | public interface IAtomicStorageFactory 6 | { 7 | IAtomicEntityWriter GetEntityWriter(); 8 | IAtomicEntityReader GetEntityReader(); 9 | IAtomicSingletonReader GetSingletonReader(); 10 | IAtomicSingletonWriter GetSingletonWriter(); 11 | 12 | 13 | /// 14 | /// Call this once on start-up to initialize folders 15 | /// 16 | IEnumerable Initialize(); 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicStorageSerializer.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | 10 | namespace Lokad.Cqrs.Feature.AtomicStorage 11 | { 12 | public interface IAtomicStorageSerializer 13 | { 14 | void Serialize(TView view, Stream stream); 15 | TView Deserialize(Stream stream); 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/IAtomicStorageStrategy.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.IO; 10 | 11 | namespace Lokad.Cqrs.Feature.AtomicStorage 12 | { 13 | public interface IAtomicStorageStrategy 14 | { 15 | string GetFolderForEntity(Type entityType); 16 | string GetFolderForSingleton(); 17 | string GetNameForEntity(Type entity, object key); 18 | string GetNameForSingleton(Type singletonType); 19 | void Serialize(TEntity entity, Stream stream); 20 | TEntity Deserialize(Stream stream); 21 | Type[] GetEntityTypes(); 22 | Type[] GetSingletonTypes(); 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/MemoryAtomicStorageModule.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Autofac; 3 | using Autofac.Core; 4 | 5 | namespace Lokad.Cqrs.Feature.AtomicStorage 6 | { 7 | public sealed class MemoryAtomicStorageModule : IModule 8 | { 9 | readonly IAtomicStorageStrategy _strategy; 10 | 11 | public MemoryAtomicStorageModule(IAtomicStorageStrategy strategy) 12 | { 13 | _strategy = strategy; 14 | } 15 | 16 | 17 | public void Configure(IComponentRegistry componentRegistry) 18 | { 19 | var builder = new ContainerBuilder(); 20 | 21 | builder.RegisterInstance(_strategy); 22 | var store = new ConcurrentDictionary(); 23 | builder.RegisterInstance(store); 24 | builder 25 | .RegisterInstance(new MemoryAtomicStorageFactory(store, _strategy)) 26 | .As(); 27 | 28 | 29 | builder 30 | .RegisterGeneric(typeof (MemoryAtomicEntityContainer<,>)) 31 | .As(typeof (IAtomicEntityReader<,>)) 32 | .As(typeof (IAtomicEntityWriter<,>)) 33 | .SingleInstance(); 34 | 35 | builder 36 | .RegisterGeneric(typeof (MemoryAtomicSingletonContainer<>)) 37 | .As(typeof (IAtomicSingletonReader<>)) 38 | .As(typeof (IAtomicSingletonWriter<>)) 39 | .SingleInstance(); 40 | 41 | 42 | builder.Update(componentRegistry); 43 | } 44 | } 45 | 46 | 47 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.AtomicStorage/NuclearStorageExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Feature.AtomicStorage 4 | { 5 | public static class NuclearStorageExtensions 6 | { 7 | public static TSingleton UpdateSingleton(this NuclearStorage storage, Action update) 8 | where TSingleton : new() 9 | { 10 | return storage.Factory.GetSingletonWriter().UpdateEnforcingNew(update); 11 | } 12 | } 13 | 14 | 15 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/Default/IConsume.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.DirectoryDispatch.Default 9 | { 10 | /// 11 | /// Default CQRS interface for interface-base domain setup of message consumers. By default Lokad.CQRS 12 | /// scans user assemblies for message handlers inheriting from this interface. 13 | /// If you don't want to reference Lokad.CQRS assemblies in your domain, 14 | /// you can declare your own consumer interface and point to it in the configuration, 15 | /// as shown in the samples. 16 | /// 17 | /// Look in the samples for more details on the usage 18 | public interface IConsume : IConsumeMessage 19 | where TMessage : IMessage 20 | { 21 | /// 22 | /// Consumes the specified message. 23 | /// 24 | /// The message. 25 | void Consume(TMessage message); 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/Default/IConsumeMessage.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.DirectoryDispatch.Default 9 | { 10 | /// 11 | /// Default CQRS interface for interface-base domain setup. By default Lokad.CQRS 12 | /// scans user assemblies for message handlers inheriting from this interface. You don't need to inherit from interface, 13 | /// use instead. 14 | /// If you don't want to reference Lokad.CQRS assemblies in your domain, 15 | /// you can declare your own consumer interface and point to it in the configuration, 16 | /// as shown in the samples. 17 | /// 18 | /// Look in the samples for more details on the usage 19 | public interface IConsumeMessage 20 | { 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/Default/IMessage.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.DirectoryDispatch.Default 9 | { 10 | /// 11 | /// Default CQRS message interface for the domain setup. By default Lokad.CQRS 12 | /// scans assemblies for message contracts deriving from this interface. 13 | /// If you don't want to reference Lokad.CQRS assemblies in your domain, 14 | /// you can declare your own message interface and point to it in the configuration, 15 | /// as shown in the samples. 16 | /// 17 | /// Look in the samples for more details on the usage 18 | public interface IMessage 19 | { 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/DirectoryDispatchFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Lokad.Cqrs.Core.Dispatch; 4 | 5 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 6 | { 7 | public static class DirectoryDispatchFactory 8 | { 9 | public static ISingleThreadMessageDispatcher CommandBatch(IComponentContext ctx, Action optionalFilter) 10 | { 11 | var builder = ctx.Resolve(); 12 | var filter = new MessageDirectoryFilter(); 13 | optionalFilter(filter); 14 | 15 | var map = builder.BuildActivationMap(filter.DoesPassFilter); 16 | 17 | var strategy = ctx.Resolve(); 18 | return new DispatchCommandBatch(map, strategy); 19 | } 20 | public static ISingleThreadMessageDispatcher OneEvent(IComponentContext ctx, Action optionalFilter) 21 | { 22 | var builder = ctx.Resolve(); 23 | var filter = new MessageDirectoryFilter(); 24 | optionalFilter(filter); 25 | 26 | var map = builder.BuildActivationMap(filter.DoesPassFilter); 27 | 28 | var strategy = ctx.Resolve(); 29 | var observer = ctx.Resolve(); 30 | return new DispatchOneEvent(map, observer, strategy); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/DispatchLifetimeScopeTags.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using Autofac; 9 | 10 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 11 | { 12 | /// 13 | /// Tags used to differentiate lifetime scopes for handling message envelopes. 14 | /// 15 | public static class DispatchLifetimeScopeTags 16 | { 17 | /// 18 | /// Used to mark created for processing message envelopes. 19 | /// 20 | public const string MessageEnvelopeScopeTag = "Envelope(UoW)"; 21 | 22 | /// 23 | /// Used to mark nested created for processing individual message items within an envelope. 24 | /// 25 | public const string MessageItemScopeTag = "Item(Handler)"; 26 | } 27 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/IMessageDispatchScope.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 4 | { 5 | /// 6 | /// Logical transaction and resolution hierarchy for dispatching this specific message. 7 | /// 8 | public interface IMessageDispatchScope : IDisposable 9 | { 10 | /// 11 | /// Dispatches the specified message to instance of the consumer type. 12 | /// 13 | /// Type of the consumer expected. 14 | /// The envelope context. 15 | /// The actual message to dispatch. 16 | void Dispatch(Type consumerType, ImmutableEnvelope envelope, ImmutableMessage message); 17 | /// 18 | /// Completes this scope. 19 | /// 20 | void Complete(); 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/IMessageDispatchStrategy.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 9 | { 10 | public interface IMessageDispatchStrategy 11 | { 12 | IMessageDispatchScope BeginEnvelopeScope(); 13 | } 14 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/IMethodContextManager.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 9 | { 10 | public interface IMethodContextManager 11 | { 12 | void SetContext(ImmutableEnvelope envelope, ImmutableMessage message); 13 | void ClearContext(); 14 | object GetContextProvider(); 15 | } 16 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/MessageActivationInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Diagnostics; 10 | 11 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 12 | { 13 | [DebuggerDisplay("{MessageType.Name}")] 14 | public sealed class MessageActivationInfo 15 | { 16 | public Type MessageType { get; internal set; } 17 | //public Type[] DirectConsumers { get; internal set; } 18 | //public Type[] DerivedConsumers { get; internal set; } 19 | public Type[] AllConsumers { get; internal set; } 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.DirectoryDispatch/MessageDirectoryBuilder.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Linq; 11 | 12 | namespace Lokad.Cqrs.Feature.DirectoryDispatch 13 | { 14 | /// 15 | /// Default implementation of the message directory builder 16 | /// 17 | public sealed class MessageDirectoryBuilder 18 | { 19 | readonly IEnumerable _mappings; 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The message mappings. 25 | public MessageDirectoryBuilder(IEnumerable mappings) 26 | { 27 | _mappings = mappings; 28 | } 29 | 30 | public MessageActivationInfo[] BuildActivationMap(Func filter) 31 | { 32 | return _mappings 33 | .Where(filter) 34 | .GroupBy(x => x.Message) 35 | .Select(x => new MessageActivationInfo 36 | { 37 | MessageType = x.Key, 38 | AllConsumers = x 39 | .Where(t => t.Consumer != typeof (MessageMapping.BusNull)) 40 | .Select(m => m.Consumer) 41 | .Distinct() 42 | .ToArray(), 43 | }) 44 | .ToArray(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.FilePartition/FileQueueWriter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.IO; 10 | using Lokad.Cqrs.Core.Outbox; 11 | 12 | namespace Lokad.Cqrs.Feature.FilePartition 13 | { 14 | public sealed class FileQueueWriter : IQueueWriter 15 | { 16 | readonly DirectoryInfo _folder; 17 | readonly IEnvelopeStreamer _streamer; 18 | 19 | public string Name { get; private set; } 20 | 21 | public FileQueueWriter(DirectoryInfo folder, string name, IEnvelopeStreamer streamer) 22 | { 23 | _folder = folder; 24 | _streamer = streamer; 25 | Name = name; 26 | } 27 | 28 | public void PutMessage(ImmutableEnvelope envelope) 29 | { 30 | var fileName = string.Format("{0:yyyy-MM-dd-HH-mm-ss-ffff}-{1}", envelope.CreatedOnUtc, Guid.NewGuid()); 31 | var full = Path.Combine(_folder.FullName, fileName); 32 | var data = _streamer.SaveEnvelopeData(envelope); 33 | File.WriteAllBytes(full, data); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.FilePartition/FileQueueWriterFactory.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Lokad.Cqrs.Core.Outbox; 3 | 4 | namespace Lokad.Cqrs.Feature.FilePartition 5 | { 6 | public sealed class FileQueueWriterFactory : IQueueWriterFactory 7 | { 8 | readonly FileStorageConfig _account; 9 | readonly IEnvelopeStreamer _streamer; 10 | readonly string _endpoint; 11 | 12 | public FileQueueWriterFactory(FileStorageConfig account, IEnvelopeStreamer streamer) 13 | { 14 | _account = account; 15 | _streamer = streamer; 16 | _endpoint = _account.AccountName; 17 | } 18 | 19 | public string Endpoint 20 | { 21 | get { return _endpoint; } 22 | } 23 | 24 | public IQueueWriter GetWriteQueue(string queueName) 25 | { 26 | var full = Path.Combine(_account.Folder.FullName, queueName); 27 | if (!Directory.Exists(full)) 28 | { 29 | Directory.CreateDirectory(full); 30 | } 31 | return 32 | new FileQueueWriter(new DirectoryInfo(full), queueName, _streamer); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.MemoryPartition/MemoryAccount.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | 3 | namespace Lokad.Cqrs.Feature.MemoryPartition 4 | { 5 | public sealed class MemoryAccount 6 | { 7 | public readonly ConcurrentDictionary> Delivery = 8 | new ConcurrentDictionary>(); 9 | } 10 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.MemoryPartition/MemoryPartitionFactory.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Collections.Concurrent; 9 | using System.Linq; 10 | 11 | namespace Lokad.Cqrs.Feature.MemoryPartition 12 | { 13 | public sealed class MemoryPartitionFactory 14 | { 15 | readonly MemoryAccount _account; 16 | 17 | public MemoryPartitionFactory(MemoryAccount account) 18 | { 19 | _account = account; 20 | } 21 | 22 | 23 | public MemoryPartitionInbox GetMemoryInbox(string[] queueNames) 24 | { 25 | var queues = queueNames 26 | .Select(n => _account.Delivery.GetOrAdd(n, s => new BlockingCollection())) 27 | .ToArray(); 28 | 29 | return new MemoryPartitionInbox(queues, queueNames); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.MemoryPartition/MemoryQueueWriter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Collections.Concurrent; 9 | using Lokad.Cqrs.Core.Outbox; 10 | 11 | namespace Lokad.Cqrs.Feature.MemoryPartition 12 | { 13 | public sealed class MemoryQueueWriter : IQueueWriter 14 | { 15 | readonly BlockingCollection _queue; 16 | 17 | public string Name { get; private set; } 18 | 19 | public MemoryQueueWriter(BlockingCollection queue, string name) 20 | { 21 | _queue = queue; 22 | Name = name; 23 | } 24 | 25 | public void PutMessage(ImmutableEnvelope envelope) 26 | { 27 | _queue.Add(envelope); 28 | } 29 | 30 | public void Init() 31 | { 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.MemoryPartition/MemoryQueueWriterFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using Lokad.Cqrs.Core.Outbox; 3 | 4 | namespace Lokad.Cqrs.Feature.MemoryPartition 5 | { 6 | public sealed class MemoryQueueWriterFactory :IQueueWriterFactory 7 | { 8 | readonly MemoryAccount _account; 9 | readonly string _endpoint; 10 | 11 | public MemoryQueueWriterFactory(MemoryAccount account, string endpoint = "memory") 12 | { 13 | _account = account; 14 | _endpoint = endpoint; 15 | } 16 | 17 | public string Endpoint 18 | { 19 | get { return _endpoint; } 20 | } 21 | 22 | public IQueueWriter GetWriteQueue(string queueName) 23 | { 24 | return 25 | new MemoryQueueWriter( 26 | _account.Delivery.GetOrAdd(queueName, s => new BlockingCollection()), queueName); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/ExtendStreamingItem.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | using System.Text; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | /// 14 | /// Helper extensions for the 15 | /// 16 | public static class ExtendStreamingItem 17 | { 18 | public static void WriteText(this IStreamingItem item, string text) 19 | { 20 | item.Write(s => 21 | { 22 | using (var writer = new StreamWriter(s)) 23 | { 24 | writer.Write(text); 25 | } 26 | }); 27 | } 28 | 29 | public static void WriteText(this IStreamingItem item, string text, Encoding encoding) 30 | { 31 | item.Write(s => 32 | { 33 | using (var writer = new StreamWriter(s, encoding)) 34 | { 35 | writer.Write(text); 36 | } 37 | }); 38 | } 39 | 40 | public static string ReadText(this IStreamingItem item) 41 | { 42 | string result = null; 43 | item.ReadInto((props, stream) => 44 | { 45 | using (var reader = new StreamReader(stream)) 46 | { 47 | result = reader.ReadToEnd(); 48 | } 49 | }); 50 | 51 | return result; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/IStreamingContainer.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Collections.Generic; 9 | 10 | namespace Lokad.Cqrs.Feature.StreamingStorage 11 | { 12 | /// 13 | /// Represents storage container reference. 14 | /// 15 | public interface IStreamingContainer 16 | { 17 | /// 18 | /// Gets the full path. 19 | /// 20 | /// The full path. 21 | string FullPath { get; } 22 | 23 | /// 24 | /// Gets the child container nested within the current container reference. 25 | /// 26 | /// The name. 27 | /// 28 | IStreamingContainer GetContainer(string name); 29 | 30 | /// 31 | /// Gets the storage item reference within the current container. 32 | /// 33 | /// The name. 34 | /// 35 | IStreamingItem GetItem(string name); 36 | 37 | /// 38 | /// Ensures that the current reference represents valid container 39 | /// 40 | /// 41 | IStreamingContainer Create(); 42 | 43 | /// 44 | /// Deletes this container 45 | /// 46 | void Delete(); 47 | 48 | /// 49 | /// Checks if the underlying container exists 50 | /// 51 | /// 52 | bool Exists(); 53 | 54 | IEnumerable ListItems(); 55 | } 56 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/IStreamingRoot.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.StreamingStorage 9 | { 10 | /// 11 | /// Storage root (Azure Blob account or file drive) 12 | /// 13 | public interface IStreamingRoot 14 | { 15 | /// 16 | /// Gets the container reference, identified by it's name 17 | /// 18 | /// The name. 19 | /// new container referece 20 | IStreamingContainer GetContainer(string name); 21 | } 22 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/LocalStreamingInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Feature.StreamingStorage 11 | { 12 | public sealed class LocalStreamingInfo 13 | { 14 | public readonly string ETag; 15 | 16 | public LocalStreamingInfo(string eTag) 17 | { 18 | ETag = eTag; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/ReaderDelegate.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | 10 | namespace Lokad.Cqrs.Feature.StreamingStorage 11 | { 12 | public delegate void ReaderDelegate(StreamingItemInfo props, Stream designationStream); 13 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingBaseException.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | [Serializable] 14 | public class StreamingBaseException : Exception 15 | { 16 | // 17 | // For guidelines regarding the creation of new exception types, see 18 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 19 | // and 20 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 21 | // 22 | 23 | public StreamingBaseException() 24 | { 25 | } 26 | 27 | public StreamingBaseException(string message) : base(message) 28 | { 29 | } 30 | 31 | public StreamingBaseException(string message, Exception inner) : base(message, inner) 32 | { 33 | } 34 | 35 | protected StreamingBaseException( 36 | SerializationInfo info, 37 | StreamingContext context) : base(info, context) 38 | { 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingConditionFailedException.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | [Serializable] 14 | public class StreamingConditionFailedException : StreamingBaseException 15 | { 16 | // 17 | // For guidelines regarding the creation of new exception types, see 18 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 19 | // and 20 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 21 | // 22 | 23 | public StreamingConditionFailedException() 24 | { 25 | } 26 | 27 | public StreamingConditionFailedException(string message) : base(message) 28 | { 29 | } 30 | 31 | public StreamingConditionFailedException(string message, Exception inner) : base(message, inner) 32 | { 33 | } 34 | 35 | protected StreamingConditionFailedException( 36 | SerializationInfo info, 37 | StreamingContext context) : base(info, context) 38 | { 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingConditionType.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs.Feature.StreamingStorage 9 | { 10 | public enum StreamingConditionType 11 | { 12 | None, 13 | /// 14 | /// Only perform the action if the client supplied entity matches the same entity on the server. 15 | /// This is mainly for methods like PUT to only update a resource if it has not been modified since 16 | /// the user last updated it. 17 | /// 18 | IfMatch, 19 | IfNoneMatch 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingContainerNotFoundException.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | [Serializable] 14 | public class StreamingContainerNotFoundException : StreamingBaseException 15 | { 16 | public StreamingContainerNotFoundException(string message, Exception inner) 17 | : base(message, inner) 18 | { 19 | } 20 | 21 | protected StreamingContainerNotFoundException( 22 | SerializationInfo info, 23 | StreamingContext context) 24 | : base(info, context) 25 | { 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingItemInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Collections.Specialized; 11 | using System.Diagnostics; 12 | 13 | namespace Lokad.Cqrs.Feature.StreamingStorage 14 | { 15 | public sealed class StreamingItemInfo 16 | { 17 | public string ETag { get; private set; } 18 | 19 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] 20 | public NameValueCollection Metadata { get; private set; } 21 | 22 | [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] 23 | public IDictionary Properties { get; private set; } 24 | 25 | //public string FullPath { get; private set; } 26 | //public string Name { get; private set; } 27 | 28 | public StreamingItemInfo( 29 | //string name, 30 | //string fullPath, 31 | string eTag, 32 | NameValueCollection metadata, 33 | IDictionary properties) 34 | { 35 | //Name = name; 36 | //FullPath = fullPath; 37 | 38 | ETag = eTag; 39 | Metadata = metadata; 40 | Properties = properties; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingItemIntegrityException.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | /// 14 | /// Happens, when data corruption was detected. Normally retrying the operation should solve the problem 15 | /// 16 | [Serializable] 17 | public class StreamingItemIntegrityException : StreamingBaseException 18 | { 19 | public StreamingItemIntegrityException() 20 | { 21 | } 22 | 23 | public StreamingItemIntegrityException(string message) : base(message) 24 | { 25 | } 26 | 27 | public StreamingItemIntegrityException(string message, Exception inner) : base(message, inner) 28 | { 29 | } 30 | 31 | protected StreamingItemIntegrityException( 32 | SerializationInfo info, 33 | StreamingContext context) : base(info, context) 34 | { 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingItemNotFoundException.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Runtime.Serialization; 10 | 11 | namespace Lokad.Cqrs.Feature.StreamingStorage 12 | { 13 | [Serializable] 14 | public class StreamingItemNotFoundException : StreamingBaseException 15 | { 16 | public StreamingItemNotFoundException(string message, Exception inner) : base(message, inner) 17 | { 18 | } 19 | 20 | 21 | protected StreamingItemNotFoundException( 22 | SerializationInfo info, 23 | StreamingContext context) 24 | : base(info, context) 25 | { 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.StreamingStorage/StreamingWriteOptions.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs.Feature.StreamingStorage 11 | { 12 | [Flags] 13 | public enum StreamingWriteOptions 14 | { 15 | None, 16 | /// 17 | /// We'll compress data if possible. 18 | /// 19 | CompressIfPossible = 0x01, 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/FileTapeStorageFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.IO; 4 | 5 | namespace Lokad.Cqrs.Feature.TapeStorage 6 | { 7 | public sealed class FileTapeStorageFactory : ITapeStorageFactory 8 | { 9 | readonly string _fullPath; 10 | readonly ConcurrentDictionary _writers = 11 | new ConcurrentDictionary(); 12 | 13 | 14 | public FileTapeStorageFactory(string fullPath) 15 | { 16 | _fullPath = fullPath; 17 | } 18 | 19 | public ITapeStream GetOrCreateStream(string name) 20 | { 21 | if (name == null) 22 | throw new ArgumentNullException("name"); 23 | if (string.IsNullOrWhiteSpace("name")) 24 | throw new ArgumentException("Incorrect value.", "name"); 25 | 26 | var writer = _writers.GetOrAdd( 27 | name, 28 | n => new FileTapeStream(Path.Combine(_fullPath, name))); 29 | 30 | return writer; 31 | } 32 | 33 | public void InitializeForWriting() 34 | { 35 | Directory.CreateDirectory(_fullPath); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/ITapeStorageFactory.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Feature.TapeStorage 2 | { 3 | /// 4 | /// Factory for storing blocks of data into append-only storage, 5 | /// that is easily to scale and replicate. This is the foundation 6 | /// for event sourcing. 7 | /// 8 | public interface ITapeStorageFactory 9 | { 10 | /// 11 | /// Gets or creates a new named stream. 12 | /// 13 | /// The name of the stream. 14 | /// new stream instance 15 | ITapeStream GetOrCreateStream(string name); 16 | /// 17 | /// Initializes this storage for writing 18 | /// 19 | void InitializeForWriting(); 20 | } 21 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/MemoryTapeStorageFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Collections.Generic; 3 | 4 | namespace Lokad.Cqrs.Feature.TapeStorage 5 | { 6 | public sealed class MemoryTapeStorageFactory : ITapeStorageFactory 7 | { 8 | readonly ConcurrentDictionary> _storage; 9 | 10 | 11 | public MemoryTapeStorageFactory(ConcurrentDictionary> storage) 12 | { 13 | _storage = storage; 14 | } 15 | 16 | public void InitializeForWriting() 17 | { 18 | } 19 | public ITapeStream GetOrCreateStream(string name) 20 | { 21 | return new MemoryTapeStream(_storage, name); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/TapeAppendConditionException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Lokad.Cqrs.Feature.TapeStorage 5 | { 6 | /// 7 | /// Is thrown internally, when storage version does not match the condition specified in 8 | /// 9 | [Serializable] 10 | public class TapeAppendConditionException : Exception 11 | { 12 | // 13 | // For guidelines regarding the creation of new exception types, see 14 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 15 | // and 16 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 17 | // 18 | 19 | public TapeAppendConditionException() {} 20 | public TapeAppendConditionException(string message) : base(message) {} 21 | public TapeAppendConditionException(string message, Exception inner) : base(message, inner) {} 22 | 23 | protected TapeAppendConditionException( 24 | SerializationInfo info, 25 | StreamingContext context) : base(info, context) {} 26 | 27 | 28 | } 29 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/TapeRecord.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs.Feature.TapeStorage 2 | { 3 | /// 4 | /// Contains information about the committed data 5 | /// 6 | public sealed class TapeRecord 7 | { 8 | public readonly long Version; 9 | public readonly byte[] Data; 10 | 11 | public TapeRecord(long version, byte[] data) 12 | { 13 | Version = version; 14 | Data = data; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Feature.TapeStorage/TapeStorageInitilization.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace Lokad.Cqrs.Feature.TapeStorage 6 | { 7 | public sealed class TapeStorageInitilization : IEngineProcess 8 | { 9 | readonly IEnumerable _storage; 10 | public TapeStorageInitilization(IEnumerable storage) 11 | { 12 | _storage = storage; 13 | } 14 | 15 | public void Dispose() 16 | { 17 | 18 | } 19 | 20 | public void Initialize() 21 | { 22 | foreach (var factory in _storage) 23 | { 24 | factory.InitializeForWriting(); 25 | } 26 | } 27 | 28 | public Task Start(CancellationToken token) 29 | { 30 | // don't do anything 31 | return new Task(() => { }); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/FileStorageConfig.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | 10 | namespace Lokad.Cqrs 11 | { 12 | public sealed class FileStorageConfig 13 | { 14 | public DirectoryInfo Folder { get; private set; } 15 | public string AccountName { get; private set; } 16 | 17 | public FileStorageConfig(DirectoryInfo folder, string accountName) 18 | { 19 | Folder = folder; 20 | AccountName = accountName; 21 | } 22 | 23 | public void Wipe() 24 | { 25 | if (Folder.Exists) 26 | Folder.Delete(true); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/IEngineProcess.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Threading; 10 | using System.Threading.Tasks; 11 | 12 | namespace Lokad.Cqrs 13 | { 14 | /// 15 | /// Generic process interface, that is registered in the container and managed by the Engine. 16 | /// It is used internally by the infrastructure. 17 | /// 18 | /// 19 | /// You can implement this interface and register it int the container, if you want to add some custom 20 | /// start-up or long-running task (order is not guaranteed). 21 | /// 22 | public interface IEngineProcess : IDisposable 23 | { 24 | /// 25 | /// Is executed by the engine on initialization phase. 26 | /// 27 | void Initialize(); 28 | 29 | /// 30 | /// Creates and starts a long-running task, given the cancellation token to stop it. 31 | /// 32 | /// The cancellation token. 33 | /// Long-running task instance 34 | Task Start(CancellationToken token); 35 | } 36 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/IEnvelopeSerializer.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.IO; 9 | using Lokad.Cqrs.Core.Envelope; 10 | 11 | namespace Lokad.Cqrs 12 | { 13 | public interface IEnvelopeSerializer 14 | { 15 | void SerializeEnvelope(Stream stream, EnvelopeContract contract); 16 | EnvelopeContract DeserializeEnvelope(Stream stream); 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/IEnvelopeStreamer.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs 9 | { 10 | public interface IEnvelopeStreamer 11 | { 12 | byte[] SaveEnvelopeReference(EnvelopeReference reference); 13 | byte[] SaveEnvelopeData(ImmutableEnvelope envelope); 14 | bool TryReadAsEnvelopeReference(byte[] buffer, out EnvelopeReference reference); 15 | ImmutableEnvelope ReadAsEnvelopeData(byte[] buffer); 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/IMessageSender.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using Lokad.Cqrs.Core.Envelope; 10 | 11 | namespace Lokad.Cqrs 12 | { 13 | /// 14 | /// Generic message publishing interface that is provided by the infrastructure, should user configure it for publishing 15 | /// 16 | public interface IMessageSender 17 | { 18 | /// 19 | /// Sends the specified messages to the designated recipient. 20 | /// 21 | /// The message to send. 22 | void SendOne(object content); 23 | void SendOne(object content, Action configure); 24 | 25 | 26 | 27 | void SendBatch(object[] content); 28 | void SendBatch(object[] content, Action builder); 29 | } 30 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/ISystemEvent.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | namespace Lokad.Cqrs 9 | { 10 | /// 11 | /// System event representing something that happened 12 | /// within the infrastructure 13 | /// 14 | public interface ISystemEvent 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/ISystemObserver.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace Lokad.Cqrs 11 | { 12 | /// 13 | /// Sends notification to the system. This is a strongly-typed equivalent of logging 14 | /// 15 | public interface ISystemObserver 16 | { 17 | /// 18 | /// Notifies the observer about the specified @event. 19 | /// 20 | /// The @event. 21 | void Notify(ISystemEvent @event); 22 | } 23 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/ImmutableAttribute.cs: -------------------------------------------------------------------------------- 1 | namespace Lokad.Cqrs 2 | { 3 | public sealed class ImmutableAttribute 4 | { 5 | public string Key { get; private set; } 6 | public string Value { get; private set; } 7 | 8 | public ImmutableAttribute(string key, string value) 9 | { 10 | Key = key; 11 | Value = value; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/MessageContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Lokad.Cqrs 4 | { 5 | public sealed class MessageContext 6 | { 7 | public readonly string EnvelopeId; 8 | public readonly int MessageIndex; 9 | public readonly DateTime CreatedUtc; 10 | 11 | public MessageContext(string envelopeId, int messageIndex, DateTime createdUtc) 12 | { 13 | EnvelopeId = envelopeId; 14 | MessageIndex = messageIndex; 15 | CreatedUtc = createdUtc; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Framework/Lokad.Cqrs.Portable/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010-2011 Lokad - CQRS for Windows Azure - New BSD License 2 | 3 | // Copyright (c) Lokad 2010-2011, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System.Reflection; 9 | using System.Runtime.InteropServices; 10 | 11 | // General Information about an assembly is controlled through the following 12 | // set of attributes. Change these attribute values to modify the information 13 | // associated with an assembly. 14 | 15 | [assembly : AssemblyTitle("Lokad.Cqrs.Portable")] 16 | [assembly : AssemblyDescription("")] 17 | [assembly : AssemblyConfiguration("")] 18 | [assembly : AssemblyCompany("Lokad SAS")] 19 | [assembly : AssemblyProduct("Lokad.Cqrs.Portable")] 20 | [assembly : AssemblyCopyright("Copyright © Lokad SAS 2011")] 21 | [assembly : AssemblyTrademark("")] 22 | [assembly : AssemblyCulture("")] 23 | 24 | // Setting ComVisible to false makes the types in this assembly not visible 25 | // to COM components. If you need to access a type in this assembly from 26 | // COM, set the ComVisible attribute to true on that type. 27 | 28 | [assembly : ComVisible(false)] 29 | 30 | // The following GUID is for the ID of the typelib if this project is exposed to COM 31 | 32 | [assembly : Guid("8f990f73-88eb-4819-b637-9ebcb11e94fe")] 33 | 34 | // Version information for an assembly consists of the following four values: 35 | // 36 | // Major Version 37 | // Minor Version 38 | // Build Number 39 | // Revision 40 | // 41 | // You can specify all the values or you can default the Build and Revision Numbers 42 | // by using the '*' as shown below: 43 | // [assembly: AssemblyVersion("1.0.*")] 44 | 45 | [assembly : AssemblyVersion("2.0.0.0")] 46 | [assembly : AssemblyFileVersion("2.0.0.0")] -------------------------------------------------------------------------------- /Framework/SharedKey.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Framework/SharedKey.snk -------------------------------------------------------------------------------- /Framework/do-path.cmd: -------------------------------------------------------------------------------- 1 | set "PATH=%ProgramFiles%\Microsoft SDKs\Windows\v6.0A\Bin;%PATH%" -------------------------------------------------------------------------------- /Framework/go.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\msbuild Lokad.Cqrs.build %* -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2011, LOKAD SAS 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | * Neither the name of LOKAD SAS nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LmfAdapter", "LmfAdapter\LmfAdapter.csproj", "{A4CA44D2-4A71-41AE-BADD-2EAF67B740E2}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {A4CA44D2-4A71-41AE-BADD-2EAF67B740E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {A4CA44D2-4A71-41AE-BADD-2EAF67B740E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {A4CA44D2-4A71-41AE-BADD-2EAF67B740E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {A4CA44D2-4A71-41AE-BADD-2EAF67B740E2}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/MessageAttributeTypeContract.cs: -------------------------------------------------------------------------------- 1 | namespace LmfAdapter 2 | { 3 | public enum MessageAttributeTypeContract : uint 4 | { 5 | Undefined = 0, 6 | ContractName = 1, 7 | ContractDefinition = 2, 8 | BinaryBody = 3, 9 | CustomString = 4, 10 | CustomBinary = 5, 11 | CustomNumber = 6, 12 | Topic = 7, 13 | Sender = 8, 14 | Identity = 9, 15 | CreatedUtc =10, 16 | StorageReference = 11, 17 | StorageContainer = 12, 18 | ErrorText = 13, 19 | Thread = 14, 20 | EntityIdentityString = 20 21 | } 22 | } -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/MessageAttributesContract.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ProtoBuf; 3 | 4 | namespace LmfAdapter 5 | { 6 | [ProtoContract] 7 | public sealed class MessageAttributesContract 8 | { 9 | [ProtoMember(1, DataFormat = DataFormat.Default)] 10 | public readonly MessageAttributeContract[] Items; 11 | 12 | public MessageAttributesContract(MessageAttributeContract[] items) 13 | { 14 | Items = items; 15 | } 16 | 17 | MessageAttributesContract() 18 | { 19 | Items = new MessageAttributeContract[0]; 20 | } 21 | 22 | public Maybe GetAttributeString(MessageAttributeTypeContract type) 23 | { 24 | for (int i = Items.Length - 1; i >= 0; i--) 25 | { 26 | var item = Items[i]; 27 | if (item.Type == type) 28 | { 29 | var value = item.StringValue; 30 | if (value == null) 31 | throw new InvalidOperationException("String attribute can't be null"); 32 | return value; 33 | } 34 | } 35 | return Maybe.Empty; 36 | } 37 | 38 | public Maybe GetAttributeDate(MessageAttributeTypeContract type) 39 | { 40 | for (int i = Items.Length - 1; i >= 0; i--) 41 | { 42 | var item = Items[i]; 43 | if (item.Type == type) 44 | { 45 | var value = item.NumberValue; 46 | if (value == 0) 47 | throw new InvalidOperationException("Date attribute can't be empty"); 48 | return DateTime.FromBinary(value); 49 | } 50 | } 51 | return Maybe.Empty; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/MessageContext.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010 Lokad Open Source - New BSD License 2 | 3 | // Copyright (c) Lokad 2010, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | 10 | namespace LmfAdapter 11 | { 12 | /// 13 | /// Information about message currently processed by this thread 14 | /// 15 | public static class MessageContext 16 | { 17 | // we can't store message as Maybe.Empty, since thread 18 | // static fields might be uninitialized 19 | [ThreadStatic] static UnpackedMessage _current; 20 | 21 | /// 22 | /// Gets the information about message currently processed by this thread 23 | /// 24 | /// Message currently processed by this thread. 25 | public static Maybe Current 26 | { 27 | get { return _current ?? Maybe.Empty; } 28 | } 29 | 30 | 31 | /// 32 | /// Gets currently processed message, which could be null 33 | /// 34 | /// The current message reference. 35 | public static UnpackedMessage CurrentReference 36 | { 37 | get { return _current; } 38 | } 39 | 40 | public static void OverrideContext(UnpackedMessage message) 41 | { 42 | if (message == null) throw new ArgumentNullException("message"); 43 | _current = message; 44 | } 45 | 46 | /// 47 | /// Clears the context. 48 | /// 49 | public static void ClearContext() 50 | { 51 | _current = null; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/MessageHeader.cs: -------------------------------------------------------------------------------- 1 | using ProtoBuf; 2 | 3 | namespace LmfAdapter 4 | { 5 | [ProtoContract] 6 | public sealed class MessageHeader 7 | { 8 | public const int FixedSize = 28; 9 | public const int DataMessageFormatVersion = 2010020701; 10 | public const int ReferenceMessageFormatVersion = 2010020702; 11 | 12 | [ProtoMember(1, DataFormat = DataFormat.FixedSize, IsRequired = true)] public readonly int MessageFormatVersion; 13 | [ProtoMember(2, DataFormat = DataFormat.FixedSize, IsRequired = true)] public readonly long AttributesLength; 14 | [ProtoMember(3, DataFormat = DataFormat.FixedSize, IsRequired = true)] public readonly long ContentLength; 15 | [ProtoMember(4, DataFormat = DataFormat.FixedSize, IsRequired = true)] public readonly int Checksum; 16 | 17 | public long GetTotalLength() 18 | { 19 | return FixedSize + AttributesLength + ContentLength; 20 | } 21 | 22 | 23 | public MessageHeader(int messageFormatVersion, long attributesLength, long contentLength, int checksum) 24 | { 25 | MessageFormatVersion = messageFormatVersion; 26 | AttributesLength = attributesLength; 27 | ContentLength = contentLength; 28 | Checksum = checksum; 29 | } 30 | 31 | public static MessageHeader ForData(long attributesLength, long contentLength, int checksum) 32 | { 33 | return new MessageHeader(DataMessageFormatVersion, attributesLength, contentLength, checksum); 34 | } 35 | 36 | public static MessageHeader ForReference(long attributesLength, int checksum) 37 | { 38 | return new MessageHeader(ReferenceMessageFormatVersion, attributesLength, 0, checksum); 39 | } 40 | 41 | MessageHeader() 42 | { 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/MessagePrinter.cs: -------------------------------------------------------------------------------- 1 | #region (c) 2010 Lokad Open Source - New BSD License 2 | 3 | // Copyright (c) Lokad 2010, http://www.lokad.com 4 | // This code is released as Open Source under the terms of the New BSD Licence 5 | 6 | #endregion 7 | 8 | using System; 9 | using System.Linq; 10 | using System.IO; 11 | 12 | namespace LmfAdapter 13 | { 14 | public static class MessagePrinter 15 | { 16 | /// 17 | /// Nicely prints the attributes to the text writer. 18 | /// 19 | /// The attributes. 20 | /// The writer. 21 | /// The indent. 22 | public static void PrintAttributes(MessageAttributesContract attributes, TextWriter writer, string indent = "") 23 | { 24 | var max = attributes.Items.Max(a => a.GetName().Length); 25 | 26 | foreach (var item in attributes.Items) 27 | { 28 | writer.Write(indent); 29 | writer.WriteLine("{0,-" + (max + 2) + "} : {1}", item.GetName(), GetNiceValue(item)); 30 | } 31 | } 32 | 33 | static object GetNiceValue(MessageAttributeContract attrib) 34 | { 35 | switch (attrib.Type) 36 | { 37 | case MessageAttributeTypeContract.CreatedUtc: 38 | return DateTime.FromBinary(attrib.NumberValue); 39 | default: 40 | return attrib.GetValue(); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/LmfAdapter/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("LmfAdapter")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("LmfAdapter")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("17c4ee91-206d-4512-b33e-5d27d035dbcc")] 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 | -------------------------------------------------------------------------------- /Prototypes/2011-05-24 Lmf conversion/protobuf-net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Prototypes/2011-05-24 Lmf conversion/protobuf-net.dll -------------------------------------------------------------------------------- /Prototypes/this folder you see not.txt: -------------------------------------------------------------------------------- 1 | This is not the folder you are looking for. 2 | 3 | Since Lokad SAS is a company is internally focused on efficient research 4 | and development, we tend to produce a lot of prototypes and small utils 5 | along the way. 6 | 7 | Normally this is a junk or some one-time experiments, but they get saved 8 | with the related project, JIC. This tends to save time once in a while. 9 | Storage is cheaper than time these days. 10 | 11 | Prototypes is the folder for this stuff in Lokad.CQRS project. 12 | 13 | 14 | All the best, 15 | Rinat Abdullin 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ReadMe.markdown: -------------------------------------------------------------------------------- 1 | # About 2 | 3 | **Lokad.CQRS** is a **.NET framework and a set of guidance materials** for _building distributed and scalable applications_ to be **run on-premises or in the cloud**. This project helps to design and develop decoupled systems locally and bring them to the distributed environments later. 4 | 5 | 6 | Check out the [introductory homepage](https://web.archive.org/web/20170517230612/http://lokad.github.io:80/lokad-cqrs/) (preserved by the web archive). 7 | 8 | # Case studies 9 | 10 | * [Lokad Hub](http://cqrs.wikidot.com/case:lokad-hub), also featured in [Microsoft CQRS Journey](https://msdn.microsoft.com/en-us/library/jj591556.aspx) 11 | * [Lokad Watchtower](http://cqrs.wikidot.com/case:lokad-watchtower) 12 | * [Lokad Shelfcheck](http://cqrs.wikidot.com/case:lokad-shelfcheck) 13 | * [Lokad Salescast](http://cqrs.wikidot.com/case:lokad-salescast) 14 | * [Human Record](http://cqrs.wikidot.com/case:humanrecord) 15 | * [EventDay](http://cqrs.wikidot.com/case:eventday) 16 | * [Lokad CallCalc](http://cqrs.wikidot.com/case:lokad-callcalc) 17 | 18 | 19 | It was also used at SkuVault as a platform for the business. However, there it was eventually replaced with a [different design](https://abdullin.com/sku-vault/2017-07-15-high-availability-and-performance/) capable of scaling above 1B events and TBs of data. [MessageVault](https://github.com/abdullin/messageVault) is currently the heart of this new approach. 20 | 21 | 22 | # CQRS Community around the world 23 | 24 | Check out the [CQRS Community around the world](http://cqrs.wikidot.com/world) to learn, share or simply hang out. 25 | 26 | 27 | # Retrospective 28 | 29 | There is a [final retrospective](https://abdullin.com/lokad-cqrs-retrospective/) of the framework. Although it enables starting the business and delivering the business value to the customers, long-term growth will encounter certain scalability and complexity bottlenecks. 30 | -------------------------------------------------------------------------------- /Resource/Misc/Graphs.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Resource/Misc/Graphs.vsd -------------------------------------------------------------------------------- /Resource/Misc/Sheets.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Resource/Misc/Sheets.xlsx -------------------------------------------------------------------------------- /Resource/_ReadMe.txt: -------------------------------------------------------------------------------- 1 | Binary resources used by Lokad.CQRS -------------------------------------------------------------------------------- /Resource/lokad-cqrs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abdullin/lokad-cqrs/6a5f623b15fc782eed4b75684bfa767b5dfa38a6/Resource/lokad-cqrs.png -------------------------------------------------------------------------------- /Resource/nuget/Lokad.CQRS.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Lokad.CQRS 5 | 2.0.0.0 6 | Lokad.com 7 | Lokad.com 8 | http://www.opensource.org/licenses/bsd-license.php 9 | http://lokad.github.com/lokad-cqrs/ 10 | http://lokad.github.com/images/logo_32x32.png 11 | false 12 | Lokad.CQRS is a .NET framework and a set of guidance materials for building distributed and scalable applications to be run on-premises or in the cloud. This project helps to design and develop decoupled systems locally and bring them to the distributed environments later. 13 | CQRS 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------