diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json deleted file mode 100644 index 18bae550c..000000000 --- a/.config/dotnet-tools.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": 1, - "isRoot": true, - "tools": { - "gitversion.tool": { - "version": "6.1.0", - "commands": [ - "dotnet-gitversion" - ], - "rollForward": false - } - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 6cbd591e0..000000000 --- a/.gitignore +++ /dev/null @@ -1,119 +0,0 @@ -# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) -[Bb]in/ -[Oo]bj/ -build/ - -# mstest test results -TestResults - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.sln.docstates - -# Build results -[Dd]ebug/ -[Rr]elease/ -x64/ -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.log -*.vspscc -*.vssscc -.builds - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper* - -# NCrunch -*.ncrunch* -.*crunch*.local.xml - -# Installshield output folder -[Ee]xpress - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish - -# Publish Web Output -*.Publish.xml - -# NuGet Packages Directory -packages - -# Windows Azure Build Output -csx -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -[Bb]in -[Oo]bj -sql -TestResults -[Tt]est[Rr]esult* -*.Cache -ClientBin -[Ss]tyle[Cc]op.* -~$* -*.dbmdl -Generated_Code #added for RIA/Silverlight projects - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -publish-net40/ -nunit.TestResult.* -/output - -# Visual Studio options and artifacts -.vs/ -*.lock.json - -# Custom -artifacts/ \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..b31f96ae1 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +neventstore.org \ No newline at end of file diff --git a/Changelog.md b/Changelog.md deleted file mode 100644 index f1c4c8d0d..000000000 --- a/Changelog.md +++ /dev/null @@ -1,200 +0,0 @@ -# NEventStore Versions - -## 10.1.1 - -### BugFix - -- Fixed Assemblies Version Numbers (AssemblyInfo files). - -## 10.1.0 - -- Improved `IEventStream` interface: `CommitChanges()` and `CommitChangesAsync()` now return `ICommit` instead of `void`. -- Updated MessagePack serializer to 3.1.3 - -### Breaking Changes - -- `IEventStream.CommitChanges()` and `IEventStream.CommitChangesAsync()` now return `ICommit` instead of `void`. - -## 10.0.1 - -### BugFix - -- Async Pipeline Hooks: initialization and PreCommit/PostCommit invocation bugs [#516](https://github.com/NEventStore/NEventStore/issues/516) - -## 10.0.0 - -- Async Methods to read from and write to streams (IStoreEvents, IEventStream, IPersistStreams, IPersistStreamsAsync, ICommitEventsAsync, IAccessSnapshotsAsync). [#513](https://github.com/NEventStore/NEventStore/issues/513) - - methods that read from a stream in an async way follow the Observer pattern and requires you to pass in an `IAsyncObservable` that will receive data as soon as they are available. -- Async Pipeline Hooks (IPipelineHookAsync). [#515](https://github.com/NEventStore/NEventStore/issues/515) -- AsyncPollingClient: a new polling client implementation that uses Async interfaces. [#505](https://github.com/NEventStore/NEventStore/issues/505) -- Removed the BinarySerializer (BinaryFormatter) from the core package and moved it to its own package [#510](https://github.com/NEventStore/NEventStore/issues/510) -- Improved comments and added more nullability checks. -- Minor performance improvements. -- Updated Testing Packages (NUnit, FluentAssertions, Microsoft.NET.Test and so on...). - -### Breaking Changes - -- `PersistStreamsExtensions.GetFrom(IPersistStreams, DateTime)` and `PersistStreamsExtensions.GetFromTo(IPersistStreams, DateTime, DateTime)` extension methods have been removed: they had inconsistent behavior with the other GetFrom(checkpointToken) methods, - they were getting data from the default bucket only. -- `PipelineHooksAwarePersistanceDecorator` renamed to `PipelineHooksAwarePersistStreamsDecorator`. -- `IPipelineHook.Select` method renamed to `IPipelineHook.SelectCommit`. -- `BinarySerializer` moved to its own package: `NEventStore.Serialization.Binary`. - - for net8.0+ call `AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true);` to enable unsafe BinaryFormatter usage. -- Improved many method signature with nullability annotations. -- `Wireup.With()` renamed `Wireup.Register()`. -- `OptimisticEventStream` constructors replaced by initialization functions: - - `new OptimisticEventStream(string bucketId, string streamId, ICommitEvents persistence, int minRevision, int maxRevision)` -> `new OptimisticEventStream(string bucketId, string streamId, ICommitEvents persistence).Initialize(int minRevision, int maxRevision)`. - - `new OptimisticEventStream(ISnapshot snapshot, ICommitEvents persistence, int maxRevision)` -> `new OptimisticEventStream(string bucketId, string streamId, ICommitEvents persistence).Initialize(ISnapshot snapshot, int maxRevision)`. - -## 9.2.0 - -- Updated nuget packages to include symbol packages and more information. -- Updated Newtonsoft.Bson 13.0.3 -- Added MessagePack serializer, thanks to [@pvagnozzi](https://github.com/pvagnozzi) -- Improved comments and removed some compilation warnings. - -## 9.1.1 - -- Fixed `build.ps1` script to correctly update Assembly Version number before building. -- Updated Readme with how Versioning works. - -## 9.1.0 - -- Support the following Target Frameworks only: netstandard2.0, net462. -- Updated Newtonsoft.Json 13.0.3 - -## 9.0.1 - -- Added documentation files to NuGet packages (improved intellisense support) [#496](https://github.com/NEventStore/NEventStore/issues/496) - -## 9.0.0 - -- Added support for .net 6 [#493](https://github.com/NEventStore/NEventStore/issues/493). -- Change / Optimization: Commit and CommitAttempt do not create internal read-only collections anymore, it can be useless given that we can change properties of events. -- NEventStore.Serialization.Json: accepts a JsonSerializerSettings to configure the serializer. - -## 8.0.0 - -- Added support for .net 5 [#489](https://github.com/NEventStore/NEventStore/issues/489). -- Added support for .net framework 4.6.1. -- Fixed InMemoryPersistenceEngine.AddSnapshot() behavior: adding multiple snapshots for the same tuple bucketId, streamId, streamRevision is not allowed; the updated snapshot will be ignored [#484](https://github.com/NEventStore/NEventStore/pull/484). -- Logging infrastructure switched to [Microsoft.Extensions.Logging](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging) [#454](https://github.com/NEventStore/NEventStore/issues/454), [#488](https://github.com/NEventStore/NEventStore/pull/488). -- Reviewed Exception (and logging) messages: many of those that refer to a StreamId should also provide BucketId information [#480](https://github.com/NEventStore/NEventStore/issues/480) - -### Breaking Changes - -- Dropped support for .NET Framework 4.5, only .NET 4.6.1+ will be supported in 8.x. .NET Framework support will be dropped in a future revision. -- Logging switched to Microsoft.Extensions.Logging, old logging code and configuration functions have been removed. - -## 7.0.0 - -- The IPersistStreams interface got some major changes: - - Added new `GetFromTo(Int64, Int64)` and `GetFromTo(string, Int64, Int64)` methods to the IPersistStreams interface. - - Extension methods `PersistStreamsExtensions.GetFrom(DateTime)` and `PersistStreamsExtensions.GetFromTo(DateTime, DateTime)` were marked obsolete and will be removed. - - A new PersistStreamsExtensions.GetCommit(Int64) method was added to retrieve a single commit [#445](https://github.com/NEventStore/NEventStore/issues/445). -- PollingClient was moved to its own NEventStore.PollingClient NuGet package [#467](https://github.com/NEventStore/NEventStore/issues/467). -- Added more information to the DuplicateCommitException error message (StreamId and BucketId), also the information provided by the Persistence providers will be reviewed [#372](https://github.com/NEventStore/NEventStore/issues/372). - -### Breaking Changes - -- The default value of 0 has been removed from the `IPersistStreams.GetFrom(Int64)` method. -- Removed the almost useless `GetFromStart()` extension method: use `IPersistStream.GetFrom(0)`. -- Bson serializer was moved from NEventStore.Serialization.Json to its own package: `NEventStore.Serialization.Bson`. Closes: [#479](https://github.com/NEventStore/NEventStore/issues/479). -- PollingClient was moved to its own package: add a reference to NEventStore.PollingClient NuGet package. Also the namespace was changed from NEventStore.Client to NEventStorePollingClient. - -## 6.1.0 - -Enlist in ambient transaction has been removed from the mail library and added to the persistence drivers implementations, each driver has its own way to support, enable or disable the feature. As of now this change will mainly impact Microsoft SQL Server users, because all other persistence plugins didn't use transactions at all. - -All the transactions (or their suppression) should be explicitly managed by the user. - -Minor optimizations were made if no pipeline hooks are used. - -### Breaking Changes - -- `PipelineHookBase`: changed the way the Dispose pattern was implemented to be compliant with the framework guidelines. Move all the Dispose logic to the overridden Dispose(bool disposing) method of your pipeline hook class. -- `OptimisticPipelineHook` optimization is not configured and enabled by default (if not enlisting in ambient transactions) anymore; it now must be explicitly enabled calling UseOptimisticPipelineHook() when configuring NEventStore. Do not use it if you plan to use transactions. To restore the previous behavior call .UseOptimisticPipelineHook() when configuring NEventStore. -- `EnlistInAmbientTransaction` has been removed from the core NEventStore library. It will be added to specific persistence drivers implementations. - -## 6.0.0 - -__Version 6.x is not backwards compatible with version 5.x.__ Updating to NEventStore 6.x without doing some preparation work will result in problems. - -### New Features - -- dotnet standard 2.0 , dotnet core 2.0 are now supported for the following projects: NEventStore, NEventStore.Domain, NEventStore.Persistence.Sql, NEventStore.Persistence.MongoDb - -### Breaking Changes - -- **Removed Dispatcher and dispatching mechanic, use the PollingClient**: it was marked obsolete in the version 5.x, you should dispatch events with other mechanisms, like using a PollingClient. -More information on this topic in the issue: [Race condition in sync and async dispatchers can result in subscribers getting commits / events out of order](https://github.com/NEventStore/NEventStore/issues/360). -- **Removed LongCheckpoint class**: checkpoint now is a plain Int64, there is no need to keep a LongCheckpoint class anymore. -- **PollingClient was removed because it used to depend on Rx**: you can [read more information here](src/NEventStore/Client/README.MD). The new polling client class is called PollingClient2, this however should be considered as a sample implementation you can use to derive your own. -- **JsonSerializer and BsonSerializer were moved in a separate assembly**: if you need them, you should reference the NEventStore.Serialization.Json assembly or implement your own serializers that depend on the Json.Net version you need. -- **EventMessage** class is now sealed. -- **`OptimisticEventStream` throws exceptions if a null message or a message with null body is added to the stream**. Previously if you called Add with null event message or add with an event message with null body, the add operation was ignored without any warning or error. - -## 6.0.0-rc-1 - -New features: - -- improved logging performances ([#468](https://github.com/NEventStore/NEventStore/issues/468)). - -Bug fixed: - -- adding events in the middle of a commit should throw ConcurrencyException ([#420](https://github.com/NEventStore/NEventStore/issues/420)). - -## 6.0.0-rc-0 - -__Version 6.x is not backwards compatible with version 5.x.__ Updating to NEventStore 6.x without doing some preparation work will result in problems. - -### New Features - -- dotnet standard 2.0 , dotnet core 2.0 are now supported for the following projects: NEventStore, NEventStore.Domain, NEventStore.Persistence.Sql, NEventStore.Persistence.MongoDb - -### Breaking changes - -- **Removed Dispatcher and dispatching mechanic, use the PollingClient**: it was marked obsolete in the version 5.x, you should dispatch events with other mechanisms, like using a PollingClient. -More information on this topic in the issue: [Race condition in sync and async dispatchers can result in subscribers getting commits / events out of order](https://github.com/NEventStore/NEventStore/issues/360). -- **Removed LongCheckpoint class**: checkpoint now is a plain Int64, there is no need to keep a LongCheckpoint class anymore. -- **PollingClient was removed because it used to depend on Rx**: you can [read more information here](src/NEventStore/Client/README.MD). The new polling client class is called PollingClient2, this however should be considered as a sample implementation you can use to derive your own. -- **JsonSerializer and BsonSerializer were moved in a separate assembly**: if you need them, you should reference the NEventStore.Serialization.Json assembly or implement your own serializers that depend on the Json.Net version you need. -- **EventMessage** class is now sealed. -- **OptimisticEventStream throws exceptions if a null message or a message with null body is added to the stream**. Previously if you called Add with null event message or add with an event message with null body, the add operation was ignored without any warning or error. - -### Other Notes - -All persistence providers: - -- [MongoDb](https://github.com/NEventStore/NEventStore.Persistence.MongoDB) -- [Sql](https://github.com/NEventStore/NEventStore.Persistence.SQL) -- [RavenDb](https://github.com/NEventStore/NEventStore.Persistence.RavenDB) - currently not maintained anymore. - -are now hosted in their own project. - -Common Domain is now moved in its [own repository](https://github.com/NEventStore/NEventStore.Domain). - -## 5.x.x - -Note: Version 5 is not backwards compatible with v4. Updating to v5 without doing some preparation work will result in problems. - -### Breaking Changes - -1. Underlying schema has changed for all v5 storage engines. In order to migrate a store from v4 to v5 use NEventStore.Migrations -1.The concept of a 'Bucket' has been added as a container for streams allowing multi-tenancy, partitions, multiple-bounded contexts, sagas, etc to be stored in the one store. The API changes have been such that, using extension methods, operations will work on the default bucket, unless a bucket Id has been explicitly supplied. This should mean minimal code changes for the user. -1.Stream Ids are now string based and are limited to 1000 characters. -In the SQL engines the stream Id's are limited to 40 characters and are hashed versions of the actual StreamId. -The hashing function can be overridden during wire-up. - -### New Features - -#### Polling Client - -As an alternative to the dispatcher mechanism and improved replay / catch-up story we have implemented a CheckpointNumber in the stores that guarantees ordering across the streams. This number is guaranteed to increment but not guaranteed to be sequential. This allows you to get all Commits from a specific checkpoint and observe new ones. This implementation is polling based (and thus works for all engines) so it doesn't have the same low-latency attributes of the dispatcher mechanism. You can see how to use it here: [https://gist.github.com/damianh/6370328](https://gist.github.com/damianh/6370328) .In this, instead of the store tracking what has been dispatched, the onus is on the client to track what it has seen. And upon restart, start subscribing from what it last saw. - -In the future I'd like to see / implement reactive clients that leverage stores that are observable. - -### Other Notes - -1. Only SQL and MongoDB persistence engines are supported in this release. RavenDB engine will be shipped later. -1. RavenDB and MongoDB persistence engines are now in their own repositories and will have be shipped independently. diff --git a/GitVersion.yml b/GitVersion.yml deleted file mode 100644 index 27f681df6..000000000 --- a/GitVersion.yml +++ /dev/null @@ -1,5 +0,0 @@ -mode: ContinuousDeployment -branches: {} -ignore: - sha: [] -merge-message-formats: {} diff --git a/Readme.md b/Readme.md deleted file mode 100644 index aae0b792f..000000000 --- a/Readme.md +++ /dev/null @@ -1,62 +0,0 @@ -NEventStore -=== - -NEventStore is a persistence library used to abstract different storage implementations when using event sourcing as storage mechanism. - -This library is developed with a specific focus on [DDD](http://en.wikipedia.org/wiki/Domain-driven_design)/[CQRS](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation#Command_query_responsibility_segregation) applications. - -NEventStore currently supports: - -- .net standard 2.0 -- .net framework 4.6.2 - -Starting from Version 6.0.0 NEventStore will use [Semantic Versioning](https://semver.org/) to track the version numbers. - -Build Status (AppVeyor) -=== - -Branches: - -- master [![Build status](https://ci.appveyor.com/api/projects/status/frg36pb2oh1j2ddi/branch/master?svg=true)](https://ci.appveyor.com/project/AGiorgetti/neventstore/branch/master) -- develop [![Build status](https://ci.appveyor.com/api/projects/status/frg36pb2oh1j2ddi/branch/develop?svg=true)](https://ci.appveyor.com/project/AGiorgetti/neventstore/branch/develop) - -Main Library Packages -=== - -- NEventStore - the core library package. -- NEventStore.Serialization.Json - Json serialization to be used with an IDocumentSerializer. -- NEventStore.Serialization.Bson - BSon serialization to be used with an IDocumentSerializer. -- NEventStore.Serialization.MsgPack - Message Pack serialization to be used with an IDocumentSerializer. -- NEventStore.PollingClient - provides an implementation for a PollingClient. - -Documentation -=== - -Please see the [documentation](https://github.com/NEventStore/NEventStore/wiki) to get started and for more information. - -ChangeLog can be [found here](https://github.com/NEventStore/NEventStore/blob/master/Changelog.md) - -### Developed with: - -[![Resharper](http://neventstore.org/images/logo_resharper_small.gif)](http://www.jetbrains.com/resharper/) -[![TeamCity](http://neventstore.org/images/logo_teamcity_small.gif)](http://www.jetbrains.com/teamcity/) -[![dotCover](http://neventstore.org/images/logo_dotcover_small.gif)](http://www.jetbrains.com/dotcover/) -[![dotTrace](http://neventstore.org/images/logo_dottrace_small.gif)](http://www.jetbrains.com/dottrace/) - -# How to build (Windows OS) - -To build the project locally on a Windows Machine: - -- Open a Powershell console in Administrative mode and run the build script `build.ps1` in the root of the repository. - -## Versioning - -Versioning is done automatically by the build script updating the -AssemblyInfo.cs file (false in .csproj files) -before the build starts. The version number is retrieved -from the git repository tags using "gitversion" tool. - -Things are handled this way because NEventStore is used a submodule in other projects and it -need to have it's own version number when building other projects. - -You should not update the version number manually, not commit the updated AssemblyInfo files. \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b1d022cbf..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: 1.0.{build} -image: Visual Studio 2022 -configuration: Release -assembly_info: - patch: true - file: '**\AssemblyInfo.*' - assembly_version: '{version}' - assembly_file_version: '{version}' - assembly_informational_version: '{version}' -dotnet_csproj: - patch: true - file: '**\*.csproj' - version: '{version}' - version_prefix: '{version}' - package_version: '{version}' - assembly_version: '{version}' - file_version: '{version}' - informational_version: '{version}' -install: -- ps: choco install gitversion.portable -y -before_build: -- ps: >- - # Display .NET Core version - - dotnet --version - - # Display minimal restore text - - dotnet restore ./src/NEventStore.Core.sln --verbosity m - - gitversion /l console /output buildserver /updateAssemblyInfo -build: - project: src/NEventStore.Core.sln - verbosity: minimal -after_build: -- cmd: >- - dotnet pack ./src/NEventStore/NEventStore.Core.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% - - dotnet pack ./src/NEventStore.PollingClient/NEventStore.PollingClient.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% - - dotnet pack ./src/NEventStore.Serialization.Json/NEventStore.Serialization.Json.Core.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% - - dotnet pack ./src/NEventStore.Serialization.Bson/NEventStore.Serialization.Bson.Core.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% - - dotnet pack ./src/NEventStore.Serialization.MsgPack/NEventStore.Serialization.MsgPack.Core.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% - - dotnet pack ./src/NEventStore.Serialization.Binary/NEventStore.Serialization.Binary.Core.csproj -c %CONFIGURATION% --no-build -o artifacts /p:PackageVersion=%GitVersion_SemVer% -test: - assemblies: - except: - - NEventStore.Persistence.AcceptanceTests.dll - - NEventStore.dll - - NEventStore.Serialization.Json.dll - - NEventStore.Serialization.Bson.dll - - NEventStore.Serialization.MsgPack.dll - - NEventStore.Serialization.Binary.dll -artifacts: -- path: '**\artifacts\**\*.*' -deploy: off \ No newline at end of file diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index 702f56acb..000000000 --- a/build.ps1 +++ /dev/null @@ -1,39 +0,0 @@ -$configurationdefault = "Release" -$artifacts = "../../artifacts" - -$configuration = Read-Host 'Configuration to build [default: Release] ?' -if ($configuration -eq '') { - $configuration = $configurationdefault -} -$runtests = Read-Host 'Run Tests (y / n) [default:n] ?' - -# Install gitversion tool -dotnet tool restore - -# Display minimal restore information -dotnet restore ./src/NEventStore.Core.sln --verbosity m - -# GitVersion -$str = dotnet tool run dotnet-gitversion /updateAssemblyInfo | out-string -$json = convertFrom-json $str -$nugetversion = $json.SemVer - -# Build -Write-Host "Building: "$nugetversion -dotnet build ./src/NEventStore.Core.sln -c $configuration --no-restore -p:ContinuousIntegrationBuild=True - -# Testing -if ($runtests -eq "y") { - Write-Host "Executing Tests" - dotnet test ./src/NEventStore.Core.sln -c $configuration --no-build - Write-Host "Tests Execution Complated" -} - -# NuGet packages -Write-Host "NuGet Packages creation" -dotnet pack ./src/NEventStore/NEventStore.Core.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion -dotnet pack ./src/NEventStore.PollingClient/NEventStore.PollingClient.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion -dotnet pack ./src/NEventStore.Serialization.Json/NEventStore.Serialization.Json.Core.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion -dotnet pack ./src/NEventStore.Serialization.Bson/NEventStore.Serialization.Bson.Core.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion -dotnet pack ./src/NEventStore.Serialization.MsgPack/NEventStore.Serialization.MsgPack.Core.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion -dotnet pack ./src/NEventStore.Serialization.Binary/NEventStore.Serialization.Binary.Core.csproj -c $configuration --no-build -o $artifacts /p:PackageVersion=$nugetversion \ No newline at end of file diff --git a/docs/Testing.md b/docs/Testing.md deleted file mode 100644 index 1613ea91c..000000000 --- a/docs/Testing.md +++ /dev/null @@ -1,23 +0,0 @@ -# Testing And Test Frameworks in NEventStore - -While upgrading the solution to support dotnet core, we also tried to migrate the tests to other test frameworks -(because not all of them supported dotnet core correctly when the migration job started). - -Several trial and errors were made, but in the end we were able to implement the tests using all the 3 major testing frameworks available in the dotnet world: - -- XUnit -- NUnit -- MSTest - -We had to write 3 version of the `SpecificationBase` class and adapt the testing attributes to each framework. - -I you inspect the code you'll see a lot of `#if NUNIT` (and the like) lines of code. - -The actual implementation compiles all the projects to use NUnit. - -You can change the behavior following these steps: - -- go through all the .csproj files and change the compilation constant from NUNIT to XUNIT or MSTEST. -- in the assemblies that contain tests you need to reference the correct Test Framework assemblies and TestAdapter for the framework you are going to use. - -Having more than one test runner might not be a good idea because some CI tools (like Appveyor) might autodetect them and execute the tests for a framework you are not using, and it will surely endup with failures and errors of your build. \ No newline at end of file diff --git a/icon.png b/icon.png deleted file mode 100644 index c6c977dab..000000000 Binary files a/icon.png and /dev/null differ diff --git a/images/bg_hr.png b/images/bg_hr.png new file mode 100644 index 000000000..7973bd698 Binary files /dev/null and b/images/bg_hr.png differ diff --git a/images/blacktocat.png b/images/blacktocat.png new file mode 100644 index 000000000..6e264fe57 Binary files /dev/null and b/images/blacktocat.png differ diff --git a/images/icon_download.png b/images/icon_download.png new file mode 100644 index 000000000..a2a287f64 Binary files /dev/null and b/images/icon_download.png differ diff --git a/images/logo_dotcover_small.gif b/images/logo_dotcover_small.gif new file mode 100644 index 000000000..caa386971 Binary files /dev/null and b/images/logo_dotcover_small.gif differ diff --git a/images/logo_dottrace_small.gif b/images/logo_dottrace_small.gif new file mode 100644 index 000000000..cfe88489a Binary files /dev/null and b/images/logo_dottrace_small.gif differ diff --git a/images/logo_resharper_small.gif b/images/logo_resharper_small.gif new file mode 100644 index 000000000..739dcb4d5 Binary files /dev/null and b/images/logo_resharper_small.gif differ diff --git a/images/logo_teamcity.gif b/images/logo_teamcity.gif new file mode 100644 index 000000000..79a362603 Binary files /dev/null and b/images/logo_teamcity.gif differ diff --git a/images/logo_teamcity_small.gif b/images/logo_teamcity_small.gif new file mode 100644 index 000000000..ef7ddbd6f Binary files /dev/null and b/images/logo_teamcity_small.gif differ diff --git a/images/sprite_download.png b/images/sprite_download.png new file mode 100644 index 000000000..f2babd575 Binary files /dev/null and b/images/sprite_download.png differ diff --git a/index.html b/index.html new file mode 100644 index 000000000..5fcc94253 --- /dev/null +++ b/index.html @@ -0,0 +1,89 @@ + + + + + + + + + + + NEventStore + + + + + +
+
+ View on GitHub + +

NEventStore

+

A persistence agnostic Event Store for .NET

+
+
+ + +
+ +
+
+ Developed with: + + + + +
+

Overview

+

+ The NEventStore is a persistence library used to abstract different storage implementations when using event + sourcing as storage mechanism. It targeted at DDD (Domain Driven Design) and CQRS (Command Query Responsibility + Segregation) based applications. It is not intended to be a general stream store. +

+

Start using NEventStore

+

See the Quick Start and browse the Documentation.

+

Announcements

+

Follow us on twitter: @NEventStore, @randompunter, @kblooie, + @andreabalducci, @A_Giorgetti +

Need Help? Have a Question?

+

+ Ask your question on Google group or post to the + Issue Tracker. +

+

Development

+

Code is on GitHub

+ +

+ Package feeds: +

+

+
+ +
+ + + + + + \ No newline at end of file diff --git a/javascripts/main.js b/javascripts/main.js new file mode 100644 index 000000000..d8135d37b --- /dev/null +++ b/javascripts/main.js @@ -0,0 +1 @@ +console.log('This would be the main JS file.'); diff --git a/license.txt b/license.txt deleted file mode 100644 index 6a5550266..000000000 --- a/license.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2013 Jonathan Oliver, Jonathan Matheus, Damian Hickey and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/params.json b/params.json new file mode 100644 index 000000000..e5862fa53 --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"name":"NEventStore","tagline":"A persistence agnostic Event Store for .NET","body":"### Welcome to GitHub Pages.\r\nThis automatic page generator is the easiest way to create beautiful pages for all of your projects. Author your page content here using GitHub Flavored Markdown, select a template crafted by a designer, and publish. After your page is generated, you can check out the new branch:\r\n\r\n```\r\n$ cd your_repo_root/repo_name\r\n$ git fetch origin\r\n$ git checkout gh-pages\r\n```\r\n\r\nIf you're using the GitHub for Mac, simply sync your repository and you'll see the new branch.\r\n\r\n### Designer Templates\r\nWe've crafted some handsome templates for you to use. Go ahead and continue to layouts to browse through them. You can easily go back to edit your page before publishing. After publishing your page, you can revisit the page generator and switch to another theme. Your Page content will be preserved if it remained markdown format.\r\n\r\n### Rather Drive Stick?\r\nIf you prefer to not use the automatic generator, push a branch named `gh-pages` to your repository to create a page manually. In addition to supporting regular HTML content, GitHub Pages support Jekyll, a simple, blog aware static site generator written by our own Tom Preston-Werner. Jekyll makes it easy to create site-wide headers and footers without having to copy them across every page. It also offers intelligent blog support and other advanced templating features.\r\n\r\n### Authors and Contributors\r\nYou can @mention a GitHub username to generate a link to their profile. The resulting `` element will link to the contributor's GitHub Profile. For example: In 2007, Chris Wanstrath (@defunkt), PJ Hyett (@pjhyett), and Tom Preston-Werner (@mojombo) founded GitHub.\r\n\r\n### Support or Contact\r\nHaving trouble with Pages? Check out the documentation at http://help.github.com/pages or contact support@github.com and we’ll help you sort it out.","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/src/.editorconfig b/src/.editorconfig deleted file mode 100644 index 3c456a6e5..000000000 --- a/src/.editorconfig +++ /dev/null @@ -1,30 +0,0 @@ -[*] -end_of_line = crlf -indent_style = space -indent_size = 4 - -[*.xml] -indent_style = space - -[*.cs] -csharp_new_line_before_open_brace = all - -# RCS1229: Use async/await when necessary. -dotnet_diagnostic.RCS1229.severity = error - -# IDE0290: Use primary constructor -csharp_style_prefer_primary_constructors = false - -# IDE0028: Simplify collection initialization -dotnet_style_collection_initializer = false - -# IDE0305: Simplify collection initialization -dotnet_diagnostic.IDE0305.severity = none - -# Logging Warnings: temporary disabled, enable them again later on - -# CA1848: Use the LoggerMessage delegates -dotnet_diagnostic.CA1848.severity = none - -# CA2254: Template should be a static expression -dotnet_diagnostic.CA2254.severity = none \ No newline at end of file diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs deleted file mode 100644 index a2d615453..000000000 --- a/src/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -[assembly: AssemblyVersion("0.0.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0.0")] diff --git a/src/CustomDictionary.xml b/src/CustomDictionary.xml deleted file mode 100644 index a13c808b0..000000000 --- a/src/CustomDictionary.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - wireup - bson - untyped - param - shard - sharding - sqlite - postgre - rds - nano - smallint - tinyint - datetime - dbo - uniqueidentifier - varbinary - xtype - bigint - bytea - uuid - precommit - changeset - nonpositive - sysobjects - gzip - precommit - - - \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index dff21ee33..000000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,7 +0,0 @@ - - - 13.0 - enable - enable - - \ No newline at end of file diff --git a/src/GlobalAssemblyInfo.cs b/src/GlobalAssemblyInfo.cs deleted file mode 100644 index 2b7d4963a..000000000 --- a/src/GlobalAssemblyInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Jonathan Oliver. All rights reserved. -// -//----------------------------------------------------------------------- - -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyCompany("NEventStore")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © Jonathan Oliver, Jonathan Mathius, Damian Hickey and Contributors 2011")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCulture("")] -[assembly: ComVisible(false)] -[assembly: CLSCompliant(false)] -[assembly: NeutralResourcesLanguage("en-US")] -[assembly: InternalsVisibleTo("NEventStore.Tests")] -[assembly: InternalsVisibleTo("NEventStore.Core.Tests")] diff --git a/src/GlobalSuppressions.cs b/src/GlobalSuppressions.cs deleted file mode 100644 index fe8e858ee..000000000 --- a/src/GlobalSuppressions.cs +++ /dev/null @@ -1,5 +0,0 @@ -//----------------------------------------------------------------------- -// -// Copyright (c) Jonathan Oliver. All rights reserved. -// -//----------------------------------------------------------------------- \ No newline at end of file diff --git a/src/NEventStore.Benchmark/Benchmarks/PersistenceBenchmarks.cs b/src/NEventStore.Benchmark/Benchmarks/PersistenceBenchmarks.cs deleted file mode 100644 index d57749da9..000000000 --- a/src/NEventStore.Benchmark/Benchmarks/PersistenceBenchmarks.cs +++ /dev/null @@ -1,124 +0,0 @@ -using BenchmarkDotNet.Attributes; -using NEventStore.Benchmark.Support; - -namespace NEventStore.Benchmark.Benchmarks -{ - [Config(typeof(AllowNonOptimized))] - [SimpleJob(launchCount: 3, warmupCount: 3, iterationCount: 3, invocationCount: 1)] - [MemoryDiagnoser] - [MeanColumn, StdErrorColumn, StdDevColumn, MinColumn, MaxColumn, IterationsColumn] - public class PersistenceBenchmarks - { - private static readonly Guid StreamId = Guid.NewGuid(); // aggregate identifier - private readonly IStoreEvents _eventStore; - - public PersistenceBenchmarks() - { - _eventStore = EventStoreHelpers.WireupEventStore(); - } - - [Params(100, 1000, 10000, 100000)] - public int CommitsToWrite { get; set; } - - [Benchmark] - public void WriteToStream() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = _eventStore.OpenStream(StreamId, 0, int.MaxValue); - for (int i = 0; i < CommitsToWrite; i++) - { - var @event = new SomeDomainEvent { Value = i.ToString() }; - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - } - - [Benchmark] - public async Task WriteToStreamAsync() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = await _eventStore.OpenStreamAsync(StreamId, 0, int.MaxValue, CancellationToken.None).ConfigureAwait(false); - for (int i = 0; i < CommitsToWrite; i++) - { - var @event = new SomeDomainEvent { Value = i.ToString() }; - stream.Add(new EventMessage { Body = @event }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); - } - } - - [GlobalSetup(Targets = new string[] { nameof(ReadFromStream), nameof(ReadFromEventStore) })] - public void ReadSetup() - { - using var stream = _eventStore.OpenStream(StreamId, 0, int.MaxValue); - for (int i = 0; i < CommitsToWrite; i++) - { - var @event = new SomeDomainEvent { Value = i.ToString() }; - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - } - - [Benchmark] - public void ReadFromStream() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = _eventStore.OpenStream(StreamId, 0, int.MaxValue); - // the whole stream has been read - // Console.WriteLine(stream.CommittedEvents.First().Body); - } - - [Benchmark] - public void ReadFromEventStore() - { - var commits = _eventStore.Advanced.GetFrom(Bucket.Default, 0); - foreach (var _ in commits) - { - // just iterate through all the commits - // Console.WriteLine(c); - } - } - - [GlobalSetup(Targets = new string[] { nameof(ReadFromStreamAsync), nameof(ReadFromEventStoreAsync) })] - public async Task ReadSetupAsync() - { - using var stream = await _eventStore.OpenStreamAsync(StreamId, 0, int.MaxValue, CancellationToken.None).ConfigureAwait(false); - for (int i = 0; i < CommitsToWrite; i++) - { - var @event = new SomeDomainEvent { Value = i.ToString() }; - stream.Add(new EventMessage { Body = @event }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); - } - } - - [Benchmark] - public async Task ReadFromStreamAsync() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = await _eventStore.OpenStreamAsync(StreamId, 0, int.MaxValue, CancellationToken.None).ConfigureAwait(false); - // the whole stream has been read - // Console.WriteLine(stream.CommittedEvents.First().Body); - } - - [Benchmark] - public Task ReadFromEventStoreAsync() - { - // just iterate through all the commits -#pragma warning disable RCS1163 // Unused parameter - return _eventStore.Advanced.GetFromAsync(Bucket.Default, 0, new LambdaAsyncObserver( - (c, _) => - { - // Console.WriteLine(c.Events.First().Body); - return Task.FromResult(true); - }), CancellationToken.None); -#pragma warning restore RCS1163 // Unused parameter - } - } -} diff --git a/src/NEventStore.Benchmark/NEventStore.Benchmark.csproj b/src/NEventStore.Benchmark/NEventStore.Benchmark.csproj deleted file mode 100644 index 35fb58158..000000000 --- a/src/NEventStore.Benchmark/NEventStore.Benchmark.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net8.0;net472 - false - - exe - - Exe - - - - TRACE;DEBUG - - - - - - - - - - - diff --git a/src/NEventStore.Benchmark/Program.cs b/src/NEventStore.Benchmark/Program.cs deleted file mode 100644 index 941e55bae..000000000 --- a/src/NEventStore.Benchmark/Program.cs +++ /dev/null @@ -1,13 +0,0 @@ -using BenchmarkDotNet.Running; -using NEventStore.Benchmark.Benchmarks; - -namespace NEventStore.Benchmark -{ - public static class Program - { - public static void Main(string[] _) - { - BenchmarkRunner.Run(); - } - } -} diff --git a/src/NEventStore.Benchmark/Support/AllowNonOptimized.cs b/src/NEventStore.Benchmark/Support/AllowNonOptimized.cs deleted file mode 100644 index 91a0caeb5..000000000 --- a/src/NEventStore.Benchmark/Support/AllowNonOptimized.cs +++ /dev/null @@ -1,18 +0,0 @@ -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Validators; -using System.Linq; - -namespace NEventStore.Benchmark.Support -{ - public class AllowNonOptimized : ManualConfig - { - public AllowNonOptimized() - { - AddValidator(JitOptimizationsValidator.DontFailOnError); // ALLOW NON-OPTIMIZED DLLS - - AddLogger(DefaultConfig.Instance.GetLoggers().ToArray()); // manual config has no loggers by default - AddExporter(DefaultConfig.Instance.GetExporters().ToArray()); // manual config has no exporters by default - AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray()); // manual config has no columns by default - } - } -} diff --git a/src/NEventStore.Benchmark/Support/EventStoreHelpers.cs b/src/NEventStore.Benchmark/Support/EventStoreHelpers.cs deleted file mode 100644 index 1bed8ce2d..000000000 --- a/src/NEventStore.Benchmark/Support/EventStoreHelpers.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace NEventStore.Benchmark.Support -{ - internal static class EventStoreHelpers - { - internal static IStoreEvents WireupEventStore() - { - return Wireup.Init() - // .LogToOutputWindow(LogLevel.Verbose) - // .LogToConsoleWindow(LogLevel.Verbose) - .UsingInMemoryPersistence() - .InitializeStorageEngine() -#if NET462 - .TrackPerformanceInstance("example") -#endif - // .HookIntoPipelineUsing(new[] { new AuthorizationPipelineHook() }) - .Build(); - } - } -} diff --git a/src/NEventStore.Benchmark/Support/SomeDomainEvent.cs b/src/NEventStore.Benchmark/Support/SomeDomainEvent.cs deleted file mode 100644 index 7b36d365b..000000000 --- a/src/NEventStore.Benchmark/Support/SomeDomainEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NEventStore.Benchmark.Support -{ - internal class SomeDomainEvent - { - public string? Value { get; set; } - } -} diff --git a/src/NEventStore.Core.sln b/src/NEventStore.Core.sln deleted file mode 100644 index 746933f4b..000000000 --- a/src/NEventStore.Core.sln +++ /dev/null @@ -1,303 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.12.35521.163 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".test", ".test", "{D3C17830-A461-4BA5-A672-461B19B33936}" - ProjectSection(SolutionItems) = preProject - NEventStore.Persistence.AcceptanceTests\PersistenceTests.Async.cs = NEventStore.Persistence.AcceptanceTests\PersistenceTests.Async.cs - NEventStore.Persistence.AcceptanceTests\PersistenceTests.cs = NEventStore.Persistence.AcceptanceTests\PersistenceTests.cs - NEventStore.Persistence.AcceptanceTests\PersistenceTests.Transactions.cs = NEventStore.Persistence.AcceptanceTests\PersistenceTests.Transactions.cs - NEventStore.Persistence.AcceptanceTests\SerializationTests.cs = NEventStore.Persistence.AcceptanceTests\SerializationTests.cs - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "serialization", "serialization", "{52F7988F-452D-46C2-A144-D85E0CF371C6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{D35087BF-941A-49EA-96A8-B10457C4D169}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Core", "NEventStore\NEventStore.Core.csproj", "{EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Persistence.AcceptanceTests.Core", "NEventStore.Persistence.AcceptanceTests\NEventStore.Persistence.AcceptanceTests.Core.csproj", "{608A1D85-0999-4A9B-956A-11B91A1CB065}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Json.Core", "NEventStore.Serialization.Json\NEventStore.Serialization.Json.Core.csproj", "{9A46374D-029C-4B87-88E3-0BE5D1D44C35}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Json.Core.Tests", "NEventStore.Serialization.Json.Tests\NEventStore.Serialization.Json.Core.Tests.csproj", "{D7029339-3794-4275-893A-E705D872BFBE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Bson.Core.Tests", "NEventStore.Serialization.Bson.Tests\NEventStore.Serialization.Bson.Core.Tests.csproj", "{2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.GZip.Core.Tests", "NEventStore.Serialization.Gzip.Tests\NEventStore.Serialization.GZip.Core.Tests.csproj", "{BCCDD838-8368-418D-82B5-5389FDDF0ADD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Core.Tests", "NEventStore.Tests\NEventStore.Core.Tests.csproj", "{8860810C-5E46-4E60-8924-C6C77BBC6EB2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{407B4AC0-6C11-4123-9BBA-094B2CADCD3A}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - ..\appveyor.yml = ..\appveyor.yml - ..\build.ps1 = ..\build.ps1 - ..\Changelog.md = ..\Changelog.md - Directory.Build.props = Directory.Build.props - ..\license.txt = ..\license.txt - ..\Readme.md = ..\Readme.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Binary.Core.Tests", "NEventStore.Serialization.Binary.Tests\NEventStore.Serialization.Binary.Core.Tests.csproj", "{9F0BFA49-8711-4143-B813-ACD0D0B003FD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Rijndael.Core.Tests", "NEventStore.Serialization.Rijndael.Tests\NEventStore.Serialization.Rijndael.Core.Tests.csproj", "{56B15268-DEBC-4E9F-8554-03737A39D71B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Benchmark", "NEventStore.Benchmark\NEventStore.Benchmark.csproj", "{2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Example", "NEventStore.Example\NEventStore.Example.csproj", "{04174210-4A5D-4F26-883E-B52B7B167EAC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.PollingClientExample", "NEventStore.PollingClientExample\NEventStore.PollingClientExample.csproj", "{310733D1-2BF4-44D7-9947-93E29FA44310}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.Serialization.Bson.Core", "NEventStore.Serialization.Bson\NEventStore.Serialization.Bson.Core.csproj", "{C45058FC-A657-4D13-AF2A-6E0B30C444A6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NEventStore.PollingClient", "NEventStore.PollingClient\NEventStore.PollingClient.csproj", "{1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NEventStore.Serialization.MsgPack.Core", "NEventStore.Serialization.MsgPack\NEventStore.Serialization.MsgPack.Core.csproj", "{187E9876-28EC-43D7-B70E-2C09E66D59BD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NEventStore.Serialization.MsgPack.Core.Tests", "NEventStore.Serialization.MsgPack.Tests\NEventStore.Serialization.MsgPack.Core.Tests.csproj", "{7FD67842-0549-4062-ACAB-3C417BD218C1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NEventStore.Serialization.Binary.Core", "NEventStore.Serialization.Binary\NEventStore.Serialization.Binary.Core.csproj", "{26297E78-023D-4F3C-4F39-A7CC4FA9AF21}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|x64.ActiveCfg = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|x64.Build.0 = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|x86.ActiveCfg = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Debug|x86.Build.0 = Debug|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|Any CPU.Build.0 = Release|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|x64.ActiveCfg = Release|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|x64.Build.0 = Release|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|x86.ActiveCfg = Release|Any CPU - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C}.Release|x86.Build.0 = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|Any CPU.Build.0 = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|x64.ActiveCfg = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|x64.Build.0 = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|x86.ActiveCfg = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Debug|x86.Build.0 = Debug|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|Any CPU.ActiveCfg = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|Any CPU.Build.0 = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|x64.ActiveCfg = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|x64.Build.0 = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|x86.ActiveCfg = Release|Any CPU - {608A1D85-0999-4A9B-956A-11B91A1CB065}.Release|x86.Build.0 = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|x64.ActiveCfg = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|x64.Build.0 = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|x86.ActiveCfg = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Debug|x86.Build.0 = Debug|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|Any CPU.Build.0 = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|x64.ActiveCfg = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|x64.Build.0 = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|x86.ActiveCfg = Release|Any CPU - {9A46374D-029C-4B87-88E3-0BE5D1D44C35}.Release|x86.Build.0 = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|x64.ActiveCfg = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|x64.Build.0 = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|x86.ActiveCfg = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Debug|x86.Build.0 = Debug|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|Any CPU.Build.0 = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|x64.ActiveCfg = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|x64.Build.0 = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|x86.ActiveCfg = Release|Any CPU - {D7029339-3794-4275-893A-E705D872BFBE}.Release|x86.Build.0 = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|x64.ActiveCfg = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|x64.Build.0 = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|x86.ActiveCfg = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Debug|x86.Build.0 = Debug|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|Any CPU.Build.0 = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|x64.ActiveCfg = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|x64.Build.0 = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|x86.ActiveCfg = Release|Any CPU - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A}.Release|x86.Build.0 = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|x64.ActiveCfg = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|x64.Build.0 = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|x86.ActiveCfg = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Debug|x86.Build.0 = Debug|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|Any CPU.Build.0 = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|x64.ActiveCfg = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|x64.Build.0 = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|x86.ActiveCfg = Release|Any CPU - {BCCDD838-8368-418D-82B5-5389FDDF0ADD}.Release|x86.Build.0 = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|x64.ActiveCfg = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|x64.Build.0 = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|x86.ActiveCfg = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Debug|x86.Build.0 = Debug|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|Any CPU.Build.0 = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|x64.ActiveCfg = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|x64.Build.0 = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|x86.ActiveCfg = Release|Any CPU - {8860810C-5E46-4E60-8924-C6C77BBC6EB2}.Release|x86.Build.0 = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|x64.ActiveCfg = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|x64.Build.0 = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|x86.ActiveCfg = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Debug|x86.Build.0 = Debug|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|Any CPU.Build.0 = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|x64.ActiveCfg = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|x64.Build.0 = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|x86.ActiveCfg = Release|Any CPU - {9F0BFA49-8711-4143-B813-ACD0D0B003FD}.Release|x86.Build.0 = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|x64.ActiveCfg = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|x64.Build.0 = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|x86.ActiveCfg = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Debug|x86.Build.0 = Debug|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|Any CPU.Build.0 = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|x64.ActiveCfg = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|x64.Build.0 = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|x86.ActiveCfg = Release|Any CPU - {56B15268-DEBC-4E9F-8554-03737A39D71B}.Release|x86.Build.0 = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|x64.ActiveCfg = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|x64.Build.0 = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|x86.ActiveCfg = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Debug|x86.Build.0 = Debug|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|Any CPU.Build.0 = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|x64.ActiveCfg = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|x64.Build.0 = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|x86.ActiveCfg = Release|Any CPU - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7}.Release|x86.Build.0 = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|x64.ActiveCfg = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|x64.Build.0 = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|x86.ActiveCfg = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Debug|x86.Build.0 = Debug|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|Any CPU.Build.0 = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|x64.ActiveCfg = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|x64.Build.0 = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|x86.ActiveCfg = Release|Any CPU - {04174210-4A5D-4F26-883E-B52B7B167EAC}.Release|x86.Build.0 = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|Any CPU.Build.0 = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|x64.ActiveCfg = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|x64.Build.0 = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|x86.ActiveCfg = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Debug|x86.Build.0 = Debug|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|Any CPU.ActiveCfg = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|Any CPU.Build.0 = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|x64.ActiveCfg = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|x64.Build.0 = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|x86.ActiveCfg = Release|Any CPU - {310733D1-2BF4-44D7-9947-93E29FA44310}.Release|x86.Build.0 = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|x64.ActiveCfg = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|x64.Build.0 = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|x86.ActiveCfg = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Debug|x86.Build.0 = Debug|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|Any CPU.Build.0 = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|x64.ActiveCfg = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|x64.Build.0 = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|x86.ActiveCfg = Release|Any CPU - {C45058FC-A657-4D13-AF2A-6E0B30C444A6}.Release|x86.Build.0 = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|x64.ActiveCfg = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|x64.Build.0 = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|x86.ActiveCfg = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Debug|x86.Build.0 = Debug|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|Any CPU.Build.0 = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|x64.ActiveCfg = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|x64.Build.0 = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|x86.ActiveCfg = Release|Any CPU - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6}.Release|x86.Build.0 = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|x64.ActiveCfg = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|x64.Build.0 = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|x86.ActiveCfg = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Debug|x86.Build.0 = Debug|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|Any CPU.Build.0 = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|x64.ActiveCfg = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|x64.Build.0 = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|x86.ActiveCfg = Release|Any CPU - {187E9876-28EC-43D7-B70E-2C09E66D59BD}.Release|x86.Build.0 = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|x64.ActiveCfg = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|x64.Build.0 = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|x86.ActiveCfg = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Debug|x86.Build.0 = Debug|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|Any CPU.Build.0 = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|x64.ActiveCfg = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|x64.Build.0 = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|x86.ActiveCfg = Release|Any CPU - {7FD67842-0549-4062-ACAB-3C417BD218C1}.Release|x86.Build.0 = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|x64.ActiveCfg = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|x64.Build.0 = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|x86.ActiveCfg = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Debug|x86.Build.0 = Debug|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|Any CPU.Build.0 = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|x64.ActiveCfg = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|x64.Build.0 = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|x86.ActiveCfg = Release|Any CPU - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {EB3ABF3B-295C-4BDD-8EA2-B60F30BC5E6C} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {608A1D85-0999-4A9B-956A-11B91A1CB065} = {D3C17830-A461-4BA5-A672-461B19B33936} - {9A46374D-029C-4B87-88E3-0BE5D1D44C35} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {D7029339-3794-4275-893A-E705D872BFBE} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {2C6CE3D7-D2DF-49F7-B3AF-5767E1C3705A} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {BCCDD838-8368-418D-82B5-5389FDDF0ADD} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {8860810C-5E46-4E60-8924-C6C77BBC6EB2} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {9F0BFA49-8711-4143-B813-ACD0D0B003FD} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {56B15268-DEBC-4E9F-8554-03737A39D71B} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {2D3523BB-CF07-47D0-82F4-6B5621A8C1D7} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {04174210-4A5D-4F26-883E-B52B7B167EAC} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {310733D1-2BF4-44D7-9947-93E29FA44310} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {C45058FC-A657-4D13-AF2A-6E0B30C444A6} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {1F03D5F0-238E-48B0-BAE4-88B1E60B69C6} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {187E9876-28EC-43D7-B70E-2C09E66D59BD} = {D35087BF-941A-49EA-96A8-B10457C4D169} - {7FD67842-0549-4062-ACAB-3C417BD218C1} = {52F7988F-452D-46C2-A144-D85E0CF371C6} - {26297E78-023D-4F3C-4F39-A7CC4FA9AF21} = {D35087BF-941A-49EA-96A8-B10457C4D169} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9397EEB2-E3A3-4748-A106-3DE17F40E698} - EndGlobalSection -EndGlobal diff --git a/src/NEventStore.Example/AggregateMemento.cs b/src/NEventStore.Example/AggregateMemento.cs deleted file mode 100644 index 208491aa3..000000000 --- a/src/NEventStore.Example/AggregateMemento.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace NEventStore.Example -{ - internal class AggregateMemento - { - public string? Value { get; set; } - - public override string? ToString() - { - return Value; - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Example/AuthorizationPipelineHook.cs b/src/NEventStore.Example/AuthorizationPipelineHook.cs deleted file mode 100644 index 6563205ba..000000000 --- a/src/NEventStore.Example/AuthorizationPipelineHook.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace NEventStore.Example -{ - public class AuthorizationPipelineHook : PipelineHookBase - { - public override ICommit? SelectCommit(ICommit committed) - { - // return null if the user isn't authorized to see this commit - return committed; - } - - public override void PostCommit(ICommit committed) - { - // anything to do after the commit has been persisted. - } - - public override bool PreCommit(CommitAttempt attempt) - { - // Can easily do logging or other such activities here - return true; // true == allow commit to continue, false = stop. - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Example/MainProgram.cs b/src/NEventStore.Example/MainProgram.cs deleted file mode 100644 index 1197b095a..000000000 --- a/src/NEventStore.Example/MainProgram.cs +++ /dev/null @@ -1,157 +0,0 @@ -using Microsoft.Extensions.Logging; - -namespace NEventStore.Example -{ - internal static class MainProgram - { - private static readonly Guid StreamId = Guid.NewGuid(); // aggregate identifier - - private static IStoreEvents? store; - - private static void Main() - { - // Console.WindowWidth = Console.LargestWindowWidth - 20; - - Console.WriteLine("------------------"); - Console.WriteLine("Using Sync Methods"); - Console.WriteLine("------------------"); - Console.WriteLine(); - - using (store = WireupEventStore()) - { - OpenOrCreateStream(); - AppendToStream(); - TakeSnapshot(); - LoadFromSnapshotForwardAndAppend(); - } - - Console.WriteLine(); - Console.WriteLine("-------------------"); - Console.WriteLine("Using Async Methods"); - Console.WriteLine("-------------------"); - Console.WriteLine(); - - Task.Run(async () => - { - using (store = WireupEventStore()) - { - await OpenOrCreateStreamAsync(); - await AppendToStreamAsync(); - await TakeSnapshotAsync(); - await LoadFromSnapshotForwardAndAppendAsync(); - } - }).GetAwaiter().GetResult(); - - Console.WriteLine("Press any key to continue..."); - Console.ReadKey(); - } - - private static IStoreEvents WireupEventStore() - { - var loggerFactory = LoggerFactory.Create(logging => - { - logging - .AddConsole() - .AddDebug() - .SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); - }); - - return Wireup.Init() - .WithLoggerFactory(loggerFactory) - .UseOptimisticPipelineHook() - .UsingInMemoryPersistence() - .InitializeStorageEngine() -#if NET462 - .TrackPerformanceInstance("example") -#endif - .HookIntoPipelineUsing(new AuthorizationPipelineHook()) - .Build(); - } - - #region Sync Methods - - private static void OpenOrCreateStream() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = store!.OpenStream(StreamId, 0, int.MaxValue); - var @event = new SomeDomainEvent { Value = "Initial event." }; - - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - - private static void AppendToStream() - { - using var stream = store!.OpenStream(StreamId); - var @event = new SomeDomainEvent { Value = "Second event." }; - - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - - private static void TakeSnapshot() - { - var memento = new AggregateMemento { Value = "snapshot" }; - store!.Advanced.AddSnapshot(new Snapshot(StreamId.ToString(), 2, memento)); - } - - private static void LoadFromSnapshotForwardAndAppend() - { - var latestSnapshot = store!.Advanced.GetSnapshot(StreamId, int.MaxValue) - ?? throw new InvalidOperationException("No snapshot found."); - - using var stream = store.OpenStream(latestSnapshot, int.MaxValue); - var @event = new SomeDomainEvent { Value = "Third event (first one after a snapshot)." }; - - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - - #endregion - - #region Async Methods - - private static async Task OpenOrCreateStreamAsync() - { - // we can call CreateStream(StreamId) if we know there isn't going to be any data. - // or we can call OpenStream(StreamId, 0, int.MaxValue) to read all commits, - // if no commits exist then it creates a new stream for us. - using var stream = await store!.OpenStreamAsync(StreamId, 0, int.MaxValue, cancellationToken: CancellationToken.None); - var @event = new SomeDomainEvent { Value = "Initial event." }; - - stream.Add(new EventMessage { Body = @event }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None); - } - - private static async Task AppendToStreamAsync() - { - using var stream = await store!.OpenStreamAsync(StreamId, cancellationToken: CancellationToken.None); - var @event = new SomeDomainEvent { Value = "Second event." }; - - stream.Add(new EventMessage { Body = @event }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None); - } - - private static Task TakeSnapshotAsync() - { - var memento = new AggregateMemento { Value = "snapshot" }; - return store!.Advanced.AddSnapshotAsync(new Snapshot(StreamId.ToString(), 2, memento), CancellationToken.None); - } - - private static async Task LoadFromSnapshotForwardAndAppendAsync() - { - var latestSnapshot = await store!.Advanced.GetSnapshotAsync(StreamId, int.MaxValue, CancellationToken.None) - ?? throw new InvalidOperationException("No snapshot found."); - - using var stream = await store.OpenStreamAsync(latestSnapshot, int.MaxValue, CancellationToken.None); - var @event = new SomeDomainEvent { Value = "Third event (first one after a snapshot)." }; - - stream.Add(new EventMessage { Body = @event }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/NEventStore.Example/NEventStore.Example.csproj b/src/NEventStore.Example/NEventStore.Example.csproj deleted file mode 100644 index 5873988cc..000000000 --- a/src/NEventStore.Example/NEventStore.Example.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - net8.0;net472 - false - - exe - - Exe - - - - TRACE;DEBUG - - - - - - - - - - - - - - - - - - diff --git a/src/NEventStore.Example/Properties/ProjectAssemblyInfo.cs b/src/NEventStore.Example/Properties/ProjectAssemblyInfo.cs deleted file mode 100644 index 33cbc2e74..000000000 --- a/src/NEventStore.Example/Properties/ProjectAssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("NEventStore.Example")] -[assembly: AssemblyDescription("")] -[assembly: Guid("6fd621e0-9047-4449-b136-249383936d5c")] \ No newline at end of file diff --git a/src/NEventStore.Example/SomeDomainEvent.cs b/src/NEventStore.Example/SomeDomainEvent.cs deleted file mode 100644 index b83e751f9..000000000 --- a/src/NEventStore.Example/SomeDomainEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NEventStore.Example -{ - internal class SomeDomainEvent - { - public string? Value { get; set; } - } -} \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/BDD/MSTest/SpecificationBase.cs b/src/NEventStore.Persistence.AcceptanceTests/BDD/MSTest/SpecificationBase.cs deleted file mode 100644 index 43f014b67..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/BDD/MSTest/SpecificationBase.cs +++ /dev/null @@ -1,108 +0,0 @@ -#if MSTEST - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace NEventStore.Persistence.AcceptanceTests.BDD -{ - /// - /// - /// base class for BDD testing in a Given-When-Then style - /// using MSTest - /// - /// in MSTest each test will be executed by a new instance of the test class. - /// - /// this will be used to implement a class that will test a single - /// action or behavior and multiple result conditions - /// - /// - /// - a class will represent a single scenario - /// - the class name will describe the scenario name - /// - /// - [TestClass] - public abstract class SpecificationBase - { - Exception? testFixtureSetupException = null; - - /// - /// - /// there's a problem with error / exception reporting in here, test fixture setup is not well suited for - /// exception handling - /// workaround: - /// http://stackoverflow.com/questions/1411676/how-to-diagnose-testfixturesetup-failed - /// - /// - /// a good idea on how to catch and test for exceptions: - /// http://www.planetgeek.ch/2015/06/22/machine-specifications-the-alternative-nunit/ - /// - /// - /// maybe catch the generated exception with something like: Catch.Exception() shown here and save it to a local variable - /// in the when() function, then test for the exception in the 'then' tests - /// - /// - [TestInitialize] // I cannot have something like a OnTimeTestInitialize in MsTest, ClassInitialize requires static methods - public async Task SetUp() - { - try - { - Context(); - await ContextAsync(); - Because(); - await BecauseAsync(); - } - catch (Exception ex) - { - testFixtureSetupException = ex; - } - } - - [TestInitialize] - // NUnit doesn't support very useful logging of failures from a OneTimeSetUp method. We'll do the logging here. - public void CheckForTestFixtureFailure() - { - if (testFixtureSetupException != null) - { - string msg = string.Format("There was a failure during Context() or Because() phases.\n\rException: {0}\n\rStackTrace: {1}", - testFixtureSetupException.Message, testFixtureSetupException.StackTrace); - Assert.Fail(msg); - } - } - - protected virtual void Context() { } - protected virtual Task ContextAsync() { return Task.CompletedTask; } - protected virtual void Because() { } - protected virtual Task BecauseAsync() { return Task.CompletedTask; } - - [ClassCleanup] - protected virtual void Cleanup() { } - } - - /// - /// Attribute used to identify the tests - /// - /// for custom actions: - /// http://nunit.org/index.php?p=actionAttributes&r=2.6.3 - /// - /// - [AttributeUsage(AttributeTargets.Method)] - public class ThenAttribute : LogTestMethod; - - [AttributeUsage(AttributeTargets.Method)] - public class FactAttribute : LogTestMethod; - - public class LogTestMethod : TestMethodAttribute - { - public override TestResult[] Execute(ITestMethod testMethod) - { - Console.WriteLine("Scenario: {0}", testMethod.TestClassName); - - var result = base.Execute(testMethod); - - Console.WriteLine(" - {0} - {1}", testMethod.TestMethodName, result[0].Outcome == UnitTestOutcome.Passed); - - return result; - } - } -} - -#endif \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/BDD/NUnit/SpecificationBase.cs b/src/NEventStore.Persistence.AcceptanceTests/BDD/NUnit/SpecificationBase.cs deleted file mode 100644 index 7f75e85e6..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/BDD/NUnit/SpecificationBase.cs +++ /dev/null @@ -1,145 +0,0 @@ -#if NUNIT - -using NUnit.Framework; -using NUnit.Framework.Interfaces; - -namespace NEventStore.Persistence.AcceptanceTests.BDD -{ - /// - /// - /// base class for BDD testing in a Given-When-Then style - /// using NUnit - /// - /// - /// this will be used to implement a class that will test a single - /// action or behavior and multiple result conditions: - /// - a class will represent a single scenario - /// - the class name will describe the scenario name - /// - /// - [TestFixture] - [LogSuiteAttribute] - [LogTestAttribute] - public abstract class SpecificationBase - { - private Exception? testFixtureSetupException = null; - - /// - /// - /// there's a problem with error / exception reporting in here, test fixture setup is not well suited for - /// exception handling - /// workaround: - /// http://stackoverflow.com/questions/1411676/how-to-diagnose-testfixturesetup-failed - /// - /// - /// a good idea on how to catch and test for exceptions: - /// http://www.planetgeek.ch/2015/06/22/machine-specifications-the-alternative-nunit/ - /// - /// - /// maybe catch the generated exception with something like: Catch.Exception() shown here and save it to a local variable - /// in the when() function, then test for the exception in the 'then' tests - /// - /// - [OneTimeSetUp] - public async Task SetUp() - { - try - { - Context(); - await ContextAsync(); - Because(); - await BecauseAsync(); - } - catch (Exception ex) - { - testFixtureSetupException = ex; - } - } - - [SetUp] - // NUnit doesn't support very useful logging of failures from a OneTimeSetUp method. We'll do the logging here. - public void CheckForTestFixtureFailure() - { - if (testFixtureSetupException != null) - { - string msg = string.Format("There was a failure during Context() or Because() phases.\n\rException: {0}\n\rStackTrace: {1}", - testFixtureSetupException.Message, testFixtureSetupException.StackTrace); - Assert.Fail(msg); - } - } - - protected virtual void Context() { } - protected virtual Task ContextAsync() { return Task.CompletedTask; } - protected virtual void Because() { } - protected virtual Task BecauseAsync() { return Task.CompletedTask; } - - [OneTimeTearDown] - protected virtual void Cleanup() { } - } - - /// - /// - /// Attribute used to identify the tests - /// - /// - /// for custom actions: - /// http://nunit.org/index.php?p=actionAttributes&r=2.6.3 - /// - /// - [AttributeUsage(AttributeTargets.Method)] - public class ThenAttribute : TestAttribute; - - [AttributeUsage(AttributeTargets.Method)] - public class FactAttribute : TestAttribute; - - [AttributeUsageAttribute(AttributeTargets.Class)] - public class LogSuiteAttribute : Attribute, ITestAction - { - public void AfterTest(ITest test) - { - // Method intentionally left empty. - } - - public void BeforeTest(ITest test) - { - Console.WriteLine("Scenario: {0}", test?.Fixture?.GetType().Name); - } - - public ActionTargets Targets - { - get { return ActionTargets.Suite; } - } - } - - /// - /// - /// Attribute used to identify the tests - /// and describe them - /// - /// - /// for custom actions: - /// http://nunit.org/index.php?p=actionAttributes&r=2.6.3 - /// http://nunit.org/index.php?p=testContext&r=2.6.3 - /// - /// - [AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false)] - public class LogTestAttribute : Attribute, ITestAction - { - public void AfterTest(ITest test) - { - Console.WriteLine(" - {0} - {1}", test?.Method?.Name, TestContext.CurrentContext.Result.Outcome.Status); - } - - public void BeforeTest(ITest test) - { - Console.WriteLine(test?.Fixture?.GetType().Name); - } - - public ActionTargets Targets - { - get { return ActionTargets.Test; } - } - } -} - -#endif \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBase.cs b/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBase.cs deleted file mode 100644 index 58832237c..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBase.cs +++ /dev/null @@ -1,34 +0,0 @@ -#if XUNIT - -namespace NEventStore.Persistence.AcceptanceTests.BDD -{ - - using Xunit; - - - [RunWith(typeof (SpecificationBaseRunner))] - public abstract class SpecificationBase - { - protected virtual void Because() - {} - - protected virtual void Cleanup() - {} - - protected virtual void Context() - {} - - public void OnFinish() - { - Cleanup(); - } - - public void OnStart() - { - Context(); - Because(); - } - } -} - -#endif \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBaseRunner.cs b/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBaseRunner.cs deleted file mode 100644 index a46340a13..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/BDD/SpecificationBaseRunner.cs +++ /dev/null @@ -1,168 +0,0 @@ -#if XUNIT - -namespace NEventStore.Persistence.AcceptanceTests.BDD -{ - using System; - using System.Collections.Generic; - using System.Reflection; - using Xunit; - using Xunit.Sdk; - - internal class SpecificationBaseRunner : ITestClassCommand - { - private readonly List _fixtures = new List(); - private SpecificationBase _objectUnderTest; - - public SpecificationBase ObjectUnderTest - { - get - { - if (_objectUnderTest == null) - { - GuardTypeUnderTest(); - _objectUnderTest = (SpecificationBase) Activator.CreateInstance(TypeUnderTest.Type); - } - - return _objectUnderTest; - } - } - - object ITestClassCommand.ObjectUnderTest - { - get { return ObjectUnderTest; } - } - - public ITypeInfo TypeUnderTest { get; set; } - - public int ChooseNextTest(ICollection testsLeftToRun) - { - return 0; - } - - public Exception ClassStart() - { - try - { - SetupFixtures(); - ObjectUnderTest.OnStart(); - return null; - } - catch (Exception ex) - { - return ex; - } - } - - public Exception ClassFinish() - { - try - { - ObjectUnderTest.OnFinish(); - - foreach (var fixtureData in _fixtures) - { - var disposable = fixtureData as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - } - - return null; - } - catch (Exception ex) - { - return ex; - } - } - - public IEnumerable EnumerateTestCommands(IMethodInfo testMethod) - { - string displayName = (TypeUnderTest.Type.Name + ", it " + testMethod.Name).Replace('_', ' '); - return new[] {new SpecTestCommand(testMethod, displayName)}; - } - - public IEnumerable EnumerateTestMethods() - { - GuardTypeUnderTest(); - - return TypeUtility.GetTestMethods(TypeUnderTest); - } - - public bool IsTestMethod(IMethodInfo testMethod) - { - return MethodUtility.IsTest(testMethod); - } - - private void SetupFixtures() - { - try - { - foreach (var @interface in TypeUnderTest.Type.GetInterfaces()) - { - if (@interface.IsGenericType) - { - Type genericDefinition = @interface.GetGenericTypeDefinition(); - - if (genericDefinition == typeof (IUseFixture<>)) - { - Type dataType = @interface.GetGenericArguments()[0]; - if (dataType == TypeUnderTest.Type) - { - throw new InvalidOperationException("Cannot use a test class as its own fixture data"); - } - - object fixtureData = null; - - fixtureData = Activator.CreateInstance(dataType); - - MethodInfo method = @interface.GetMethod("SetFixture", new[] {dataType}); - _fixtures.Add(fixtureData); - method.Invoke(ObjectUnderTest, new[] {fixtureData}); - } - } - } - } - catch (TargetInvocationException ex) - { - ExceptionUtility.RethrowWithNoStackTraceLoss(ex.InnerException); - } - } - - private void GuardTypeUnderTest() - { - if (TypeUnderTest == null) - { - throw new InvalidOperationException("Forgot to set TypeUnderTest before calling ObjectUnderTest"); - } - - if (!typeof (SpecificationBase).IsAssignableFrom(TypeUnderTest.Type)) - { - throw new InvalidOperationException("SpecificationBaseRunner can only be used with types that derive from SpecificationBase"); - } - } - - private class SpecTestCommand : TestCommand - { - public SpecTestCommand(IMethodInfo testMethod, string displayName) : base(testMethod, displayName, 0) - {} - - public override MethodResult Execute(object testClass) - { - try - { - testMethod.Invoke(testClass, null); - } - catch (ParameterCountMismatchException) - { - throw new InvalidOperationException("Observation " + TypeName + "." + MethodName + " cannot have parameters"); - } - - return new PassedResult(testMethod, DisplayName); - } - } - } - -} - -#endif \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/Catch.cs b/src/NEventStore.Persistence.AcceptanceTests/Catch.cs deleted file mode 100644 index a99a08b1d..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/Catch.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace NEventStore.Persistence.AcceptanceTests -{ - public static class Catch - { - public static Exception? Exception(Action action) - { - try - { - action(); - } - catch (Exception ex) - { - return ex; - } - - return null; - } - - public static async Task ExceptionAsync(Func action) - { - try - { - await action(); - } - catch (Exception ex) - { - return ex; - } - - return null; - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/ConfigurationExtensions.cs b/src/NEventStore.Persistence.AcceptanceTests/ConfigurationExtensions.cs deleted file mode 100644 index bc734f738..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/ConfigurationExtensions.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace NEventStore.Persistence.AcceptanceTests -{ - using System; - using System.Configuration; - using System.Linq; - - public static class ConfigurationExtensions - { - public static string GetSetting(this string settingName) - { - return GetCommandLineArgument("/" + settingName + ":") ?? - Environment.GetEnvironmentVariable(settingName) ?? ConfigurationManager.AppSettings[settingName]; - } - - private static string GetCommandLineArgument(string settingName) - { - return - Environment.GetCommandLineArgs() - .Where(arg => arg.StartsWith(settingName)) - .Select(arg => arg.Replace(settingName, string.Empty)) - .FirstOrDefault(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/ExtensionMethods.cs b/src/NEventStore.Persistence.AcceptanceTests/ExtensionMethods.cs deleted file mode 100644 index 435b434b1..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/ExtensionMethods.cs +++ /dev/null @@ -1,186 +0,0 @@ -namespace NEventStore.Persistence.AcceptanceTests -{ - public static class ExtensionMethods - { - public static HashSet ToHashSet(this IEnumerable collection) - { - return new HashSet(collection); - } - - public static LinkedList ToLinkedList(this IEnumerable collection) - { - return new LinkedList(collection); - } - - public static ICommit? CommitSingle(this IPersistStreams persistence, string? streamId = null) - { - CommitAttempt commitAttempt = (streamId ?? Guid.NewGuid().ToString()).BuildAttempt(); - return persistence.Commit(commitAttempt); - } - - public static Task CommitSingleAsync(this IPersistStreams persistence, string? streamId = null) - { - CommitAttempt commitAttempt = (streamId ?? Guid.NewGuid().ToString()).BuildAttempt(); - return persistence.CommitAsync(commitAttempt, CancellationToken.None); - } - - public static ICommit? CommitNext(this IPersistStreams persistence, ICommit previous) - { - var nextAttempt = previous.BuildNextAttempt(); - return persistence.Commit(nextAttempt); - } - - public static Task CommitNextAsync(this IPersistStreams persistence, ICommit previous) - { - var nextAttempt = previous.BuildNextAttempt(); - return persistence.CommitAsync(nextAttempt, CancellationToken.None); - } - - public static ICommit? CommitNext(this IPersistStreams persistence, CommitAttempt previous) - { - var nextAttempt = previous.BuildNextAttempt(); - return persistence.Commit(nextAttempt); - } - - public static Task CommitNextAsync(this IPersistStreams persistence, CommitAttempt previous) - { - var nextAttempt = previous.BuildNextAttempt(); - return persistence.CommitAsync(nextAttempt, CancellationToken.None); - } - - public static IEnumerable CommitMany(this IPersistStreams persistence, int numberOfCommits, string? streamId = null, string? bucketId = null) - { - var commits = new List(); - CommitAttempt? attempt = null; - - for (int i = 0; i < numberOfCommits; i++) - { - attempt = attempt == null ? (streamId ?? Guid.NewGuid().ToString()).BuildAttempt(null, bucketId) : attempt.BuildNextAttempt(); - persistence.Commit(attempt); - commits.Add(attempt); - } - - return commits; - } - - public static async Task> CommitManyAsync(this IPersistStreams persistence, int numberOfCommits, string? streamId = null, string? bucketId = null) - { - var commits = new List(); - CommitAttempt? attempt = null; - for (int i = 0; i < numberOfCommits; i++) - { - attempt = attempt == null ? (streamId ?? Guid.NewGuid().ToString()).BuildAttempt(null, bucketId) : attempt.BuildNextAttempt(); - await persistence.CommitAsync(attempt, CancellationToken.None).ConfigureAwait(false); - commits.Add(attempt); - } - return commits; - } - - public static CommitAttempt BuildAttempt(this string streamId, DateTime? now = null, string? bucketId = null) - { - now ??= SystemTime.UtcNow; - bucketId ??= Bucket.Default; - - var messages = new EventMessage[] - { - new() {Body = new SomeDomainEvent {SomeProperty = "Test"}}, - new() {Body = new SomeDomainEvent {SomeProperty = "Test2"}}, - }; - - return new CommitAttempt( - bucketId: bucketId, - streamId: streamId, - streamRevision: 2, - commitId: Guid.NewGuid(), - commitSequence: 1, - commitStamp: now.Value, - headers: new Dictionary { { "A header", "A string value" }, { "Another header", 2 } }, - events: messages - ); - } - - public static CommitAttempt BuildNextAttempt(this ICommit commit) - { - var messages = new EventMessage[] - { - new() {Body = new SomeDomainEvent {SomeProperty = "Another test"}}, - new() {Body = new SomeDomainEvent {SomeProperty = "Another test2"}}, - }; - - return new CommitAttempt(commit.BucketId, - commit.StreamId, - commit.StreamRevision + messages.Length, - Guid.NewGuid(), - commit.CommitSequence + 1, - commit.CommitStamp.AddSeconds(1), - new Dictionary(), - messages); - } - - public static CommitAttempt BuildNextAttempt(this CommitAttempt commit) - { - var messages = new EventMessage[] - { - new() {Body = new SomeDomainEvent {SomeProperty = "Another test"}}, - new() {Body = new SomeDomainEvent {SomeProperty = "Another test2"}}, - }; - - return new CommitAttempt(commit.BucketId, - commit.StreamId, - commit.StreamRevision + 2, - Guid.NewGuid(), - commit.CommitSequence + 1, - commit.CommitStamp.AddSeconds(1), - new Dictionary(), - messages); - } - - public static SimpleMessage Populate(this SimpleMessage message) - { - message ??= new SimpleMessage(); - - return new SimpleMessage - { - Id = Guid.NewGuid(), - Count = 1234, - Created = new DateTime(2000, 2, 3, 4, 5, 6, 7).ToUniversalTime(), - Value = message.Value + "Hello, World!", - Contents = { "a", null, string.Empty, "d" } - }; - } - - public static CommitAttempt BuildCommit(this string streamId) - { - const int streamRevision = 2; - const int commitSequence = 2; - Guid commitId = Guid.NewGuid(); - var headers = new Dictionary { { "Key", "Value" }, { "Key2", (long)1234 }, { "Key3", null! } }; - var events = new[] - { - new EventMessage - { - Headers = {{"MsgKey1", TimeSpan.MinValue}, {"MsgKey2", Guid.NewGuid()}, {"MsgKey3", 1.1M}, {"MsgKey4", (ushort) 1}}, - Body = "some value" - }, - new EventMessage - { - Headers = {{"MsgKey1", new Uri("http://www.google.com/")}, {"MsgKey4", "some header"}}, - Body = new[] {"message body"} - } - }; - - return new CommitAttempt(streamId, streamRevision, commitId, commitSequence, SystemTime.UtcNow, headers, events); - } - - [Serializable] - public class SomeDomainEvent - { - public string? SomeProperty { get; set; } - - public override string? ToString() - { - return SomeProperty; - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/NEventStore.Persistence.AcceptanceTests.Core.csproj b/src/NEventStore.Persistence.AcceptanceTests/NEventStore.Persistence.AcceptanceTests.Core.csproj deleted file mode 100644 index 4c8eedd06..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/NEventStore.Persistence.AcceptanceTests.Core.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - net8.0;net472 - false - NEventStore.Persistence.AcceptanceTests - false - NEventStore.Persistence.AcceptanceTests - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Async.cs b/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Async.cs deleted file mode 100644 index 1feab90ee..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Async.cs +++ /dev/null @@ -1,1631 +0,0 @@ -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -using NUnit.Framework; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.Persistence.AcceptanceTests.Async -{ -#if MSTEST - [TestClass] -#endif - public class when_a_commit_header_has_a_name_that_contains_a_period : PersistenceEngineConcernAsync - { - private ICommit? _persisted; - private string? _streamId; - - protected override Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - var attempt = new CommitAttempt(_streamId, - 2, - Guid.NewGuid(), - 1, - DateTime.UtcNow, - new Dictionary { { "key.1", "value" } }, - [new EventMessage { Body = new ExtensionMethods.SomeDomainEvent { SomeProperty = "Test" } }]); - return Persistence.CommitAsync(attempt, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_streamId!, 0, int.MaxValue, observer, CancellationToken.None); - _persisted = observer.Commits[0]; - } - - [Fact] - public void should_correctly_deserialize_headers() - { - _persisted.Should().NotBeNull(); - _persisted!.Headers.Keys.Should().Contain("key.1"); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_commit_is_successfully_persisted : PersistenceEngineConcernAsync - { - private CommitAttempt? _attempt; - private DateTime _now; - private ICommit? _persisted; - private string? _streamId; - - protected override Task ContextAsync() - { - _now = SystemTime.UtcNow.AddYears(1); - _streamId = Guid.NewGuid().ToString(); - _attempt = _streamId.BuildAttempt(_now); - - return Persistence.CommitAsync(_attempt, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_streamId!, 0, int.MaxValue, observer, CancellationToken.None); - _persisted = observer.Commits[0]; - } - - [Fact] - public void should_correctly_persist_the_stream_identifier() - { - _persisted!.StreamId.Should().Be(_attempt!.StreamId); - } - - [Fact] - public void should_correctly_persist_the_stream_stream_revision() - { - _persisted!.StreamRevision.Should().Be(_attempt!.StreamRevision); - } - - [Fact] - public void should_correctly_persist_the_commit_identifier() - { - _persisted!.CommitId.Should().Be(_attempt!.CommitId); - } - - [Fact] - public void should_correctly_persist_the_commit_sequence() - { - _persisted!.CommitSequence.Should().Be(_attempt!.CommitSequence); - } - - // persistence engines have varying levels of precision with respect to time. - [Fact] - public void should_correctly_persist_the_commit_stamp() - { - var difference = _persisted!.CommitStamp.Subtract(_now); - difference.Days.Should().Be(0); - difference.Hours.Should().Be(0); - difference.Minutes.Should().Be(0); - difference.Should().BeLessOrEqualTo(TimeSpan.FromSeconds(1)); - } - - [Fact] - public void should_correctly_persist_the_headers() - { - _persisted!.Headers.Count.Should().Be(_attempt!.Headers.Count); - } - - [Fact] - public void should_correctly_persist_the_events() - { - _persisted!.Events.Count.Should().Be(_attempt!.Events.Count); - } - - [Fact] - public async Task should_cause_the_stream_to_be_found_in_the_list_of_streams_to_snapshot() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(1, observer, CancellationToken.None); - observer.StreamHeads - .FirstOrDefault(x => x.StreamId == _streamId).Should().NotBeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_given_revision : PersistenceEngineConcernAsync - { - private const int LoadFromCommitContainingRevision = 3; - private const int UpToCommitWithContainingRevision = 5; - private ICommit[]? _committed; - private ICommit? _oldest, _oldest2, _oldest3; - private string? _streamId; - - protected override async Task ContextAsync() - { - _oldest = await Persistence.CommitSingleAsync(); // 2 events, revision 1-2 - _oldest2 = await Persistence.CommitNextAsync(_oldest!); // 2 events, revision 3-4 - _oldest3 = await Persistence.CommitNextAsync(_oldest2!); // 2 events, revision 5-6 - await Persistence.CommitNextAsync(_oldest3!); // 2 events, revision 7-8 - - _streamId = _oldest!.StreamId; - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_streamId!, LoadFromCommitContainingRevision, UpToCommitWithContainingRevision, observer, CancellationToken.None); - _committed = observer.Commits.ToArray(); - } - - [Fact] - public void should_start_from_the_commit_which_contains_the_min_stream_revision_specified() - { - _committed![0].CommitId.Should().Be(_oldest2!.CommitId); // contains revision 3 - } - - [Fact] - public void should_read_up_to_the_commit_which_contains_the_max_stream_revision_specified() - { - _committed!.Last().CommitId.Should().Be(_oldest3!.CommitId); // contains revision 5 - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_given_revision_to_commit_revision : PersistenceEngineConcernAsync - { - private const int LoadFromCommitContainingRevision = 3; - private const int UpToCommitWithContainingRevision = 6; - private ICommit[]? _committed; - private ICommit? _oldest, _oldest2, _oldest3; - private string? _streamId; - - protected override async Task ContextAsync() - { - _oldest = await Persistence.CommitSingleAsync(); // 2 events, revision 1-2 - _oldest2 = await Persistence.CommitNextAsync(_oldest!); // 2 events, revision 3-4 - _oldest3 = await Persistence.CommitNextAsync(_oldest2!); // 2 events, revision 5-6 - await Persistence.CommitNextAsync(_oldest3!); // 2 events, revision 7-8 - - _streamId = _oldest!.StreamId; - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_streamId!, LoadFromCommitContainingRevision, UpToCommitWithContainingRevision, observer, CancellationToken.None); - _committed = observer.Commits.ToArray(); - } - - [Fact] - public void should_start_from_the_commit_which_contains_the_min_stream_revision_specified() - { - _committed![0].CommitId.Should().Be(_oldest2!.CommitId); // contains revision 3 - } - - [Fact] - public void should_read_up_to_the_commit_which_contains_the_max_stream_revision_specified() - { - _committed!.Last().CommitId.Should().Be(_oldest3!.CommitId); // contains revision 6 - } - } - - public class when_observer_stops_reading_the_stream_after_2_commits : PersistenceEngineConcernAsync - { - private ICommit? _oldest, _oldest2, _oldest3; - private string? _streamId; - - protected override async Task ContextAsync() - { - _oldest = await Persistence.CommitSingleAsync(); // 2 events, revision 1-2 - _oldest2 = await Persistence.CommitNextAsync(_oldest!); // 2 events, revision 3-4 - _oldest3 = await Persistence.CommitNextAsync(_oldest2!); // 2 events, revision 5-6 - await Persistence.CommitNextAsync(_oldest3!); // 2 events, revision 7-8 - - _streamId = _oldest!.StreamId; - } - - [Fact] - public async Task ICommitEvents_GetFromAsync_stops_after_2_commits() - { - bool _observerCompleted = false; - var _committed = new List(); - var observer = new LambdaAsyncObserver( - onNextAsync: (c, _) => - { - if (_committed.Count <= 1) - { - _committed.Add(c); - return Task.FromResult(true); - } - // do not read more than 2 commits - return Task.FromResult(false); - }, - onCompletedAsync: (_) => - { - _observerCompleted = true; - return Task.CompletedTask; - }); - await Persistence.GetFromAsync(Bucket.Default, _streamId!, 0, int.MaxValue, observer, CancellationToken.None); - - _committed!.Count.Should().Be(2); - _observerCompleted.Should().BeTrue(); - } - - [Fact] - public async Task IPersistStreams_GetFromAsync_Checkpoint_stops_after_2_commits() - { - bool _observerCompleted = false; - var _committed = new List(); - var observer = new LambdaAsyncObserver( - onNextAsync: (c, _) => - { - if (_committed.Count <= 1) - { - _committed.Add(c); - return Task.FromResult(true); - } - // do not read more than 2 commits - return Task.FromResult(false); - }, - onCompletedAsync: (_) => - { - _observerCompleted = true; - return Task.CompletedTask; - }); - await Persistence.GetFromAsync(0, observer, CancellationToken.None); - - _committed!.Count.Should().Be(2); - _observerCompleted.Should().BeTrue(); - } - - [Fact] - public async Task IPersistStreams_GetFromToAsync_Checkpoint_stops_after_2_commits() - { - bool _observerCompleted = false; - var _committed = new List(); - var observer = new LambdaAsyncObserver( - onNextAsync: (c, _) => - { - if (_committed.Count <= 1) - { - _committed.Add(c); - return Task.FromResult(true); - } - // do not read more than 2 commits - return Task.FromResult(false); - }, - onCompletedAsync: (_) => - { - _observerCompleted = true; - return Task.CompletedTask; - }); - await Persistence.GetFromToAsync(0, long.MaxValue, observer, CancellationToken.None); - - _committed!.Count.Should().Be(2); - _observerCompleted.Should().BeTrue(); - } - - [Fact] - public async Task IPersistStreams_GetFromAsync_Bucket_Checkpoint_stops_after_2_commits() - { - bool _observerCompleted = false; - var _committed = new List(); - var observer = new LambdaAsyncObserver( - onNextAsync: (c, _) => - { - if (_committed.Count <= 1) - { - _committed.Add(c); - return Task.FromResult(true); - } - // do not read more than 2 commits - return Task.FromResult(false); - }, - onCompletedAsync: (_) => - { - _observerCompleted = true; - return Task.CompletedTask; - }); - await Persistence.GetFromAsync(Bucket.Default, 0, observer, CancellationToken.None); - - _committed!.Count.Should().Be(2); - _observerCompleted.Should().BeTrue(); - } - - [Fact] - public async Task IPersistStreams_GetFromToAsync_Bucket_Checkpoint_stops_after_2_commits() - { - bool _observerCompleted = false; - var _committed = new List(); - var observer = new LambdaAsyncObserver( - onNextAsync: (c, _) => - { - if (_committed.Count <= 1) - { - _committed.Add(c); - return Task.FromResult(true); - } - // do not read more than 2 commits - return Task.FromResult(false); - }, - onCompletedAsync: (_) => - { - _observerCompleted = true; - return Task.CompletedTask; - }); - await Persistence.GetFromToAsync(Bucket.Default, 0, long.MaxValue, observer, CancellationToken.None); - - _committed!.Count.Should().Be(2); - _observerCompleted.Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_revision : PersistenceEngineConcernAsync - { - private CommitAttempt? _attemptWithSameRevision; - private Exception? _thrown; - - protected override async Task ContextAsync() - { - var commit = await Persistence.CommitSingleAsync(); - _attemptWithSameRevision = commit!.StreamId.BuildAttempt(); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_attemptWithSameRevision!, CancellationToken.None)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - - // This test ensure the uniqueness of BucketId+StreamId+CommitSequence - // to avoid concurrency issues -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_sequence : PersistenceEngineConcernAsync - { - private CommitAttempt? _attempt1, _attempt2; - private Exception? _thrown; - - protected override Task ContextAsync() - { - string streamId = Guid.NewGuid().ToString(); - _attempt1 = streamId.BuildAttempt(); - _attempt2 = new CommitAttempt( - _attempt1.BucketId, // <--- Same bucket - _attempt1.StreamId, // <--- Same stream it - _attempt1.StreamRevision + 10, - Guid.NewGuid(), - _attempt1.CommitSequence, // <--- Same commit seq - DateTime.UtcNow, - _attempt1.Headers, - [ - new EventMessage(){ Body = new ExtensionMethods.SomeDomainEvent {SomeProperty = "Test 3"}} - ] - ); - - return Persistence.CommitAsync(_attempt1, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_attempt2!, CancellationToken.None)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - - //TODO:This test looks exactly like the one above. What are we trying to prove? -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_overwrite_a_committed_sequence : PersistenceEngineConcernAsync - { - private CommitAttempt? _failedAttempt; - private Exception? _thrown; - - protected override async Task ContextAsync() - { - string streamId = Guid.NewGuid().ToString(); - CommitAttempt successfulAttempt = streamId.BuildAttempt(); - await Persistence.CommitAsync(successfulAttempt, CancellationToken.None); - _failedAttempt = streamId.BuildAttempt(); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_failedAttempt!, CancellationToken.None)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_persist_a_commit_twice : PersistenceEngineConcernAsync - { - private CommitAttempt? _attemptTwice; - private Exception? _thrown; - - protected override async Task ContextAsync() - { - var commit = await Persistence.CommitSingleAsync(); - _attemptTwice = new CommitAttempt( - commit!.BucketId, - commit.StreamId, - commit.StreamRevision, - commit.CommitId, - commit.CommitSequence, - commit.CommitStamp, - commit.Headers.ToDictionary(k => k.Key, v => v.Value), - commit.Events.ToArray()); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_attemptTwice!, CancellationToken.None)); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_persist_a_commitId_twice_on_same_stream : PersistenceEngineConcernAsync - { - private CommitAttempt? _attemptTwice; - private Exception? _thrown; - - protected override async Task ContextAsync() - { - var commit = await Persistence.CommitSingleAsync(); - _attemptTwice = new CommitAttempt( - commit!.BucketId, - commit.StreamId, - commit.StreamRevision + 1, - commit.CommitId, - commit.CommitSequence + 1, - commit.CommitStamp, - commit.Headers.ToDictionary(k => k.Key, v => v.Value), - commit.Events.ToArray() - ); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_attemptTwice!, CancellationToken.None)); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_more_events_than_the_configured_page_size : PersistenceEngineConcernAsync - { - private CommitAttempt[]? _committed; - private ICommit[]? _loaded; - private string? _streamId; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _committed = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 2, _streamId)).ToArray(); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_streamId!, 0, int.MaxValue, observer, CancellationToken.None); - _loaded = observer.Commits.ToArray(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted() - { - _loaded!.Length.Should().Be(_committed!.Length); - } - - [Fact] - public void should_load_the_same_commits_which_have_been_persisted() - { - _committed! - .All(commit => _loaded!.SingleOrDefault(loaded => loaded.CommitId == commit.CommitId) != null) - .Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_saving_a_snapshot : PersistenceEngineConcernAsync - { - private bool _added; - private Snapshot? _snapshot; - private string? _streamId; - - protected override Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_streamId, 1, "Snapshot"); - return Persistence.CommitSingleAsync(_streamId); - } - - protected override async Task BecauseAsync() - { - _added = await Persistence.AddSnapshotAsync(_snapshot!, CancellationToken.None); - } - - [Fact] - public void should_indicate_the_snapshot_was_added() - { - _added.Should().BeTrue(); - } - - [Fact] - public async Task should_be_able_to_retrieve_the_snapshot() - { - (await Persistence.GetSnapshotAsync(_streamId!, _snapshot!.StreamRevision, CancellationToken.None)).Should().NotBeNull(); - } - } - - /// - /// having multiple snapshots for the same tuple: bucketId, streamId, streamRevision - /// should not be allowed, the resulting behavior should be ignoring or updating the - /// snapshot, that was the original design (it's up to the driver decide what to do) - /// this behavior can be changed in a future implementation. - /// -#if MSTEST - [TestClass] -#endif - public class when_adding_multiple_snapshots_for_same_bucketId_streamId_streamRevision : PersistenceEngineConcernAsync - { - private bool _added; - private Snapshot? _snapshot; - private Snapshot? _updatedSnapshot; - private string? _streamId; - - private Exception? _thrown; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_streamId, 1, "Snapshot"); - await Persistence.CommitSingleAsync(_streamId); - - await Persistence.AddSnapshotAsync(_snapshot, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _updatedSnapshot = new Snapshot(_streamId!, 1, "Updated Snapshot"); - _thrown = await Catch.ExceptionAsync(async () => _added = await Persistence.AddSnapshotAsync(_updatedSnapshot, CancellationToken.None)); - } - - [Fact] - public void should_not_raise_exception() - { - _thrown.Should().BeNull(); - } - - [Fact] - public async Task should_be_able_to_retrieve_the_correct_snapshot_original_or_updated_depends_on_driver_implementation() - { - var snapshot = await Persistence.GetSnapshotAsync(_streamId!, _snapshot!.StreamRevision, CancellationToken.None); - snapshot.Should().NotBeNull(); - if (_added) - { - snapshot!.Payload.Should().Be(_updatedSnapshot!.Payload, "The snapshot was added, I expected to get the most updated version"); - } - else - { - snapshot!.Payload.Should().Be(_snapshot.Payload, "The snapshot was not added, I expected to get the original version"); - } - } - } - -#if MSTEST - [TestClass] -#endif - public class when_retrieving_a_snapshot : PersistenceEngineConcernAsync - { - private Snapshot? _correct; - private ISnapshot? _snapshot; - private string? _streamId; - private Snapshot? _tooFarForward; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - var commit1 = await Persistence.CommitSingleAsync(_streamId); // rev 1-2 - var commit2 = await Persistence.CommitNextAsync(commit1!); // rev 3-4 - await Persistence.CommitNextAsync(commit2!); // rev 5-6 - - await Persistence.AddSnapshotAsync(new Snapshot(_streamId, 1, string.Empty), CancellationToken.None); //Too far back - _correct = new Snapshot(_streamId, 3, "Snapshot"); - await Persistence.AddSnapshotAsync(_correct, CancellationToken.None); - _tooFarForward = new Snapshot(_streamId, 5, string.Empty); - await Persistence.AddSnapshotAsync(_tooFarForward, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _snapshot = await Persistence.GetSnapshotAsync(_streamId!, _tooFarForward!.StreamRevision - 1, CancellationToken.None); - } - - [Fact] - public void should_load_the_most_recent_prior_snapshot() - { - _snapshot!.StreamRevision.Should().Be(_correct!.StreamRevision); - } - - [Fact] - public void should_have_the_correct_snapshot_payload() - { - _snapshot!.Payload.Should().Be(_correct!.Payload); - } - - [Fact] - public void should_have_the_correct_stream_id() - { - _snapshot!.StreamId.Should().Be(_correct!.StreamId); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_snapshot_has_been_added_to_the_most_recent_commit_of_a_stream : PersistenceEngineConcernAsync - { - private const string SnapshotData = "snapshot"; - private ICommit? _newest; - private ICommit? _oldest, _oldest2; - private string? _streamId; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _oldest = await Persistence.CommitSingleAsync(_streamId); - _oldest2 = await Persistence.CommitNextAsync(_oldest!); - _newest = await Persistence.CommitNextAsync(_oldest2!); - } - - protected override Task BecauseAsync() - { - return Persistence.AddSnapshotAsync(new Snapshot(_streamId!, _newest!.StreamRevision, SnapshotData), CancellationToken.None); - } - - [Fact] - public async Task should_no_longer_find_the_stream_in_the_set_of_streams_to_be_snapshot() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(1, observer, CancellationToken.None); - observer.StreamHeads - .Any(x => x.StreamId == _streamId).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_commit_after_a_snapshot : PersistenceEngineConcernAsync - { - private const int WithinThreshold = 2; - private const int OverThreshold = 3; - private const string SnapshotData = "snapshot"; - private ICommit? _oldest, _oldest2; - private string? _streamId; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _oldest = await Persistence.CommitSingleAsync(_streamId); - _oldest2 = await Persistence.CommitNextAsync(_oldest!); - await Persistence.AddSnapshotAsync(new Snapshot(_streamId, _oldest2!.StreamRevision, SnapshotData), CancellationToken.None); - } - - protected override Task BecauseAsync() - { - return Persistence.CommitAsync(_oldest2!.BuildNextAttempt(), CancellationToken.None); - } - - // Because Raven and Mongo update the stream head asynchronously, this test will occasionally fail - [Fact] - public async Task should_find_the_stream_in_the_set_of_streams_to_be_snapshot_when_within_the_threshold() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(WithinThreshold, observer, CancellationToken.None); - observer.StreamHeads - .FirstOrDefault(x => x.StreamId == _streamId).Should().NotBeNull(); - } - - [Fact] - public async Task should_not_find_the_stream_in_the_set_of_streams_to_be_snapshot_when_over_the_threshold() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(OverThreshold, observer, CancellationToken.None); - observer.StreamHeads - .Any(x => x.StreamId == _streamId).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_a_particular_point_in_time : PersistenceEngineConcernAsync - { - private ICommit[]? _committed; - private CommitAttempt? _first; - private DateTime _now; - private ICommit? _second; - private string? _streamId; - private ICommit? _third; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - - _now = SystemTime.UtcNow.AddYears(1); - _first = _streamId.BuildAttempt(_now.AddSeconds(1)); - await Persistence.CommitAsync(_first, CancellationToken.None); - - _second = await Persistence.CommitNextAsync(_first); - _third = await Persistence.CommitNextAsync(_second!); - await Persistence.CommitNextAsync(_third!); - } - - protected override void Because() - { - _committed = Persistence.GetFrom(Bucket.Default, _now).ToArray(); - } - - [Fact] - public void should_return_all_commits_on_or_after_the_point_in_time_specified() - { - _committed!.Length.Should().Be(4); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_point_in_time : PersistenceEngineConcernAsync - { - private CommitAttempt[]? _committed; - private ICommit[]? _loaded; - private DateTime _start; - - protected override async Task ContextAsync() - { - _start = SystemTime.UtcNow; - // Due to loss in precision in various storage engines, we're rounding down to the - // nearest second to ensure include all commits from the 'start'. - _start = _start.AddSeconds(-1); - _committed = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 2)).ToArray(); - } - - protected override void Because() - { - _loaded = Persistence.GetFrom(Bucket.Default, _start).ToArray(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted() - { - _loaded!.Length.Should().Be(_committed!.Length); - } - - [Fact] - public void should_load_the_same_commits_which_have_been_persisted() - { - _committed! - .All(commit => _loaded!.SingleOrDefault(loaded => loaded.CommitId == commit.CommitId) != null) - .Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_checkpoint : PersistenceEngineConcernAsync - { - private List? _committed; - private List? _loaded; - private const int checkPoint = 2; - - protected override async Task ContextAsync() - { - _committed = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1)).Select(c => c.CommitId).ToList(); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(checkPoint, observer, CancellationToken.None).ConfigureAwait(false); - _loaded = observer.Commits.Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint() - { - _loaded!.Count.Should().Be(_committed!.Count - checkPoint); - } - - [Fact] - public void should_load_only_the_commits_starting_from_the_checkpoint() - { - _committed!.Skip(checkPoint).All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_of_a_bucket_from_a_particular_checkpoint : PersistenceEngineConcernAsync - { - private List? _committedOnBucket1; - private List? _committedOnBucket2; - private List? _loaded; - private const int checkPoint = 2; - - protected override async Task ContextAsync() - { - _committedOnBucket1 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, "b1")).Select(c => c.CommitId).ToList(); - _committedOnBucket2 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, "b2")).Select(c => c.CommitId).ToList(); - _committedOnBucket1.AddRange((await Persistence.CommitManyAsync(4, null, "b1")).Select(c => c.CommitId)); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync("b1", checkPoint, observer, CancellationToken.None).ConfigureAwait(false); - _loaded = observer.Commits.Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint() - { - _loaded!.Count.Should().Be(_committedOnBucket1!.Count - checkPoint); - } - - [Fact] - public void should_load_only_the_commits_on_bucket1_starting_from_the_checkpoint() - { - _committedOnBucket1!.Skip(checkPoint).All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - - [Fact] - public void should_not_load_the_commits_from_bucket2() - { - _committedOnBucket2!.All(x => !_loaded!.Contains(x)).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_checkpoint_to_a_checkpoint : PersistenceEngineConcernAsync - { - private readonly List _committed = []; - private List? _loaded; - private const int startCheckpoint = 2; - private int endCheckpoint; - - protected override async Task ContextAsync() - { - var committedOnBucket1 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, Bucket.Default)).Select(c => c.CommitId).ToList(); - var committedOnBucket2 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, "Bucket1")).Select(c => c.CommitId).ToList(); - _committed.AddRange(committedOnBucket1); - _committed.AddRange(committedOnBucket2); - endCheckpoint = (2 * (ConfiguredPageSizeForTesting + 1)) - 1; - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromToAsync(startCheckpoint, endCheckpoint, observer, CancellationToken.None).ConfigureAwait(false); - _loaded = observer.Commits.Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint_to_the_checkpoint() - { - _loaded!.Count.Should().Be(endCheckpoint - startCheckpoint); - } - - [Fact] - public void should_load_only_the_commits_starting_from_the_checkpoint_to_the_checkpoint() - { - _committed - .Skip(startCheckpoint) - .Take(_committed.Count - startCheckpoint - 1) - //.Take(endCheckpoint - startCheckpoint) - .All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_of_a_bucket_from_a_particular_checkpoint_to_a_checkpoint : PersistenceEngineConcernAsync - { - private List? _committedOnBucket1; - private List? _committedOnBucket2; - private List? _loaded; - private const int startCheckpoint = 2; - private int endCheckpoint; - - protected override async Task ContextAsync() - { - _committedOnBucket1 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, "b1")).Select(c => c.CommitId).ToList(); - _committedOnBucket2 = (await Persistence.CommitManyAsync(ConfiguredPageSizeForTesting + 1, null, "b2")).Select(c => c.CommitId).ToList(); - _committedOnBucket1.AddRange((await Persistence.CommitManyAsync(4, null, "b1")).Select(c => c.CommitId)); - endCheckpoint = ((2 * (ConfiguredPageSizeForTesting + 1)) + 4) - 1; - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromToAsync("b1", startCheckpoint, endCheckpoint, observer, CancellationToken.None).ConfigureAwait(false); - _loaded = observer.Commits.Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint_to_the_checkpoint() - { - _loaded!.Count.Should().Be(_committedOnBucket1!.Count - startCheckpoint - 1); - } - - [Fact] - public void should_load_only_the_commits_on_bucket1_starting_from_the_checkpoint_to_the_checkpoint() - { - _committedOnBucket1! - .Skip(startCheckpoint) - .Take(_committedOnBucket1!.Count - startCheckpoint - 1) - .All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - - [Fact] - public void should_not_load_the_commits_from_bucket2() - { - _committedOnBucket2!.All(x => !_loaded!.Contains(x)).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_the_year_1_AD : PersistenceEngineConcernAsync - { - private Exception? _thrown; - - protected override async Task BecauseAsync() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - _thrown = await Catch.ExceptionAsync(() => Persistence.GetFromAsync(Bucket.Default, 0, new CommitStreamObserver(), CancellationToken.None)); - } - - [Fact] - public void should_NOT_throw_an_exception() - { - _thrown.Should().BeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_all_commits : PersistenceEngineConcernAsync - { - protected override Task ContextAsync() - { - return Persistence.CommitSingleAsync(); - } - - protected override Task BecauseAsync() - { - return Persistence.PurgeAsync(CancellationToken.None); - } - - [Fact] - public async Task should_not_find_any_commits_stored() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(Bucket.Default, 0, observer, CancellationToken.None).ConfigureAwait(false); - observer.Commits.Count.Should().Be(0); - } - - [Fact] - public async Task should_not_find_any_streams_to_snapshot() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(0, observer, CancellationToken.None); - observer.StreamHeads - .Count.Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_invoking_after_disposal : PersistenceEngineConcernAsync - { - private Exception? _thrown; - - protected override void Context() - { - Persistence.Dispose(); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitSingleAsync()); - } - - [Fact] - public void should_throw_an_ObjectDisposedException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_id_as_a_stream_same_bucket : PersistenceEngineConcernAsync - { - private string? _streamId; - private static Exception? _thrown; - - protected override Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - return Persistence.CommitAsync(_streamId.BuildAttempt(), CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_streamId!.BuildAttempt(), CancellationToken.None)); - } - - [Fact] - public void should_throw() - { - _thrown.Should().NotBeNull(); - } - - [Fact] - public void should_be_duplicate_commit_exception() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_id_as_a_stream_in_another_bucket : PersistenceEngineConcernAsync - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - private string? _streamId; - private static CommitAttempt? _attemptForBucketB; - private static Exception? _thrown; - private DateTime _attemptACommitStamp; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - DateTime now = SystemTime.UtcNow; - await Persistence.CommitAsync(_streamId.BuildAttempt(now, _bucketAId), CancellationToken.None); - - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_bucketAId, _streamId, 0, int.MaxValue, observer, CancellationToken.None); - _attemptACommitStamp = observer.Commits[0].CommitStamp; - - _attemptForBucketB = _streamId.BuildAttempt(now.Subtract(TimeSpan.FromDays(1)), _bucketBId); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Persistence.CommitAsync(_attemptForBucketB!, CancellationToken.None)); - } - - [Fact] - public void should_succeed() - { - _thrown.Should().BeNull(); - } - - [Fact] - public async Task should_persist_to_the_correct_bucket() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_bucketBId, _streamId!, 0, int.MaxValue, observer, CancellationToken.None); - var stream = observer.Commits; - - stream.Should().NotBeNull(); - stream.Count.Should().Be(1); - } - - [Fact] - public async Task should_not_affect_the_stream_from_the_other_bucket() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_bucketAId, _streamId!, 0, int.MaxValue, observer, CancellationToken.None); - var stream = observer.Commits; - - stream.Should().NotBeNull(); - stream.Count.Should().Be(1); - stream[0].CommitStamp.Should().Be(_attemptACommitStamp); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_saving_a_snapshot_for_a_stream_with_the_same_id_as_a_stream_in_another_bucket : PersistenceEngineConcernAsync - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private string? _streamId; - - private static Snapshot? _snapshot; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_bucketBId, _streamId, 1, "Snapshot"); - await Persistence.CommitAsync(_streamId.BuildAttempt(bucketId: _bucketAId), CancellationToken.None); - await Persistence.CommitAsync(_streamId.BuildAttempt(bucketId: _bucketBId), CancellationToken.None); - } - - protected override Task BecauseAsync() - { - return Persistence.AddSnapshotAsync(_snapshot!, CancellationToken.None); - } - - [Fact] - public async Task should_affect_snapshots_from_another_bucket() - { - (await Persistence.GetSnapshotAsync(_bucketAId, _streamId!, _snapshot!.StreamRevision, CancellationToken.None)).Should().BeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_a_particular_point_in_time_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcernAsync - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private static DateTime _now; - private static ICommit[]? _returnedCommits; - private CommitAttempt? _commitToBucketB; - - protected override async Task ContextAsync() - { - _now = SystemTime.UtcNow.AddYears(1); - - var commitToBucketA = Guid.NewGuid().ToString().BuildAttempt(_now.AddSeconds(1), _bucketAId); - - await Persistence.CommitAsync(commitToBucketA, CancellationToken.None); - commitToBucketA = commitToBucketA.BuildNextAttempt(); - await Persistence.CommitAsync(commitToBucketA, CancellationToken.None); - commitToBucketA = commitToBucketA.BuildNextAttempt(); - await Persistence.CommitAsync(commitToBucketA, CancellationToken.None); - await Persistence.CommitAsync(commitToBucketA.BuildNextAttempt(), CancellationToken.None); - - _commitToBucketB = Guid.NewGuid().ToString().BuildAttempt(_now.AddSeconds(1), _bucketBId); - - await Persistence.CommitAsync(_commitToBucketB, CancellationToken.None); - } - - protected override void Because() - { - _returnedCommits = Persistence.GetFrom(_bucketAId, _now).ToArray(); - } - - [Fact] - public void should_not_return_commits_from_other_buckets() - { - _returnedCommits!.Any(c => c.CommitId.Equals(_commitToBucketB!.CommitId)).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_getting_all_commits_since_checkpoint_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcernAsync - { - private ICommit[]? _commits; - - protected override async Task ContextAsync() - { - const string bucketAId = "a"; - const string bucketBId = "b"; - await Persistence.CommitAsync(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketAId), CancellationToken.None); - await Persistence.CommitAsync(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketBId), CancellationToken.None); - await Persistence.CommitAsync(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketAId), CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - _commits = observer.Commits.ToArray(); - } - - [Fact] - public void should_not_be_empty() - { - _commits.Should().NotBeEmpty(); - } - - [Fact] - public void should_be_in_order_by_checkpoint() - { - Int64 checkpoint = 0; - foreach (var commit in _commits!) - { - Int64 commitCheckpoint = commit.CheckpointToken; - commitCheckpoint.Should().BeGreaterThan(checkpoint); - checkpoint = commit.CheckpointToken; - } - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_all_commits_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcernAsync - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private string? _streamId; - - protected override async Task ContextAsync() - { - _streamId = Guid.NewGuid().ToString(); - await Persistence.CommitAsync(_streamId.BuildAttempt(bucketId: _bucketAId), CancellationToken.None); - await Persistence.CommitAsync(_streamId.BuildAttempt(bucketId: _bucketBId), CancellationToken.None); - var _snapshotA = new Snapshot(bucketId: _bucketAId, _streamId, 1, "SnapshotA"); - await Persistence.AddSnapshotAsync(_snapshotA, CancellationToken.None); - var _snapshotB = new Snapshot(bucketId: _bucketBId, _streamId, 1, "SnapshotB"); - await Persistence.AddSnapshotAsync(_snapshotB, CancellationToken.None); - } - - protected override Task BecauseAsync() - { - return Persistence.PurgeAsync(CancellationToken.None); - } - - [Fact] - public async Task should_purge_all_commits_stored_in_bucket_a() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_bucketAId, 0, observer, CancellationToken.None).ConfigureAwait(false); - observer.Commits.Count.Should().Be(0); - } - - [Fact] - public async Task should_purge_all_commits_stored_in_bucket_b() - { - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(_bucketBId, 0, observer, CancellationToken.None).ConfigureAwait(false); - observer.Commits.Count.Should().Be(0); - } - - [Fact] - public async Task should_purge_all_streams_to_snapshot_in_bucket_a() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(_bucketAId, 0, observer, CancellationToken.None); - observer.StreamHeads.Count.Should().Be(0); - } - - [Fact] - public async Task should_purge_all_streams_to_snapshot_in_bucket_b() - { - var observer = new StreamHeadObserver(); - await Persistence.GetStreamsToSnapshotAsync(_bucketBId, 0, observer, CancellationToken.None); - observer.StreamHeads.Count.Should().Be(0); - } - } - - [Serializable] - public class TestEventForAsync - { - public String? S { get; set; } - } - -#if MSTEST - [TestClass] -#endif - public class when_calling_CommitChanges : PersistenceEngineConcern - { - private Guid? _commitId; - private ICommit? _persistedCommit; - private ICommit[]? _commits; - - protected override async Task BecauseAsync() - { - var eventStore = new OptimisticEventStore(Persistence, null, null); - using IEventStream stream = await eventStore.OpenStreamAsync(Guid.NewGuid()).ConfigureAwait(false); - stream.Add(new EventMessage { Body = new TestEvent() { S = "Hi " } }); - _commitId = Guid.NewGuid(); - _persistedCommit = await stream.CommitChangesAsync(_commitId.Value).ConfigureAwait(false); - - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - _commits = observer.Commits.ToArray(); - } - - [Fact] - public void A_Commit_had_been_persisted() - { - _persistedCommit.Should().NotBeNull(); - _persistedCommit!.CommitId.Should().Be(_commitId!.Value); - _persistedCommit.CommitSequence.Should().Be(1); - _persistedCommit.Events.Count.Should().Be(1); - _persistedCommit.Events.Single().Body.Should().BeOfType(); - ((TestEvent)_persistedCommit.Events.Single().Body!).S.Should().Be("Hi "); - } - - [Fact] - public void Should_have_expected_number_of_commits() - { - _commits!.Length.Should().Be(1); - // if should have the right event - _commits[0].CommitId.Should().Be(_commitId!.Value); - _commits[0].Events.Count.Should().Be(1); - _commits[0].Events.Single().Body.Should().BeOfType(); - ((TestEvent)_commits[0].Events.Single().Body!).S.Should().Be("Hi "); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_gettingFromCheckpoint_amount_of_commits_exceeds_PageSize : PersistenceEngineConcernAsync - { - private ICommit[]? _commits; - private int _moreThanPageSize; - - protected override async Task BecauseAsync() - { - _moreThanPageSize = ConfiguredPageSizeForTesting + 1; - var eventStore = new OptimisticEventStore(Persistence, null, null); - // TODO: Not sure how to set the actual page size to the const defined above - for (int i = 0; i < _moreThanPageSize; i++) - { - using IEventStream stream = await eventStore.OpenStreamAsync(Guid.NewGuid()).ConfigureAwait(false); - stream.Add(new EventMessage { Body = new TestEventForAsync() { S = "Hi " + i } }); - await stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None).ConfigureAwait(false); - } - - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - _commits = observer.Commits.ToArray(); - } - - [Fact] - public void Should_have_expected_number_of_commits() - { - _commits!.Length.Should().Be(_moreThanPageSize); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_payload_is_large : PersistenceEngineConcernAsync - { - [Fact] - public async Task can_commit() - { - const int bodyLength = 100000; - var attempt = new CommitAttempt( - Bucket.Default, - Guid.NewGuid().ToString(), - 1, - Guid.NewGuid(), - 1, - DateTime.UtcNow, - new Dictionary(), - [new EventMessage { Body = new string('a', bodyLength) }]); - await Persistence.CommitAsync(attempt, CancellationToken.None); - - var observer = new CommitStreamObserver(); - await Persistence.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - ICommit commits = observer.Commits.Single(); - - commits.Events.Single().Body.ToString()!.Length.Should().Be(bodyLength); - } - } - - /// - /// We are adapting the tests to use 3 different frameworks: - /// - XUnit: the attached test runner does the job (fixture setup and cleanup) - /// - NUnit (.net core project) - /// - MSTest (.net core project) - /// - public abstract class PersistenceEngineConcernAsync : SpecificationBase -#if XUNIT - , IUseFixture -#endif -#if NUNIT || MSTEST - , IDisposable -#endif - { - protected PersistenceEngineFixtureAsync? Fixture { get; private set; } - - protected IPersistStreams Persistence - { - get { return Fixture!.Persistence!; } - } - - protected int ConfiguredPageSizeForTesting - { - get { return 2; } - } - - /// - /// Can be used by XUNIT to initialize the tests. - /// - public void SetFixture(PersistenceEngineFixtureAsync data) - { - Fixture = data; - Fixture.Initialize(ConfiguredPageSizeForTesting); - } - -#if NUNIT || MSTEST - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - Fixture?.Dispose(); - } - - /// - /// - /// This code was meant to be run right before every test in the fixture to give time - /// to do further initialization before the PersistenceEngineFixture was created. - /// Unfortunately the 3 frameworks - /// have very different ways of doing this: - /// - NUnit: TestFixtureSetUp - /// - MSTest: ClassInitialize (not inherited, will be ignored if defined on a base class) - /// - xUnit: IUseFixture + SetFixture - /// We need a way to also have some configuration before the PersistenceEngineFixture is created. - /// - /// - /// We've decided to use the test constructor to do the job, it's your responsibility to guarantee - /// One time initialization (for anything that need it, if you have multiple tests on a fixture) - /// depending on the framework you are using. - /// - /// - /// quick workaround: - /// - change the parameters of the "Fixture" properties. - /// - call the 'Reinitialize()' method can be called to rerun the initialization after we changed the configuration - /// in the constructor. - /// or - /// - call the SetFixture() to reinitialize everything. - /// - /// - protected PersistenceEngineConcernAsync() : this(new PersistenceEngineFixtureAsync()) - { } - - protected PersistenceEngineConcernAsync(PersistenceEngineFixtureAsync fixture) - { - SetFixture(fixture); - } -#endif - } - - public partial class PersistenceEngineFixtureAsync : IDisposable - { - public IPersistStreams? Persistence { get; private set; } - - private readonly Func _createPersistence; - -#if NET462 - private bool _tracking = false; - private string _trackingInstanceName; - - /// - /// Automatic Performance Counters and tracking was disabled for full - /// framework tests because their initialization - /// can fail when the tests run on build machines (like AppVeyor and similar). - /// You can enable it back calling this function before - /// - /// - /// - public PersistenceEngineFixture TrackPerformanceInstance(string instanceName = "tests") - { - _trackingInstanceName = instanceName; - _tracking = true; - return this; - } -#endif - - public void Initialize(int pageSize) - { -#if NET462 - // performance counters cab be disabled for full framework tests because their initialization - // can fail when the tests run on build machines (like AppVeyor and similar) - if (_tracking) - { - Persistence = new NEventStore.Diagnostics.PerformanceCounterPersistenceEngine(_createPersistence(pageSize), _trackingInstanceName); - } - else - { - Persistence = _createPersistence(pageSize); - } -#else - Persistence = _createPersistence(pageSize); -#endif - Persistence.Initialize(); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (Persistence?.IsDisposed == false) - { - Persistence.Drop(); - Persistence.Dispose(); - } - } - } -} - -#pragma warning restore 169 // ReSharper disable InconsistentNaming -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Transactions.cs b/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Transactions.cs deleted file mode 100644 index 2884ab731..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.Transactions.cs +++ /dev/null @@ -1,161 +0,0 @@ -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles -#pragma warning disable S101 // Types should be named in PascalCase - -namespace NEventStore.Persistence.AcceptanceTests -{ - using System; - using System.Collections.Generic; - using System.Linq; - using NEventStore.Persistence.AcceptanceTests.BDD; - using FluentAssertions; -#if MSTEST - using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT - using NUnit.Framework; - using System.Threading.Tasks; - using System.Transactions; - using System.Threading; - using System.Globalization; -#endif -#if XUNIT - using Xunit; - using Xunit.Should; -#endif - - /* Transactions support must be investigated, it should be valid only for Databases that supports it (InMemoryPersistence will not). */ -#if MSTEST - [TestClass] -#endif - public class TransactionConcern : PersistenceEngineConcern - { - private ICommit[] _commits; - private const int Loop = 2; - private const int StreamsPerTransaction = 20; - - protected override void Because() - { - Parallel.For(0, Loop, i => - { - var eventStore = new OptimisticEventStore(Persistence, null); - using (var scope = new TransactionScope(TransactionScopeOption.Required, - new TransactionOptions { IsolationLevel = IsolationLevel.Serializable })) - { - int j; - for (j = 0; j < StreamsPerTransaction; j++) - { - using (var stream = eventStore.OpenStream(i.ToString() + "-" + j.ToString())) - { - for (int k = 0; k < 10; k++) - { - stream.Add(new EventMessage { Body = "body" + k }); - } - stream.CommitChanges(Guid.NewGuid()); - } - } - scope.Complete(); - } - }); - _commits = Persistence.GetFrom().ToArray(); - } - - [Fact] - public void Should_have_expected_number_of_commits() - { - _commits.Length.Should().Be(Loop * StreamsPerTransaction); - } - - [Fact] - public void ScopeCompleteAndSerializable() - { - Reinitialize(); - const int loop = 10; - using (var scope = new TransactionScope( - TransactionScopeOption.Required, - new TransactionOptions - { - IsolationLevel = IsolationLevel.Serializable - })) - { - Parallel.For(0, loop, i => - { - Console.WriteLine("Creating stream {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId); - var eventStore = new OptimisticEventStore(Persistence, null); - string streamId = i.ToString(CultureInfo.InvariantCulture); - using (var stream = eventStore.OpenStream(streamId)) - { - stream.Add(new EventMessage { Body = "body1" }); - stream.Add(new EventMessage { Body = "body2" }); - stream.CommitChanges(Guid.NewGuid()); - } - }); - scope.Complete(); - } - ICommit[] commits = Persistence.GetFrom(0).ToArray(); - commits.Length.Should().Be(loop); - } - - [Fact] - public void ScopeNotCompleteAndReadCommitted() - { - Reinitialize(); - const int loop = 10; - using (new TransactionScope( - TransactionScopeOption.Required, - new TransactionOptions - { - IsolationLevel = IsolationLevel.ReadCommitted - })) - { - Parallel.For(0, loop, i => - { - Console.WriteLine(@"Creating stream {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId); - var eventStore = new OptimisticEventStore(Persistence, null); - string streamId = i.ToString(CultureInfo.InvariantCulture); - using (var stream = eventStore.OpenStream(streamId)) - { - stream.Add(new EventMessage { Body = "body1" }); - stream.Add(new EventMessage { Body = "body2" }); - stream.CommitChanges(Guid.NewGuid()); - } - }); - } - ICommit[] commits = Persistence.GetFrom(0).ToArray(); - commits.Length.Should().Be(0); - } - - [Fact] - public void ScopeNotCompleteAndSerializable() - { - Reinitialize(); - const int loop = 10; - using (new TransactionScope( - TransactionScopeOption.Required, - new TransactionOptions - { - IsolationLevel = IsolationLevel.ReadCommitted - })) - { - Parallel.For(0, loop, i => - { - Console.WriteLine(@"Creating stream {0} on thread {1}", i, Thread.CurrentThread.ManagedThreadId); - var eventStore = new OptimisticEventStore(Persistence, null); - string streamId = i.ToString(CultureInfo.InvariantCulture); - using (var stream = eventStore.OpenStream(streamId)) - { - stream.Add(new EventMessage { Body = "body1" }); - stream.Add(new EventMessage { Body = "body2" }); - stream.CommitChanges(Guid.NewGuid()); - } - }); - } - ICommit[] commits = Persistence.GetFrom(0).ToArray(); - commits.Length.Should().Be(0); - } - } -} - -#pragma warning restore S101 // Types should be named in PascalCase -#pragma warning restore 169 // ReSharper disable InconsistentNaming -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.cs b/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.cs deleted file mode 100644 index 6b9388dd4..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/PersistenceTests.cs +++ /dev/null @@ -1,1417 +0,0 @@ - -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -using NUnit.Framework; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.Persistence.AcceptanceTests -{ -#if MSTEST - [TestClass] -#endif - public class when_a_commit_header_has_a_name_that_contains_a_period : PersistenceEngineConcern - { - private ICommit? _persisted; - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - var attempt = new CommitAttempt(_streamId, - 2, - Guid.NewGuid(), - 1, - DateTime.UtcNow, - new Dictionary { { "key.1", "value" } }, - [new EventMessage { Body = new ExtensionMethods.SomeDomainEvent { SomeProperty = "Test" } }]); - Persistence.Commit(attempt); - } - - protected override void Because() - { - _persisted = Persistence.GetFrom(_streamId!, 0, int.MaxValue).First(); - } - - [Fact] - public void should_correctly_deserialize_headers() - { - _persisted!.Headers.Keys.Should().Contain("key.1"); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_commit_is_successfully_persisted : PersistenceEngineConcern - { - private CommitAttempt? _attempt; - private DateTime _now; - private ICommit? _persisted; - private string? _streamId; - - protected override void Context() - { - _now = SystemTime.UtcNow.AddYears(1); - _streamId = Guid.NewGuid().ToString(); - _attempt = _streamId.BuildAttempt(_now); - - Persistence.Commit(_attempt); - } - - protected override void Because() - { - _persisted = Persistence.GetFrom(_streamId!, 0, int.MaxValue).First(); - } - - [Fact] - public void should_correctly_persist_the_stream_identifier() - { - _persisted!.StreamId.Should().Be(_attempt!.StreamId); - } - - [Fact] - public void should_correctly_persist_the_stream_stream_revision() - { - _persisted!.StreamRevision.Should().Be(_attempt!.StreamRevision); - } - - [Fact] - public void should_correctly_persist_the_commit_identifier() - { - _persisted!.CommitId.Should().Be(_attempt!.CommitId); - } - - [Fact] - public void should_correctly_persist_the_commit_sequence() - { - _persisted!.CommitSequence.Should().Be(_attempt!.CommitSequence); - } - - // persistence engines have varying levels of precision with respect to time. - [Fact] - public void should_correctly_persist_the_commit_stamp() - { - var difference = _persisted!.CommitStamp.Subtract(_now); - difference.Days.Should().Be(0); - difference.Hours.Should().Be(0); - difference.Minutes.Should().Be(0); - difference.Should().BeLessOrEqualTo(TimeSpan.FromSeconds(1)); - } - - [Fact] - public void should_correctly_persist_the_headers() - { - _persisted!.Headers.Count.Should().Be(_attempt!.Headers.Count); - } - - [Fact] - public void should_correctly_persist_the_events() - { - _persisted!.Events.Count.Should().Be(_attempt!.Events.Count); - } - - [Fact] - public void should_cause_the_stream_to_be_found_in_the_list_of_streams_to_snapshot() - { - Persistence.GetStreamsToSnapshot(1).FirstOrDefault(x => x.StreamId == _streamId).Should().NotBeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_given_revision : PersistenceEngineConcern - { - private const int LoadFromCommitContainingRevision = 3; - private const int UpToCommitWithContainingRevision = 5; - private ICommit[]? _committed; - private ICommit? _oldest, _oldest2, _oldest3; - private string? _streamId; - - protected override void Context() - { - _oldest = Persistence.CommitSingle(); // 2 events, revision 1-2 - _oldest2 = Persistence.CommitNext(_oldest!); // 2 events, revision 3-4 - _oldest3 = Persistence.CommitNext(_oldest2!); // 2 events, revision 5-6 - Persistence.CommitNext(_oldest3!); // 2 events, revision 7-8 - - _streamId = _oldest!.StreamId; - } - - protected override void Because() - { - _committed = Persistence.GetFrom(_streamId!, LoadFromCommitContainingRevision, UpToCommitWithContainingRevision).ToArray(); - } - - [Fact] - public void should_start_from_the_commit_which_contains_the_min_stream_revision_specified() - { - _committed![0].CommitId.Should().Be(_oldest2!.CommitId); // contains revision 3 - } - - [Fact] - public void should_read_up_to_the_commit_which_contains_the_max_stream_revision_specified() - { - _committed!.Last().CommitId.Should().Be(_oldest3!.CommitId); // contains revision 5 - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_given_revision_to_commit_revision : PersistenceEngineConcern - { - private const int LoadFromCommitContainingRevision = 3; - private const int UpToCommitWithContainingRevision = 6; - private ICommit[]? _committed; - private ICommit? _oldest, _oldest2, _oldest3; - private string? _streamId; - - protected override void Context() - { - _oldest = Persistence.CommitSingle(); // 2 events, revision 1-2 - _oldest2 = Persistence.CommitNext(_oldest!); // 2 events, revision 3-4 - _oldest3 = Persistence.CommitNext(_oldest2!); // 2 events, revision 5-6 - Persistence.CommitNext(_oldest3!); // 2 events, revision 7-8 - - _streamId = _oldest!.StreamId; - } - - protected override void Because() - { - _committed = Persistence.GetFrom(_streamId!, LoadFromCommitContainingRevision, UpToCommitWithContainingRevision).ToArray(); - } - - [Fact] - public void should_start_from_the_commit_which_contains_the_min_stream_revision_specified() - { - _committed![0].CommitId.Should().Be(_oldest2!.CommitId); // contains revision 3 - } - - [Fact] - public void should_read_up_to_the_commit_which_contains_the_max_stream_revision_specified() - { - _committed!.Last().CommitId.Should().Be(_oldest3!.CommitId); // contains revision 6 - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_revision : PersistenceEngineConcern - { - private CommitAttempt? _attemptWithSameRevision; - private Exception? _thrown; - - protected override void Context() - { - var commit = Persistence.CommitSingle(); - _attemptWithSameRevision = commit!.StreamId.BuildAttempt(); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_attemptWithSameRevision!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - - // This test ensure the uniqueness of BucketId+StreamId+CommitSequence - // to avoid concurrency issues -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_sequence : PersistenceEngineConcern - { - private CommitAttempt? _attempt1, _attempt2; - private Exception? _thrown; - - protected override void Context() - { - string streamId = Guid.NewGuid().ToString(); - _attempt1 = streamId.BuildAttempt(); - _attempt2 = new CommitAttempt( - _attempt1.BucketId, // <--- Same bucket - _attempt1.StreamId, // <--- Same stream it - _attempt1.StreamRevision + 10, - Guid.NewGuid(), - _attempt1.CommitSequence, // <--- Same commit seq - DateTime.UtcNow, - _attempt1.Headers, - [ - new EventMessage(){ Body = new ExtensionMethods.SomeDomainEvent {SomeProperty = "Test 3"}} - ] - ); - - Persistence.Commit(_attempt1); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_attempt2!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - - //TODO:This test looks exactly like the one above. What are we trying to prove? -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_overwrite_a_committed_sequence : PersistenceEngineConcern - { - private CommitAttempt? _failedAttempt; - private Exception? _thrown; - - protected override void Context() - { - string streamId = Guid.NewGuid().ToString(); - CommitAttempt successfulAttempt = streamId.BuildAttempt(); - Persistence.Commit(successfulAttempt); - _failedAttempt = streamId.BuildAttempt(); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_failedAttempt!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_persist_a_commit_twice : PersistenceEngineConcern - { - private CommitAttempt? _attemptTwice; - private Exception? _thrown; - - protected override void Context() - { - var commit = Persistence.CommitSingle(); - _attemptTwice = new CommitAttempt( - commit!.BucketId, - commit.StreamId, - commit.StreamRevision, - commit.CommitId, - commit.CommitSequence, - commit.CommitStamp, - commit.Headers.ToDictionary(k => k.Key, v => v.Value), - commit.Events.ToArray()); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_attemptTwice!)); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_persist_a_commitId_twice_on_same_stream : PersistenceEngineConcern - { - private CommitAttempt? _attemptTwice; - private Exception? _thrown; - - protected override void Context() - { - var commit = Persistence.CommitSingle(); - _attemptTwice = new CommitAttempt( - commit!.BucketId, - commit.StreamId, - commit.StreamRevision + 1, - commit.CommitId, - commit.CommitSequence + 1, - commit.CommitStamp, - commit.Headers.ToDictionary(k => k.Key, v => v.Value), - commit.Events.ToArray() - ); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_attemptTwice!)); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_more_events_than_the_configured_page_size : PersistenceEngineConcern - { - private CommitAttempt[]? _committed; - private ICommit[]? _loaded; - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _committed = Persistence.CommitMany(ConfiguredPageSizeForTesting + 2, _streamId).ToArray(); - } - - protected override void Because() - { - _loaded = Persistence.GetFrom(_streamId!, 0, int.MaxValue).ToArray(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted() - { - _loaded!.Length.Should().Be(_committed!.Length); - } - - [Fact] - public void should_load_the_same_commits_which_have_been_persisted() - { - _committed! - .All(commit => _loaded!.SingleOrDefault(loaded => loaded.CommitId == commit.CommitId) != null) - .Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_saving_a_snapshot : PersistenceEngineConcern - { - private bool _added; - private Snapshot? _snapshot; - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_streamId, 1, "Snapshot"); - Persistence.CommitSingle(_streamId); - } - - protected override void Because() - { - _added = Persistence.AddSnapshot(_snapshot!); - } - - [Fact] - public void should_indicate_the_snapshot_was_added() - { - _added.Should().BeTrue(); - } - - [Fact] - public void should_be_able_to_retrieve_the_snapshot() - { - Persistence.GetSnapshot(_streamId!, _snapshot!.StreamRevision).Should().NotBeNull(); - } - } - - /// - /// having multiple snapshots for the same tuple: bucketId, streamId, streamRevision - /// should not be allowed, the resulting behavior should be ignoring or updating the - /// snapshot, that was the original design (it's up to the driver decide what to do) - /// this behavior can be changed in a future implementation. - /// -#if MSTEST - [TestClass] -#endif - public class when_adding_multiple_snapshots_for_same_bucketId_streamId_streamRevision : PersistenceEngineConcern - { - private bool _added; - private Snapshot? _snapshot; - private Snapshot? _updatedSnapshot; - private string? _streamId; - - private Exception? _thrown; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_streamId, 1, "Snapshot"); - Persistence.CommitSingle(_streamId); - - Persistence.AddSnapshot(_snapshot); - } - - protected override void Because() - { - _updatedSnapshot = new Snapshot(_streamId!, 1, "Updated Snapshot"); - _thrown = Catch.Exception(() => _added = Persistence.AddSnapshot(_updatedSnapshot)); - } - - [Fact] - public void should_not_raise_exception() - { - _thrown.Should().BeNull(); - } - - [Fact] - public void should_be_able_to_retrieve_the_correct_snapshot_original_or_updated_depends_on_driver_implementation() - { - var snapshot = Persistence.GetSnapshot(_streamId!, _snapshot!.StreamRevision); - snapshot.Should().NotBeNull(); - if (_added) - { - snapshot!.Payload.Should().Be(_updatedSnapshot!.Payload, "The snapshot was added, I expected to get the most updated version"); - } - else - { - snapshot!.Payload.Should().Be(_snapshot.Payload, "The snapshot was not added, I expected to get the original version"); - } - } - } - -#if MSTEST - [TestClass] -#endif - public class when_retrieving_a_snapshot : PersistenceEngineConcern - { - private Snapshot? _correct; - private ISnapshot? _snapshot; - private string? _streamId; - private Snapshot? _tooFarForward; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - var commit1 = Persistence.CommitSingle(_streamId); // rev 1-2 - var commit2 = Persistence.CommitNext(commit1!); // rev 3-4 - Persistence.CommitNext(commit2!); // rev 5-6 - - Persistence.AddSnapshot(new Snapshot(_streamId, 1, string.Empty)); //Too far back - _correct = new Snapshot(_streamId, 3, "Snapshot"); - Persistence.AddSnapshot(_correct); - _tooFarForward = new Snapshot(_streamId, 5, string.Empty); - Persistence.AddSnapshot(_tooFarForward); - } - - protected override void Because() - { - _snapshot = Persistence.GetSnapshot(_streamId!, _tooFarForward!.StreamRevision - 1); - } - - [Fact] - public void should_load_the_most_recent_prior_snapshot() - { - _snapshot!.StreamRevision.Should().Be(_correct!.StreamRevision); - } - - [Fact] - public void should_have_the_correct_snapshot_payload() - { - _snapshot!.Payload.Should().Be(_correct!.Payload); - } - - [Fact] - public void should_have_the_correct_stream_id() - { - _snapshot!.StreamId.Should().Be(_correct!.StreamId); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_snapshot_has_been_added_to_the_most_recent_commit_of_a_stream : PersistenceEngineConcern - { - private const string SnapshotData = "snapshot"; - private ICommit? _newest; - private ICommit? _oldest, _oldest2; - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _oldest = Persistence.CommitSingle(_streamId); - _oldest2 = Persistence.CommitNext(_oldest!); - _newest = Persistence.CommitNext(_oldest2!); - } - - protected override void Because() - { - Persistence.AddSnapshot(new Snapshot(_streamId!, _newest!.StreamRevision, SnapshotData)); - } - - [Fact] - public void should_no_longer_find_the_stream_in_the_set_of_streams_to_be_snapshot() - { - Persistence.GetStreamsToSnapshot(1).Any(x => x.StreamId == _streamId).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_commit_after_a_snapshot : PersistenceEngineConcern - { - private const int WithinThreshold = 2; - private const int OverThreshold = 3; - private const string SnapshotData = "snapshot"; - private ICommit? _oldest, _oldest2; - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _oldest = Persistence.CommitSingle(_streamId); - _oldest2 = Persistence.CommitNext(_oldest!); - Persistence.AddSnapshot(new Snapshot(_streamId, _oldest2!.StreamRevision, SnapshotData)); - } - - protected override void Because() - { - Persistence.Commit(_oldest2!.BuildNextAttempt()); - } - - // Because Raven and Mongo update the stream head asynchronously, occasionally will fail this test - [Fact] - public void should_find_the_stream_in_the_set_of_streams_to_be_snapshot_when_within_the_threshold() - { - Persistence.GetStreamsToSnapshot(WithinThreshold).FirstOrDefault(x => x.StreamId == _streamId).Should().NotBeNull(); - } - - [Fact] - public void should_not_find_the_stream_in_the_set_of_streams_to_be_snapshot_when_over_the_threshold() - { - Persistence.GetStreamsToSnapshot(OverThreshold).Any(x => x.StreamId == _streamId).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_a_particular_point_in_time : PersistenceEngineConcern - { - private ICommit[]? _committed; - private CommitAttempt? _first; - private DateTime _now; - private ICommit? _second; - private string? _streamId; - private ICommit? _third; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - - _now = SystemTime.UtcNow.AddYears(1); - _first = _streamId.BuildAttempt(_now.AddSeconds(1)); - Persistence.Commit(_first); - - _second = Persistence.CommitNext(_first); - _third = Persistence.CommitNext(_second!); - Persistence.CommitNext(_third!); - } - - protected override void Because() - { - _committed = Persistence.GetFrom(Bucket.Default, _now).ToArray(); - } - - [Fact] - public void should_return_all_commits_on_or_after_the_point_in_time_specified() - { - _committed!.Length.Should().Be(4); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_point_in_time : PersistenceEngineConcern - { - private CommitAttempt[]? _committed; - private ICommit[]? _loaded; - private DateTime _start; - - protected override void Context() - { - _start = SystemTime.UtcNow; - // Due to loss in precision in various storage engines, we're rounding down to the - // nearest second to ensure include all commits from the 'start'. - _start = _start.AddSeconds(-1); - _committed = Persistence.CommitMany(ConfiguredPageSizeForTesting + 2).ToArray(); - } - - protected override void Because() - { - _loaded = Persistence.GetFrom(Bucket.Default, _start).ToArray(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted() - { - _loaded!.Length.Should().Be(_committed!.Length); - } - - [Fact] - public void should_load_the_same_commits_which_have_been_persisted() - { - _committed! - .All(commit => _loaded!.SingleOrDefault(loaded => loaded.CommitId == commit.CommitId) != null) - .Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_checkpoint : PersistenceEngineConcern - { - private List? _committed; - private List? _loaded; - private const int checkPoint = 2; - - protected override void Context() - { - _committed = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1).Select(c => c.CommitId).ToList(); - } - - protected override void Because() - { - _loaded = Persistence.GetFrom(checkPoint).Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint() - { - _loaded!.Count.Should().Be(_committed!.Count - checkPoint); - } - - [Fact] - public void should_load_only_the_commits_starting_from_the_checkpoint() - { - _committed!.Skip(checkPoint).All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_of_a_bucket_from_a_particular_checkpoint : PersistenceEngineConcern - { - private List? _committedOnBucket1; - private List? _committedOnBucket2; - private List? _loaded; - private const int checkPoint = 2; - - protected override void Context() - { - _committedOnBucket1 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, "b1").Select(c => c.CommitId).ToList(); - _committedOnBucket2 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, "b2").Select(c => c.CommitId).ToList(); - _committedOnBucket1.AddRange(Persistence.CommitMany(4, null, "b1").Select(c => c.CommitId)); - } - - protected override void Because() - { - _loaded = Persistence.GetFrom("b1", checkPoint).Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint() - { - _loaded!.Count.Should().Be(_committedOnBucket1!.Count - checkPoint); - } - - [Fact] - public void should_load_only_the_commits_on_bucket1_starting_from_the_checkpoint() - { - _committedOnBucket1!.Skip(checkPoint).All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - - [Fact] - public void should_not_load_the_commits_from_bucket2() - { - _committedOnBucket2!.All(x => !_loaded!.Contains(x)).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_from_a_particular_checkpoint_to_a_checkpoint : PersistenceEngineConcern - { - private readonly List _committed = []; - private List? _loaded; - private const int startCheckpoint = 2; - private int endCheckpoint; - - protected override void Context() - { - var committedOnBucket1 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, Bucket.Default).Select(c => c.CommitId).ToList(); - var committedOnBucket2 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, "Bucket1").Select(c => c.CommitId).ToList(); - _committed.AddRange(committedOnBucket1); - _committed.AddRange(committedOnBucket2); - endCheckpoint = (2 * (ConfiguredPageSizeForTesting + 1)) - 1; - } - - protected override void Because() - { - _loaded = Persistence.GetFromTo(startCheckpoint, endCheckpoint).Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint_to_the_checkpoint() - { - _loaded!.Count.Should().Be(endCheckpoint - startCheckpoint); - } - - [Fact] - public void should_load_only_the_commits_starting_from_the_checkpoint_to_the_checkpoint() - { - _committed - .Skip(startCheckpoint) - .Take(_committed.Count - startCheckpoint - 1) - //.Take(endCheckpoint - startCheckpoint) - .All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - } - -#if MSTEST - [TestClass] -#endif - public class when_paging_over_all_commits_of_a_bucket_from_a_particular_checkpoint_to_a_checkpoint : PersistenceEngineConcern - { - private List? _committedOnBucket1; - private List? _committedOnBucket2; - private List? _loaded; - private const int startCheckpoint = 2; - private int endCheckpoint; - - protected override void Context() - { - _committedOnBucket1 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, "b1").Select(c => c.CommitId).ToList(); - _committedOnBucket2 = Persistence.CommitMany(ConfiguredPageSizeForTesting + 1, null, "b2").Select(c => c.CommitId).ToList(); - _committedOnBucket1.AddRange(Persistence.CommitMany(4, null, "b1").Select(c => c.CommitId)); - endCheckpoint = ((2 * (ConfiguredPageSizeForTesting + 1)) + 4) - 1; - } - - protected override void Because() - { - _loaded = Persistence.GetFromTo("b1", startCheckpoint, endCheckpoint).Select(c => c.CommitId).ToList(); - } - - [Fact] - public void should_load_the_same_number_of_commits_which_have_been_persisted_starting_from_the_checkpoint_to_the_checkpoint() - { - _loaded!.Count.Should().Be(_committedOnBucket1!.Count - startCheckpoint - 1); - } - - [Fact] - public void should_load_only_the_commits_on_bucket1_starting_from_the_checkpoint_to_the_checkpoint() - { - _committedOnBucket1! - .Skip(startCheckpoint) - .Take(_committedOnBucket1!.Count - startCheckpoint - 1) - .All(x => _loaded!.Contains(x)).Should().BeTrue(); // all commits should be found in loaded collection - } - - [Fact] - public void should_not_load_the_commits_from_bucket2() - { - _committedOnBucket2!.All(x => !_loaded!.Contains(x)).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_the_year_1_AD : PersistenceEngineConcern - { - private Exception? _thrown; - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - _thrown = Catch.Exception(() => Persistence.GetFrom(Bucket.Default, 0).FirstOrDefault()); - } - - [Fact] - public void should_NOT_throw_an_exception() - { - _thrown.Should().BeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_all_commits : PersistenceEngineConcern - { - protected override void Context() - { - Persistence.CommitSingle(); - } - - protected override void Because() - { - Persistence.Purge(); - } - - [Fact] - public void should_not_find_any_commits_stored() - { - Persistence.GetFrom(Bucket.Default, 0).Count().Should().Be(0); - } - - [Fact] - public void should_not_find_any_streams_to_snapshot() - { - Persistence.GetStreamsToSnapshot(0).Count().Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_invoking_after_disposal : PersistenceEngineConcern - { - private Exception? _thrown; - - protected override void Context() - { - Persistence.Dispose(); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.CommitSingle()); - } - - [Fact] - public void should_throw_an_ObjectDisposedException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_id_as_a_stream_same_bucket : PersistenceEngineConcern - { - private string? _streamId; - private static Exception? _thrown; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - Persistence.Commit(_streamId.BuildAttempt()); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_streamId!.BuildAttempt())); - } - - [Fact] - public void should_throw() - { - _thrown.Should().NotBeNull(); - } - - [Fact] - public void should_be_duplicate_commit_exception() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_stream_with_the_same_id_as_a_stream_in_another_bucket : PersistenceEngineConcern - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - private string? _streamId; - private static CommitAttempt? _attemptForBucketB; - private static Exception? _thrown; - private DateTime _attemptACommitStamp; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - DateTime now = SystemTime.UtcNow; - Persistence.Commit(_streamId.BuildAttempt(now, _bucketAId)); - _attemptACommitStamp = Persistence.GetFrom(_bucketAId, _streamId, 0, int.MaxValue).First().CommitStamp; - _attemptForBucketB = _streamId.BuildAttempt(now.Subtract(TimeSpan.FromDays(1)), _bucketBId); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Persistence.Commit(_attemptForBucketB!)); - } - - [Fact] - public void should_succeed() - { - _thrown.Should().BeNull(); - } - - [Fact] - public void should_persist_to_the_correct_bucket() - { - ICommit[] stream = Persistence.GetFrom(_bucketBId, _streamId!, 0, int.MaxValue).ToArray(); - stream.Should().NotBeNull(); - stream.Length.Should().Be(1); - } - - [Fact] - public void should_not_affect_the_stream_from_the_other_bucket() - { - ICommit[] stream = Persistence.GetFrom(_bucketAId, _streamId!, 0, int.MaxValue).ToArray(); - stream.Should().NotBeNull(); - stream.Length.Should().Be(1); - stream[0].CommitStamp.Should().Be(_attemptACommitStamp); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_saving_a_snapshot_for_a_stream_with_the_same_id_as_a_stream_in_another_bucket : PersistenceEngineConcern - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private string? _streamId; - - private static Snapshot? _snapshot; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - _snapshot = new Snapshot(_bucketBId, _streamId, 1, "Snapshot"); - Persistence.Commit(_streamId.BuildAttempt(bucketId: _bucketAId)); - Persistence.Commit(_streamId.BuildAttempt(bucketId: _bucketBId)); - } - - protected override void Because() - { - Persistence.AddSnapshot(_snapshot!); - } - - [Fact] - public void should_affect_snapshots_from_another_bucket() - { - Persistence.GetSnapshot(_bucketAId, _streamId!, _snapshot!.StreamRevision).Should().BeNull(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_commits_from_a_particular_point_in_time_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcern - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private static DateTime _now; - private static ICommit[]? _returnedCommits; - private CommitAttempt? _commitToBucketB; - - protected override void Context() - { - _now = SystemTime.UtcNow.AddYears(1); - - var commitToBucketA = Guid.NewGuid().ToString().BuildAttempt(_now.AddSeconds(1), _bucketAId); - - Persistence.Commit(commitToBucketA); - commitToBucketA = commitToBucketA.BuildNextAttempt(); - Persistence.Commit(commitToBucketA); - commitToBucketA = commitToBucketA.BuildNextAttempt(); - Persistence.Commit(commitToBucketA); - Persistence.Commit(commitToBucketA.BuildNextAttempt()); - - _commitToBucketB = Guid.NewGuid().ToString().BuildAttempt(_now.AddSeconds(1), _bucketBId); - - Persistence.Commit(_commitToBucketB); - } - - protected override void Because() - { - _returnedCommits = Persistence.GetFrom(_bucketAId, _now).ToArray(); - } - - [Fact] - public void should_not_return_commits_from_other_buckets() - { - _returnedCommits!.Any(c => c.CommitId.Equals(_commitToBucketB!.CommitId)).Should().BeFalse(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_getting_all_commits_since_checkpoint_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcern - { - private ICommit[]? _commits; - - protected override void Context() - { - const string bucketAId = "a"; - const string bucketBId = "b"; - Persistence.Commit(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketAId)); - Persistence.Commit(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketBId)); - Persistence.Commit(Guid.NewGuid().ToString().BuildAttempt(bucketId: bucketAId)); - } - - protected override void Because() - { - _commits = Persistence.GetFrom(0).ToArray(); - } - - [Fact] - public void should_not_be_empty() - { - _commits.Should().NotBeEmpty(); - } - - [Fact] - public void should_be_in_order_by_checkpoint() - { - Int64 checkpoint = 0; - foreach (var commit in _commits!) - { - Int64 commitCheckpoint = commit.CheckpointToken; - commitCheckpoint.Should().BeGreaterThan(checkpoint); - checkpoint = commit.CheckpointToken; - } - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_all_commits_and_there_are_streams_in_multiple_buckets : PersistenceEngineConcern - { - private const string _bucketAId = "a"; - private const string _bucketBId = "b"; - - private string? _streamId; - - protected override void Context() - { - _streamId = Guid.NewGuid().ToString(); - Persistence.Commit(_streamId.BuildAttempt(bucketId: _bucketAId)); - Persistence.Commit(_streamId.BuildAttempt(bucketId: _bucketBId)); - var _snapshotA = new Snapshot(bucketId: _bucketAId, _streamId, 1, "SnapshotA"); - Persistence.AddSnapshot(_snapshotA); - var _snapshotB = new Snapshot(bucketId: _bucketBId, _streamId, 1, "SnapshotB"); - Persistence.AddSnapshot(_snapshotB); - } - - protected override void Because() - { - Persistence.Purge(); - } - - [Fact] - public void should_purge_all_commits_stored_in_bucket_a() - { - Persistence.GetFrom(_bucketAId, 0).Count().Should().Be(0); - } - - [Fact] - public void should_purge_all_commits_stored_in_bucket_b() - { - Persistence.GetFrom(_bucketBId, 0).Count().Should().Be(0); - } - - [Fact] - public void should_purge_all_streams_to_snapshot_in_bucket_a() - { - Persistence.GetStreamsToSnapshot(_bucketAId, 0).Count().Should().Be(0); - } - - [Fact] - public void should_purge_all_streams_to_snapshot_in_bucket_b() - { - Persistence.GetStreamsToSnapshot(_bucketBId, 0).Count().Should().Be(0); - } - } - - [Serializable] - public class TestEvent - { - public String? S { get; set; } - } - -#if MSTEST - [TestClass] -#endif - public class when_calling_CommitChanges : PersistenceEngineConcern - { - private Guid? _commitId; - private ICommit? _persistedCommit; - private ICommit[]? _commits; - - protected override void Because() - { - var eventStore = new OptimisticEventStore(Persistence, null, null); - using IEventStream stream = eventStore.OpenStream(Guid.NewGuid()); - stream.Add(new EventMessage { Body = new TestEvent() { S = "Hi " } }); - _commitId = Guid.NewGuid(); - _persistedCommit = stream.CommitChanges(_commitId.Value); - - _commits = Persistence.GetFrom(0).ToArray(); - } - - [Fact] - public void A_Commit_had_been_persisted() - { - _persistedCommit.Should().NotBeNull(); - _persistedCommit!.CommitId.Should().Be(_commitId!.Value); - _persistedCommit.CommitSequence.Should().Be(1); - _persistedCommit.Events.Count.Should().Be(1); - _persistedCommit.Events.Single().Body.Should().BeOfType(); - ((TestEvent)_persistedCommit.Events.Single().Body!).S.Should().Be("Hi "); - } - - [Fact] - public void Should_have_expected_number_of_commits() - { - _commits!.Length.Should().Be(1); - // if should have the right event - _commits[0].CommitId.Should().Be(_commitId!.Value); - _commits[0].Events.Count.Should().Be(1); - _commits[0].Events.Single().Body.Should().BeOfType(); - ((TestEvent)_commits[0].Events.Single().Body!).S.Should().Be("Hi "); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_gettingFromCheckpoint_amount_of_commits_exceeds_PageSize : PersistenceEngineConcern - { - private ICommit[]? _commits; - private int _moreThanPageSize; - - protected override void Because() - { - _moreThanPageSize = ConfiguredPageSizeForTesting + 1; - var eventStore = new OptimisticEventStore(Persistence, null, null); - // TODO: Not sure how to set the actual page size to the const defined above - for (int i = 0; i < _moreThanPageSize; i++) - { - using IEventStream stream = eventStore.OpenStream(Guid.NewGuid()); - stream.Add(new EventMessage { Body = new TestEvent() { S = "Hi " + i } }); - stream.CommitChanges(Guid.NewGuid()); - } - _commits = Persistence.GetFrom(0).ToArray(); - } - - [Fact] - public void Should_have_expected_number_of_commits() - { - _commits!.Length.Should().Be(_moreThanPageSize); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_payload_is_large : PersistenceEngineConcern - { - [Fact] - public void can_commit() - { - const int bodyLength = 100000; - var attempt = new CommitAttempt( - Bucket.Default, - Guid.NewGuid().ToString(), - 1, - Guid.NewGuid(), - 1, - DateTime.UtcNow, - new Dictionary(), - [new EventMessage { Body = new string('a', bodyLength) }]); - Persistence.Commit(attempt); - - ICommit commits = Persistence.GetFrom(0).Single(); - commits.Events.Single().Body.ToString()!.Length.Should().Be(bodyLength); - } - } - - /// - /// We are adapting the tests to use 3 different frameworks: - /// - XUnit: the attached test runner does the job (fixture setup and cleanup) - /// - NUnit (.net core project) - /// - MSTest (.net core project) - /// - public abstract class PersistenceEngineConcern : SpecificationBase -#if XUNIT - , IUseFixture -#endif -#if NUNIT || MSTEST - , IDisposable -#endif - { - protected PersistenceEngineFixture? Fixture { get; private set; } - - protected IPersistStreams Persistence - { - get { return Fixture!.Persistence!; } - } - - protected int ConfiguredPageSizeForTesting - { - get { return 2; } - } - - /// - /// Can be used by XUNIT to initialize the tests. - /// - public void SetFixture(PersistenceEngineFixture data) - { - Fixture = data; - Fixture.Initialize(ConfiguredPageSizeForTesting); - } - -#if NUNIT || MSTEST - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - Fixture?.Dispose(); - } - - /// - /// - /// This code was meant to be run right before every test in the fixture to give time - /// to do further initialization before the PersistenceEngineFixture was created. - /// Unfortunately the 3 frameworks - /// have very different ways of doing this: - /// - NUnit: TestFixtureSetUp - /// - MSTest: ClassInitialize (not inherited, will be ignored if defined on a base class) - /// - xUnit: IUseFixture + SetFixture - /// We need a way to also have some configuration before the PersistenceEngineFixture is created. - /// - /// - /// We've decided to use the test constructor to do the job, it's your responsibility to guarantee - /// One time initialization (for anything that need it, if you have multiple tests on a fixture) - /// depending on the framework you are using. - /// - /// - /// quick workaround: - /// - change the parameters of the "Fixture" properties. - /// - call the 'Reinitialize()' method can be called to rerun the initialization after we changed the configuration - /// in the constructor. - /// or - /// - call the SetFixture() to reinitialize everything. - /// - /// - protected PersistenceEngineConcern() : this(new PersistenceEngineFixture()) - { } - - protected PersistenceEngineConcern(PersistenceEngineFixture fixture) - { - SetFixture(fixture); - } -#endif - } - - public partial class PersistenceEngineFixture : IDisposable - { - public IPersistStreams? Persistence { get; private set; } - - private readonly Func _createPersistence; - -#if NET462 - private bool _tracking = false; - private string _trackingInstanceName; - - /// - /// Automatic Performance Counters and tracking was disabled for full - /// framework tests because their initialization - /// can fail when the tests run on build machines (like AppVeyor and similar). - /// You can enable it back calling this function before - /// - /// - /// - public PersistenceEngineFixture TrackPerformanceInstance(string instanceName = "tests") - { - _trackingInstanceName = instanceName; - _tracking = true; - return this; - } -#endif - - public void Initialize(int pageSize) - { -#if NET462 - // performance counters cab be disabled for full framework tests because their initialization - // can fail when the tests run on build machines (like AppVeyor and similar) - if (_tracking) - { - Persistence = new NEventStore.Diagnostics.PerformanceCounterPersistenceEngine(_createPersistence(pageSize), _trackingInstanceName); - } - else - { - Persistence = _createPersistence(pageSize); - } -#else - Persistence = _createPersistence(pageSize); -#endif - Persistence.Initialize(); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (Persistence?.IsDisposed == false) - { - Persistence.Drop(); - Persistence.Dispose(); - } - } - } -} - -#pragma warning restore 169 // ReSharper disable InconsistentNaming -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Persistence.AcceptanceTests/Properties/AssemblyInfo.cs b/src/NEventStore.Persistence.AcceptanceTests/Properties/AssemblyInfo.cs deleted file mode 100644 index 3fa652324..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("NEventStore.Persistence.AcceptanceTests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore.Persistence.AcceptanceTests")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("f85a343a-1aae-4a01-a91d-efd76322d9d8")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Persistence.AcceptanceTests/SerializationTests.cs b/src/NEventStore.Persistence.AcceptanceTests/SerializationTests.cs deleted file mode 100644 index 2372aaf63..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/SerializationTests.cs +++ /dev/null @@ -1,217 +0,0 @@ -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles -#pragma warning disable S101 // Types should be named in PascalCase - -namespace NEventStore.Serialization.AcceptanceTests -{ -#if MSTEST - [TestClass] -#endif - public class when_serializing_a_simple_message : SerializationConcern - { - private readonly SimpleMessage _message = new SimpleMessage().Populate(); - private SimpleMessage? _deserialized; - private byte[]? _serialized; - - protected override void Context() - { - _serialized = Serializer.Serialize(_message); - } - - protected override void Because() - { - _deserialized = Serializer.Deserialize(_serialized!); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_same_Id_as_the_serialized_message() - { - _deserialized!.Id.Should().Be(_message.Id); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_same_Value_as_the_serialized_message() - { - _deserialized!.Value.Should().Be(_message.Value); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_same_Created_value_as_the_serialized_message() - { - _deserialized!.Created.Should().Be(_message.Created); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_same_Count_as_the_serialized_message() - { - _deserialized!.Count.Should().Be(_message.Count); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_number_of_elements_as_the_serialized_message() - { - _deserialized!.Contents.Count.Should().Be(_message.Contents.Count); - } - - [Fact] - public void should_deserialize_a_message_which_contains_the_same_Contents_as_the_serialized_message() - { - _deserialized!.Contents.SequenceEqual(_message.Contents).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_serializing_a_list_of_event_messages : SerializationConcern - { - private readonly List Messages = new List - { - new EventMessage {Body = "some value"}, - new EventMessage {Body = 42}, - new EventMessage {Body = new SimpleMessage()} - }; - - private List? _deserialized; - private byte[]? _serialized; - - protected override void Context() - { - _serialized = Serializer.Serialize(Messages); - } - - protected override void Because() - { - _deserialized = Serializer.Deserialize>(_serialized!); - } - - [Fact] - public void should_deserialize_the_same_number_of_event_messages_as_it_serialized() - { - Messages.Count.Should().Be(_deserialized!.Count); - } - - [Fact] - public void should_deserialize_the_the_complex_types_within_the_event_messages() - { - _deserialized!.Last().Body.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_serializing_a_list_of_commit_headers : SerializationConcern - { - private readonly Dictionary _headers = new Dictionary - { - {"HeaderKey", "SomeValue"}, - {"AnotherKey", 42}, - {"AndAnotherKey", Guid.NewGuid()}, - {"LastKey", new SimpleMessage()} - }; - - private Dictionary? _deserialized; - private byte[]? _serialized; - - protected override void Context() - { - _serialized = Serializer.Serialize(_headers); - } - - protected override void Because() - { - _deserialized = Serializer.Deserialize>(_serialized!); - } - - [Fact] - public void should_deserialize_the_same_number_of_event_messages_as_it_serialized() - { - _headers.Count.Should().Be(_deserialized!.Count); - } - - [Fact] - public void should_deserialize_the_the_complex_types_within_the_event_messages() - { - _deserialized!.Last().Value.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_serializing_an_untyped_payload_on_a_snapshot : SerializationConcern - { - private Snapshot? _deserialized; - private IDictionary>? _payload; - private byte[]? _serialized; - private Snapshot? _snapshot; - - protected override void Context() - { - _payload = new Dictionary>(); - _snapshot = new Snapshot(Guid.NewGuid().ToString(), 42, _payload); - _serialized = Serializer.Serialize(_snapshot); - } - - protected override void Because() - { - _deserialized = Serializer.Deserialize(_serialized!); - } - - [Fact] - public void should_correctly_deserialize_the_untyped_payload_contents() - { - _deserialized!.Payload.Should().BeEquivalentTo(_snapshot!.Payload); - } - - [Fact] - public void should_correctly_deserialize_the_untyped_payload_type() - { - _deserialized!.Payload.Should().BeOfType(_snapshot!.Payload.GetType()); - } - } - - public abstract class SerializationConcern : SpecificationBase - { - private readonly SerializerFixture _data; - - public ISerialize Serializer - { - get { return _data.Serializer; } - } - - protected SerializationConcern() - { - _data = new SerializerFixture(); - } - } - - public partial class SerializerFixture - { - private readonly Func _createSerializer; - private ISerialize? _serializer; - - public ISerialize Serializer - { - get { return _serializer ??= _createSerializer(); } - } - } -} - -#pragma warning restore S101 // Types should be named in PascalCase -#pragma warning restore 169 // ReSharper disable InconsistentNaming -#pragma warning restore IDE1006 // Naming Styles \ No newline at end of file diff --git a/src/NEventStore.Persistence.AcceptanceTests/SimpleMessage.cs b/src/NEventStore.Persistence.AcceptanceTests/SimpleMessage.cs deleted file mode 100644 index 84f519312..000000000 --- a/src/NEventStore.Persistence.AcceptanceTests/SimpleMessage.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace NEventStore.Persistence.AcceptanceTests -{ - [Serializable] - public class SimpleMessage - { - public SimpleMessage() - { - Contents = []; - } - - public Guid Id { get; set; } - public DateTime Created { get; set; } - public string? Value { get; set; } - public int Count { get; set; } - - public List Contents { get; private set; } - } -} \ No newline at end of file diff --git a/src/NEventStore.PollingClient/AsyncPollingClient.cs b/src/NEventStore.PollingClient/AsyncPollingClient.cs deleted file mode 100644 index c0ad0d8be..000000000 --- a/src/NEventStore.PollingClient/AsyncPollingClient.cs +++ /dev/null @@ -1,333 +0,0 @@ -using NEventStore.Logging; -using NEventStore.Persistence; -using Microsoft.Extensions.Logging; - -namespace NEventStore.PollingClient -{ - /// - /// A Polling Client that uses the Asynchronous API of the store. - /// - public class AsyncPollingClient : IDisposable - { - /// - /// Decorator used to enable Commit Re-Sequencing. - /// During normal operations Commits might arrive out of order, or there can be holes in the sequence for whatever reason. - /// In a rebuild scenario the stream is stable and commits will be read in the correct order, holes can be safely skipped. - /// - private class CommitSequencer : IAsyncObserver - { - private readonly AsyncPollingClientObserver _observer; - private readonly ILogger _logger = LogFactory.BuildLogger(typeof(CommitSequencer)); - /// - /// How many retries we did on a hole. - /// - public int NumOfRetries { get; private set; } - /// - /// Max number of retries before skipping the hole. - /// - public int MaxNumOfRetriesBeforeSkip { get; set; } = 5; - - public CommitSequencer(AsyncPollingClientObserver observer, long checkpoint) - { - _observer = observer; - _observer.ProcessedCheckpoint = checkpoint; - } - - public Task OnCompletedAsync(CancellationToken cancellationToken) - { - return _observer.OnCompletedAsync(cancellationToken); - } - - public Task OnErrorAsync(Exception ex, CancellationToken cancellationToken) - { - return _observer.OnErrorAsync(ex, cancellationToken); - } - - public Task OnNextAsync(ICommit value, CancellationToken cancellationToken) - { - if (value.CheckpointToken != _observer.ProcessedCheckpoint + 1) - { - if (NumOfRetries < MaxNumOfRetriesBeforeSkip) - { - NumOfRetries++; - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug("Hole detected on {Checkpoint} - {NumOfRetries}", value.CheckpointToken, NumOfRetries); - } - // stop the reading, the caller will wait then resume reading from the same checkpoint - return Task.FromResult(false); - } - // we reached the max number of retries, skip the hole - if (_logger.IsEnabled(LogLevel.Warning)) - { - _logger.LogWarning("Skipping hole on {Checkpoint}", value.CheckpointToken); - } - } - - NumOfRetries = 0; - return _observer.OnNextAsync(value, cancellationToken); - } - } - - /// - /// Async Observer Decorator that wraps the original observer: it is used to: - /// - Track the last processed commit. - /// - Track if the user request to stop the polling from inside the observer. - /// - private class AsyncPollingClientObserver : IAsyncObserver - { - private readonly IAsyncObserver _observer; - - public bool StopPolling { get; private set; } - /// - /// The last correctly processed commit. - /// - public long ProcessedCheckpoint { get; internal set; } - - public AsyncPollingClientObserver(IAsyncObserver observer) - { - _observer = observer; - } - public Task OnCompletedAsync(CancellationToken cancellationToken) - { - return _observer.OnCompletedAsync(cancellationToken); - } - - public Task OnErrorAsync(Exception ex, CancellationToken cancellationToken) - { - return _observer.OnErrorAsync(ex, cancellationToken); - } - - public async Task OnNextAsync(ICommit value, CancellationToken cancellationToken) - { - StopPolling = false; - var goOn = await _observer.OnNextAsync(value, cancellationToken).ConfigureAwait(false); - StopPolling = !goOn; - ProcessedCheckpoint = value.CheckpointToken; - return goOn; - } - } - - private readonly ILogger _logger; - private readonly IPersistStreams _persistStreams; - private readonly AsyncPollingClientObserver _commitObserver; - private readonly Int32 _waitInterval; - private readonly int _holeDetectionWaitInterval; - private Func? _pollingFunc; - private Int64 _checkpointToken; - private CancellationTokenSource? _cancellationTokeSource; - private bool _stopped = true; - private int _isPolling; - private CommitSequencer? _commitSequencer; - - /// - /// Creates an NEventStore Polling Client - /// - /// the store to check - /// the observer to notify - /// Interval in Milliseconds to wait when the provider - /// return no more commit and the next request - /// Interval in Milliseconds to wait before retry when a hole was detected in the stream. 0 = disable hole detection. - public AsyncPollingClient( - IPersistStreams persistStreams, - IAsyncObserver commitObserver, - Int32 waitInterval = 100, - Int32 holeDetectionWaitInterval = 0) - { - if (commitObserver is null) - { - throw new ArgumentNullException(nameof(commitObserver)); - } - - _persistStreams = persistStreams ?? throw new ArgumentNullException(nameof(persistStreams)); - _commitObserver = new AsyncPollingClientObserver(commitObserver); - _logger = LogFactory.BuildLogger(GetType()); - _waitInterval = waitInterval; - _holeDetectionWaitInterval = holeDetectionWaitInterval; - LastActivityTimestamp = DateTime.UtcNow; - } - - /// - /// Tells the caller the last tick count when the last activity occurred. This is useful for the caller - /// to setup Health check that verify if the polling client is really active and it is really loading new commits. - /// This value is obtained with DateTime.UtcNow - /// - public DateTime LastActivityTimestamp { get; private set; } - - /// - /// If the polling client encounter an exception it immediately retry, but we need to tell to the caller code - /// that the last polling encounter an error. This is needed to detect a polling client stuck as an example - /// with deserialization problems. - /// - public String? LastPollingError { get; private set; } - - /// - /// Start the polling client. - /// - public void Start(Int64 checkpointToken = 0) - { - _cancellationTokeSource = new CancellationTokenSource(); - ConfigurePollingClient(checkpointToken); - StartPollingThread(_cancellationTokeSource.Token); - } - - /// - /// Start the polling client. - /// - public void Start(string bucketId, Int64 checkpointToken = 0) - { - _cancellationTokeSource = new CancellationTokenSource(); - ConfigurePollingClient(checkpointToken, bucketId); - StartPollingThread(_cancellationTokeSource.Token); - } - - /// - /// Configure the polling function to get commits from the store. - /// - internal void ConfigurePollingClient(Int64 checkpointToken = 0, string? bucketId = null) - { - _checkpointToken = checkpointToken; - IAsyncObserver commitObserver; - if (_holeDetectionWaitInterval > 0) - { - _commitSequencer = new CommitSequencer(_commitObserver, _checkpointToken); - commitObserver = _commitSequencer; - } - else - { - commitObserver = _commitObserver; - } - if (bucketId == null) - _pollingFunc = (long checkpointToken, CancellationToken cancellationToken) => _persistStreams.GetFromAsync(checkpointToken, commitObserver, cancellationToken); - else - _pollingFunc = (long checkpointToken, CancellationToken cancellationToken) => _persistStreams.GetFromAsync(bucketId, checkpointToken, commitObserver, cancellationToken); - } - - /// - /// Simply start the timer that will queue wake up tokens. - /// - private void StartPollingThread(CancellationToken cancellationToken) - { - if (_pollingFunc == null) return; - _stopped = false; - Task.Run(async () => - { - try - { - while (!cancellationToken.IsCancellationRequested && !_commitObserver.StopPolling) - { - await PollAsync(cancellationToken).ConfigureAwait(false); - - if (!cancellationToken.IsCancellationRequested) - { - await Task.Delay(_waitInterval, cancellationToken).ConfigureAwait(false); - } - } - } - finally - { - _stopped = true; - } - }, cancellationToken) - .ContinueWith(t => - { - if (t.IsFaulted) - { - var ex = t.Exception.Flatten().InnerException; - _logger.LogError($"Error during Poll, first exception: {ex.Message}.\n{ex}"); - LastPollingError = ex.Message; - } - }, cancellationToken); - } - - /// - /// Stop the polling client. - /// - public async Task StopAsync() - { - _cancellationTokeSource?.Cancel(); - _cancellationTokeSource = null; - - while (!_stopped) - { - await Task.Delay(100).ConfigureAwait(false); - } - } - - /// - /// Poll the store for new commits. - /// - public async Task PollAsync(CancellationToken token) - { - if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0) - { - try - { - LastActivityTimestamp = DateTime.UtcNow; - if (_commitSequencer == null) - { - await _pollingFunc!(_checkpointToken, token).ConfigureAwait(false); - _checkpointToken = _commitObserver.ProcessedCheckpoint; - } - else - { - do - { - await _pollingFunc!(_checkpointToken, token).ConfigureAwait(false); - _checkpointToken = _commitObserver.ProcessedCheckpoint; - if (_commitObserver.StopPolling) - { - break; - } - // todo: should also check if the user requested to stop the polling from the observer ? - if (_commitSequencer.NumOfRetries > 0) - { - await Task.Delay(_holeDetectionWaitInterval, token).ConfigureAwait(false); - } - } - while (!token.IsCancellationRequested && _commitSequencer.NumOfRetries > 0); - } - } - finally - { - Interlocked.Exchange(ref _isPolling, 0); - } - } - } - - private Boolean _isDisposed; - - /// - /// Dispose the polling client. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose the polling client. - /// - protected virtual void Dispose(Boolean isDisposing) - { - if (_isDisposed) - { - return; - } - if (isDisposing) - { - StopAsync().Wait(); - } - _isDisposed = true; - } - - /// - /// Finalizer. - /// - ~AsyncPollingClient() - { - Dispose(false); - } - } -} diff --git a/src/NEventStore.PollingClient/CommitSequencer.cs b/src/NEventStore.PollingClient/CommitSequencer.cs deleted file mode 100644 index ea8a8883a..000000000 --- a/src/NEventStore.PollingClient/CommitSequencer.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Helpers; -using NEventStore.Logging; -using System.Globalization; - -namespace NEventStore.PollingClient -{ - /// - /// A commit sequencer that can be used with - /// - public class CommitSequencer - { - private readonly ILogger _logger; - - private readonly Func _commitCallback; - - private Int64 _lastCommitRead; - - private readonly Int32 _outOfSequenceTimeoutInMilliseconds; - - /// - /// Initializes a new instance of the CommitSequencer class. - /// - public CommitSequencer(Func commitCallback, long lastCommitRead, int outOfSequenceTimeoutInMilliseconds) - { - _logger = LogFactory.BuildLogger(GetType()); - _commitCallback = commitCallback; - _lastCommitRead = lastCommitRead; - _outOfSequenceTimeoutInMilliseconds = outOfSequenceTimeoutInMilliseconds; - } - - private DateTime? outOfSequenceTimestamp; - - /// - /// Handles the specified commit. - /// - public PollingClient2.HandlingResult Handle(ICommit commit) - { - var lc = commit.CheckpointToken; - if (lc == _lastCommitRead + 1) - { - //is ok no need to re-sequence. - return InnerHandleResult(commit, lc); - } - else if (_lastCommitRead >= lc) - { - if (_logger.IsEnabled(LogLevel.Warning)) - { - _logger.LogWarning(String.Format(CultureInfo.InvariantCulture, "Wrong sequence in commit, last read: {0} actual read: {1}", _lastCommitRead, lc)); - } - return PollingClient2.HandlingResult.MoveToNext; - } - - if (outOfSequenceTimestamp == null) - { - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug("Sequencer found out of sequence, last dispatched: {LastDispatchedCheckpoint} now dispatching: {NowDispatchingCheckpoint}", _lastCommitRead, lc); - } - outOfSequenceTimestamp = DateTimeService.Now; - } - else - { - var interval = DateTimeService.Now.Subtract(outOfSequenceTimestamp.Value); - if (interval.TotalMilliseconds > _outOfSequenceTimeoutInMilliseconds) - { - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug("Sequencer out of sequence timeout after {TotalMilliseconds} ms, last dispatched: {LastDispatchedCheckpoint} now dispatching: {NowDispatchingCheckpoint}", interval.TotalMilliseconds, _lastCommitRead, lc); - } - return InnerHandleResult(commit, lc); - } - if (_logger.IsEnabled(LogLevel.Debug)) - { - _logger.LogDebug("Sequencer still out of sequence from {TotalMilliseconds} ms, last dispatched: {LastDispatchedCheckpoint} now dispatching: {NowDispatchingCheckpoint}", interval.TotalMilliseconds, _lastCommitRead, lc); - } - } - - return PollingClient2.HandlingResult.Retry; - } - - private PollingClient2.HandlingResult InnerHandleResult(ICommit commit, Int64 lc) - { - var innerReturn = _commitCallback(commit); - outOfSequenceTimestamp = null; - if (innerReturn == PollingClient2.HandlingResult.MoveToNext) - { - _lastCommitRead = lc; - } - return innerReturn; - } - } -} diff --git a/src/NEventStore.PollingClient/NEventStore.PollingClient.csproj b/src/NEventStore.PollingClient/NEventStore.PollingClient.csproj deleted file mode 100644 index 0adfc1a86..000000000 --- a/src/NEventStore.PollingClient/NEventStore.PollingClient.csproj +++ /dev/null @@ -1,64 +0,0 @@ - - - netstandard2.0 - false - NEventStore.PollingClient - NEventStore.PollingClient - false - TRACE;DEBUG - - - NEventStore.PollingClient - NEventStore.PollingClient - NEventStore Dev Team - http://neventstore.org - false - The purpose of the EventStore is to represent a series of events as a stream. NEventStore is a persistence agnostic event sourcing library for .NET. The primary use is most often associated with CQRS. This package is an implementation of a Polling Client that reads data from an EventStore. - events, event sourcing, cqrs, storage, persistence, database - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - True - \ - - - True - \ - - - True - \ - - - - - - \ No newline at end of file diff --git a/src/NEventStore.PollingClient/PollingClient2.cs b/src/NEventStore.PollingClient/PollingClient2.cs deleted file mode 100644 index 3f6e35b39..000000000 --- a/src/NEventStore.PollingClient/PollingClient2.cs +++ /dev/null @@ -1,278 +0,0 @@ -using NEventStore.Logging; -using NEventStore.Persistence; -using System.Collections.Concurrent; -using Microsoft.Extensions.Logging; -using System.Globalization; - -namespace NEventStore.PollingClient -{ - /// - /// A Polling Client that uses the Synchronous API of the store. - /// - public class PollingClient2 : IDisposable - { - /// - /// Result of the handling of a commit. - /// - public enum HandlingResult - { - /// - /// Move to the next commit. - /// - MoveToNext = 0, - /// - /// Retry the current commit. - /// - Retry = 1, - /// - /// Stop the polling client. - /// - Stop = 2, - } - - private readonly ILogger _logger; - - private readonly Func _commitCallback; - - private readonly IPersistStreams _persistStreams; - - private readonly Int32 _waitInterval; - private readonly Thread _pollingThread; - private readonly System.Timers.Timer _pollingWakeUpTimer; - - private Func>? _pollingFunc; - - private Int64 _checkpointToken; - - /// - /// Creates an NEventStore Polling Client - /// - /// the store to check - /// callback to execute at each commit - /// Interval in Milliseconds to wait when the provider - /// return no more commit and the next request - public PollingClient2( - IPersistStreams persistStreams, - Func callback, - Int32 waitInterval = 100) - { - _commitCallback = callback ?? throw new ArgumentNullException(nameof(callback), "Cannot use polling client without callback"); - _persistStreams = persistStreams ?? throw new ArgumentNullException(nameof(persistStreams), "PersistStreams cannot be null"); - - _logger = LogFactory.BuildLogger(GetType()); - _waitInterval = waitInterval; - _pollingWakeUpTimer = new System.Timers.Timer(); - _pollingWakeUpTimer.Elapsed += (sender, e) => WakeUpPollingClient(); - _pollingWakeUpTimer.Interval = _waitInterval; - - //Create polling thread - _pollingThread = new Thread(InnerPollingLoop); - _pollingThread.Start(); - - LastActivityTimestamp = DateTime.UtcNow; - } - - /// - /// Tells the caller the last tick count when the last activity occurred. This is useful for the caller - /// to setup Health check that verify if the polling client is really active and it is really loading new commits. - /// This value is obtained with DateTime.UtcNow - /// - public DateTime LastActivityTimestamp { get; private set; } - - /// - /// If the polling client encounter an exception it immediately retry, but we need to tell to the caller code - /// that the last polling encounter an error. This is needed to detect a polling client stuck as an example - /// with deserialization problems. - /// - public String? LastPollingError { get; private set; } - - /// - /// Start the polling client. - /// - public void StartFrom(Int64 checkpointToken = 0) - { - _checkpointToken = checkpointToken; - ConfigurePollingFunction(); - StartPollingThread(); - } - - /// - /// Start the polling client. - /// - public void StartFromBucket(string bucketId, Int64 checkpointToken = 0) - { - _checkpointToken = checkpointToken; - ConfigurePollingFunction(bucketId); - StartPollingThread(); - } - - /// - /// Simply start the timer that will queue wake up tokens. - /// - private void StartPollingThread() - { - _pollingWakeUpTimer.Start(); - } - - /// - /// Configure the polling function to get commits from the store. - /// - internal void ConfigurePollingFunction(string? bucketId = null) - { - if (bucketId == null) - _pollingFunc = () => _persistStreams.GetFrom(_checkpointToken); - else - _pollingFunc = () => _persistStreams.GetFrom(bucketId, _checkpointToken); - } - - /// - /// Stop the polling client. - /// - public void Stop() - { - _stopRequest = true; - _pollingWakeUpTimer?.Stop(); - - WakeUpPollingClient(); - } - - /// - /// Poll now. - /// - public void PollNow() - { - WakeUpPollingClient(); - } - - /// - /// Add an object to wake up the polling client. - /// - private void WakeUpPollingClient() - { - //Avoid adding more than one wake up object. - if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0) - { - //If we have not a wake up object add one. - if (_pollCollection.Count == 0) - _pollCollection.Add(new object()); - - Interlocked.Exchange(ref _isPolling, 0); - } - } - - private int _isPolling; - - private Boolean _stopRequest; - - /// - /// This blocking collection is used to Wake up the polling thread - /// and to ensure that only the polling thread is polling from - /// event stream. - /// - private readonly BlockingCollection _pollCollection = []; - - private void InnerPollingLoop(object obj) - { - foreach (var _ in _pollCollection.GetConsumingEnumerable()) - { - //check stop request - if (_stopRequest) - return; - - if (InnerPoll()) - return; - } - } - - /// - /// Added to avoid flooding of logging during polling. - /// - private DateTime _lastPollingErrorLogTimestamp = DateTime.MinValue; - - /// - /// This is the inner polling function that does the polling and - /// returns true if there were errors that should stop the polling client. - /// - /// Returns true if we need to stop the outer cycle. - private bool InnerPoll() - { - LastActivityTimestamp = DateTime.UtcNow; - if (_pollingFunc == null) return false; - - try - { - var commits = _pollingFunc(); - - //if we have an error in the provider, the error will be thrown during enumeration - foreach (var commit in commits) - { - //We need to reset the error, because we read correctly a commit - LastPollingError = null; - LastActivityTimestamp = DateTime.UtcNow; - if (_stopRequest) - { - return true; - } - var result = _commitCallback(commit); - if (result == HandlingResult.Retry) - { - if (_logger.IsEnabled(LogLevel.Trace)) - { - _logger.LogTrace("Commit callback ask retry for checkpointToken: {CommitCheckpointToken} - last dispatched: {LastDispatchedCheckpointToken}", commit.CheckpointToken, _checkpointToken); - } - break; - } - else if (result == HandlingResult.Stop) - { - Stop(); - return true; - } - _checkpointToken = commit.CheckpointToken; - } - //if we reach here, we had no error contacting the persistence store. - LastPollingError = null; - } - catch (Exception ex) - { - // These exceptions are expected to be transient - LastPollingError = ex.Message; - - // These exceptions are expected to be transient, we log at maximum a log entry each minute. - if (DateTime.UtcNow.Subtract(_lastPollingErrorLogTimestamp).TotalMinutes > 1) - { - _logger.LogError(String.Format(CultureInfo.InvariantCulture, "Error during polling client {0}", ex.ToString())); - _lastPollingErrorLogTimestamp = DateTime.UtcNow; - } - - //A transient reading error is possible, but we need to wait a little bit before retrying. - Thread.Sleep(1000); - } - - return false; - } - - private Boolean _isDisposed; - - /// - /// Dispose the polling client. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose the polling client. - /// - public void Dispose(Boolean isDisposing) - { - if (_isDisposed) return; - if (isDisposing) - { - Stop(); - } - _isDisposed = true; - } - } -} diff --git a/src/NEventStore.PollingClient/PollingClientException.cs b/src/NEventStore.PollingClient/PollingClientException.cs deleted file mode 100644 index 42e89e8dd..000000000 --- a/src/NEventStore.PollingClient/PollingClientException.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace NEventStore.PollingClient -{ - /// - /// ApplicationException has been deprecated in .NET Core - /// - [Serializable] - public class PollingClientException : Exception - { - /// - /// Initializes a new instance of the class. - /// - public PollingClientException() { } - /// - /// Initializes a new instance of the class. - /// - public PollingClientException(string message) : base(message) { } - /// - /// Initializes a new instance of the class. - /// - public PollingClientException(string message, Exception inner) : base(message, inner) { } - /// - /// Initializes a new instance of the class. - /// - protected PollingClientException( - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) : base(info, context) { } - } -} diff --git a/src/NEventStore.PollingClient/Properties/ProjectAssemblyInfo.cs b/src/NEventStore.PollingClient/Properties/ProjectAssemblyInfo.cs deleted file mode 100644 index 0269eb2dc..000000000 --- a/src/NEventStore.PollingClient/Properties/ProjectAssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("NEventStore")] -[assembly: AssemblyDescription("")] -[assembly: Guid("9cb4668f-d7b2-4ad9-8f9b-2af9903d2db2")] \ No newline at end of file diff --git a/src/NEventStore.PollingClient/README.MD b/src/NEventStore.PollingClient/README.MD deleted file mode 100644 index cdb8186b4..000000000 --- a/src/NEventStore.PollingClient/README.MD +++ /dev/null @@ -1,208 +0,0 @@ -# Polling Client - -This project contains a 'reference' implementation of a Polling Client for NEventStore. - -Its duty is to constantly ask the NEventStore if there are new commits made by the users, read them and dispatch the committed events to their handlers. - -You are encouraged to write your own PollingClient that suits your needs, you can use the code in this project as a starting point. - -## New Polling client without RX - -To remove dependency from RX library, the old PollingClient was removed from the project. - -The entire code for OldPollingClient is included in this README, If you still need it in your project you can simply include this class in your code as well as the dependencies from RX. - -With the new PollingClient2 you should simply pass a Function that will be called to handle the commit, you can use Rx if you like that approach approach, or even better you can use TPL Dataflow that is probably more suited. - -If you want to use the new polling client with RX you can look at PollingClientRx inside Test project. - -### Old Polling Client Code - - namespace NEventStore.Client - { - using System; - using System.Collections.Generic; - using System.Reactive; - using System.Reactive.Subjects; - using System.Threading; - using System.Threading.Tasks; - using NEventStore.Logging; - using NEventStore.Persistence; - - /// - /// Represents a client that poll the storage for latest commits. - /// - public sealed class PollingClient : ClientBase - { - private readonly int _interval; - - public PollingClient(IPersistStreams persistStreams, int interval = 5000) : base(persistStreams) - { - if (persistStreams == null) - { - throw new ArgumentNullException("persistStreams"); - } - if (interval <= 0) - { - throw new ArgumentException(Messages.MustBeGreaterThanZero.FormatWith("interval")); - } - _interval = interval; - } - - /// - /// Observe commits from the sepecified checkpoint token. If the token is null, - /// all commits from the beginning will be observed. - /// - /// The checkpoint token. - /// - /// An instance. - /// - public override IObserveCommits ObserveFrom(Int64 checkpointToken = 0) - { - return new PollingObserveCommits(PersistStreams, _interval, null, checkpointToken); - } - - public override IObserveCommits ObserveFromBucket(string bucketId, Int64 checkpointToken = 0) - { - return new PollingObserveCommits(PersistStreams, _interval, bucketId, checkpointToken); - } - - private class PollingObserveCommits : IObserveCommits - { - private ILog Logger = LogFactory.BuildLogger(typeof (PollingClient)); - private readonly IPersistStreams _persistStreams; - private Int64 _checkpointToken; - private readonly int _interval; - private readonly string _bucketId; - private readonly Subject _subject = new Subject(); - private readonly CancellationTokenSource _stopRequested = new CancellationTokenSource(); - private TaskCompletionSource _runningTaskCompletionSource; - private int _isPolling = 0; - - public PollingObserveCommits(IPersistStreams persistStreams, int interval, string bucketId, Int64 checkpointToken = 0) - { - _persistStreams = persistStreams; - _checkpointToken = checkpointToken; - _interval = interval; - _bucketId = bucketId; - } - - public IDisposable Subscribe(IObserver observer) - { - return _subject.Subscribe(observer); - } - - public void Dispose() - { - _stopRequested.Cancel(); - _subject.Dispose(); - if (_runningTaskCompletionSource != null) - { - _runningTaskCompletionSource.TrySetResult(new Unit()); - } - } - - public Task Start() - { - if (_runningTaskCompletionSource != null) - { - return _runningTaskCompletionSource.Task; - } - _runningTaskCompletionSource = new TaskCompletionSource(); - PollLoop(); - return _runningTaskCompletionSource.Task; - } - - public void PollNow() - { - DoPoll(); - } - - private void PollLoop() - { - if (_stopRequested.IsCancellationRequested) - { - Dispose(); - return; - } - TaskHelpers.Delay(_interval, _stopRequested.Token) - .WhenCompleted(_ => - { - DoPoll(); - PollLoop(); - },_ => Dispose()); - } - - private void DoPoll() - { - if (Interlocked.CompareExchange(ref _isPolling, 1, 0) == 0) - { - try - { - var commits = _bucketId == null ? - _persistStreams.GetFrom(_checkpointToken) : - _persistStreams.GetFrom(_bucketId, _checkpointToken); - - foreach (var commit in commits) - { - if (_stopRequested.IsCancellationRequested) - { - _subject.OnCompleted(); - return; - } - _subject.OnNext(commit); - _checkpointToken = commit.CheckpointToken; - } - } - catch (Exception ex) - { - // These exceptions are expected to be transient - Logger.Error(ex.ToString()); - } - Interlocked.Exchange(ref _isPolling, 0); - } - } - } - } - - public abstract class ClientBase - { - private readonly IPersistStreams _persistStreams; - - protected ClientBase(IPersistStreams persistStreams) - { - _persistStreams = persistStreams; - } - - protected IPersistStreams PersistStreams - { - get { return _persistStreams; } - } - - - /// - /// Observe commits from the sepecified checkpoint token. If the token is null, - /// all commits from the beginning will be observed. - /// - /// The checkpoint token. - /// An instance. - public abstract IObserveCommits ObserveFrom(Int64 checkpointToken = 0); - - /// - /// Observe commits from a bucket after the sepecified checkpoint token. If the token is null, - /// all commits from the beginning will be observed. - /// - /// The bucket id - /// The checkpoint token. - /// An instance. - public abstract IObserveCommits ObserveFromBucket(string bucketId, Int64 checkpointToken = 0); - } - - public interface IObserveCommits : IObservable, IDisposable - { - Task Start(); - - void PollNow(); - } - } - diff --git a/src/NEventStore.PollingClientExample/MainProgram.cs b/src/NEventStore.PollingClientExample/MainProgram.cs deleted file mode 100644 index 825768a7c..000000000 --- a/src/NEventStore.PollingClientExample/MainProgram.cs +++ /dev/null @@ -1,95 +0,0 @@ -using NEventStore.PollingClient; -using Microsoft.Extensions.Logging; - -namespace NEventStore.PollingClientExample -{ - internal static class MainProgram - { - private static void Main() - { - using var store = WireupEventStore(); - // append some commits to the EventStore - AppendToStream(store, "Stream1"); - AppendToStream(store, "Stream2"); - AppendToStream(store, "Stream1"); - - Console.WriteLine("--------------------------"); - Console.WriteLine("Starting PollingClient2..."); - Console.WriteLine(); - - // now test the polling client - Int64 checkpointToken = LoadCheckpoint(); - var client = new PollingClient2(store.Advanced, commit => - { - // Project the commit etc - Console.WriteLine("BucketId={0};StreamId={1};CommitSequence={2}", commit.BucketId, commit.StreamId, commit.CommitSequence); - // Track the most recent checkpoint - checkpointToken = commit.CheckpointToken; - return PollingClient2.HandlingResult.MoveToNext; - }, - waitInterval: 3000); - - client.StartFrom(checkpointToken); - Console.WriteLine("Wait for the Stream to end, then press any key to continue..."); - Console.ReadKey(); - client.Stop(); - - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine("Starting AsyncPollingClient..."); - Console.WriteLine(); - - checkpointToken = LoadCheckpoint(); - var observer = new LambdaAsyncObserver((commit, _) => - { - // Project the commit etc - Console.WriteLine("BucketId={0};StreamId={1};CommitSequence={2}", commit.BucketId, commit.StreamId, commit.CommitSequence); - // Track the most recent checkpoint - checkpointToken = commit.CheckpointToken; - return Task.FromResult(true); - }); - var asyncClient = new AsyncPollingClient(store.Advanced, observer, waitInterval: 3000, holeDetectionWaitInterval: 100); - asyncClient.Start(checkpointToken); - - Console.WriteLine("Press any key to continue..."); - Console.ReadKey(); - asyncClient.StopAsync() - .GetAwaiter().GetResult(); - } - - private static Int64 LoadCheckpoint() - { - // Load the checkpoint value from disk / local db/ etc - return 0; - } - - private static IStoreEvents WireupEventStore() - { - var loggerFactory = LoggerFactory.Create(logging => - { - logging - .AddConsole() - .AddDebug() - .SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace); - }); - - return Wireup.Init() - .WithLoggerFactory(loggerFactory) - .UsingInMemoryPersistence() - .InitializeStorageEngine() -#if NET462 - .TrackPerformanceInstance("example") -#endif - .Build(); - } - - private static void AppendToStream(IStoreEvents store, string streamId) - { - using var stream = store.OpenStream(streamId); - var @event = new SomeDomainEvent { Value = "event" }; - - stream.Add(new EventMessage { Body = @event }); - stream.CommitChanges(Guid.NewGuid()); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.PollingClientExample/NEventStore.PollingClientExample.csproj b/src/NEventStore.PollingClientExample/NEventStore.PollingClientExample.csproj deleted file mode 100644 index 7571208c5..000000000 --- a/src/NEventStore.PollingClientExample/NEventStore.PollingClientExample.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - net8.0;net472 - false - - exe - - Exe - - - - TRACE;DEBUG - - - - - - - - - - - - - - - - - - - diff --git a/src/NEventStore.PollingClientExample/Properties/ProjectAssemblyInfo.cs b/src/NEventStore.PollingClientExample/Properties/ProjectAssemblyInfo.cs deleted file mode 100644 index 33cbc2e74..000000000 --- a/src/NEventStore.PollingClientExample/Properties/ProjectAssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("NEventStore.Example")] -[assembly: AssemblyDescription("")] -[assembly: Guid("6fd621e0-9047-4449-b136-249383936d5c")] \ No newline at end of file diff --git a/src/NEventStore.PollingClientExample/SomeDomainEvent.cs b/src/NEventStore.PollingClientExample/SomeDomainEvent.cs deleted file mode 100644 index 96a47fffb..000000000 --- a/src/NEventStore.PollingClientExample/SomeDomainEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace NEventStore.PollingClientExample -{ - internal class SomeDomainEvent - { - public string? Value { get; set; } - } -} diff --git a/src/NEventStore.Serialization.Binary.Tests/NEventStore.Serialization.Binary.Core.Tests.csproj b/src/NEventStore.Serialization.Binary.Tests/NEventStore.Serialization.Binary.Core.Tests.csproj deleted file mode 100644 index 711e8fcc8..000000000 --- a/src/NEventStore.Serialization.Binary.Tests/NEventStore.Serialization.Binary.Core.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.Binary.Tests - NEventStore.Serialization.Binary.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.Binary.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index 25dac50c3..000000000 --- a/src/NEventStore.Serialization.Binary.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.Json.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.Binary.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Binary.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 186e9e034..000000000 --- a/src/NEventStore.Serialization.Binary.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Binary.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5bc73f44-a60e-4b2e-984d-81f56806cc79")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.Binary.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.Binary.Tests/SerializerFixture.cs deleted file mode 100644 index 185b1c314..000000000 --- a/src/NEventStore.Serialization.Binary.Tests/SerializerFixture.cs +++ /dev/null @@ -1,20 +0,0 @@ -using NEventStore.Serialization.Binary; - -// ReSharper disable CheckNamespace -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - public partial class SerializerFixture - { - public SerializerFixture() - { -#if NET8_0_OR_GREATER - AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true); -#endif -#pragma warning disable CS0618 // Type or member is obsolete - _createSerializer = () => - new BinarySerializer(); -#pragma warning restore CS0618 // Type or member is obsolete - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary.Tests/packages.config b/src/NEventStore.Serialization.Binary.Tests/packages.config deleted file mode 100644 index 3676eab81..000000000 --- a/src/NEventStore.Serialization.Binary.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary/BinarySerializationWireupExtension.cs b/src/NEventStore.Serialization.Binary/BinarySerializationWireupExtension.cs deleted file mode 100644 index 7bb7bdfd6..000000000 --- a/src/NEventStore.Serialization.Binary/BinarySerializationWireupExtension.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Diagnostics; - -namespace NEventStore.Serialization.Binary -{ - /// - /// Binary serialization wire-up extensions. - /// - public static class BinarySerializationWireupExtension - { - /// - /// Use the MessagePack serializer. - /// - /// Wire-up to extend - /// Serialization Wire-up - [DebuggerStepThrough] - [Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.")] - public static SerializationWireup UsingBinarySerialization(this PersistenceWireup wireup) - { -#if NET8_0_OR_GREATER - AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true); -#endif - return wireup.UsingCustomSerialization(new BinarySerializer()); - } - } -} diff --git a/src/NEventStore.Serialization.Binary/BinarySerializer.cs b/src/NEventStore.Serialization.Binary/BinarySerializer.cs deleted file mode 100644 index 775b26339..000000000 --- a/src/NEventStore.Serialization.Binary/BinarySerializer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Runtime.Serialization.Formatters.Binary; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Serialization.Binary -{ - /// - /// Delegates to to perform the actual serialization. - /// - [Obsolete("BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.")] - public class BinarySerializer : ISerialize - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(BinarySerializer)); - private readonly BinaryFormatter _formatter = new(); - - /// - public virtual void Serialize(Stream output, T graph) where T : notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - _formatter.Serialize(output, graph); - } - - /// - public virtual T Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - return (T)_formatter.Deserialize(input); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary/Messages.Designer.cs b/src/NEventStore.Serialization.Binary/Messages.Designer.cs deleted file mode 100644 index 80ff790b3..000000000 --- a/src/NEventStore.Serialization.Binary/Messages.Designer.cs +++ /dev/null @@ -1,81 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore.Serialization.Binary { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Serialization.Binary.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Deserializing stream to object of type '{0}'.. - /// - internal static string DeserializingStream { - get { - return ResourceManager.GetString("DeserializingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Serializing object graph of type '{0}'.. - /// - internal static string SerializingGraph { - get { - return ResourceManager.GetString("SerializingGraph", resourceCulture); - } - } - } -} diff --git a/src/NEventStore.Serialization.Binary/Messages.resx b/src/NEventStore.Serialization.Binary/Messages.resx deleted file mode 100644 index 971eea1e1..000000000 --- a/src/NEventStore.Serialization.Binary/Messages.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Deserializing stream to object of type '{0}'. - - - Serializing object graph of type '{0}'. - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary/NEventStore.Serialization.Binary.Core.csproj b/src/NEventStore.Serialization.Binary/NEventStore.Serialization.Binary.Core.csproj deleted file mode 100644 index 09e594492..000000000 --- a/src/NEventStore.Serialization.Binary/NEventStore.Serialization.Binary.Core.csproj +++ /dev/null @@ -1,80 +0,0 @@ - - - netstandard2.0;net8.0 - false - NEventStore.Serialization.Binary - NEventStore.Serialization.Binary - - - NEventStore.Serialization.Binary - NEventStore Binary Serializers - NEventStore Dev Team - http://neventstore.org - false - This package contains Bson serializers for NEventStore library. These serializers were removed from the core package to limit dependencies from external libraries. - events, event sourcing, cqrs, storage, persistence, database - - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - TRACE;DEBUG - - - - True - \ - - - True - \ - - - True - \ - - - - - - - - Messages.resx - True - True - - - - - NEventStore.Serialization.Binary - Messages.Designer.cs - ResXFileCodeGenerator - - - - - 9.0.0 - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Binary/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Binary/Properties/AssemblyInfo.cs deleted file mode 100644 index 0e5d8c1c8..000000000 --- a/src/NEventStore.Serialization.Binary/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Binary")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore.Serialization.Binary")] -[assembly: AssemblyCopyright("Copyright © 2011")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("41CFA1C0-8B82-4F50-A758-056B556679F6")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("0.0.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0.0")] \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson.Tests/NEventStore.Serialization.Bson.Core.Tests.csproj b/src/NEventStore.Serialization.Bson.Tests/NEventStore.Serialization.Bson.Core.Tests.csproj deleted file mode 100644 index db8d704ac..000000000 --- a/src/NEventStore.Serialization.Bson.Tests/NEventStore.Serialization.Bson.Core.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.Bson.Tests - NEventStore.Serialization.Bson.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.Bson.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index e0ea056df..000000000 --- a/src/NEventStore.Serialization.Bson.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.Bson.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.Bson.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Bson.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 914757de1..000000000 --- a/src/NEventStore.Serialization.Bson.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Bson.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("94518417-F5DE-44D7-B20B-0DD8BB86DC6C")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.Bson.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.Bson.Tests/SerializerFixture.cs deleted file mode 100644 index 3d9a2028a..000000000 --- a/src/NEventStore.Serialization.Bson.Tests/SerializerFixture.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable CheckNamespace -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - using NEventStore.Serialization.Bson; - - public partial class SerializerFixture - { - public SerializerFixture() - { - _createSerializer = () => - new BsonSerializer(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson.Tests/packages.config b/src/NEventStore.Serialization.Bson.Tests/packages.config deleted file mode 100644 index 3676eab81..000000000 --- a/src/NEventStore.Serialization.Bson.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson/BsonSerializationWireupExtension.cs b/src/NEventStore.Serialization.Bson/BsonSerializationWireupExtension.cs deleted file mode 100644 index 8b0bd99fb..000000000 --- a/src/NEventStore.Serialization.Bson/BsonSerializationWireupExtension.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace NEventStore.Serialization.Bson -{ - /// - /// Bson serialization wire-up extensions. - /// - public static class BsonSerializationWireupExtension - { - /// - /// Specify we want to use Bson serialization. - /// - public static SerializationWireup UsingBsonSerialization(this PersistenceWireup wireup) - { - return wireup.UsingCustomSerialization(new BsonSerializer()); - } - } -} diff --git a/src/NEventStore.Serialization.Bson/BsonSerializer.cs b/src/NEventStore.Serialization.Bson/BsonSerializer.cs deleted file mode 100644 index 5c0870111..000000000 --- a/src/NEventStore.Serialization.Bson/BsonSerializer.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System.Collections; -using NEventStore.Logging; -using Newtonsoft.Json.Bson; -using Newtonsoft.Json; -using Microsoft.Extensions.Logging; - -namespace NEventStore.Serialization.Bson -{ - /// - /// Represents a BSON serializer. - /// - public class BsonSerializer : ISerialize - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(BsonSerializer)); - - private readonly IEnumerable _knownTypes = [typeof(List), typeof(Dictionary)]; - - private readonly JsonSerializer _typedSerializer = new() - { - TypeNameHandling = TypeNameHandling.All, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore - }; - - private readonly JsonSerializer _untypedSerializer = new() - { - TypeNameHandling = TypeNameHandling.Auto, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore - }; - - /// - /// Initializes a new instance of the BsonSerializer class. - /// - public BsonSerializer(params Type[]? knownTypes) - { - if (knownTypes?.Length == 0) - { - knownTypes = null; - } - - _knownTypes = knownTypes ?? _knownTypes; - - if (Logger.IsEnabled(LogLevel.Debug)) - { - foreach (var type in _knownTypes) - { - Logger.LogDebug(Messages.RegisteringKnownType, type); - } - } - } - - /// - public virtual void Serialize(Stream output, T graph) where T: notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - using var writer = new BsonDataWriter(output) { DateTimeKindHandling = DateTimeKind.Utc }; - Serialize(writer, graph); - } - - /// - public virtual T? Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - using var reader = new BsonDataReader(input, IsArray(typeof(T)), DateTimeKind.Utc); - return Deserialize(reader); - } - - /// - /// Serialize an object to a JsonWriter. - /// - protected virtual void Serialize(JsonWriter writer, object graph) - { - GetSerializer(graph.GetType()).Serialize(writer, graph); - } - - /// - /// Deserialize an object from a JsonReader. - /// - protected virtual T? Deserialize(JsonReader reader) - { - Type type = typeof(T); - return (T?)GetSerializer(type).Deserialize(reader, type); - } - - /// - /// Get the serializer for the given type. - /// - protected virtual Newtonsoft.Json.JsonSerializer GetSerializer(Type typeToSerialize) - { - if (_knownTypes.Contains(typeToSerialize)) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.UsingUntypedSerializer, typeToSerialize); - } - return _untypedSerializer; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.UsingTypedSerializer, typeToSerialize); - } - return _typedSerializer; - } - - private static bool IsArray(Type type) - { - bool array = typeof(IEnumerable).IsAssignableFrom(type) && !typeof(IDictionary).IsAssignableFrom(type); - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.TypeIsArray, type, array); - } - - return array; - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson/Messages.Designer.cs b/src/NEventStore.Serialization.Bson/Messages.Designer.cs deleted file mode 100644 index ec95a95da..000000000 --- a/src/NEventStore.Serialization.Bson/Messages.Designer.cs +++ /dev/null @@ -1,117 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore.Serialization.Bson { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Serialization.Bson.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Deserializing stream to object of type '{0}'.. - /// - internal static string DeserializingStream { - get { - return ResourceManager.GetString("DeserializingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering type '{0}' as a known type.. - /// - internal static string RegisteringKnownType { - get { - return ResourceManager.GetString("RegisteringKnownType", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Serializing object graph of type '{0}'.. - /// - internal static string SerializingGraph { - get { - return ResourceManager.GetString("SerializingGraph", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Objects of type '{0}' are considered to be an array: '{1}'.. - /// - internal static string TypeIsArray { - get { - return ResourceManager.GetString("TypeIsArray", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The object to be serialized is of type '{0}'. Using a typed serializer for the unknown type.. - /// - internal static string UsingTypedSerializer { - get { - return ResourceManager.GetString("UsingTypedSerializer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The object to be serialized is of type '{0}'. Using an untyped serializer for the known type.. - /// - internal static string UsingUntypedSerializer { - get { - return ResourceManager.GetString("UsingUntypedSerializer", resourceCulture); - } - } - } -} diff --git a/src/NEventStore.Serialization.Bson/Messages.resx b/src/NEventStore.Serialization.Bson/Messages.resx deleted file mode 100644 index 390f70808..000000000 --- a/src/NEventStore.Serialization.Bson/Messages.resx +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Deserializing stream to object of type '{0}'. - - - Serializing object graph of type '{0}'. - - - Registering type '{0}' as a known type. - - - Objects of type '{0}' are considered to be an array: '{1}'. - - - The object to be serialized is of type '{0}'. Using a typed serializer for the unknown type. - - - The object to be serialized is of type '{0}'. Using an untyped serializer for the known type. - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson/NEventStore.Serialization.Bson.Core.csproj b/src/NEventStore.Serialization.Bson/NEventStore.Serialization.Bson.Core.csproj deleted file mode 100644 index 655bfd458..000000000 --- a/src/NEventStore.Serialization.Bson/NEventStore.Serialization.Bson.Core.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - netstandard2.0 - false - NEventStore.Serialization.Bson - NEventStore.Serialization.Bson - - - NEventStore.Serialization.Bson - NEventStore Bson Serializers - NEventStore Dev Team - http://neventstore.org - false - This package contains Bson serializers for NEventStore library. These serializers were removed from the core package to limit dependencies from external libraries. - events, event sourcing, cqrs, storage, persistence, database - - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - TRACE;DEBUG - - - - True - \ - - - True - \ - - - True - \ - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - True - True - Messages.resx - - - - - ResXFileCodeGenerator - Messages.Designer.cs - NEventStore.Serialization.Bson - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Bson/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Bson/Properties/AssemblyInfo.cs deleted file mode 100644 index 8d6722a14..000000000 --- a/src/NEventStore.Serialization.Bson/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Bson")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore.Serialization.Bson")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7bbb9172-7b2c-4854-9b59-952b54122632")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("0.0.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0.0")] diff --git a/src/NEventStore.Serialization.Gzip.Tests/NEventStore.Serialization.GZip.Core.Tests.csproj b/src/NEventStore.Serialization.Gzip.Tests/NEventStore.Serialization.GZip.Core.Tests.csproj deleted file mode 100644 index cd5532795..000000000 --- a/src/NEventStore.Serialization.Gzip.Tests/NEventStore.Serialization.GZip.Core.Tests.csproj +++ /dev/null @@ -1,47 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.GZip.Tests - NEventStore.Serialization.GZip.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Gzip.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.Gzip.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index b8ee80d9f..000000000 --- a/src/NEventStore.Serialization.Gzip.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.GZip.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.Gzip.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Gzip.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index cddbe103b..000000000 --- a/src/NEventStore.Serialization.Gzip.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Gzip.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5BB89C20-A481-4A15-9478-C0F69E419239")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.Gzip.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.Gzip.Tests/SerializerFixture.cs deleted file mode 100644 index a6a348ecd..000000000 --- a/src/NEventStore.Serialization.Gzip.Tests/SerializerFixture.cs +++ /dev/null @@ -1,20 +0,0 @@ -// ReSharper disable CheckNamespace -using NEventStore.Serialization.Binary; - -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - public partial class SerializerFixture - { - public SerializerFixture() - { -#if NET8_0_OR_GREATER - AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true); -#endif -#pragma warning disable CS0618 // Type or member is obsolete - _createSerializer = () => - new GzipSerializer(new BinarySerializer()); -#pragma warning restore CS0618 // Type or member is obsolete - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Gzip.Tests/packages.config b/src/NEventStore.Serialization.Gzip.Tests/packages.config deleted file mode 100644 index 3676eab81..000000000 --- a/src/NEventStore.Serialization.Gzip.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json.Tests/NEventStore.Serialization.Json.Core.Tests.csproj b/src/NEventStore.Serialization.Json.Tests/NEventStore.Serialization.Json.Core.Tests.csproj deleted file mode 100644 index a751aefbf..000000000 --- a/src/NEventStore.Serialization.Json.Tests/NEventStore.Serialization.Json.Core.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.Json.Tests - NEventStore.Serialization.Json.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.Json.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index e6f66c26f..000000000 --- a/src/NEventStore.Serialization.Json.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.Json.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.Json.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Json.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index f8bf36ef2..000000000 --- a/src/NEventStore.Serialization.Json.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Json.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9775F040-BA9C-48C1-BB16-1A1D6B86A3F1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.Json.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.Json.Tests/SerializerFixture.cs deleted file mode 100644 index 040a7c2c6..000000000 --- a/src/NEventStore.Serialization.Json.Tests/SerializerFixture.cs +++ /dev/null @@ -1,15 +0,0 @@ -using NEventStore.Serialization.Json; - -// ReSharper disable CheckNamespace -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - public partial class SerializerFixture - { - public SerializerFixture() - { - _createSerializer = () => - new JsonSerializer(null); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json.Tests/packages.config b/src/NEventStore.Serialization.Json.Tests/packages.config deleted file mode 100644 index dff6f66d1..000000000 --- a/src/NEventStore.Serialization.Json.Tests/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json/JsonSerializationWireupExtension.cs b/src/NEventStore.Serialization.Json/JsonSerializationWireupExtension.cs deleted file mode 100644 index 503ccaa41..000000000 --- a/src/NEventStore.Serialization.Json/JsonSerializationWireupExtension.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Newtonsoft.Json; - -namespace NEventStore.Serialization.Json -{ - /// - /// Newtonsoft Json serialization wire-up extensions. - /// - public static class JsonSerializationWireupExtension - { - /// - /// Specify we want to use Json serialization using Newtonsoft.Json - /// - /// The persistence wire-up. - /// - /// Allows to customize some Serializer options, however some of them will - /// be under control of this specific implementation and will be overwritten no matter - /// what the user specifies: - /// - TypeNameHandling = TypeNameHandling.All - /// - DefaultValueHandling = DefaultValueHandling.Ignore - /// - NullValueHandling = NullValueHandling.Ignore - /// - public static SerializationWireup UsingJsonSerialization( - this PersistenceWireup wireup, - JsonSerializerSettings? jsonSerializerSettings = null) - { - return wireup.UsingCustomSerialization(new JsonSerializer(jsonSerializerSettings)); - } - } -} diff --git a/src/NEventStore.Serialization.Json/JsonSerializer.cs b/src/NEventStore.Serialization.Json/JsonSerializer.cs deleted file mode 100644 index fa5cfdc90..000000000 --- a/src/NEventStore.Serialization.Json/JsonSerializer.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System.Text; -using Newtonsoft.Json; -using NEventStore.Logging; -using Microsoft.Extensions.Logging; - -namespace NEventStore.Serialization.Json -{ - /// - /// The Newtonsoft JSON serializer. - /// - public class JsonSerializer : ISerialize - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(JsonSerializer)); - private readonly IEnumerable _knownTypes = [typeof(List), typeof(Dictionary)]; - - private readonly Newtonsoft.Json.JsonSerializer _typedSerializer; - - private readonly Newtonsoft.Json.JsonSerializer _untypedSerializer; - - /// - /// NEventStore Json Serialization using Newtonsoft.Json - /// - /// Allows to configure some Json serialization options, - /// some of them will be overwritten given the values passed to parameter - /// - /// Every Type specified here will be serialized with: - /// - TypeNameHandling = TypeNameHandling.Auto - /// - DefaultValueHandling = DefaultValueHandling.Ignore - /// - NullValueHandling = NullValueHandling.Ignore - /// Every other type will be serialized with: - /// - TypeNameHandling = TypeNameHandling.All - /// - DefaultValueHandling = DefaultValueHandling.Ignore - /// - NullValueHandling = NullValueHandling.Ignore - /// - public JsonSerializer(JsonSerializerSettings? jsonSerializerSettings, params Type[]? knownTypes) - { - if (knownTypes?.Length == 0) - { - knownTypes = null; - } - - _knownTypes = knownTypes ?? _knownTypes; - - _typedSerializer = Newtonsoft.Json.JsonSerializer.Create(jsonSerializerSettings); - _typedSerializer.TypeNameHandling = TypeNameHandling.All; - _typedSerializer.DefaultValueHandling = DefaultValueHandling.Ignore; - _typedSerializer.NullValueHandling = NullValueHandling.Ignore; - - _untypedSerializer = Newtonsoft.Json.JsonSerializer.Create(jsonSerializerSettings); - _untypedSerializer.TypeNameHandling = TypeNameHandling.Auto; - _untypedSerializer.DefaultValueHandling = DefaultValueHandling.Ignore; - _untypedSerializer.NullValueHandling = NullValueHandling.Ignore; - - if (Logger.IsEnabled(LogLevel.Debug)) - { - foreach (var type in _knownTypes) - { - Logger.LogDebug(Messages.RegisteringKnownType, type); - } - } - } - - /// - public virtual void Serialize(Stream output, T graph) where T: notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - using var streamWriter = new StreamWriter(output, Encoding.UTF8); - using var jsonTextWriter = new JsonTextWriter(streamWriter); - Serialize(jsonTextWriter, graph); - } - - /// - public virtual T? Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - using var streamReader = new StreamReader(input, Encoding.UTF8); - using var jsonTextReader = new JsonTextReader(streamReader); - return Deserialize(jsonTextReader); - } - - /// - /// Serialize an object to a JsonWriter. - /// - protected virtual void Serialize(JsonWriter writer, object graph) - { - GetSerializer(graph.GetType()).Serialize(writer, graph); - } - - /// - /// Deserialize an object from a JsonReader. - /// - protected virtual T? Deserialize(JsonReader reader) - { - Type type = typeof(T); - return (T?)GetSerializer(type).Deserialize(reader, type); - } - - /// - /// Get the serializer for the given type. - /// - protected virtual Newtonsoft.Json.JsonSerializer GetSerializer(Type typeToSerialize) - { - if (_knownTypes.Contains(typeToSerialize)) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.UsingUntypedSerializer, typeToSerialize); - } - return _untypedSerializer; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.UsingTypedSerializer, typeToSerialize); - } - return _typedSerializer; - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json/Messages.Designer.cs b/src/NEventStore.Serialization.Json/Messages.Designer.cs deleted file mode 100644 index 533c6643a..000000000 --- a/src/NEventStore.Serialization.Json/Messages.Designer.cs +++ /dev/null @@ -1,108 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore.Serialization.Json { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Serialization.Json.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Deserializing stream to object of type '{0}'.. - /// - internal static string DeserializingStream { - get { - return ResourceManager.GetString("DeserializingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering type '{0}' as a known type.. - /// - internal static string RegisteringKnownType { - get { - return ResourceManager.GetString("RegisteringKnownType", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Serializing object graph of type '{0}'.. - /// - internal static string SerializingGraph { - get { - return ResourceManager.GetString("SerializingGraph", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The object to be serialized is of type '{0}'. Using a typed serializer for the unknown type.. - /// - internal static string UsingTypedSerializer { - get { - return ResourceManager.GetString("UsingTypedSerializer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The object to be serialized is of type '{0}'. Using an untyped serializer for the known type.. - /// - internal static string UsingUntypedSerializer { - get { - return ResourceManager.GetString("UsingUntypedSerializer", resourceCulture); - } - } - } -} diff --git a/src/NEventStore.Serialization.Json/Messages.resx b/src/NEventStore.Serialization.Json/Messages.resx deleted file mode 100644 index 34a0c4cfe..000000000 --- a/src/NEventStore.Serialization.Json/Messages.resx +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Deserializing stream to object of type '{0}'. - - - Serializing object graph of type '{0}'. - - - Registering type '{0}' as a known type. - - - The object to be serialized is of type '{0}'. Using a typed serializer for the unknown type. - - - The object to be serialized is of type '{0}'. Using an untyped serializer for the known type. - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json/NEventStore.Serialization.Json.Core.csproj b/src/NEventStore.Serialization.Json/NEventStore.Serialization.Json.Core.csproj deleted file mode 100644 index 62eb557e3..000000000 --- a/src/NEventStore.Serialization.Json/NEventStore.Serialization.Json.Core.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - netstandard2.0 - false - NEventStore.Serialization.Json - NEventStore.Serialization.Json - - - NEventStore.Serialization.Json - NEventStore Json Serializers - NEventStore Dev Team - http://neventstore.org - false - This package contains Json serializers for NEventStore library. These serializers were removed from the core package to limit dependencies from external libraries. - events, event sourcing, cqrs, storage, persistence, database - - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - TRACE;DEBUG - - - - True - \ - - - True - \ - - - True - \ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - True - True - Messages.resx - - - - - ResXFileCodeGenerator - Messages.Designer.cs - NEventStore.Serialization.Json - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Json/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Json/Properties/AssemblyInfo.cs deleted file mode 100644 index 1e6a65202..000000000 --- a/src/NEventStore.Serialization.Json/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Json")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore.Serialization.Json")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7bbb9172-7b2c-4854-9b59-952b54122632")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("0.0.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0.0")] diff --git a/src/NEventStore.Serialization.MsgPack.Tests/NEventStore.Serialization.MsgPack.Core.Tests.csproj b/src/NEventStore.Serialization.MsgPack.Tests/NEventStore.Serialization.MsgPack.Core.Tests.csproj deleted file mode 100644 index 5f948e032..000000000 --- a/src/NEventStore.Serialization.MsgPack.Tests/NEventStore.Serialization.MsgPack.Core.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.MsgPack.Tests - NEventStore.Serialization.MsgPack.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.MsgPack.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index e78b055bf..000000000 --- a/src/NEventStore.Serialization.MsgPack.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.MsgPack.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.MsgPack.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.MsgPack.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 41a702b36..000000000 --- a/src/NEventStore.Serialization.MsgPack.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.MsgPack.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("646D1249-63B9-46AD-8F9D-BFC58D3AC6F1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.MsgPack.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.MsgPack.Tests/SerializerFixture.cs deleted file mode 100644 index 76b30107f..000000000 --- a/src/NEventStore.Serialization.MsgPack.Tests/SerializerFixture.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable CheckNamespace -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - using NEventStore.Serialization.MsgPack; - - public partial class SerializerFixture - { - public SerializerFixture() - { - _createSerializer = () => - new MsgPackSerializer(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack.Tests/packages.config b/src/NEventStore.Serialization.MsgPack.Tests/packages.config deleted file mode 100644 index ff6f4c98d..000000000 --- a/src/NEventStore.Serialization.MsgPack.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack/Messages.Designer.cs b/src/NEventStore.Serialization.MsgPack/Messages.Designer.cs deleted file mode 100644 index 44d7751fb..000000000 --- a/src/NEventStore.Serialization.MsgPack/Messages.Designer.cs +++ /dev/null @@ -1,81 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore.Serialization.MsgPack { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Serialization.MsgPack.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Deserializing stream to object of type '{0}'.. - /// - internal static string DeserializingStream { - get { - return ResourceManager.GetString("DeserializingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Serializing object graph of type '{0}'.. - /// - internal static string SerializingGraph { - get { - return ResourceManager.GetString("SerializingGraph", resourceCulture); - } - } - } -} diff --git a/src/NEventStore.Serialization.MsgPack/Messages.resx b/src/NEventStore.Serialization.MsgPack/Messages.resx deleted file mode 100644 index 971eea1e1..000000000 --- a/src/NEventStore.Serialization.MsgPack/Messages.resx +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Deserializing stream to object of type '{0}'. - - - Serializing object graph of type '{0}'. - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack/MsgPackSerializationWireupExtension.cs b/src/NEventStore.Serialization.MsgPack/MsgPackSerializationWireupExtension.cs deleted file mode 100644 index e26d20f1a..000000000 --- a/src/NEventStore.Serialization.MsgPack/MsgPackSerializationWireupExtension.cs +++ /dev/null @@ -1,20 +0,0 @@ -using MessagePack; -using System.Diagnostics; - -namespace NEventStore.Serialization.MsgPack -{ - /// - /// MsgPack serialization wire-up extensions. - /// - public static class MsgPackSerializationWireupExtension - { - /// - /// Use the MessagePack serializer. - /// - /// Wire-up to extend - /// MsgPack serialization options - /// Serialization Wire-up - [DebuggerStepThrough] - public static SerializationWireup UsingMsgPackSerialization(this PersistenceWireup wireup, MessagePackSerializerOptions? option = null) => wireup.UsingCustomSerialization(new MsgPackSerializer(option)); - } -} diff --git a/src/NEventStore.Serialization.MsgPack/MsgPackSerializer.cs b/src/NEventStore.Serialization.MsgPack/MsgPackSerializer.cs deleted file mode 100644 index fa61054db..000000000 --- a/src/NEventStore.Serialization.MsgPack/MsgPackSerializer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using MessagePack; -using MessagePack.Resolvers; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Serialization.MsgPack -{ - /// - /// MsgPack serializer - /// - public class MsgPackSerializer : ISerialize - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(MsgPackSerializer)); - /// - /// Serializer options - /// - private readonly MessagePackSerializerOptions _options; - - /// - /// Initializes a new instance. - /// - /// MsgPack Options. - public MsgPackSerializer(MessagePackSerializerOptions? options = null) - { - _options = options ?? new MessagePackSerializerOptions(TypelessContractlessStandardResolver.Instance); - } - - /// - /// Serializes an object. - /// - /// Object type - /// Output stream - /// Object to deserialize. - public virtual void Serialize(Stream output, T graph) where T : notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - MessagePackSerializer.Serialize(output, graph, _options); - } - - /// - /// Deserializes an object from stream. - /// - /// Object type. - /// Stream input - /// Deserialized object - public virtual T Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - return MessagePackSerializer.Deserialize(input, _options); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack/NEventStore.Serialization.MsgPack.Core.csproj b/src/NEventStore.Serialization.MsgPack/NEventStore.Serialization.MsgPack.Core.csproj deleted file mode 100644 index 00d1a0999..000000000 --- a/src/NEventStore.Serialization.MsgPack/NEventStore.Serialization.MsgPack.Core.csproj +++ /dev/null @@ -1,76 +0,0 @@ - - - netstandard2.0 - false - NEventStore.Serialization.MsgPack - NEventStore.Serialization.MsgPack - - - NEventStore.Serialization.MsgPack - NEventStore MsgPack Serializers - NEventStore Dev Team - http://neventstore.org - false - This package contains Bson serializers for NEventStore library. These serializers were removed from the core package to limit dependencies from external libraries. - events, event sourcing, cqrs, storage, persistence, database - - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - TRACE;DEBUG - - - - True - \ - - - True - \ - - - True - \ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - True - True - Messages.resx - - - - - ResXFileCodeGenerator - Messages.Designer.cs - NEventStore.Serialization.MsgPack - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.MsgPack/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.MsgPack/Properties/AssemblyInfo.cs deleted file mode 100644 index c6ab41871..000000000 --- a/src/NEventStore.Serialization.MsgPack/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.MsgPack")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore.Serialization.MsgPack")] -[assembly: AssemblyCopyright("Copyright © 2024")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b0b4110c-9285-4c18-ba2c-e5d4b1731b5b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("0.0.0.0")] -[assembly: AssemblyFileVersion("0.0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0.0")] \ No newline at end of file diff --git a/src/NEventStore.Serialization.Rijndael.Tests/NEventStore.Serialization.Rijndael.Core.Tests.csproj b/src/NEventStore.Serialization.Rijndael.Tests/NEventStore.Serialization.Rijndael.Core.Tests.csproj deleted file mode 100644 index 2474df0c5..000000000 --- a/src/NEventStore.Serialization.Rijndael.Tests/NEventStore.Serialization.Rijndael.Core.Tests.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - net8.0;net472 - false - - exe - - NEventStore.Serialization.Rijndael.Tests - NEventStore.Serialization.Rijndael.Tests - - - - TRACE;DEBUG;NUNIT - - - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Serialization.Rijndael.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Serialization.Rijndael.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index 25dac50c3..000000000 --- a/src/NEventStore.Serialization.Rijndael.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Serialization.Json.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Serialization.Rijndael.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Serialization.Rijndael.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index d59819ba7..000000000 --- a/src/NEventStore.Serialization.Rijndael.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Serialization.Rijndael.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("A4E30DF3-EE23-4C74-B03B-FB438C66B688")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Serialization.Rijndael.Tests/SerializerFixture.cs b/src/NEventStore.Serialization.Rijndael.Tests/SerializerFixture.cs deleted file mode 100644 index fd77acd63..000000000 --- a/src/NEventStore.Serialization.Rijndael.Tests/SerializerFixture.cs +++ /dev/null @@ -1,22 +0,0 @@ -// ReSharper disable CheckNamespace -using NEventStore.Serialization.Binary; - -namespace NEventStore.Serialization.AcceptanceTests -// ReSharper restore CheckNamespace -{ - public partial class SerializerFixture - { - private static readonly byte[] EncryptionKey = new byte[] - {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0}; - - public SerializerFixture() - { -#if NET8_0_OR_GREATER - AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true); -#endif -#pragma warning disable CS0618 // Type or member is obsolete - _createSerializer = () => new RijndaelSerializer(new BinarySerializer(), EncryptionKey); -#pragma warning restore CS0618 // Type or member is obsolete - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Serialization.Rijndael.Tests/packages.config b/src/NEventStore.Serialization.Rijndael.Tests/packages.config deleted file mode 100644 index 3676eab81..000000000 --- a/src/NEventStore.Serialization.Rijndael.Tests/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Tests/Client/AsyncPollingClientTests.cs b/src/NEventStore.Tests/Client/AsyncPollingClientTests.cs deleted file mode 100644 index 6af985a44..000000000 --- a/src/NEventStore.Tests/Client/AsyncPollingClientTests.cs +++ /dev/null @@ -1,203 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles - -using FakeItEasy; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.PollingClient.Async -{ -#if MSTEST - [TestClass] -#endif - public class Creating_AsyncPollingClient_Tests - { - [Fact] - public void When_persist_streams_is_null_then_should_throw() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - Catch.Exception(() => new AsyncPollingClient(null, new CommitStreamObserver()).Should().BeOfType()); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void When_interval_less_than_zero_then_should_throw() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - Catch.Exception(() => new AsyncPollingClient(A.Fake(), null)).Should().BeOfType(); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - } - -#if MSTEST - [TestClass] -#endif - public class base_handling_committed_events : using_AsyncPollingClient - { - private readonly List commits = []; - - protected override void Context() - { - Observer = new LambdaAsyncObserver((c, _) => { commits.Add(c); return Task.FromResult(true); }); - base.Context(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.Start(0); - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 1); - commits.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class base_handling_committed_events_and_new_events : using_AsyncPollingClient - { - private readonly List commits = []; - - protected override void Context() - { - Observer = new LambdaAsyncObserver((c, _) => { commits.Add(c); return Task.FromResult(true); }); - base.Context(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.Start(0); - for (int i = 0; i < 15; i++) - { - StoreEvents.Advanced.CommitSingle(); - } - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 16); - commits.Count.Should().Be(16); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_stopping_commit_polling_client : using_AsyncPollingClient - { - private readonly List commits = []; - - protected override void Context() - { - Observer = new LambdaAsyncObserver((c, _) => { commits.Add(c); return Task.FromResult(false); }); - base.Context(); - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.Start(0); - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 2, timeoutInSeconds: 1); - commits.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_manual_polling : using_AsyncPollingClient - { - private readonly List commits = []; - - protected override void Context() - { - Observer = new LambdaAsyncObserver((c, _) => { commits.Add(c); return Task.FromResult(true); }); - base.Context(); - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override Task BecauseAsync() - { - Sut.ConfigurePollingClient(); - return Sut.PollAsync(CancellationToken.None); - } - - [Fact] - public void commits_are_retried_then_move_next() - { - WaitForCondition(() => commits.Count >= 2, timeoutInSeconds: 3); - commits.Count.Should().Be(2); - commits - .Select(c => c.CheckpointToken) - .SequenceEqual([1L, 2L]) - .Should().BeTrue(); - } - } - - public abstract class using_AsyncPollingClient : SpecificationBase - { - protected const int PollingInterval = 100; - protected AsyncPollingClient? sut; - private IStoreEvents? _storeEvents; - - protected AsyncPollingClient Sut - { - get { return sut!; } - } - - protected IStoreEvents StoreEvents - { - get { return _storeEvents!; } - } - - protected IAsyncObserver Observer { get; set; } = new CommitStreamObserver(); - - protected override void Context() - { - _storeEvents = Wireup.Init().UsingInMemoryPersistence().Build(); - sut = new AsyncPollingClient(_storeEvents.Advanced, Observer, PollingInterval); - } - - protected override void Cleanup() - { - _storeEvents?.Dispose(); - Sut.Dispose(); - } - - protected void WaitForCondition(Func predicate, Int32 timeoutInSeconds = 4) - { - DateTime startTest = DateTime.Now; - while (!predicate() && DateTime.Now.Subtract(startTest).TotalSeconds < timeoutInSeconds) - { - Thread.Sleep(100); - } - } - } -} - -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Tests/Client/CommitSequencerTests.cs b/src/NEventStore.Tests/Client/CommitSequencerTests.cs deleted file mode 100644 index 78d7dd358..000000000 --- a/src/NEventStore.Tests/Client/CommitSequencerTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles - -using System.Collections.Concurrent; -using NEventStore.Helpers; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -using NUnit.Framework; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.PollingClient -{ -#if MSTEST - [TestClass] -#endif -#if NUNIT - [TestFixture] -#endif - public class CommitSequencerTests - { - private int _outOfSequenceTimeoutInMilliseconds; - - private CommitSequencer InitCommitSequencer(Func? callBack = null) - { - callBack ??= _ => PollingClient2.HandlingResult.MoveToNext; - _outOfSequenceTimeoutInMilliseconds = 2000; - return new CommitSequencer(c => callBack(c), 0, _outOfSequenceTimeoutInMilliseconds); - } - - [Fact] - public void verify_check_sequential_missing_commit() - { - var sut = InitCommitSequencer(); - - var result = sut.Handle(new TestICommit() { CheckpointToken = 1L }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - result = sut.Handle(new TestICommit() { CheckpointToken = 3L }); - result.Should().Be(PollingClient2.HandlingResult.Retry); - } - - [Fact] - public void verify_timeout_on_missing_commit_not_elapsed() - { - var sut = InitCommitSequencer(); - - DateTime start = DateTime.Now; - var result = sut.Handle(new TestICommit() { CheckpointToken = 1L }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - using (DateTimeService.Override(start)) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.Retry); - } - using (DateTimeService.Override(start.AddMilliseconds(_outOfSequenceTimeoutInMilliseconds - 100))) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.Retry); - } - } - - [Fact] - public void verify_idempotence_on_read_same_commit() - { - Int32 callBackCount = 0; - var sut = InitCommitSequencer(_ => - { - callBackCount++; - return PollingClient2.HandlingResult.MoveToNext; - }); - - var result = sut.Handle(new TestICommit() { CheckpointToken = 1 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - callBackCount.Should().Be(1); - result = sut.Handle(new TestICommit() { CheckpointToken = 1 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - callBackCount.Should().Be(1); - } - - [Fact] - public void verify_timeout_on_missing_commit_then_next_commit() - { - var sut = InitCommitSequencer(); - - DateTime start = DateTime.Now; - var result = sut.Handle(new TestICommit() { CheckpointToken = 1 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - using (DateTimeService.Override(start)) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.Retry); - } - using (DateTimeService.Override(start.AddMilliseconds(_outOfSequenceTimeoutInMilliseconds - 100))) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 2 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - } - } - - [Fact] - public void verify_timeout_on_missing_commit_elapsed() - { - var sut = InitCommitSequencer(); - - DateTime start = DateTime.Now; - var result = sut.Handle(new TestICommit() { CheckpointToken = 1 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - using (DateTimeService.Override(start)) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.Retry); - } - using (DateTimeService.Override(start.AddMilliseconds(_outOfSequenceTimeoutInMilliseconds + 100))) - { - result = sut.Handle(new TestICommit() { CheckpointToken = 3 }); - result.Should().Be(PollingClient2.HandlingResult.MoveToNext); - } - } - - public class TestICommit : ICommit - { - public string BucketId - { - get { return ""; } - } - - public string StreamId - { - get { return ""; } - } - - public int StreamRevision - { - get { return 0; } - } - - public Guid CommitId - { - get { return Guid.Empty; } - } - - public int CommitSequence - { - get { return 0; } - } - - public DateTime CommitStamp - { - get { return DateTimeService.Now; } - } - - public IDictionary Headers - { - get { return new ConcurrentDictionary(); } - } - - public ICollection Events - { - get { return new List(); } - } - - public Int64 CheckpointToken { get; set; } - } - } -} - -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Tests/Client/PollingClient2Tests.cs b/src/NEventStore.Tests/Client/PollingClient2Tests.cs deleted file mode 100644 index 1dcb93bee..000000000 --- a/src/NEventStore.Tests/Client/PollingClient2Tests.cs +++ /dev/null @@ -1,294 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles - -using FakeItEasy; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.PollingClient -{ -#if MSTEST - [TestClass] -#endif - public class CreatingPollingClient2Tests - { - [Fact] - public void When_persist_streams_is_null_then_should_throw() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - Catch.Exception(() => new PollingClient2(null, _ => PollingClient2.HandlingResult.MoveToNext)).Should().BeOfType(); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void When_interval_less_than_zero_then_should_throw() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - Catch.Exception(() => new PollingClient2(A.Fake(), null)).Should().BeOfType(); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - } - -#if MSTEST - [TestClass] -#endif - public class base_handling_committed_events : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - return PollingClient2.HandlingResult.MoveToNext; - }; - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.StartFrom(0); - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 1); - commits.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class base_handling_committed_events_and_new_events : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - return PollingClient2.HandlingResult.MoveToNext; - }; - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.StartFrom(0); - for (int i = 0; i < 15; i++) - { - StoreEvents.Advanced.CommitSingle(); - } - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 16); - commits.Count.Should().Be(16); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_stopping_commit_polling_client : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - return PollingClient2.HandlingResult.Stop; - }; - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.StartFrom(0); - } - - [Fact] - public void commits_are_correctly_dispatched() - { - WaitForCondition(() => commits.Count >= 2, timeoutInSeconds: 1); - commits.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_retry_commit_polling_client : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - if (commits.Count < 3) - return PollingClient2.HandlingResult.Retry; - - return PollingClient2.HandlingResult.MoveToNext; - }; - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.StartFrom(0); - } - - [Fact] - public void commits_are_retried() - { - WaitForCondition(() => commits.Count >= 3, timeoutInSeconds: 1); - commits.Count.Should().Be(3); - commits.All(c => c.CheckpointToken == 1).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_retry_then_move_next : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - if (commits.Count < 3 && c.CheckpointToken == 1) - return PollingClient2.HandlingResult.Retry; - - return PollingClient2.HandlingResult.MoveToNext; - }; - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.StartFrom(0); - } - - [Fact] - public void commits_are_retried_then_move_next() - { - WaitForCondition(() => commits.Count >= 4, timeoutInSeconds: 1); - commits.Count.Should().Be(4); - commits - .Select(c => c.CheckpointToken) - .SequenceEqual([1L, 1L, 1, 2]) - .Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class verify_manual_polling : using_polling_client2 - { - private readonly List commits = []; - - protected override void Context() - { - base.Context(); - HandleFunction = c => - { - commits.Add(c); - return PollingClient2.HandlingResult.MoveToNext; - }; - StoreEvents.Advanced.CommitSingle(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Because() - { - Sut.ConfigurePollingFunction(); - Sut.PollNow(); - } - - [Fact] - public void commits_are_retried_then_move_next() - { - WaitForCondition(() => commits.Count >= 2, timeoutInSeconds: 3); - commits.Count.Should().Be(2); - commits - .Select(c => c.CheckpointToken) - .SequenceEqual([1L, 2L]) - .Should().BeTrue(); - } - } - - public abstract class using_polling_client2 : SpecificationBase - { - protected const int PollingInterval = 100; - protected PollingClient2? sut; - private IStoreEvents? _storeEvents; - - protected PollingClient2 Sut - { - get { return sut!; } - } - - protected IStoreEvents StoreEvents - { - get { return _storeEvents!; } - } - - protected Func? HandleFunction; - - protected override void Context() - { - HandleFunction = _ => PollingClient2.HandlingResult.MoveToNext; - _storeEvents = Wireup.Init().UsingInMemoryPersistence().Build(); - sut = new PollingClient2(_storeEvents.Advanced, c => HandleFunction(c), PollingInterval); - } - - protected override void Cleanup() - { - _storeEvents?.Dispose(); - Sut.Dispose(); - } - - protected void WaitForCondition(Func predicate, Int32 timeoutInSeconds = 4) - { - DateTime startTest = DateTime.Now; - while (!predicate() && DateTime.Now.Subtract(startTest).TotalSeconds < timeoutInSeconds) - { - Thread.Sleep(100); - } - } - } -} - -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Tests/Client/PollingClientRx.cs b/src/NEventStore.Tests/Client/PollingClientRx.cs deleted file mode 100644 index e20df0de4..000000000 --- a/src/NEventStore.Tests/Client/PollingClientRx.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace NEventStore.PollingClient -{ - using System; - using System.Reactive.Subjects; - using NEventStore.Persistence; - - /// - /// Represents a client that poll the storage for latest commits. - /// - public sealed class PollingClientRx - { - private readonly PollingClient2 _pollingClient2; - - private readonly Subject _subject; - - public PollingClientRx( - IPersistStreams persistStreams, - Int32 waitInterval = 5000) - { - if (persistStreams is null) - { - throw new ArgumentNullException(nameof(persistStreams)); - } - if (waitInterval <= 0) - { - throw new ArgumentException("Must be greater than 0", nameof(waitInterval)); - } - _subject = new Subject(); - _pollingClient2 = new PollingClient2(persistStreams, c => - { - _subject.OnNext(c); - return PollingClient2.HandlingResult.MoveToNext; - }, - waitInterval: waitInterval); - } - - public IDisposable Subscribe(IObserver observer) - { - return _subject.Subscribe(observer); - } - - private Int64 _checkpointToObserveFrom; - - public IObservable ObserveFrom(Int64 checkpointToken = 0) - { - _checkpointToObserveFrom = checkpointToken; - return _subject; - } - - internal void Start() - { - _pollingClient2.StartFrom(_checkpointToObserveFrom); - } - - internal void Dispose() - { - _pollingClient2.Dispose(); - } - - internal void StartFromBucket(string bucketId) - { - _pollingClient2.StartFromBucket(bucketId, 0); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Tests/Client/PollingClientRxTests.cs b/src/NEventStore.Tests/Client/PollingClientRxTests.cs deleted file mode 100644 index 4c202858e..000000000 --- a/src/NEventStore.Tests/Client/PollingClientRxTests.cs +++ /dev/null @@ -1,279 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles -using System.Reactive.Linq; -using System.Reactive.Threading.Tasks; -using FakeItEasy; -using FluentAssertions; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.PollingClient -{ -#if MSTEST - [TestClass] -#endif - public class CreatingPollingClientTests - { - [Fact] - public void When_persist_streams_is_null_then_should_throw() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - Catch.Exception(() => new PollingClientRx(null)).Should().BeOfType(); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void When_interval_less_than_zero_then_should_throw() - { - Catch.Exception(() => new PollingClientRx(A.Fake(), -1)).Should().BeOfType(); - } - - [Fact] - public void When_interval_is_zero_then_should_throw() - { - Catch.Exception(() => new PollingClientRx(A.Fake(), 0)).Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_commit_is_committed_before_subscribing : using_polling_client - { - private IObservable? _observeCommits; - private Task? _commitObserved; - - protected override void Context() - { - base.Context(); - StoreEvents.Advanced.CommitSingle(); - _observeCommits = PollingClient.ObserveFrom(); - _commitObserved = _observeCommits.FirstAsync().ToTask(); - } - - protected override void Because() - { - PollingClient.Start(); - } - - protected override void Cleanup() - { - PollingClient.Dispose(); - } - - [Fact] - public void should_observe_commit() - { - _commitObserved!.Wait(PollingInterval * 2).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_commit_is_committed_before_and_after_subscribing : using_polling_client - { - private IObservable? _observeCommits; - private Task? _twoCommitsObserved; - - protected override void Context() - { - base.Context(); - StoreEvents.Advanced.CommitSingle(); - _observeCommits = PollingClient.ObserveFrom(); - _twoCommitsObserved = _observeCommits.Take(2).ToTask(); - } - - protected override void Because() - { - PollingClient.Start(); - StoreEvents.Advanced.CommitSingle(); - } - - protected override void Cleanup() - { - PollingClient.Dispose(); - } - - [Fact] - public void should_observe_two_commits() - { - _twoCommitsObserved!.Wait(PollingInterval * 2).Should().BeTrue(); - } - } - - //#if MSTEST - // [TestClass] - //#endif - //public class with_two_observers_and_multiple_commits : using_polling_client - //{ - // private IObserveCommits _observeCommits1; - // private IObserveCommits _observeCommits2; - // private Task _observeCommits1Complete; - // private Task _observeCommits2Complete; - - // protected override void Context() - // { - // base.Context(); - // StoreEvents.Advanced.CommitSingle(); - // _observeCommits1 = PollingClient.ObserveFrom(); - // _observeCommits1Complete = _observeCommits1.Take(5).ToTask(); - - // _observeCommits2 = PollingClient.ObserveFrom(); - // _observeCommits2Complete = _observeCommits1.Take(10).ToTask(); - // } - - // protected override void Because() - // { - // _observeCommits1.Start(); - // _observeCommits2.Start(); - // Task.Factory.StartNew(() => - // { - // for (int i = 0; i < 15; i++) - // { - // StoreEvents.Advanced.CommitSingle(); - // } - // }); - // } - - // protected override void Cleanup() - // { - // _observeCommits1.Dispose(); - // _observeCommits2.Dispose(); - // } - - // [Fact] - // public void should_observe_commits_on_first_observer() - // { - // _observeCommits1Complete.Wait(PollingInterval * 10).ShouldBe(true); - // } - - // [Fact] - // public void should_observe_commits_on_second_observer() - // { - // _observeCommits2Complete.Wait(PollingInterval * 10).ShouldBe(true); - // } - //} - -#if MSTEST - [TestClass] -#endif - public class with_two_subscriptions_on_a_single_observer_and_multiple_commits : using_polling_client - { - private IObservable? _observeCommits1; - private Task? _observeCommits1Complete; - private Task? _observeCommits2Complete; - - protected override void Context() - { - base.Context(); - StoreEvents.Advanced.CommitSingle(); - _observeCommits1 = PollingClient.ObserveFrom(); - _observeCommits1Complete = _observeCommits1.Take(5).ToTask(); - _observeCommits2Complete = _observeCommits1.Take(10).ToTask(); - } - - protected override void Because() - { - PollingClient.Start(); - Task.Factory.StartNew(() => - { - for (int i = 0; i < 15; i++) - { - StoreEvents.Advanced.CommitSingle(); - } - }); - } - - protected override void Cleanup() - { - PollingClient.Dispose(); - } - - [Fact] - public void should_observe_commits_on_first_observer() - { - _observeCommits1Complete!.Wait(PollingInterval * 10).Should().BeTrue(); - } - - [Fact] - public void should_observe_commits_on_second_observer() - { - _observeCommits2Complete!.Wait(PollingInterval * 10).Should().BeTrue(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_polling_from_bucket1 : using_polling_client - { - private IObservable? _observeCommits; - private Task? _commitObserved; - - protected override void Context() - { - base.Context(); - StoreEvents.Advanced.CommitMany(4, null, "bucket_2"); - StoreEvents.Advanced.CommitMany(4, null, "bucket_1"); - _observeCommits = PollingClient.ObserveFrom(); - _commitObserved = _observeCommits.FirstAsync().ToTask(); - } - - protected override void Because() - { - PollingClient.StartFromBucket("bucket_1"); - } - - protected override void Cleanup() - { - PollingClient.Dispose(); - } - - [Fact] - public void should_observe_commit_from_bucket1() - { - _commitObserved!.Wait(PollingInterval * 2).Should().BeTrue(); - _commitObserved.Result.BucketId.Should().Be("bucket_1"); - } - } - - public abstract class using_polling_client : SpecificationBase - { - protected const int PollingInterval = 100; - private PollingClientRx? _pollingClient; - private IStoreEvents? _storeEvents; - - protected PollingClientRx PollingClient - { - get { return _pollingClient!; } - } - - protected IStoreEvents StoreEvents - { - get { return _storeEvents!; } - } - - protected override void Context() - { - _storeEvents = Wireup.Init().UsingInMemoryPersistence().Build(); - _pollingClient = new PollingClientRx(_storeEvents.Advanced, PollingInterval); - } - - protected override void Cleanup() - { - _storeEvents!.Dispose(); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles \ No newline at end of file diff --git a/src/NEventStore.Tests/ConversionTests/EventUpconverterPipelineHookTests.cs b/src/NEventStore.Tests/ConversionTests/EventUpconverterPipelineHookTests.cs deleted file mode 100644 index e405dfabc..000000000 --- a/src/NEventStore.Tests/ConversionTests/EventUpconverterPipelineHookTests.cs +++ /dev/null @@ -1,235 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles - -using System.Reflection; -using NEventStore.Conversion; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.ConversionTests -{ -#if MSTEST - [TestClass] -#endif - public class when_opening_a_commit_that_does_not_have_convertible_events : using_event_converter - { - private ICommit? _commit; - - private ICommit? _converted; - - protected override void Context() - { - _commit = CreateCommit(new EventMessage { Body = new NonConvertingEvent() }); - } - - protected override void Because() - { - _converted = EventUpconverter.SelectCommit(_commit!); - } - - [Fact] - public void should_not_be_converted() - { - _converted.Should().BeSameAs(_commit); - } - - [Fact] - public void should_have_the_same_instance_of_the_event() - { - _converted!.Events.Single().Should().Be(_commit!.Events.Single()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_commit_that_has_convertible_events : using_event_converter - { - private ICommit? _commit; - - private readonly Guid _id = Guid.NewGuid(); - private ICommit? _converted; - - protected override void Context() - { - _commit = CreateCommit(new EventMessage { Body = new ConvertingEvent(_id) }); - } - - protected override void Because() - { - _converted = EventUpconverter.SelectCommit(_commit!); - } - - [Fact] - public void should_be_of_the_converted_type() - { - _converted!.Events.Single().Body.GetType().Should().Be(typeof(ConvertingEvent3)); - } - - [Fact] - public void should_have_the_same_id_of_the_committed_event() - { - ((ConvertingEvent3)_converted!.Events.Single().Body).Id.Should().Be(_id); - } - } - - // ReSharper disable InconsistentNaming -#if MSTEST - [TestClass] -#endif - public class when_an_event_converter_implements_the_IConvertEvents_interface_explicitly : using_event_converter - // ReSharper restore InconsistentNaming - { - private ICommit? _commit; - private readonly Guid _id = Guid.NewGuid(); - private ICommit? _converted; - private EventMessage? _eventMessage; - - protected override void Context() - { - _eventMessage = new EventMessage { Body = new ConvertingEvent2(_id, "FooEvent") }; - - _commit = CreateCommit(_eventMessage); - } - - protected override void Because() - { - _converted = EventUpconverter.SelectCommit(_commit!); - } - - [Fact] - public void should_be_of_the_converted_type() - { - _converted!.Events.Single().Body.GetType().Should().Be(typeof(ConvertingEvent3)); - } - - [Fact] - public void should_have_the_same_id_of_the_committed_event() - { - ((ConvertingEvent3)_converted!.Events.Single().Body).Id.Should().Be(_id); - } - } - - public abstract class using_event_converter : SpecificationBase - { - private IEnumerable? _assemblies; - private Dictionary>? _converters; - private EventUpconverterPipelineHook? _eventUpconverter; - - protected EventUpconverterPipelineHook EventUpconverter - { - get { return _eventUpconverter ??= CreateUpConverterHook(); } - } - - private EventUpconverterPipelineHook CreateUpConverterHook() - { - _assemblies = GetAllAssemblies(); - _converters = GetConverters(_assemblies); - return new EventUpconverterPipelineHook(_converters); - } - - private static Dictionary> GetConverters(IEnumerable toScan) - { - IEnumerable>> c = from a in toScan - from t in a.GetTypes() - let i = t.GetInterface(typeof(IUpconvertEvents<,>).FullName!) - where i != null - let sourceType = i.GetGenericArguments().First() - let convertMethod = i.GetMethods(BindingFlags.Public | BindingFlags.Instance).First() - let instance = Activator.CreateInstance(t) - select new KeyValuePair>(sourceType, e => convertMethod.Invoke(instance, [e])); - try - { - return c.ToDictionary(x => x.Key, x => x.Value); - } - catch (ArgumentException ex) - { - throw new MultipleConvertersFoundException(ex.Message, ex); - } - } - - private static IEnumerable GetAllAssemblies() - { - return - Assembly.GetCallingAssembly().GetReferencedAssemblies().Select(Assembly.Load).Concat([Assembly.GetCallingAssembly()]); - } - - protected static ICommit CreateCommit(EventMessage eventMessage) - { - return new Commit(Bucket.Default, - Guid.NewGuid().ToString(), - 1, - Guid.NewGuid(), - 1, - DateTime.MinValue, - 1, - null, - [eventMessage]); - } - } - - public class ConvertingEventConverter : IUpconvertEvents - { - public ConvertingEvent2 Convert(ConvertingEvent sourceEvent) - { - return new ConvertingEvent2(sourceEvent.Id, "Temp"); - } - } - - public class ExplicitConvertingEventConverter : IUpconvertEvents - { - ConvertingEvent3 IUpconvertEvents.Convert(ConvertingEvent2 sourceEvent) - { - return new ConvertingEvent3(sourceEvent.Id, "Temp", true); - } - } - - public class NonConvertingEvent; - - public class ConvertingEvent - { - public ConvertingEvent(Guid id) - { - Id = id; - } - - public Guid Id { get; set; } - } - - public class ConvertingEvent2 - { - public ConvertingEvent2(Guid id, string name) - { - Id = id; - Name = name; - } - - public Guid Id { get; set; } - public string Name { get; set; } - } - - public class ConvertingEvent3 - { - public ConvertingEvent3(Guid id, string name, bool imExplicit) - { - Id = id; - Name = name; - ImExplicit = imExplicit; - } - - public Guid Id { get; set; } - public string Name { get; set; } - public bool ImExplicit { get; set; } - } -} - -#pragma warning restore IDE1006 // Naming Styles \ No newline at end of file diff --git a/src/NEventStore.Tests/DefaultSerializationWireupTests.cs b/src/NEventStore.Tests/DefaultSerializationWireupTests.cs deleted file mode 100644 index 8b9a3f7ac..000000000 --- a/src/NEventStore.Tests/DefaultSerializationWireupTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -#pragma warning disable IDE1006 // Naming Styles - -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -using NEventStore.Persistence.InMemory; -using NEventStore.Tests; -using NEventStore.Persistence; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore -{ -#if MSTEST - [TestClass] -#endif - public class when_building_an_event_store_without_an_explicit_serializer : SpecificationBase - { - private TestableWireup? _wireup; - private Exception? _exception; - private IStoreEvents? _eventStore; - - protected override void Context() - { - _wireup = Wireup.Init() - // .UsingInMemoryPersistence() // the InMemoryPersistence should be the default serializer - .UseTestableWireup(); - } - - protected override void Because() - { - _exception = Catch.Exception(() => _eventStore = _wireup!.Build()); - } - - protected override void Cleanup() - { - _eventStore?.Dispose(); - } - - [Fact] - public void should_not_throw_an_argument_null_exception() - { - // _exception.Should().NotBeOfType(); - _exception.Should().BeNull(); - } - - [Fact] - public void should_have_InMemoryPersistenceEngine_as_default_serializer() - { - var defaultPersistence = _wireup!.Container.Resolve(); - defaultPersistence.Should().BeOfType(typeof(InMemoryPersistenceEngine)); - - // cannot check eventstore.Advanced type because the persistence is wrapped - // by a PipelineHooksPersistenceAwareDecorator - // _eventStore.Advanced.Should().BeOfType(typeof(InMemoryPersistenceEngine)); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Tests/EnumerableCounter.cs b/src/NEventStore.Tests/EnumerableCounter.cs deleted file mode 100644 index 4e4c77287..000000000 --- a/src/NEventStore.Tests/EnumerableCounter.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections; - -namespace NEventStore -{ - internal class EnumerableCounter : IEnumerable - { - private readonly IEnumerable _enumerable; - - public EnumerableCounter(IEnumerable enumerable) - { - _enumerable = enumerable; - GetEnumeratorCallCount = 0; - } - - public int GetEnumeratorCallCount { get; private set; } - - public IEnumerator GetEnumerator() - { - GetEnumeratorCallCount++; - return _enumerable.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Tests/NEventStore.Core.Tests.csproj b/src/NEventStore.Tests/NEventStore.Core.Tests.csproj deleted file mode 100644 index dab010f72..000000000 --- a/src/NEventStore.Tests/NEventStore.Core.Tests.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - net8.0;net472 - false - false - NEventStore.Tests - NEventStore.Tests - - - - TRACE;DEBUG;NUNIT - NUNIT - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/NEventStore.Tests/NUnitTestAdapterTestsDiscovery.cs b/src/NEventStore.Tests/NUnitTestAdapterTestsDiscovery.cs deleted file mode 100644 index cba13cb9f..000000000 --- a/src/NEventStore.Tests/NUnitTestAdapterTestsDiscovery.cs +++ /dev/null @@ -1,17 +0,0 @@ -using NUnit.Framework; - -namespace NEventStore.Tests -{ - /// - /// this is needed to allow NUnit test adapter to discover the tests, - /// if we do not have any class explicitly marked with the TestFixture attribute - /// all the assembly will be ignored (even if some class inherit from something which is - /// marked with the attribute in a reference assembly) - /// -#if NUNIT - [TestFixture] - public class NUnitTestAdapterTestsDiscovery - { - } -#endif -} diff --git a/src/NEventStore.Tests/OptimisticEventStoreTests.Async.cs b/src/NEventStore.Tests/OptimisticEventStoreTests.Async.cs deleted file mode 100644 index ca4a92cc9..000000000 --- a/src/NEventStore.Tests/OptimisticEventStoreTests.Async.cs +++ /dev/null @@ -1,752 +0,0 @@ - -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -using FluentAssertions; -using FakeItEasy; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using System.IO; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.Async -{ -#if MSTEST - [TestClass] -#endif - public class when_creating_a_new_stream : using_persistence - { - private IEventStream? _stream; - - protected override void Because() - { - _stream = Store.CreateStream(streamId); - } - - [Fact] - public void should_return_a_new_stream() - { - _stream.Should().NotBeNull(); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_a_zero_stream_revision() - { - _stream!.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_a_zero_commit_sequence() - { - _stream!.CommitSequence.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_empty_headers() - { - _stream!.UncommittedHeaders.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_an_empty_stream_starting_at_revision_zero : using_persistence - { - private IEventStream? _stream; - - protected override void Context() - { - // read an empty stream! - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 0, 0, A>.Ignored, CancellationToken.None)) - .Returns(Task.CompletedTask); - } - - protected override async Task BecauseAsync() - { - _stream = await Store.OpenStreamAsync(streamId, 0, 0, CancellationToken.None).ConfigureAwait(false); - } - - [Fact] - public void should_return_a_new_stream() - { - _stream.Should().NotBeNull(); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_a_zero_stream_revision() - { - _stream!.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_a_zero_commit_sequence() - { - _stream!.CommitSequence.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_empty_headers() - { - _stream!.UncommittedHeaders.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_an_empty_stream_starting_above_revision_zero : using_persistence - { - private const int MinRevision = 1; - private Exception? _thrown; - - protected override void Context() - { - // read an empty stream! - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, MinRevision, int.MaxValue, A>.Ignored, CancellationToken.None)) - .Returns(Task.CompletedTask); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Store.OpenStreamAsync(streamId, MinRevision)).ConfigureAwait(false); - } - - [Fact] - public void should_throw_a_StreamNotFoundException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_populated_stream : using_persistence - { - private const int MinRevision = 17; - private const int MaxRevision = 42; - private ICommit? _committed; - private IEventStream? _stream; - - protected override void Context() - { - _committed = BuildCommitStub(1, MinRevision, 1); - - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_committed, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - - var hook = A.Fake(); - A.CallTo(() => hook.SelectCommit(_committed)).Returns(_committed); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.SelectCommitAsync(_committed, A.Ignored)).Returns(Task.FromResult(_committed)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override async Task BecauseAsync() - { - _stream = await Store.OpenStreamAsync(streamId, MinRevision, MaxRevision).ConfigureAwait(false); - } - - [Fact] - public void should_invoke_the_underlying_infrastructure_with_the_values_provided() - { - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_provide_the_commits_to_the_selection_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.SelectCommit(_committed!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commits_to_the_async_selection_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.SelectCommitAsync(_committed!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_return_an_event_stream_containing_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_populated_stream_from_a_snapshot : using_persistence - { - private const int MaxRevision = int.MaxValue; - private ICommit[]? _committed; - private Snapshot? _snapshot; - - protected override void Context() - { - _snapshot = new Snapshot(streamId, 42, "snapshot"); - _committed = [BuildCommitStub(1, 42, 0)]; - - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 42, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Store.OpenStreamAsync(_snapshot!, MaxRevision, CancellationToken.None); - } - - [Fact] - public void should_query_the_underlying_storage_using_the_revision_of_the_snapshot() - { - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 42, MaxRevision, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_stream_from_a_snapshot_that_is_at_the_revision_of_the_stream_head : using_persistence - { - private const int HeadStreamRevision = 42; - private const int HeadCommitSequence = 15; - private EnumerableCounter? _committed; - private Snapshot? _snapshot; - private IEventStream? _stream; - - protected override void Context() - { - _snapshot = new Snapshot(streamId, HeadStreamRevision, "snapshot"); - _committed = new EnumerableCounter( - [BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence)]); - - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, HeadStreamRevision, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override async Task BecauseAsync() - { - _stream = await Store.OpenStreamAsync(_snapshot!, int.MaxValue, CancellationToken.None).ConfigureAwait(false); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_revision_of_the_stream_head() - { - _stream!.StreamRevision.Should().Be(HeadStreamRevision); - } - - [Fact] - public void should_return_a_stream_with_a_commit_sequence_of_the_stream_head() - { - _stream!.CommitSequence.Should().Be(HeadCommitSequence); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Count.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Count.Should().Be(0); - } - - [Fact] - public void should_only_enumerate_the_set_of_commits_once() - { - _committed!.GetEnumeratorCallCount.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_revision_zero : using_persistence - { - protected override void Context() - { - - // read an empty stream! - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)) - .Returns(Task.CompletedTask); - } - - protected override Task BecauseAsync() - { - return Store.GetFromAsync(streamId, 0, int.MaxValue, new CommitStreamObserver(), CancellationToken.None); - } - - [Fact] - public void should_pass_a_revision_range_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_up_to_revision_revision_zero : using_persistence - { - private ICommit? _committed; - - protected override void Context() - { - _committed = BuildCommitStub(1, 1, 1); - - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_committed, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Store.OpenStreamAsync(streamId, 0, 0); - } - - [Fact] - public void should_pass_the_maximum_possible_revision_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_null_snapshot : using_persistence - { - private Exception? thrown; - - protected override async Task BecauseAsync() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - thrown = await Catch.ExceptionAsync(() => Store.OpenStreamAsync(null , int.MaxValue, CancellationToken.None)).ConfigureAwait(false); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw_an_ArgumentNullException() - { - thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_snapshot_up_to_revision_revision_zero : using_persistence - { - private ICommit? _committed; - private Snapshot? snapshot; - - protected override void Context() - { - snapshot = new Snapshot(streamId, 1, "snapshot"); - _committed = BuildCommitStub(1, 1, 1); - - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, snapshot.StreamRevision, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_committed, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Store.OpenStreamAsync(snapshot!, 0, CancellationToken.None); - } - - [Fact] - public void should_pass_the_maximum_possible_revision_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFromAsync(Bucket.Default, streamId, snapshot!.StreamRevision, int.MaxValue, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_null_attempt_back_to_the_stream : using_persistence - { - private Exception? thrown; - - protected override async Task BecauseAsync() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - thrown = await Catch.ExceptionAsync(() => Store.CommitAsync(null, CancellationToken.None)).ConfigureAwait(false); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw_an_ArgumentNullException() - { - thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_valid_and_populated_attempt_to_a_stream : using_persistence - { - private CommitAttempt? _populatedAttempt; - private ICommit? _populatedCommit; - - protected override void Context() - { - _populatedAttempt = BuildCommitAttemptStub(1, 1); - - A.CallTo(() => Persistence.CommitAsync(_populatedAttempt, CancellationToken.None)) - .ReturnsLazily((CommitAttempt attempt, CancellationToken _) => - { - _populatedCommit = new Commit(attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events); - return _populatedCommit; - }); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_populatedAttempt, A.Ignored)).Returns(Task.FromResult(true)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override Task BecauseAsync() - { - return Store.CommitAsync(_populatedAttempt!, CancellationToken.None); - } - - [Fact] - public void should_provide_the_commit_to_the_PreCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PreCommit(_populatedAttempt!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_to_the_async_PreCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PreCommitAsync(_populatedAttempt!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_attempt_to_the_configured_persistence_mechanism() - { - A.CallTo(() => Persistence.CommitAsync(_populatedAttempt!, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_populatedCommit!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_populatedCommit!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_PreCommit_hook_rejects_a_commit : using_persistence - { - private CommitAttempt? _attempt; - private ICommit? _commit; - - protected override void Context() - { - _attempt = BuildCommitAttemptStub(1, 1); - _commit = BuildCommitStub(1, 1, 1); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_attempt)).Returns(false); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_attempt, A.Ignored)).Returns(Task.FromResult(true)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override Task BecauseAsync() - { - return Store.CommitAsync(_attempt!, CancellationToken.None); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.CommitAsync(_attempt!, CancellationToken.None)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_commit!)).MustNotHaveHappened()); - } - - [Fact] - public void should_not_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_an_async_PreCommit_hook_rejects_a_commit : using_persistence - { - private CommitAttempt? _attempt; - private ICommit? _commit; - - protected override void Context() - { - _attempt = BuildCommitAttemptStub(1, 1); - _commit = BuildCommitStub(1, 1, 1); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_attempt)).Returns(true); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_attempt, A.Ignored)).Returns(Task.FromResult(false)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override Task BecauseAsync() - { - return Store.CommitAsync(_attempt!, CancellationToken.None); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.CommitAsync(_attempt!, CancellationToken.None)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_commit!)).MustNotHaveHappened()); - } - - [Fact] - public void should_not_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_with_pipeline_hooks : using_persistence - { - protected override void Because() - { - PipelineHooks.Add(A.Fake()); - } - - [Fact] - public void should_return_a_reference_to_the_underlying_persistence_infrastructure_decorator() - { - Store.Advanced.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_with_async_pipeline_hooks : using_persistence - { - protected override void Because() - { - PipelineHooksAsync.Add(A.Fake()); - } - - [Fact] - public void should_return_a_reference_to_the_underlying_persistence_infrastructure_decorator() - { - Store.Advanced.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_without_pipeline_hooks : using_persistence - { - [Fact] - public void should_return_a_reference_to_the_underlying_persistence() - { - Store.Advanced.Should().BeOfType(Persistence.GetType()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_disposing_the_event_store : using_persistence - { - protected override void Because() - { - Store.Dispose(); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => Persistence.Dispose()).MustHaveHappenedOnceExactly(); - } - } - - public abstract class using_persistence : SpecificationBase - { - private IPersistStreams? persistence; - - private List? pipelineHooks; - private List? pipelineHooksAsync; - private OptimisticEventStore? store; - protected string streamId = Guid.NewGuid().ToString(); - - protected IPersistStreams Persistence - { - get { return persistence ??= A.Fake(); } - } - - protected List PipelineHooks - { - get { return pipelineHooks ??= []; } - } - - protected List PipelineHooksAsync - { - get { return pipelineHooksAsync ??= []; } - } - - protected OptimisticEventStore Store - { - get { return store ??= new OptimisticEventStore(Persistence, PipelineHooks.Select(x => x), PipelineHooksAsync.Select(x => x)); } - } - - protected override void Cleanup() - { - streamId = Guid.NewGuid().ToString(); - } - - protected CommitAttempt BuildCommitAttemptStub(Guid commitId) - { - return new CommitAttempt(Bucket.Default, streamId, 1, commitId, 1, SystemTime.UtcNow, null, []); - } - - protected ICommit BuildCommitStub(long checkpointToken, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - - protected CommitAttempt BuildCommitAttemptStub(int streamRevision, int commitSequence) - { - var events = new[] { new EventMessage() }; - return new CommitAttempt(Bucket.Default, streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, null, events); - } - - protected ICommit BuildCommitStub(long checkpointToken, Guid commitId, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, streamId, streamRevision, commitId, commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -#pragma warning restore 169 // ReSharper enable InconsistentNaming \ No newline at end of file diff --git a/src/NEventStore.Tests/OptimisticEventStoreTests.cs b/src/NEventStore.Tests/OptimisticEventStoreTests.cs deleted file mode 100644 index 2666f0653..000000000 --- a/src/NEventStore.Tests/OptimisticEventStoreTests.cs +++ /dev/null @@ -1,720 +0,0 @@ - -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -using FluentAssertions; -using FakeItEasy; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore -{ -#if MSTEST - [TestClass] -#endif - public class when_creating_a_new_stream : using_persistence - { - private IEventStream? _stream; - - protected override void Because() - { - _stream = Store.CreateStream(streamId); - } - - [Fact] - public void should_return_a_new_stream() - { - _stream.Should().NotBeNull(); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_a_zero_stream_revision() - { - _stream!.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_a_zero_commit_sequence() - { - _stream!.CommitSequence.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_empty_headers() - { - _stream!.UncommittedHeaders.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_an_empty_stream_starting_at_revision_zero : using_persistence - { - private IEventStream? _stream; - - protected override void Context() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 0, 0)).Returns([]); - } - - protected override void Because() - { - _stream = Store.OpenStream(streamId, 0, 0); - } - - [Fact] - public void should_return_a_new_stream() - { - _stream.Should().NotBeNull(); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_a_zero_stream_revision() - { - _stream!.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_a_zero_commit_sequence() - { - _stream!.CommitSequence.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_return_a_stream_with_empty_headers() - { - _stream!.UncommittedHeaders.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_an_empty_stream_starting_above_revision_zero : using_persistence - { - private const int MinRevision = 1; - private Exception? _thrown; - - protected override void Context() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, MinRevision, int.MaxValue)) - .Returns([]); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Store.OpenStream(streamId, MinRevision)); - } - - [Fact] - public void should_throw_a_StreamNotFoundException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_populated_stream : using_persistence - { - private const int MinRevision = 17; - private const int MaxRevision = 42; - private ICommit? _committed; - private IEventStream? _stream; - - protected override void Context() - { - _committed = BuildCommitStub(1, MinRevision, 1); - - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, MinRevision, MaxRevision)) - .Returns([_committed]); - - var hook = A.Fake(); - A.CallTo(() => hook.SelectCommit(_committed)).Returns(_committed); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.SelectCommitAsync(_committed, A.Ignored)).Returns(Task.FromResult(_committed)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override void Because() - { - _stream = Store.OpenStream(streamId, MinRevision, MaxRevision); - } - - [Fact] - public void should_invoke_the_underlying_infrastructure_with_the_values_provided() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, MinRevision, MaxRevision)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_provide_the_commits_to_the_selection_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.SelectCommit(_committed!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commits_to_the_async_selection_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.SelectCommitAsync(_committed!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_return_an_event_stream_containing_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_populated_stream_from_a_snapshot : using_persistence - { - private const int MaxRevision = int.MaxValue; - private ICommit[]? _committed; - private Snapshot? _snapshot; - - protected override void Context() - { - _snapshot = new Snapshot(streamId, 42, "snapshot"); - _committed = [BuildCommitStub(1, 42, 0)]; - - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 42, MaxRevision)).Returns(_committed); - } - - protected override void Because() - { - Store.OpenStream(_snapshot!, MaxRevision); - } - - [Fact] - public void should_query_the_underlying_storage_using_the_revision_of_the_snapshot() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 42, MaxRevision)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_opening_a_stream_from_a_snapshot_that_is_at_the_revision_of_the_stream_head : using_persistence - { - private const int HeadStreamRevision = 42; - private const int HeadCommitSequence = 15; - private EnumerableCounter? _committed; - private Snapshot? _snapshot; - private IEventStream? _stream; - - protected override void Context() - { - _snapshot = new Snapshot(streamId, HeadStreamRevision, "snapshot"); - _committed = new EnumerableCounter( - [BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence)]); - - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, HeadStreamRevision, int.MaxValue)) - .Returns(_committed); - } - - protected override void Because() - { - _stream = Store.OpenStream(_snapshot!, int.MaxValue); - } - - [Fact] - public void should_return_a_stream_with_the_correct_stream_identifier() - { - _stream!.StreamId.Should().Be(streamId); - } - - [Fact] - public void should_return_a_stream_with_revision_of_the_stream_head() - { - _stream!.StreamRevision.Should().Be(HeadStreamRevision); - } - - [Fact] - public void should_return_a_stream_with_a_commit_sequence_of_the_stream_head() - { - _stream!.CommitSequence.Should().Be(HeadCommitSequence); - } - - [Fact] - public void should_return_a_stream_with_no_committed_events() - { - _stream!.CommittedEvents.Count.Should().Be(0); - } - - [Fact] - public void should_return_a_stream_with_no_uncommitted_events() - { - _stream!.UncommittedEvents.Count.Should().Be(0); - } - - [Fact] - public void should_only_enumerate_the_set_of_commits_once() - { - _committed!.GetEnumeratorCallCount.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_revision_zero : using_persistence - { - protected override void Context() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 0, int.MaxValue)) - .Returns([]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // This forces the enumeration of the commits. - Store.GetFrom(streamId, 0, int.MaxValue).ToList(); - } - - [Fact] - public void should_pass_a_revision_range_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 0, int.MaxValue)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_up_to_revision_revision_zero : using_persistence - { - private ICommit? _committed; - - protected override void Context() - { - _committed = BuildCommitStub(1, 1, 1); - - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 0, int.MaxValue)).Returns([_committed]); - } - - protected override void Because() - { - Store.OpenStream(streamId, 0, 0); - } - - [Fact] - public void should_pass_the_maximum_possible_revision_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, 0, int.MaxValue)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_null_snapshot : using_persistence - { - private Exception? thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - thrown = Catch.Exception(() => Store.OpenStream(null, int.MaxValue)); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw_an_ArgumentNullException() - { - thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_from_a_snapshot_up_to_revision_revision_zero : using_persistence - { - private ICommit? _committed; - private Snapshot? snapshot; - - protected override void Context() - { - snapshot = new Snapshot(streamId, 1, "snapshot"); - _committed = BuildCommitStub(1, 1, 1); - - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, snapshot.StreamRevision, int.MaxValue)) - .Returns([_committed]); - } - - protected override void Because() - { - Store.OpenStream(snapshot!, 0); - } - - [Fact] - public void should_pass_the_maximum_possible_revision_to_the_persistence_infrastructure() - { - A.CallTo(() => Persistence.GetFrom(Bucket.Default, streamId, snapshot!.StreamRevision, int.MaxValue)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_a_null_attempt_back_to_the_stream : using_persistence - { - private Exception? thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - thrown = Catch.Exception(() => Store.Commit(null)); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw_an_ArgumentNullException() - { - thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_valid_and_populated_attempt_to_a_stream : using_persistence - { - private CommitAttempt? _populatedAttempt; - private ICommit? _populatedCommit; - - protected override void Context() - { - _populatedAttempt = BuildCommitAttemptStub(1, 1); - - A.CallTo(() => Persistence.Commit(_populatedAttempt)) - .ReturnsLazily((CommitAttempt attempt) => - { - _populatedCommit = new Commit(attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events); - return _populatedCommit; - }); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_populatedAttempt)).Returns(true); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_populatedAttempt, A.Ignored)).Returns(Task.FromResult(true)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override void Because() - { - Store.Commit(_populatedAttempt!); - } - - [Fact] - public void should_provide_the_commit_to_the_PreCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PreCommit(_populatedAttempt!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_to_the_async_PreCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PreCommitAsync(_populatedAttempt!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_attempt_to_the_configured_persistence_mechanism() - { - A.CallTo(() => Persistence.Commit(_populatedAttempt!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_populatedCommit!)).MustHaveHappenedOnceExactly()); - } - - [Fact] - public void should_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_populatedCommit!, A.Ignored)).MustHaveHappenedOnceExactly()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_a_PreCommit_hook_rejects_a_commit : using_persistence - { - private CommitAttempt? _attempt; - private ICommit? _commit; - - protected override void Context() - { - _attempt = BuildCommitAttemptStub(1, 1); - _commit = BuildCommitStub(1, 1, 1); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_attempt)).Returns(false); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_attempt, A.Ignored)).Returns(Task.FromResult(true)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override void Because() - { - Store.Commit(_attempt!); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.Commit(_attempt!)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_commit!)).MustNotHaveHappened()); - } - - [Fact] - public void should_not_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_an_async_PreCommit_hook_rejects_a_commit : using_persistence - { - private CommitAttempt? _attempt; - private ICommit? _commit; - - protected override void Context() - { - _attempt = BuildCommitAttemptStub(1, 1); - _commit = BuildCommitStub(1, 1, 1); - - var hook = A.Fake(); - A.CallTo(() => hook.PreCommit(_attempt)).Returns(true); - PipelineHooks.Add(hook); - - var hookAsync = A.Fake(); - A.CallTo(() => hookAsync.PreCommitAsync(_attempt, A.Ignored)).Returns(Task.FromResult(false)); - PipelineHooksAsync.Add(hookAsync); - } - - protected override void Because() - { - Store.Commit(_attempt!); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.Commit(_attempt!)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_provide_the_commit_to_the_PostCommit_hooks() - { - PipelineHooks.ForEach(x => A.CallTo(() => x.PostCommit(_commit!)).MustNotHaveHappened()); - } - - [Fact] - public void should_not_provide_the_commit_to_the_async_PostCommit_hooks() - { - PipelineHooksAsync.ForEach(x => A.CallTo(() => x.PostCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_with_pipeline_hooks : using_persistence - { - protected override void Because() - { - PipelineHooks.Add(A.Fake()); - } - - [Fact] - public void should_return_a_reference_to_the_underlying_persistence_infrastructure_decorator() - { - Store.Advanced.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_with_async_pipeline_hooks : using_persistence - { - protected override void Because() - { - PipelineHooksAsync.Add(A.Fake()); - } - - [Fact] - public void should_return_a_reference_to_the_underlying_persistence_infrastructure_decorator() - { - Store.Advanced.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_accessing_the_underlying_persistence_without_pipeline_hooks : using_persistence - { - [Fact] - public void should_return_a_reference_to_the_underlying_persistence() - { - Store.Advanced.Should().BeOfType(Persistence.GetType()); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_disposing_the_event_store : using_persistence - { - protected override void Because() - { - Store.Dispose(); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => Persistence.Dispose()).MustHaveHappenedOnceExactly(); - } - } - - public abstract class using_persistence : SpecificationBase - { - private IPersistStreams? persistence; - - private List? pipelineHooks; - private List? pipelineHooksAsync; - private OptimisticEventStore? store; - protected string streamId = Guid.NewGuid().ToString(); - - protected IPersistStreams Persistence - { - get { return persistence ??= A.Fake(); } - } - - protected List PipelineHooks - { - get { return pipelineHooks ??= []; } - } - - protected List PipelineHooksAsync - { - get { return pipelineHooksAsync ??= []; } - } - - protected OptimisticEventStore Store - { - get { return store ??= new OptimisticEventStore(Persistence, PipelineHooks.Select(x => x), PipelineHooksAsync.Select(x => x)); } - } - - protected override void Cleanup() - { - streamId = Guid.NewGuid().ToString(); - } - - protected CommitAttempt BuildCommitAttemptStub(Guid commitId) - { - return new CommitAttempt(Bucket.Default, streamId, 1, commitId, 1, SystemTime.UtcNow, null, []); - } - - protected ICommit BuildCommitStub(long checkpointToken, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - - protected CommitAttempt BuildCommitAttemptStub(int streamRevision, int commitSequence) - { - var events = new[] { new EventMessage() }; - return new CommitAttempt(Bucket.Default, streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, null, events); - } - - protected ICommit BuildCommitStub(long checkpointToken, Guid commitId, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, streamId, streamRevision, commitId, commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -#pragma warning restore 169 // ReSharper enable InconsistentNaming \ No newline at end of file diff --git a/src/NEventStore.Tests/OptimisticEventStreamTests.Async.cs b/src/NEventStore.Tests/OptimisticEventStreamTests.Async.cs deleted file mode 100644 index 31da8a9e6..000000000 --- a/src/NEventStore.Tests/OptimisticEventStreamTests.Async.cs +++ /dev/null @@ -1,1038 +0,0 @@ -using FakeItEasy; -using FluentAssertions; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -#pragma warning disable 169 // ReSharper enable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -namespace NEventStore.Async -{ -#if MSTEST - [TestClass] -#endif - public class when_building_a_stream : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eachCommitHas = 2; // events - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eachCommitHas), // 1-2 - BuildCommitStub(2, 4, 2, _eachCommitHas), // 3-4 - BuildCommitStub(3, 6, 3, _eachCommitHas), // 5-6 - BuildCommitStub(4, 8, 4, _eachCommitHas) // 7-8 - ]; - - _committed[0].Headers["Common"] = string.Empty; - _committed[1].Headers["Common"] = string.Empty; - _committed[2].Headers["Common"] = string.Empty; - _committed[3].Headers["Common"] = string.Empty; - _committed[0].Headers["Unique"] = string.Empty; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None); - } - - [Fact] - public void should_have_the_correct_stream_identifier() - { - Stream.StreamId.Should().Be(StreamId); - } - - [Fact] - public void should_have_the_correct_head_stream_revision() - { - Stream.StreamRevision.Should().Be(MaxRevision); - } - - [Fact] - public void should_have_the_correct_head_commit_sequence() - { - Stream.CommitSequence.Should().Be(_committed!.Last().CommitSequence); - } - - [Fact] - public void should_not_include_events_below_the_minimum_revision_indicated() - { - Stream.CommittedEvents.First().Should().Be(_committed![0].Events.Last()); - } - - [Fact] - public void should_not_include_events_above_the_maximum_revision_indicated() - { - Stream.CommittedEvents.Last().Should().Be(_committed!.Last().Events.First()); - } - - [Fact] - public void should_have_all_of_the_committed_events_up_to_the_stream_revision_specified() - { - Stream.CommittedEvents.Count.Should().Be(MaxRevision - MinRevision + 1); - } - - [Fact] - public void should_contain_the_headers_from_the_underlying_commits() - { - Stream.CommittedHeaders.Count.Should().Be(2); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_initializing_an_already_initialized_stream: on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eachCommitHas = 2; // events - private ICommit[]? _committed; - private Exception? _thrownInitializeRevisionRange; - private Exception? _thrownInitializeSnapshot; - - protected override Task ContextAsync() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eachCommitHas), // 1-2 - BuildCommitStub(2, 4, 2, _eachCommitHas), // 3-4 - BuildCommitStub(3, 6, 3, _eachCommitHas), // 5-6 - BuildCommitStub(4, 8, 4, _eachCommitHas) // 7-8 - ]; - - _committed[0].Headers["Common"] = string.Empty; - _committed[1].Headers["Common"] = string.Empty; - _committed[2].Headers["Common"] = string.Empty; - _committed[3].Headers["Common"] = string.Empty; - _committed[0].Headers["Unique"] = string.Empty; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _thrownInitializeRevisionRange = await Catch.ExceptionAsync(() => Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None)).ConfigureAwait(false); - _thrownInitializeSnapshot = await Catch.ExceptionAsync(() => Stream.InitializeAsync(new Snapshot(BucketId, StreamId, MinRevision, new object()), MaxRevision, CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void cannot_initialize_a_stream_using_revision_range() - { - _thrownInitializeRevisionRange.Should().BeOfType(); - } - - [Fact] - public void cannot_initialize_a_stream_using_snapshot() - { - _thrownInitializeSnapshot.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_initializing_an_already_used_stream_with_revision_range : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private Exception? _thrownInitializeRevisionRange; - private Exception? _thrownInitializeSnapshot; - - protected override void Context() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Add(new EventMessage { Body = "Test" }); - } - - protected override async Task BecauseAsync() - { - _thrownInitializeRevisionRange = await Catch.ExceptionAsync(() => Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None)).ConfigureAwait(false); - _thrownInitializeSnapshot = await Catch.ExceptionAsync(() => Stream.InitializeAsync(new Snapshot(BucketId, StreamId, MinRevision, new object()), MaxRevision, CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void cannot_initialize_a_stream_using_revision_range() - { - _thrownInitializeRevisionRange.Should().BeOfType(); - } - - [Fact] - public void cannot_initialize_a_stream_using_snapshot() - { - _thrownInitializeSnapshot.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_the_head_event_revision_is_less_than_the_max_desired_revision : on_the_event_stream - { - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(0, int.MaxValue, CancellationToken.None); - } - - [Fact] - public void should_set_the_stream_revision_to_the_revision_of_the_most_recent_event() - { - Stream.StreamRevision.Should().Be(_committed!.Last().StreamRevision); - } - - [Fact] - public void should_set_the_commit_sequence_the_most_recent_commit_sequence() - { - Stream.CommitSequence.Should().Be(_committed!.Last().CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_up_to_revision : on_the_event_stream - { - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, 0, 6, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(0, 6, CancellationToken.None); - } - - [Fact] - public void should_set_the_stream_revision_to_the_revision_of_the_correct_commit() - { - Stream.StreamRevision.Should().Be(_committed![2].StreamRevision); - } - - [Fact] - public void should_set_the_commit_sequence_to_the_sequence_of_the_correct_commit() - { - Stream.CommitSequence.Should().Be(_committed![2].CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_null_event_message : on_the_event_stream - { - private Exception? _thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - _thrown = Catch.Exception(() => Stream.Add(null)); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_an_unpopulated_event_message : on_the_event_stream - { - private Exception? _thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - _thrown = Catch.Exception(() => Stream.Add(new EventMessage { Body = null })); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_fully_populated_event_message : on_the_event_stream - { - protected override void Because() - { - Stream.Add(new EventMessage { Body = "populated" }); - } - - [Fact] - public void should_add_the_event_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_multiple_populated_event_messages : on_the_event_stream - { - protected override void Because() - { - Stream.Add(new EventMessage { Body = "populated" }); - Stream.Add(new EventMessage { Body = "also populated" }); - } - - [Fact] - public void should_add_all_of_the_events_provided_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(2); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_simple_object_as_an_event_message : on_the_event_stream - { - private const string MyEvent = "some event data"; - - protected override void Because() - { - Stream.Add(new EventMessage { Body = MyEvent }); - } - - [Fact] - public void should_add_the_uncommitted_event_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(1); - } - - [Fact] - public void should_wrap_the_uncommitted_event_in_an_EventMessage_object() - { - Stream.UncommittedEvents.First().Body.Should().Be(MyEvent); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_clearing_any_uncommitted_changes : on_the_event_stream - { - protected override void Context() - { - Stream.Add(new EventMessage { Body = string.Empty }); - } - - protected override void Because() - { - Stream.ClearChanges(); - } - - [Fact] - public void should_clear_all_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_an_empty_changeset : on_the_event_stream - { - protected override Task BecauseAsync() - { - return Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_increment_the_current_stream_revision() - { - Stream.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_not_increment_the_current_commit_sequence() - { - Stream.CommitSequence.Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_any_uncommitted_changes : on_the_event_stream - { - private readonly Guid _commitId = Guid.NewGuid(); - private readonly Dictionary _headers = new() { { "key", "value" } }; - private readonly EventMessage _uncommitted = new() { Body = string.Empty }; - private CommitAttempt? _constructed; - - protected override void Context() - { - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)) - .Invokes((CommitAttempt commit, CancellationToken _) => _constructed = commit) - .ReturnsLazily((CommitAttempt attempt, CancellationToken _) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - Stream.Add(_uncommitted); - foreach (var item in _headers) - { - Stream.UncommittedHeaders[item.Key] = item.Value; - } - } - - protected override Task BecauseAsync() - { - return Stream.CommitChangesAsync(_commitId, CancellationToken.None); - } - - [Fact] - public void should_provide_a_commit_to_the_underlying_infrastructure() - { - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_build_the_commit_with_the_correct_bucket_identifier() - { - _constructed!.BucketId.Should().Be(BucketId); - } - - [Fact] - public void should_build_the_commit_with_the_correct_stream_identifier() - { - _constructed!.StreamId.Should().Be(StreamId); - } - - [Fact] - public void should_build_the_commit_with_the_correct_stream_revision() - { - _constructed!.StreamRevision.Should().Be(DefaultStreamRevision); - } - - [Fact] - public void should_build_the_commit_with_the_correct_commit_identifier() - { - _constructed!.CommitId.Should().Be(_commitId); - } - - [Fact] - public void should_build_the_commit_with_an_incremented_commit_sequence() - { - _constructed!.CommitSequence.Should().Be(DefaultCommitSequence); - } - - [Fact] - public void should_build_the_commit_with_the_correct_commit_stamp() - { - SystemTime.UtcNow.Should().Be(_constructed!.CommitStamp); - } - - [Fact] - public void should_build_the_commit_with_the_headers_provided() - { - _constructed!.Headers[_headers.First().Key].Should().Be(_headers.First().Value); - } - - [Fact] - public void should_build_the_commit_containing_all_uncommitted_events() - { - _constructed!.Events.Count.Should().Be(_headers.Count); - } - - [Fact] - public void should_build_the_commit_using_the_event_messages_provided() - { - _constructed!.Events.First().Should().Be(_uncommitted); - } - - [Fact] - public void should_contain_a_copy_of_the_headers_provided() - { - _constructed!.Headers.Should().NotBeEmpty(); - } - - [Fact] - public void should_update_the_stream_revision() - { - Stream.StreamRevision.Should().Be(_constructed!.StreamRevision); - } - - [Fact] - public void should_update_the_commit_sequence() - { - Stream.CommitSequence.Should().Be(_constructed!.CommitSequence); - } - - [Fact] - public void should_add_the_uncommitted_events_the_committed_events() - { - Stream.CommittedEvents.Last().Should().Be(_uncommitted); - } - - [Fact] - public void should_clear_the_uncommitted_events_on_the_stream() - { - Stream.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_clear_the_uncommitted_headers_on_the_stream() - { - Stream.UncommittedHeaders.Should().BeEmpty(); - } - - [Fact] - public void should_copy_the_uncommitted_headers_to_the_committed_stream_headers() - { - Stream.CommittedHeaders.Count.Should().Be(_headers.Count); - } - } - - /// - /// This behavior is primarily to support a NoSQL storage solution where CommitId is not being used as the "primary key" - /// in a NoSQL environment, we'll most likely use StreamId + CommitSequence, which also enables optimistic concurrency. - /// -#if MSTEST - [TestClass] -#endif - public class when_committing_with_an_identifier_that_was_previously_read : on_the_event_stream - { - private ICommit[]? _committed; - private Guid _duplicateCommitId; - private Exception? _thrown; - - protected override Task ContextAsync() - { - _committed = [BuildCommitStub(1, 1, 1, 1)]; - _duplicateCommitId = _committed[0].CommitId; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(0, int.MaxValue, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(_duplicateCommitId, CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_after_another_thread_or_process_has_moved_the_stream_head : on_the_event_stream - { - private const int StreamRevision = 1; - private readonly EventMessage _uncommitted = new() { Body = string.Empty }; - private ICommit[]? _committed; - private ICommit[]? _discoveredOnCommit; - private Exception? _thrown; - - protected override async Task ContextAsync() - { - _committed = [BuildCommitStub(1, 1, 1, 1)]; - _discoveredOnCommit = [BuildCommitStub(2, 3, 2, 2)]; - - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)).Throws(new ConcurrencyException()); - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, StreamRevision, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, StreamRevision +1, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _discoveredOnCommit) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - await Stream.InitializeAsync(StreamRevision, int.MaxValue, CancellationToken.None); - Stream.Add(_uncommitted); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - - [Fact] - public void should_query_the_underlying_storage_to_discover_the_new_commits() - { - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, StreamRevision + 1, int.MaxValue, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_update_the_stream_revision_accordingly() - { - Stream.StreamRevision.Should().Be(_discoveredOnCommit![0].StreamRevision); - } - - [Fact] - public void should_update_the_commit_sequence_accordingly() - { - Stream.CommitSequence.Should().Be(_discoveredOnCommit![0].CommitSequence); - } - - [Fact] - public void should_add_the_newly_discovered_committed_events_to_the_set_of_committed_events_accordingly() - { - Stream.CommittedEvents.Count.Should().Be(_discoveredOnCommit![0].Events.Count + 1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_invoke_behavior_on_a_disposed_stream : on_the_event_stream - { - private Exception? _thrown; - - protected override void Context() - { - Stream.Dispose(); - } - - protected override async Task BecauseAsync() - { - _thrown = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void should_throw_a_ObjectDisposedException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_modify_the_event_collections : on_the_event_stream - { - [Fact] - public void should_throw_an_exception_when_adding_to_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Add(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_adding_to_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Add(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_clearing_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Clear()).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_clearing_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Clear()).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_removing_from_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Remove(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_removing_from_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Remove(new EventMessage())).Should().BeOfType(); - } - } - - /// - /// All other cases should be handled by persistence providers that have unique indexes on - /// the CommitSequence (the providers should be able to detect that the last commit loaded, after - /// which we are appending new events, is not the last one of the stream) - /// https://github.com/NEventStore/NEventStore/issues/420 - /// -#if MSTEST - [TestClass] -#endif - public class issue_420_when_adding_events_in_the_middle_of_the_last_commit : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - private Exception? _thrown1; - private Exception? _thrown2; - - protected override Task ContextAsync() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)) - .ReturnsLazily((CommitAttempt attempt, CancellationToken _) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - Stream.Add(new EventMessage() { Body = "Test" }); - // this should fail and cause the stream to be reloaded - _thrown1 = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - // this should succeed, events will be appended at the end - _thrown2 = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void should_throw_ConcurrencyException() - { - _thrown1.Should().BeOfType(); - } - - public void second_attempt_should_succeed_stream_was_refreshed() - { - _thrown2.Should().BeNull(); - } - - [Fact] - public void events_will_be_appended_to_the_stream_when_committed_on_second_attempt() - { - Stream.CommittedEvents.Count.Should().Be(7); - Stream.CommittedEvents.Last().Body.Should().Be("Test"); - } - } - - /// - /// All other cases should be handled by persistence providers that have unique indexes on - /// the CommitSequence (the providers should be able to detect that the last commit loaded, after - /// which we are appending new events, is not the last one of the stream) - /// https://github.com/NEventStore/NEventStore/issues/420 - /// -#if MSTEST - [TestClass] -#endif - public class issue_420_when_adding_events_in_the_middle_a_commit_if_persistence_returns_too_many_commits : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 6; - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - private Exception? _thrown1; - private Exception? _thrown2; - - protected override Task ContextAsync() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 <-- asked up to this one - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - // the persistence returns all the data in the stream - A.CallTo(() => PersistenceAsync.GetFromAsync(BucketId, StreamId, MinRevision, MaxRevision, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - foreach (var _commit in _committed) - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - } - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - A.CallTo(() => PersistenceAsync.CommitAsync(A._, CancellationToken.None)) - .ReturnsLazily((CommitAttempt attempt, CancellationToken _) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - return Stream.InitializeAsync(MinRevision, MaxRevision, CancellationToken.None); - } - - protected override async Task BecauseAsync() - { - Stream.Add(new EventMessage() { Body = "Test" }); - // this should fail and cause the stream to be reloaded - _thrown1 = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - // this should succeed, events will be appended at the end - _thrown2 = await Catch.ExceptionAsync(() => Stream.CommitChangesAsync(Guid.NewGuid(), CancellationToken.None)).ConfigureAwait(false); - } - - [Fact] - public void first_attempt_should_throw_ConcurrencyException() - { - _thrown1.Should().BeOfType(); - } - - [Fact] - public void second_attempt_should_succeed_stream_was_refreshed() - { - _thrown2.Should().BeNull(); - } - - [Fact] - public void events_will_be_appended_to_the_stream_when_committed_on_second_attempt() - { - Stream.CommittedEvents.Count.Should().Be(6); - Stream.CommittedEvents.Last().Body.Should().Be("Test"); - } - } - - public abstract class on_the_event_stream : SpecificationBase -#if XUNIT - , IUseFixture -#endif - { - protected const int DefaultStreamRevision = 1; - protected const int DefaultCommitSequence = 1; - private ICommitEvents? _persistence; - private ICommitEventsAsync? _persistenceAsync; - private OptimisticEventStream? _stream; - protected const string BucketId = "bucket"; - protected readonly string StreamId = Guid.NewGuid().ToString(); - -#if MSTEST - // todo: we have a problem with ClassInitialize and inheritance, they are not called - // a possible workaround is to use the appdomain unload: https://vijayvepa.wordpress.com/2011/06/16/test-classinitialize-and-classcleanup-inheritance/ - // but each test is run in isolation in MSTest - [ClassInitialize] - public static void ClassInitialize(TestContext context) - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - [ClassCleanup] - public static void ClassCleanup() - { - SystemTime.Resolver = null; - } - - public on_the_event_stream() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - protected override void Cleanup() - { - SystemTime.Resolver = null; - } -#endif - -#if NUNIT - // can also consider using the NUnit test attributes instead of the constructor - - protected on_the_event_stream() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - protected override void Cleanup() - { - SystemTime.Resolver = null; - } - -#endif - - protected ICommitEvents Persistence - { - get { return _persistence ??= A.Fake(); } - } - protected ICommitEventsAsync PersistenceAsync - { - get { return _persistenceAsync ??= A.Fake(); } - } - - protected OptimisticEventStream Stream - { - get { return _stream ??= new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); } - set { _stream = value; } - } - - protected ICommit BuildCommitStub(long checkpointToken, int revision, int sequence, int eventCount) - { - var events = new List(eventCount); - for (int i = 0; i < eventCount; i++) - { - events.Add(new EventMessage() { Body = "Body " + (revision - eventCount + i + 1) }); - } - - return new Commit(Bucket.Default, StreamId, revision, Guid.NewGuid(), sequence, SystemTime.UtcNow, checkpointToken, null, events); - } - } - - public class FakeTimeFixture : IDisposable - { - public FakeTimeFixture() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - public void Dispose() - { - SystemTime.Resolver = null; - GC.SuppressFinalize(this); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -#pragma warning restore 169 // ReSharper enable InconsistentNaming \ No newline at end of file diff --git a/src/NEventStore.Tests/OptimisticEventStreamTests.cs b/src/NEventStore.Tests/OptimisticEventStreamTests.cs deleted file mode 100644 index ca3faa403..000000000 --- a/src/NEventStore.Tests/OptimisticEventStreamTests.cs +++ /dev/null @@ -1,966 +0,0 @@ -using FakeItEasy; -using FluentAssertions; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -#pragma warning disable 169 // ReSharper enable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -namespace NEventStore -{ -#if MSTEST - [TestClass] -#endif - public class when_building_a_stream : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eachCommitHas = 2; // events - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eachCommitHas), // 1-2 - BuildCommitStub(2, 4, 2, _eachCommitHas), // 3-4 - BuildCommitStub(3, 6, 3, _eachCommitHas), // 5-6 - BuildCommitStub(4, 8, 4, _eachCommitHas) // 7-8 - ]; - - _committed[0].Headers["Common"] = string.Empty; - _committed[1].Headers["Common"] = string.Empty; - _committed[2].Headers["Common"] = string.Empty; - _committed[3].Headers["Common"] = string.Empty; - _committed[0].Headers["Unique"] = string.Empty; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, MinRevision, MaxRevision)).Returns(_committed); - } - - protected override void Because() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(MinRevision, MaxRevision); - } - - [Fact] - public void should_have_the_correct_stream_identifier() - { - Stream.StreamId.Should().Be(StreamId); - } - - [Fact] - public void should_have_the_correct_head_stream_revision() - { - Stream.StreamRevision.Should().Be(MaxRevision); - } - - [Fact] - public void should_have_the_correct_head_commit_sequence() - { - Stream.CommitSequence.Should().Be(_committed!.Last().CommitSequence); - } - - [Fact] - public void should_not_include_events_below_the_minimum_revision_indicated() - { - Stream.CommittedEvents.First().Should().Be(_committed![0].Events.Last()); - } - - [Fact] - public void should_not_include_events_above_the_maximum_revision_indicated() - { - Stream.CommittedEvents.Last().Should().Be(_committed!.Last().Events.First()); - } - - [Fact] - public void should_have_all_of_the_committed_events_up_to_the_stream_revision_specified() - { - Stream.CommittedEvents.Count.Should().Be(MaxRevision - MinRevision + 1); - } - - [Fact] - public void should_contain_the_headers_from_the_underlying_commits() - { - Stream.CommittedHeaders.Count.Should().Be(2); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_initializing_an_already_initialized_stream: on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eachCommitHas = 2; // events - private ICommit[]? _committed; - private Exception? _thrownInitializeRevisionRange; - private Exception? _thrownInitializeSnapshot; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eachCommitHas), // 1-2 - BuildCommitStub(2, 4, 2, _eachCommitHas), // 3-4 - BuildCommitStub(3, 6, 3, _eachCommitHas), // 5-6 - BuildCommitStub(4, 8, 4, _eachCommitHas) // 7-8 - ]; - - _committed[0].Headers["Common"] = string.Empty; - _committed[1].Headers["Common"] = string.Empty; - _committed[2].Headers["Common"] = string.Empty; - _committed[3].Headers["Common"] = string.Empty; - _committed[0].Headers["Unique"] = string.Empty; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, MinRevision, MaxRevision)).Returns(_committed); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(MinRevision, MaxRevision); - } - - protected override void Because() - { - _thrownInitializeRevisionRange = Catch.Exception(() => Stream.Initialize(MinRevision, MaxRevision)); - _thrownInitializeSnapshot = Catch.Exception(() => Stream.Initialize(new Snapshot(BucketId, StreamId, MinRevision, new object()), MaxRevision)); - } - - [Fact] - public void cannot_initialize_a_stream_using_revision_range() - { - _thrownInitializeRevisionRange.Should().BeOfType(); - } - - [Fact] - public void cannot_initialize_a_stream_using_snapshot() - { - _thrownInitializeSnapshot.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_initializing_an_already_used_stream_with_revision_range : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private Exception? _thrownInitializeRevisionRange; - private Exception? _thrownInitializeSnapshot; - - protected override void Context() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Add(new EventMessage { Body = "Test" }); - } - - protected override void Because() - { - _thrownInitializeRevisionRange = Catch.Exception(() => Stream.Initialize(MinRevision, MaxRevision)); - _thrownInitializeSnapshot = Catch.Exception(() => Stream.Initialize(new Snapshot(BucketId, StreamId, MinRevision, new object()), MaxRevision)); - } - - [Fact] - public void cannot_initialize_a_stream_using_revision_range() - { - _thrownInitializeRevisionRange.Should().BeOfType(); - } - - [Fact] - public void cannot_initialize_a_stream_using_snapshot() - { - _thrownInitializeSnapshot.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_the_head_event_revision_is_less_than_the_max_desired_revision : on_the_event_stream - { - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, 0, int.MaxValue)).Returns(_committed); - } - - protected override void Because() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(0, int.MaxValue); - } - - [Fact] - public void should_set_the_stream_revision_to_the_revision_of_the_most_recent_event() - { - Stream.StreamRevision.Should().Be(_committed!.Last().StreamRevision); - } - - [Fact] - public void should_set_the_commit_sequence_the_most_recent_commit_sequence() - { - Stream.CommitSequence.Should().Be(_committed!.Last().CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_up_to_revision : on_the_event_stream - { - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, 0, 6)).Returns(_committed); - } - - protected override void Because() - { - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(0, 6); - } - - [Fact] - public void should_set_the_stream_revision_to_the_revision_of_the_correct_commit() - { - Stream.StreamRevision.Should().Be(_committed![2].StreamRevision); - } - - [Fact] - public void should_set_the_commit_sequence_to_the_sequence_of_the_correct_commit() - { - Stream.CommitSequence.Should().Be(_committed![2].CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_null_event_message : on_the_event_stream - { - private Exception? _thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - _thrown = Catch.Exception(() => Stream.Add(null)); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_an_unpopulated_event_message : on_the_event_stream - { - private Exception? _thrown; - - protected override void Because() - { -#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type. - _thrown = Catch.Exception(() => Stream.Add(new EventMessage { Body = null })); -#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type. - } - - [Fact] - public void should_throw() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_fully_populated_event_message : on_the_event_stream - { - protected override void Because() - { - Stream.Add(new EventMessage { Body = "populated" }); - } - - [Fact] - public void should_add_the_event_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_multiple_populated_event_messages : on_the_event_stream - { - protected override void Because() - { - Stream.Add(new EventMessage { Body = "populated" }); - Stream.Add(new EventMessage { Body = "also populated" }); - } - - [Fact] - public void should_add_all_of_the_events_provided_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(2); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_adding_a_simple_object_as_an_event_message : on_the_event_stream - { - private const string MyEvent = "some event data"; - - protected override void Because() - { - Stream.Add(new EventMessage { Body = MyEvent }); - } - - [Fact] - public void should_add_the_uncommitted_event_to_the_set_of_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(1); - } - - [Fact] - public void should_wrap_the_uncommitted_event_in_an_EventMessage_object() - { - Stream.UncommittedEvents.First().Body.Should().Be(MyEvent); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_clearing_any_uncommitted_changes : on_the_event_stream - { - protected override void Context() - { - Stream.Add(new EventMessage { Body = string.Empty }); - } - - protected override void Because() - { - Stream.ClearChanges(); - } - - [Fact] - public void should_clear_all_uncommitted_events() - { - Stream.UncommittedEvents.Count.Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_an_empty_changeset : on_the_event_stream - { - protected override void Because() - { - Stream.CommitChanges(Guid.NewGuid()); - } - - [Fact] - public void should_not_call_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.Commit(A._)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_increment_the_current_stream_revision() - { - Stream.StreamRevision.Should().Be(0); - } - - [Fact] - public void should_not_increment_the_current_commit_sequence() - { - Stream.CommitSequence.Should().Be(0); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_any_uncommitted_changes : on_the_event_stream - { - private readonly Guid _commitId = Guid.NewGuid(); - private readonly Dictionary _headers = new() { { "key", "value" } }; - private readonly EventMessage _uncommitted = new() { Body = string.Empty }; - private CommitAttempt? _constructed; - - protected override void Context() - { - A.CallTo(() => Persistence.Commit(A._)) - .Invokes((CommitAttempt _) => _constructed = _) - .ReturnsLazily((CommitAttempt attempt) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - Stream.Add(_uncommitted); - foreach (var item in _headers) - { - Stream.UncommittedHeaders[item.Key] = item.Value; - } - } - - protected override void Because() - { - Stream.CommitChanges(_commitId); - } - - [Fact] - public void should_provide_a_commit_to_the_underlying_infrastructure() - { - A.CallTo(() => Persistence.Commit(A._)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_build_the_commit_with_the_correct_bucket_identifier() - { - _constructed!.BucketId.Should().Be(BucketId); - } - - [Fact] - public void should_build_the_commit_with_the_correct_stream_identifier() - { - _constructed!.StreamId.Should().Be(StreamId); - } - - [Fact] - public void should_build_the_commit_with_the_correct_stream_revision() - { - _constructed!.StreamRevision.Should().Be(DefaultStreamRevision); - } - - [Fact] - public void should_build_the_commit_with_the_correct_commit_identifier() - { - _constructed!.CommitId.Should().Be(_commitId); - } - - [Fact] - public void should_build_the_commit_with_an_incremented_commit_sequence() - { - _constructed!.CommitSequence.Should().Be(DefaultCommitSequence); - } - - [Fact] - public void should_build_the_commit_with_the_correct_commit_stamp() - { - SystemTime.UtcNow.Should().Be(_constructed!.CommitStamp); - } - - [Fact] - public void should_build_the_commit_with_the_headers_provided() - { - _constructed!.Headers[_headers.First().Key].Should().Be(_headers.First().Value); - } - - [Fact] - public void should_build_the_commit_containing_all_uncommitted_events() - { - _constructed!.Events.Count.Should().Be(_headers.Count); - } - - [Fact] - public void should_build_the_commit_using_the_event_messages_provided() - { - _constructed!.Events.First().Should().Be(_uncommitted); - } - - [Fact] - public void should_contain_a_copy_of_the_headers_provided() - { - _constructed!.Headers.Should().NotBeEmpty(); - } - - [Fact] - public void should_update_the_stream_revision() - { - Stream.StreamRevision.Should().Be(_constructed!.StreamRevision); - } - - [Fact] - public void should_update_the_commit_sequence() - { - Stream.CommitSequence.Should().Be(_constructed!.CommitSequence); - } - - [Fact] - public void should_add_the_uncommitted_events_the_committed_events() - { - Stream.CommittedEvents.Last().Should().Be(_uncommitted); - } - - [Fact] - public void should_clear_the_uncommitted_events_on_the_stream() - { - Stream.UncommittedEvents.Should().BeEmpty(); - } - - [Fact] - public void should_clear_the_uncommitted_headers_on_the_stream() - { - Stream.UncommittedHeaders.Should().BeEmpty(); - } - - [Fact] - public void should_copy_the_uncommitted_headers_to_the_committed_stream_headers() - { - Stream.CommittedHeaders.Count.Should().Be(_headers.Count); - } - } - - /// - /// This behavior is primarily to support a NoSQL storage solution where CommitId is not being used as the "primary key" - /// in a NoSQL environment, we'll most likely use StreamId + CommitSequence, which also enables optimistic concurrency. - /// -#if MSTEST - [TestClass] -#endif - public class when_committing_with_an_identifier_that_was_previously_read : on_the_event_stream - { - private ICommit[]? _committed; - private Guid _duplicateCommitId; - private Exception? _thrown; - - protected override void Context() - { - _committed = [BuildCommitStub(1, 1, 1, 1)]; - _duplicateCommitId = _committed[0].CommitId; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, 0, int.MaxValue)).Returns(_committed); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(0, int.MaxValue); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Stream.CommitChanges(_duplicateCommitId)); - } - - [Fact] - public void should_throw_a_DuplicateCommitException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_after_another_thread_or_process_has_moved_the_stream_head : on_the_event_stream - { - private const int StreamRevision = 1; - private readonly EventMessage _uncommitted = new() { Body = string.Empty }; - private ICommit[]? _committed; - private ICommit[]? _discoveredOnCommit; - private Exception? _thrown; - - protected override void Context() - { - _committed = [BuildCommitStub(1, 1, 1, 1)]; - _discoveredOnCommit = [BuildCommitStub(2, 3, 2, 2)]; - - A.CallTo(() => Persistence.Commit(A._)).Throws(new ConcurrencyException()); - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, StreamRevision, int.MaxValue)).Returns(_committed); - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, StreamRevision + 1, int.MaxValue)).Returns(_discoveredOnCommit); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(StreamRevision, int.MaxValue); - Stream.Add(_uncommitted); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - - [Fact] - public void should_query_the_underlying_storage_to_discover_the_new_commits() - { - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, StreamRevision + 1, int.MaxValue)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_update_the_stream_revision_accordingly() - { - Stream.StreamRevision.Should().Be(_discoveredOnCommit![0].StreamRevision); - } - - [Fact] - public void should_update_the_commit_sequence_accordingly() - { - Stream.CommitSequence.Should().Be(_discoveredOnCommit![0].CommitSequence); - } - - [Fact] - public void should_add_the_newly_discovered_committed_events_to_the_set_of_committed_events_accordingly() - { - Stream.CommittedEvents.Count.Should().Be(_discoveredOnCommit![0].Events.Count + 1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_invoke_behavior_on_a_disposed_stream : on_the_event_stream - { - private Exception? _thrown; - - protected override void Context() - { - Stream.Dispose(); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - } - - [Fact] - public void should_throw_a_ObjectDisposedException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_attempting_to_modify_the_event_collections : on_the_event_stream - { - [Fact] - public void should_throw_an_exception_when_adding_to_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Add(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_adding_to_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Add(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_clearing_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Clear()).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_clearing_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Clear()).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_removing_from_the_committed_collection() - { - Catch.Exception(() => Stream.CommittedEvents.Remove(new EventMessage())).Should().BeOfType(); - } - - [Fact] - public void should_throw_an_exception_when_removing_from_the_uncommitted_collection() - { - Catch.Exception(() => Stream.UncommittedEvents.Remove(new EventMessage())).Should().BeOfType(); - } - } - - /// - /// All other cases should be handled by persistence providers that have unique indexes on - /// the CommitSequence (the providers should be able to detect that the last commit loaded, after - /// which we are appending new events, is not the last one of the stream) - /// https://github.com/NEventStore/NEventStore/issues/420 - /// -#if MSTEST - [TestClass] -#endif - public class issue_420_when_adding_events_in_the_middle_of_the_last_commit : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 7; - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - private Exception? _thrown1; - private Exception? _thrown2; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, MinRevision, MaxRevision)).Returns(_committed); - A.CallTo(() => Persistence.Commit(A._)) - .ReturnsLazily((CommitAttempt attempt) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(MinRevision, MaxRevision); - } - - protected override void Because() - { - Stream.Add(new EventMessage() { Body = "Test" }); - // this should fail and cause the stream to be reloaded - _thrown1 = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - // this should succeed, events will be appended at the end - _thrown2 = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - } - - [Fact] - public void should_throw_ConcurrencyException() - { - _thrown1.Should().BeOfType(); - } - - public void second_attempt_should_succeed_stream_was_refreshed() - { - _thrown2.Should().BeNull(); - } - - [Fact] - public void events_will_be_appended_to_the_stream_when_committed_on_second_attempt() - { - Stream.CommittedEvents.Count.Should().Be(7); - Stream.CommittedEvents.Last().Body.Should().Be("Test"); - } - } - - /// - /// All other cases should be handled by persistence providers that have unique indexes on - /// the CommitSequence (the providers should be able to detect that the last commit loaded, after - /// which we are appending new events, is not the last one of the stream) - /// https://github.com/NEventStore/NEventStore/issues/420 - /// -#if MSTEST - [TestClass] -#endif - public class issue_420_when_adding_events_in_the_middle_a_commit_if_persistence_returns_too_many_commits : on_the_event_stream - { - private const int MinRevision = 2; - private const int MaxRevision = 6; - private readonly int _eventsPerCommit = 2; - private ICommit[]? _committed; - private Exception? _thrown1; - private Exception? _thrown2; - - protected override void Context() - { - _committed = - [ - BuildCommitStub(1, 2, 1, _eventsPerCommit), // 1-2 - BuildCommitStub(2, 4, 2, _eventsPerCommit), // 3-4 - BuildCommitStub(3, 6, 3, _eventsPerCommit), // 5-6 <-- asked up to this one - BuildCommitStub(4, 8, 4, _eventsPerCommit) // 7-8 - ]; - - // the persistence returns all the data in the stream - A.CallTo(() => Persistence.GetFrom(BucketId, StreamId, MinRevision, MaxRevision)).Returns(_committed); - A.CallTo(() => Persistence.Commit(A._)) - .ReturnsLazily((CommitAttempt attempt) => new Commit( - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - 1, - attempt.Headers, - attempt.Events)); - - Stream = new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); - Stream.Initialize(MinRevision, MaxRevision); - } - - protected override void Because() - { - Stream.Add(new EventMessage() { Body = "Test" }); - // this should fail and cause the stream to be reloaded - _thrown1 = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - // this should succeed, events will be appended at the end - _thrown2 = Catch.Exception(() => Stream.CommitChanges(Guid.NewGuid())); - } - - [Fact] - public void first_attempt_should_throw_ConcurrencyException() - { - _thrown1.Should().BeOfType(); - } - - [Fact] - public void second_attempt_should_succeed_stream_was_refreshed() - { - _thrown2.Should().BeNull(); - } - - [Fact] - public void events_will_be_appended_to_the_stream_when_committed_on_second_attempt() - { - Stream.CommittedEvents.Count.Should().Be(6); - Stream.CommittedEvents.Last().Body.Should().Be("Test"); - } - } - - public abstract class on_the_event_stream : SpecificationBase -#if XUNIT - , IUseFixture -#endif - { - protected const int DefaultStreamRevision = 1; - protected const int DefaultCommitSequence = 1; - private ICommitEvents? _persistence; - private ICommitEventsAsync? _persistenceAsync; - private OptimisticEventStream? _stream; - protected const string BucketId = "bucket"; - protected readonly string StreamId = Guid.NewGuid().ToString(); - -#if MSTEST - // todo: we have a problem with ClassInitialize and inheritance, they are not called - // a possible workaround is to use the appdomain unload: https://vijayvepa.wordpress.com/2011/06/16/test-classinitialize-and-classcleanup-inheritance/ - // but each test is run in isolation in MSTest - [ClassInitialize] - public static void ClassInitialize(TestContext context) - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - [ClassCleanup] - public static void ClassCleanup() - { - SystemTime.Resolver = null; - } - - public on_the_event_stream() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - protected override void Cleanup() - { - SystemTime.Resolver = null; - } -#endif - -#if NUNIT - // can also consider using the NUnit test attributes instead of the constructor - - protected on_the_event_stream() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - protected override void Cleanup() - { - SystemTime.Resolver = null; - } - -#endif - - protected ICommitEvents Persistence - { - get { return _persistence ??= A.Fake(); } - } - protected ICommitEventsAsync PersistenceAsync - { - get { return _persistenceAsync ??= A.Fake(); } - } - - protected OptimisticEventStream Stream - { - get { return _stream ??= new OptimisticEventStream(BucketId, StreamId, Persistence, PersistenceAsync); } - set { _stream = value; } - } - - protected ICommit BuildCommitStub(long checkpointToken, int revision, int sequence, int eventCount) - { - var events = new List(eventCount); - for (int i = 0; i < eventCount; i++) - { - events.Add(new EventMessage() { Body = "Body " + (revision - eventCount + i + 1) }); - } - - return new Commit(Bucket.Default, StreamId, revision, Guid.NewGuid(), sequence, SystemTime.UtcNow, checkpointToken, null, events); - } - } - - public class FakeTimeFixture : IDisposable - { - public FakeTimeFixture() - { - SystemTime.Resolver = () => new DateTime(2012, 1, 1, 13, 0, 0); - } - - public void Dispose() - { - SystemTime.Resolver = null; - GC.SuppressFinalize(this); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -#pragma warning restore 169 // ReSharper enable InconsistentNaming \ No newline at end of file diff --git a/src/NEventStore.Tests/OptimisticPipelineHookTests.cs b/src/NEventStore.Tests/OptimisticPipelineHookTests.cs deleted file mode 100644 index 383861bab..000000000 --- a/src/NEventStore.Tests/OptimisticPipelineHookTests.cs +++ /dev/null @@ -1,458 +0,0 @@ - -#pragma warning disable 169 // ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests; -using NEventStore.Persistence.AcceptanceTests.BDD; -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore -{ - public static class OptimisticPipelineHookTests - { -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_sequence_beyond_the_known_end_of_a_stream : using_commit_hooks - { - private const int HeadStreamRevision = 5; - private const int HeadCommitSequence = 1; - private const int ExpectedNextCommitSequence = HeadCommitSequence + 1; - private const int BeyondEndOfStreamCommitSequence = ExpectedNextCommitSequence + 1; - private ICommit? _alreadyCommitted; - private CommitAttempt? _beyondEndOfStream; - private Exception? _thrown; - - protected override void Context() - { - _alreadyCommitted = BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence); - _beyondEndOfStream = BuildCommitAttemptStub(HeadStreamRevision + 1, BeyondEndOfStreamCommitSequence); - - Hook.PostCommit(_alreadyCommitted); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Hook.PreCommit(_beyondEndOfStream!)); - } - - [Fact] - public void should_throw_a_PersistenceException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_revision_beyond_the_known_end_of_a_stream : using_commit_hooks - { - private const int HeadCommitSequence = 1; - private const int HeadStreamRevision = 1; - private const int NumberOfEventsBeingCommitted = 1; - private const int ExpectedNextStreamRevision = HeadStreamRevision + 1 + NumberOfEventsBeingCommitted; - private const int BeyondEndOfStreamRevision = ExpectedNextStreamRevision + 1; - private ICommit? _alreadyCommitted; - private CommitAttempt? _beyondEndOfStream; - private Exception? _thrown; - - protected override void Context() - { - _alreadyCommitted = BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence); - _beyondEndOfStream = BuildCommitAttemptStub(BeyondEndOfStreamRevision, HeadCommitSequence + 1); - - Hook.PostCommit(_alreadyCommitted); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Hook.PreCommit(_beyondEndOfStream!)); - } - - [Fact] - public void should_throw_a_PersistenceException() - { - _thrown.Should().BeOfType(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_sequence_less_or_equal_to_the_most_recent_sequence_for_the_stream : using_commit_hooks - { - private const int HeadStreamRevision = 42; - private const int HeadCommitSequence = 42; - private const int DuplicateCommitSequence = HeadCommitSequence; - private CommitAttempt? Attempt; - private ICommit? Committed; - - private Exception? thrown; - - protected override void Context() - { - Committed = BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence); - Attempt = BuildCommitAttemptStub(HeadStreamRevision + 1, DuplicateCommitSequence); - - Hook.PostCommit(Committed); - } - - protected override void Because() - { - thrown = Catch.Exception(() => Hook.PreCommit(Attempt!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - thrown.Should().BeOfType(); - } - - [Fact] - public void ConcurrencyException_should_have_good_message() - { - thrown!.Message.Should().Contain(Attempt!.StreamId); - thrown.Message.Should().Contain("CommitSequence [" + Attempt.CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_revision_less_or_equal_to_than_the_most_recent_revision_read_for_the_stream : using_commit_hooks - { - private const int HeadStreamRevision = 3; - private const int HeadCommitSequence = 2; - private const int DuplicateStreamRevision = HeadStreamRevision; - private ICommit? _committed; - private CommitAttempt? _failedAttempt; - private Exception? _thrown; - - protected override void Context() - { - _committed = BuildCommitStub(1, HeadStreamRevision, HeadCommitSequence); - _failedAttempt = BuildCommitAttemptStub(DuplicateStreamRevision, HeadCommitSequence + 1); - - Hook.PostCommit(_committed); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Hook.PreCommit(_failedAttempt!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - - [Fact] - public void ConcurrencyException_should_have_good_message() - { - _thrown!.Message.Should().Contain(_failedAttempt!.StreamId); - _thrown.Message.Should().Contain("StreamRevision [" + _failedAttempt.CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_commit_sequence_less_than_or_equal_to_the_most_recent_commit_for_the_stream : using_commit_hooks - { - private const int DuplicateCommitSequence = 1; - private CommitAttempt? _failedAttempt; - private ICommit? _successfulAttempt; - private Exception? _thrown; - - protected override void Context() - { - _successfulAttempt = BuildCommitStub(1, 1, DuplicateCommitSequence); - _failedAttempt = BuildCommitAttemptStub(2, DuplicateCommitSequence); - - Hook.PostCommit(_successfulAttempt); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Hook.PreCommit(_failedAttempt!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - - [Fact] - public void ConcurrencyException_should_have_good_message() - { - _thrown!.Message.Should().Contain(_failedAttempt!.StreamId); - _thrown.Message.Should().Contain("CommitSequence [" + _failedAttempt.CommitSequence); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing_with_a_stream_revision_less_than_or_equal_to_the_most_recent_commit_for_the_stream : using_commit_hooks - { - private const int DuplicateStreamRevision = 2; - - private CommitAttempt? _failedAttempt; - private ICommit? _successfulAttempt; - private Exception? _thrown; - - protected override void Context() - { - _successfulAttempt = BuildCommitStub(1, DuplicateStreamRevision, 1); - _failedAttempt = BuildCommitAttemptStub(DuplicateStreamRevision, 2); - - Hook.PostCommit(_successfulAttempt); - } - - protected override void Because() - { - _thrown = Catch.Exception(() => Hook.PreCommit(_failedAttempt!)); - } - - [Fact] - public void should_throw_a_ConcurrencyException() - { - _thrown.Should().BeOfType(); - } - - [Fact] - public void Concurrency_exception_should_have_good_message() - { - _thrown!.Message.Should().Contain(_failedAttempt!.StreamId); - _thrown.Message.Should().Contain(_failedAttempt.StreamRevision.ToString()); - } - } - - public class when_tracking_commits : SpecificationBase - { - private const int MaxStreamsToTrack = 2; - private ICommit[]? _trackedCommitAttempts; - - private OptimisticPipelineHook? _hook; - - protected override void Context() - { - _trackedCommitAttempts = - [ - BuildCommit(1, Guid.NewGuid(), Guid.NewGuid()), - BuildCommit(2, Guid.NewGuid(), Guid.NewGuid()), - BuildCommit(3, Guid.NewGuid(), Guid.NewGuid()) - ]; - - _hook = new OptimisticPipelineHook(MaxStreamsToTrack); - } - - protected override void Because() - { - foreach (var commit in _trackedCommitAttempts!) - { - _hook!.Track(commit); - } - } - - [Fact] - public void should_only_contain_streams_explicitly_tracked() - { - ICommit untracked = BuildCommit(4, Guid.Empty, _trackedCommitAttempts![0].CommitId); - _hook!.Contains(untracked).Should().BeFalse(); - } - - [Fact] - public void should_find_tracked_streams() - { - var lastCommit = _trackedCommitAttempts!.Last(); - ICommit stillTracked = BuildCommit(lastCommit.CheckpointToken, lastCommit.StreamId, lastCommit.CommitId); - _hook!.Contains(stillTracked).Should().BeTrue(); - } - - [Fact] - public void should_only_track_the_specified_number_of_streams() - { - var firstCommit = _trackedCommitAttempts![0]; - ICommit droppedFromTracking = BuildCommit(firstCommit.CheckpointToken, firstCommit.StreamId, firstCommit.CommitId); - _hook!.Contains(droppedFromTracking).Should().BeFalse(); - } - - private static Commit BuildCommit(long checkpointToken, Guid streamId, Guid commitId) - { - return BuildCommit(checkpointToken, streamId.ToString(), commitId); - } - - private static Commit BuildCommit(long checkpointToken, string streamId, Guid commitId) - { - return new Commit(Bucket.Default, streamId, 1, commitId, 1, SystemTime.UtcNow, checkpointToken, null, null); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging : SpecificationBase - { - private ICommit? _trackedCommit; - private OptimisticPipelineHook? _hook; - - protected override void Context() - { - _trackedCommit = BuildCommit(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()); - _hook = new OptimisticPipelineHook(); - _hook.Track(_trackedCommit); - } - - protected override void Because() - { - _hook!.OnPurge(); - } - - [Fact] - public void should_not_track_commit() - { - _hook!.Contains(_trackedCommit!).Should().BeFalse(); - } - - private static Commit BuildCommit(Guid bucketId, Guid streamId, Guid commitId) - { - return new Commit(bucketId.ToString(), streamId.ToString(), 0, commitId, 0, SystemTime.UtcNow, - 1, null, null); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_a_bucket : SpecificationBase - { - private Commit? _trackedCommitBucket1; - private Commit? _trackedCommitBucket2; - private OptimisticPipelineHook? _hook; - - protected override void Context() - { - _trackedCommitBucket1 = BuildCommit(1, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()); - _trackedCommitBucket2 = BuildCommit(2, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid()); - _hook = new OptimisticPipelineHook(); - _hook.Track(_trackedCommitBucket1); - _hook.Track(_trackedCommitBucket2); - } - - protected override void Because() - { - _hook!.OnPurge(_trackedCommitBucket1!.BucketId); - } - - [Fact] - public void should_not_track_the_commit_in_bucket() - { - _hook!.Contains(_trackedCommitBucket1!).Should().BeFalse(); - } - - [Fact] - public void should_track_the_commit_in_other_bucket() - { - _hook!.Contains(_trackedCommitBucket2!).Should().BeTrue(); - } - - private static Commit BuildCommit(long checkpointToken, Guid bucketId, Guid streamId, Guid commitId) - { - return new Commit(bucketId.ToString(), streamId.ToString(), 0, commitId, 0, SystemTime.UtcNow, - checkpointToken, null, null); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_deleting_a_stream : SpecificationBase - { - private Commit? _trackedCommit; - private Commit? _trackedCommitDeleted; - private OptimisticPipelineHook? _hook; - private readonly Guid _bucketId = Guid.NewGuid(); - private readonly Guid _streamIdDeleted = Guid.NewGuid(); - - protected override void Context() - { - _trackedCommit = BuildCommit(1, _bucketId, Guid.NewGuid(), Guid.NewGuid()); - _trackedCommitDeleted = BuildCommit(2, _bucketId, _streamIdDeleted, Guid.NewGuid()); - _hook = new OptimisticPipelineHook(); - _hook.Track(_trackedCommit); - _hook.Track(_trackedCommitDeleted); - } - - protected override void Because() - { - _hook!.OnDeleteStream(_trackedCommitDeleted!.BucketId, _trackedCommitDeleted.StreamId); - } - - [Fact] - public void should_not_track_the_commit_in_the_deleted_stream() - { - _hook!.Contains(_trackedCommitDeleted!).Should().BeFalse(); - } - - [Fact] - public void should_track_the_commit_that_is_not_in_the_deleted_stream() - { - _hook!.Contains(_trackedCommit!).Should().BeTrue(); - } - - private static Commit BuildCommit(long checkpointToken, Guid bucketId, Guid streamId, Guid commitId) - { - return new Commit(bucketId.ToString(), streamId.ToString(), 0, commitId, 0, SystemTime.UtcNow, - checkpointToken, null, null); - } - } - - public abstract class using_commit_hooks : SpecificationBase - { - protected readonly OptimisticPipelineHook Hook = new(); - private readonly string _streamId = Guid.NewGuid().ToString(); - - /* - protected CommitAttempt BuildCommitAttempt(Guid commitId) - { - return new CommitAttempt(_streamId, 1, commitId, 1, SystemTime.UtcNow, null, null); - } - */ - - protected ICommit BuildCommitStub(long checkpointToken, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, _streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - - protected CommitAttempt BuildCommitAttemptStub(int streamRevision, int commitSequence) - { - EventMessage[] events = [new EventMessage()]; - return new CommitAttempt(Bucket.Default, _streamId, streamRevision, Guid.NewGuid(), commitSequence, SystemTime.UtcNow, null, events); - } - - protected ICommit BuildCommitStub(long checkpointToken, Guid commitId, int streamRevision, int commitSequence) - { - List events = new[] { new EventMessage() }.ToList(); - return new Commit(Bucket.Default, _streamId, streamRevision, commitId, commitSequence, SystemTime.UtcNow, checkpointToken, null, events); - } - } - } -} - -#pragma warning restore 169 // ReSharper enable InconsistentNaming -#pragma warning restore IDE1006 // Naming Styles \ No newline at end of file diff --git a/src/NEventStore.Tests/Persistence/InMemory/InMemoryPersistenceTests.cs b/src/NEventStore.Tests/Persistence/InMemory/InMemoryPersistenceTests.cs deleted file mode 100644 index a947d4ea8..000000000 --- a/src/NEventStore.Tests/Persistence/InMemory/InMemoryPersistenceTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using NEventStore.Persistence.AcceptanceTests.BDD; -#pragma warning disable IDE1006 // Naming Styles - -using FluentAssertions; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -namespace NEventStore.Persistence.InMemory -{ -#if MSTEST - [TestClass] -#endif - public class when_getting_from_to_then_should_not_get_later_commits : SpecificationBase - { - private readonly DateTime _endDate = new(2013, 1, 2); - private readonly DateTime _startDate = new(2013, 1, 1); - private ICommit[]? _commits; - private InMemoryPersistenceEngine? _engine; - - protected override void Context() - { - _engine = new InMemoryPersistenceEngine(); - _engine.Initialize(); - var streamId = Guid.NewGuid().ToString(); - _engine.Commit(new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, _startDate, new Dictionary(), [new EventMessage()])); - _engine.Commit(new CommitAttempt(streamId, 2, Guid.NewGuid(), 2, _endDate, new Dictionary(), [new EventMessage()])); - } - - protected override void Because() - { - _commits = _engine!.GetFromTo(Bucket.Default, _startDate, _endDate).ToArray(); - } - - [Fact] - public void should_return_two_commits() - { - _commits!.Length.Should().Be(1); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_getting_from_to_checkpoint_then_should_not_get_later_commits : SpecificationBase - { - private readonly DateTime _endDate = new(2013, 1, 2); - private readonly DateTime _startDate = new(2013, 1, 1); - private ICommit[]? _commits; - private InMemoryPersistenceEngine? _engine; - private ICommit? _commit1; - private ICommit? _commit2; - - protected override void Context() - { - _engine = new InMemoryPersistenceEngine(); - _engine.Initialize(); - var streamId = Guid.NewGuid().ToString(); - _commit1 = _engine.Commit(new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, _startDate, new Dictionary(), [new EventMessage()])); - _commit2 = _engine.Commit(new CommitAttempt(streamId, 2, Guid.NewGuid(), 2, _endDate, new Dictionary(), [new EventMessage()])); - _engine.Commit(new CommitAttempt(streamId, 3, Guid.NewGuid(), 3, _endDate.AddDays(1), new Dictionary(), [new EventMessage()])); - } - - protected override void Because() - { - _commits = _engine!.GetFromTo(Bucket.Default, _commit1!.CheckpointToken, _commit2!.CheckpointToken).ToArray(); - } - - [Fact] - public void should_return_two_commits() - { - _commits!.Length.Should().Be(1); - _commit2!.Should().Be(_commits![0]); - } - } -} - -#pragma warning restore IDE1006 // Naming Styles diff --git a/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixture.cs b/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixture.cs deleted file mode 100644 index 15463be7f..000000000 --- a/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixture.cs +++ /dev/null @@ -1,14 +0,0 @@ -// ReSharper disable once CheckNamespace -using NEventStore.Persistence.InMemory; - -namespace NEventStore.Persistence.AcceptanceTests -{ - public partial class PersistenceEngineFixture - { - public PersistenceEngineFixture() - { - _createPersistence = _ => - new InMemoryPersistenceEngine(); - } - } -} diff --git a/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixtureAsync.cs b/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixtureAsync.cs deleted file mode 100644 index 4b3ab88c3..000000000 --- a/src/NEventStore.Tests/Persistence/InMemory/PersistenceEngineFixtureAsync.cs +++ /dev/null @@ -1,14 +0,0 @@ -// ReSharper disable once CheckNamespace -using NEventStore.Persistence.InMemory; - -namespace NEventStore.Persistence.AcceptanceTests.Async -{ - public partial class PersistenceEngineFixtureAsync - { - public PersistenceEngineFixtureAsync() - { - _createPersistence = _ => - new InMemoryPersistenceEngine(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.Async.cs b/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.Async.cs deleted file mode 100644 index 4513d2e81..000000000 --- a/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.Async.cs +++ /dev/null @@ -1,823 +0,0 @@ -using FakeItEasy; -using FluentAssertions; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -using FluentAssertions; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -#pragma warning disable 169 -// ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -namespace NEventStore.Async -{ -#if MSTEST - [TestClass] -#endif - public class when_disposing_the_decorator : using_underlying_persistence - { - protected override void Because() - { - Decorator.Dispose(); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => persistence.Dispose()).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_date : using_underlying_persistence - { - private ICommit? _commit; - private DateTime _date; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _date = DateTime.Now; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, _date, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(Bucket.Default, _date)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits. - Decorator.GetFrom(Bucket.Default, _date).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(Bucket.Default, _date)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_min_to_max_revision : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromAsync(Bucket.Default, _commit.StreamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits. - var streamObserver = new CommitStreamObserver(); - return Decorator.GetFromAsync(Bucket.Default, _commit!.StreamId, 0, int.MaxValue, streamObserver, CancellationToken.None); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromAsync(Bucket.Default, _commit!.StreamId, 0, int.MaxValue, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_a_bucket_from_date_to_date : using_underlying_persistence - { - private ICommit? _commit; - private DateTime _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private DateTime _start; - - protected override void Context() - { - _start = DateTime.Now; - _end = DateTime.Now; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits - Decorator.GetFromTo(Bucket.Default, _start, _end).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_all_buckets_from_checkpoint_to_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private Int64 _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private Int64 _start; - - protected override void Context() - { - _start = 0; - _end = 1; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromToAsync(_start, _end, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (long fromCheckpointToken, long toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Decorator.GetFromToAsync(_start, _end, new CommitStreamObserver(), CancellationToken.None); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromToAsync(_start, _end, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_a_bucket_from_checkpoint_to_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private Int64 _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private Int64 _start; - - protected override void Context() - { - _start = 0; - _end = 1; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromToAsync(Bucket.Default, _start, _end, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, long fromCheckpointToken, long toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Decorator.GetFromToAsync(Bucket.Default, _start, _end, new CommitStreamObserver(), CancellationToken.None); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromToAsync(Bucket.Default, _start, _end, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing : using_underlying_persistence - { - private CommitAttempt? _attempt; - - protected override void Context() - { - _attempt = new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, DateTime.Now, null, [new EventMessage()]); - } - - protected override Task BecauseAsync() - { - return Decorator.CommitAsync(_attempt!, CancellationToken.None); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => persistence.CommitAsync(_attempt!, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (long checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Decorator.GetFromAsync(0, new CommitStreamObserver(), CancellationToken.None); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromAsync(Bucket.Default, 0, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (string bucketId, long checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override Task BecauseAsync() - { - return Decorator.GetFromAsync(Bucket.Default, 0, new CommitStreamObserver(), CancellationToken.None); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromAsync(Bucket.Default, 0, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override Task BecauseAsync() - { - return Decorator.PurgeAsync(CancellationToken.None); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnPurge(null)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnPurgeAsync(null, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_a_bucket : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - private const string _bucketId = "Bucket"; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override Task BecauseAsync() - { - return Decorator.PurgeAsync(_bucketId, CancellationToken.None); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnPurge(_bucketId)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnPurgeAsync(_bucketId, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_deleting_a_stream : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - private const string _bucketId = "Bucket"; - private const string _streamId = "Stream"; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override Task BecauseAsync() - { - return Decorator.DeleteStreamAsync(_bucketId, _streamId, CancellationToken.None); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnDeleteStream(_bucketId, _streamId)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnDeleteStreamAsync(_bucketId, _streamId, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint_with_filtering_PipelineHook_Sync : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private IList? _commits; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(null); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (long checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Decorator.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - _commits = observer.Commits; - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_first_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_pipeline_hooks() - { - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_pass_the_events_through_the_first_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_async_pipeline_hooks() - { - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void commit_list_should_be_empty() - { - _commits.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint_with_filtering_PipelineHook_Async : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private IList? _commits; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(null)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)) - .ReturnsLazily(async (long checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellation) => - { - await asyncObserver.OnNextAsync(_commit, cancellation).ConfigureAwait(false); - await asyncObserver.OnCompletedAsync(cancellation).ConfigureAwait(false); - }); - } - - protected override async Task BecauseAsync() - { - var observer = new CommitStreamObserver(); - await Decorator.GetFromAsync(0, observer, CancellationToken.None).ConfigureAwait(false); - _commits = observer.Commits; - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromAsync(0, A>.Ignored, CancellationToken.None)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_first_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_the_events_through_the_second_pipeline_hooks() - { - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_the_events_through_the_first_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_async_pipeline_hooks() - { - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void commit_list_should_be_empty() - { - _commits.Should().BeEmpty(); - } - } - - public abstract class using_underlying_persistence : SpecificationBase - { - private PipelineHooksAwarePersistStreamsDecorator? decorator; - protected readonly IPersistStreams persistence = A.Fake(); - protected readonly List pipelineHooks = []; - protected readonly List pipelineHooksAsync = []; - protected readonly string streamId = Guid.NewGuid().ToString(); - - public PipelineHooksAwarePersistStreamsDecorator Decorator - { - get { return decorator ??= new PipelineHooksAwarePersistStreamsDecorator(persistence, pipelineHooks.Select(x => x), pipelineHooksAsync.Select(x => x)); } - set { decorator = value; } - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -// ReSharper enable InconsistentNaming -#pragma warning restore 169 \ No newline at end of file diff --git a/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.cs b/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.cs deleted file mode 100644 index 5ba601795..000000000 --- a/src/NEventStore.Tests/PipelineHooksAwarePersistanceDecoratorTests.cs +++ /dev/null @@ -1,788 +0,0 @@ -using FakeItEasy; -using FluentAssertions; -using NEventStore.Persistence; -using NEventStore.Persistence.AcceptanceTests.BDD; -#if MSTEST -using Microsoft.VisualStudio.TestTools.UnitTesting; -using FluentAssertions; -#endif -#if NUNIT -#endif -#if XUNIT -using Xunit; -using Xunit.Should; -#endif - -#pragma warning disable 169 -// ReSharper disable InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles - -namespace NEventStore -{ -#if MSTEST - [TestClass] -#endif - public class when_disposing_the_decorator : using_underlying_persistence - { - protected override void Because() - { - Decorator.Dispose(); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => persistence.Dispose()).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_date : using_underlying_persistence - { - private ICommit? _commit; - private DateTime _date; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _date = DateTime.Now; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, _date, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(Bucket.Default, _date)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits. - Decorator.GetFrom(Bucket.Default, _date).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(Bucket.Default, _date)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_min_to_max_revision : using_underlying_persistence - { - private Commit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(Bucket.Default, _commit.StreamId, 0, int.MaxValue)) - .Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits. - Decorator.GetFrom(Bucket.Default, _commit!.StreamId, 0, int.MaxValue).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(Bucket.Default, _commit!.StreamId, 0, int.MaxValue)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_a_bucket_from_date_to_date : using_underlying_persistence - { - private ICommit? _commit; - private DateTime _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private DateTime _start; - - protected override void Context() - { - _start = DateTime.Now; - _end = DateTime.Now; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits - Decorator.GetFromTo(Bucket.Default, _start, _end).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_all_buckets_from_checkpoint_to_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private Int64 _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private Int64 _start; - - protected override void Context() - { - _start = 0; - _end = 1; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromTo(_start, _end)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits - Decorator.GetFromTo(_start, _end).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromTo(_start, _end)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_all_events_in_a_bucket_from_checkpoint_to_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private Int64 _end; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private Int64 _start; - - protected override void Context() - { - _start = 0; - _end = 1; - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).Returns([_commit]); - } - - protected override void Because() - { - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - // Forces enumeration of commits - Decorator.GetFromTo(Bucket.Default, _start, _end).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFromTo(Bucket.Default, _start, _end)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_committing : using_underlying_persistence - { - private CommitAttempt? _attempt; - - protected override void Context() - { - _attempt = new CommitAttempt(streamId, 1, Guid.NewGuid(), 1, DateTime.Now, null, [new EventMessage()]); - } - - protected override void Because() - { - Decorator.Commit(_attempt!); - } - - [Fact] - public void should_dispose_the_underlying_persistence() - { - A.CallTo(() => persistence.Commit(_attempt!)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(0)).Returns([_commit]); - } - - protected override void Because() - { - Decorator.GetFrom(0).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(0)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_in_a_bucket_from_checkpoint : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(Bucket.Default, 0)).Returns([_commit]); - } - - protected override void Because() - { - Decorator.GetFrom(Bucket.Default, 0).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(Bucket.Default, 0)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override void Because() - { - Decorator.Purge(); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnPurge(null)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnPurgeAsync(null, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_purging_a_bucket : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - private const string _bucketId = "Bucket"; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override void Because() - { - Decorator.Purge(_bucketId); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnPurge(_bucketId)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnPurgeAsync(_bucketId, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_deleting_a_stream : using_underlying_persistence - { - private IPipelineHook? _hook; - private IPipelineHookAsync? _hookAsync; - private const string _bucketId = "Bucket"; - private const string _streamId = "Stream"; - - protected override void Context() - { - _hook = A.Fake(); - pipelineHooks.Add(_hook); - - _hookAsync = A.Fake(); - pipelineHooksAsync.Add(_hookAsync); - } - - protected override void Because() - { - Decorator.DeleteStream(_bucketId, _streamId); - } - - [Fact] - public void should_call_the_pipeline_hook_purge() - { - A.CallTo(() => _hook!.OnDeleteStream(_bucketId, _streamId)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_call_the_async_pipeline_hook_purge() - { - A.CallTo(() => _hookAsync!.OnDeleteStreamAsync(_bucketId, _streamId, A.Ignored)).MustHaveHappenedOnceExactly(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint_with_filtering_PipelineHook_Sync : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private List? _commits; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(null); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(0)).Returns([_commit]); - } - - protected override void Because() - { - _commits = Decorator.GetFrom(0).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(0)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_first_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_pipeline_hooks() - { - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_pass_the_events_through_the_first_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_async_pipeline_hooks() - { - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void commit_list_should_be_empty() - { - _commits.Should().BeEmpty(); - } - } - -#if MSTEST - [TestClass] -#endif - public class when_reading_the_all_events_from_checkpoint_with_filtering_PipelineHook_Async : using_underlying_persistence - { - private ICommit? _commit; - private IPipelineHook? _hook1; - private IPipelineHook? _hook2; - private IPipelineHookAsync? _hook1Async; - private IPipelineHookAsync? _hook2Async; - private List? _commits; - - protected override void Context() - { - _commit = new Commit(Bucket.Default, streamId, 1, Guid.NewGuid(), 1, DateTime.Now, 1, null, null); - - _hook1 = A.Fake(); - A.CallTo(() => _hook1.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook1); - - _hook2 = A.Fake(); - A.CallTo(() => _hook2.SelectCommit(_commit)).Returns(_commit); - pipelineHooks.Add(_hook2); - - _hook1Async = A.Fake(); - A.CallTo(() => _hook1Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(null)); - pipelineHooksAsync.Add(_hook1Async); - - _hook2Async = A.Fake(); - A.CallTo(() => _hook2Async.SelectCommitAsync(_commit, A.Ignored)).Returns(Task.FromResult(_commit)); - pipelineHooksAsync.Add(_hook2Async); - - A.CallTo(() => persistence.GetFrom(0)).Returns([_commit]); - } - - protected override void Because() - { - _commits = Decorator.GetFrom(0).ToList(); - } - - [Fact] - public void should_call_the_underlying_persistence_to_get_events() - { - A.CallTo(() => persistence.GetFrom(0)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_all_events_through_the_first_pipeline_hooks() - { - A.CallTo(() => _hook1!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_the_events_through_the_second_pipeline_hooks() - { - A.CallTo(() => _hook2!.SelectCommit(_commit!)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_pass_the_events_through_the_first_async_pipeline_hooks() - { - A.CallTo(() => _hook1Async!.SelectCommitAsync(_commit!, A.Ignored)).MustHaveHappenedOnceExactly(); - } - - [Fact] - public void should_not_pass_the_events_through_the_second_async_pipeline_hooks() - { - A.CallTo(() => _hook2Async!.SelectCommitAsync(_commit!, A.Ignored)).MustNotHaveHappened(); - } - - [Fact] - public void commit_list_should_be_empty() - { - _commits.Should().BeEmpty(); - } - } - - public abstract class using_underlying_persistence : SpecificationBase - { - private PipelineHooksAwarePersistStreamsDecorator? decorator; - protected readonly IPersistStreams persistence = A.Fake(); - protected readonly List pipelineHooks = []; - protected readonly List pipelineHooksAsync = []; - protected readonly string streamId = Guid.NewGuid().ToString(); - - public PipelineHooksAwarePersistStreamsDecorator Decorator - { - get { return decorator ??= new PipelineHooksAwarePersistStreamsDecorator(persistence, pipelineHooks.Select(x => x), pipelineHooksAsync.Select(x => x)); } - set { decorator = value; } - } - } -} - -#pragma warning restore IDE1006 // Naming Styles -// ReSharper enable InconsistentNaming -#pragma warning restore 169 \ No newline at end of file diff --git a/src/NEventStore.Tests/Properties/AssemblyInfo.cs b/src/NEventStore.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index cee49ba8b..000000000 --- a/src/NEventStore.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NEventStore.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NEventStore")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("ce2d3ce5-5061-43e0-8b5b-6e14c8ab0e7b")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -//[assembly: AssemblyVersion("8.0.0.0")] -//[assembly: AssemblyFileVersion("8.0.0.0")] -//[assembly: AssemblyInformationalVersion("8.0.0-beta.5+Branch.release-8.0.0.Sha.4029904d0dae687763bdf2f11ad4c7754927a8c6")] diff --git a/src/NEventStore.Tests/TestableWireup.cs b/src/NEventStore.Tests/TestableWireup.cs deleted file mode 100644 index 7c8305b24..000000000 --- a/src/NEventStore.Tests/TestableWireup.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace NEventStore.Tests -{ - public class TestableWireup : Wireup - { - public TestableWireup(Wireup inner) : base(inner) - { - } - - public new NanoContainer Container - { - get { return base.Container; } - } - } -} diff --git a/src/NEventStore.Tests/TestableWireupExtensions.cs b/src/NEventStore.Tests/TestableWireupExtensions.cs deleted file mode 100644 index 9dd623511..000000000 --- a/src/NEventStore.Tests/TestableWireupExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace NEventStore.Tests -{ - public static class TestableWireupExtensions - { - public static TestableWireup UseTestableWireup(this Wireup wireup) - { - return new TestableWireup(wireup); - } - } -} diff --git a/src/NEventStore/AccessSnapshotsExtensions.cs b/src/NEventStore/AccessSnapshotsExtensions.cs deleted file mode 100644 index 1016e9379..000000000 --- a/src/NEventStore/AccessSnapshotsExtensions.cs +++ /dev/null @@ -1,126 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Provides extension methods for and . - /// - public static class AccessSnapshotsExtensions - { - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated from the default bucket. - /// - /// The instance. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static ISnapshot? GetSnapshot(this IAccessSnapshots accessSnapshots, Guid streamId, int maxRevision) - { - return GetSnapshot(accessSnapshots, streamId.ToString(), maxRevision); - } - - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated from the default bucket. - /// - /// The instance. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static ISnapshot? GetSnapshot(this IAccessSnapshots accessSnapshots, string streamId, int maxRevision) - { - return accessSnapshots.GetSnapshot(Bucket.Default, streamId, maxRevision); - } - - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated. - /// - /// The instance. - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static ISnapshot? GetSnapshot(this IAccessSnapshots accessSnapshots, string bucketId, Guid streamId, int maxRevision) - { - return accessSnapshots.GetSnapshot(bucketId, streamId.ToString(), maxRevision); - } - - /// - /// Gets identifiers for all streams whose head and last snapshot revisions differ by at least the threshold specified for the default bucket. - /// - /// The instance. - /// The maximum difference between the head and most recent snapshot revisions. - /// The streams for which the head and snapshot revisions differ by at least the threshold specified. - /// - /// - public static IEnumerable GetStreamsToSnapshot(this IAccessSnapshots accessSnapshots, int maxThreshold) - { - return accessSnapshots.GetStreamsToSnapshot(Bucket.Default, maxThreshold); - } - - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated from the default bucket. - /// - /// The instance. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// The token to monitor for cancellation requests. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static Task GetSnapshotAsync(this IAccessSnapshotsAsync accessSnapshots, Guid streamId, int maxRevision, CancellationToken cancellationToken = default) - { - return GetSnapshotAsync(accessSnapshots, streamId.ToString(), maxRevision, cancellationToken); - } - - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated from the default bucket. - /// - /// The instance. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// The token to monitor for cancellation requests. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static Task GetSnapshotAsync(this IAccessSnapshotsAsync accessSnapshots, string streamId, int maxRevision, CancellationToken cancellationToken = default) - { - return accessSnapshots.GetSnapshotAsync(Bucket.Default, streamId, maxRevision, cancellationToken); - } - - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated. - /// - /// The instance. - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// The token to monitor for cancellation requests. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - public static Task GetSnapshotAsync(this IAccessSnapshotsAsync accessSnapshots, string bucketId, Guid streamId, int maxRevision, CancellationToken cancellationToken = default) - { - return accessSnapshots.GetSnapshotAsync(bucketId, streamId.ToString(), maxRevision, cancellationToken); - } - - /// - /// Gets identifiers for all streams whose head and last snapshot revisions differ by at least the threshold specified for the default bucket. - /// - /// The instance. - /// The maximum difference between the head and most recent snapshot revisions. - /// The observer to receive the streams. - /// The token to monitor for cancellation requests. - /// - /// - public static Task GetStreamsToSnapshotAsync(this IAccessSnapshotsAsync accessSnapshots, int maxThreshold, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default) - { - return accessSnapshots.GetStreamsToSnapshotAsync(Bucket.Default, maxThreshold, asyncObserver, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Bucket.cs b/src/NEventStore/Bucket.cs deleted file mode 100644 index 7ddcc95c8..000000000 --- a/src/NEventStore/Bucket.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides a way to identify a bucket. - /// - public static class Bucket - { - /// - /// The default bucket Id. - /// - public const string Default = "default"; - } -} \ No newline at end of file diff --git a/src/NEventStore/CommitAttempt.cs b/src/NEventStore/CommitAttempt.cs deleted file mode 100644 index c59c25d10..000000000 --- a/src/NEventStore/CommitAttempt.cs +++ /dev/null @@ -1,136 +0,0 @@ -#pragma warning disable RCS1170 // Use read-only auto-implemented property. - -namespace NEventStore -{ - /// - /// Commit Attempt represents a single attempt to commit a set of events to a stream. - /// - public class CommitAttempt - { - /// - /// Initializes a new instance of the Commit class for the default bucket. - /// - /// The value which uniquely identifies the stream in a bucket to which the commit belongs. - /// The value which indicates the revision of the most recent event in the stream to which this commit applies. - /// The value which uniquely identifies the commit within the stream. - /// The value which indicates the sequence (or position) in the stream to which this commit applies. - /// The point in time at which the commit was persisted. - /// The metadata which provides additional, unstructured information about this commit. - /// The collection of event messages to be committed as a single unit. - public CommitAttempt( - Guid streamId, - int streamRevision, - Guid commitId, - int commitSequence, - DateTime commitStamp, - IDictionary? headers, - ICollection events) - : this(Bucket.Default, streamId.ToString(), streamRevision, commitId, commitSequence, commitStamp, headers, events) - { } - - /// - /// Initializes a new instance of the Commit class for the default bucket. - /// - /// The value which uniquely identifies the stream in a bucket to which the commit belongs. - /// The value which indicates the revision of the most recent event in the stream to which this commit applies. - /// The value which uniquely identifies the commit within the stream. - /// The value which indicates the sequence (or position) in the stream to which this commit applies. - /// The point in time at which the commit was persisted. - /// The metadata which provides additional, unstructured information about this commit. - /// The collection of event messages to be committed as a single unit. - public CommitAttempt( - string streamId, - int streamRevision, - Guid commitId, - int commitSequence, - DateTime commitStamp, - IDictionary? headers, - ICollection events) - : this(Bucket.Default, streamId, streamRevision, commitId, commitSequence, commitStamp, headers, events) - { } - - /// - /// Initializes a new instance of the Commit class. - /// - /// The value which identifies bucket to which the stream and the commit belongs - /// The value which uniquely identifies the stream in a bucket to which the commit belongs. - /// The value which indicates the revision of the most recent event in the stream to which this commit applies. - /// The value which uniquely identifies the commit within the stream. - /// The value which indicates the sequence (or position) in the stream to which this commit applies. - /// The point in time at which the commit was persisted. - /// The metadata which provides additional, unstructured information about this commit. - /// The collection of event messages to be committed as a single unit. - public CommitAttempt( - string bucketId, - string streamId, - int streamRevision, - Guid commitId, - int commitSequence, - DateTime commitStamp, - IDictionary? headers, - ICollection events) - { - Guard.NotNullOrWhiteSpace(() => bucketId, bucketId); - Guard.NotNullOrWhiteSpace(() => streamId, streamId); - Guard.NotLessThanOrEqualTo(() => streamRevision, streamRevision, 0); - Guard.NotDefault(() => commitId, commitId); - Guard.NotLessThanOrEqualTo(() => commitSequence, commitSequence, 0); - Guard.NotLessThan(() => commitSequence, streamRevision, 0); - Guard.NotEmpty(() => events, events); - - BucketId = bucketId; - StreamId = streamId; - StreamRevision = streamRevision; - CommitId = commitId; - CommitSequence = commitSequence; - CommitStamp = commitStamp; - Headers = headers ?? new Dictionary(); - Events = events; - //Events = events == null ? - // new ReadOnlyCollection(new List()) : - // new ReadOnlyCollection(events.ToList()); - } - - /// - /// Gets the value which identifies bucket to which the stream and the commit belongs. - /// - public string BucketId { get; private set; } - - /// - /// Gets the value which uniquely identifies the stream to which the commit belongs. - /// - public string StreamId { get; private set; } - - /// - /// Gets the value which indicates the revision of the most recent event in the stream to which this commit applies. - /// - public int StreamRevision { get; private set; } - - /// - /// Gets the value which uniquely identifies the commit within the stream. - /// - public Guid CommitId { get; private set; } - - /// - /// Gets the value which indicates the sequence (or position) in the stream to which this commit applies. - /// - public int CommitSequence { get; private set; } - - /// - /// Gets the point in time at which the commit was persisted. - /// - public DateTime CommitStamp { get; private set; } - - /// - /// Gets the metadata which provides additional, unstructured information about this commit. - /// - public IDictionary Headers { get; private set; } - - /// - /// Gets the collection of event messages to be committed as a single unit. - /// - public ICollection Events { get; private set; } - } -} - -#pragma warning restore RCS1170 // Use read-only auto-implemented property. \ No newline at end of file diff --git a/src/NEventStore/CommitEqualityComparer.cs b/src/NEventStore/CommitEqualityComparer.cs deleted file mode 100644 index b402e9149..000000000 --- a/src/NEventStore/CommitEqualityComparer.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace NEventStore -{ - /// - /// Compares two commits for equality based on their bucket identity, stream identity, and commit identity. - /// - public sealed class CommitEqualityComparer : IEqualityComparer - { - /// - public bool Equals(ICommit x, ICommit y) - { - if (ReferenceEquals(x, y)) - { - return true; - } - if (x is null) - { - return false; - } - if (y is null) - { - return false; - } - if (x.GetType() != y.GetType()) - { - return false; - } - return string.Equals(x.BucketId, y.BucketId, StringComparison.Ordinal) - && string.Equals(x.StreamId, y.StreamId, StringComparison.Ordinal) - && string.Equals(x.CommitId, y.CommitId); - } - - /// - public int GetHashCode(ICommit obj) - { - unchecked - { - int hashCode = obj.BucketId?.GetHashCode() ?? 0; - hashCode = (hashCode * 397) ^ (obj.StreamId?.GetHashCode() ?? 0); - return (hashCode * 397) ^ obj.CommitId.GetHashCode(); - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/CommitEventsExtensions.cs b/src/NEventStore/CommitEventsExtensions.cs deleted file mode 100644 index f10af7a8c..000000000 --- a/src/NEventStore/CommitEventsExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Provides extension methods for and instances. - /// - public static class CommitEventsExtensions - { - /// - /// Gets the corresponding commits from the stream indicated starting at the revision specified until the - /// end of the stream sorted in ascending order--from oldest to newest from the default bucket. - /// - /// The instance. - /// The stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events from the stream specified sorted in ascending order. - /// - /// - public static IEnumerable GetFrom(this ICommitEvents commitEvents, string streamId, int minRevision, int maxRevision) - { - return commitEvents.GetFrom(Bucket.Default, streamId, minRevision, maxRevision); - } - - /// - /// Gets the corresponding commits from the stream indicated starting at the revision specified until the - /// end of the stream sorted in ascending order--from oldest to newest from the default bucket. - /// - /// The instance. - /// The stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// Observer to receive the commits. - /// The token to monitor for cancellation requests. - /// - /// - public static Task GetFromAsync(this ICommitEventsAsync commitEvents, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken = default) - { - return commitEvents.GetFromAsync(Bucket.Default, streamId, minRevision, maxRevision, observer, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/CommitStreamObserver.cs b/src/NEventStore/CommitStreamObserver.cs deleted file mode 100644 index d91026f16..000000000 --- a/src/NEventStore/CommitStreamObserver.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Runtime.ExceptionServices; - -namespace NEventStore -{ - /// - /// Represents an async observer that can receive and stores commits from a stream. - /// Can be used as base class for other observers. - /// - public class CommitStreamObserver : IAsyncObserver - { - /// - /// The list of commits read from the stream. - /// - public IList Commits { get; } = []; - - /// - /// Indicates if the read operation has completed. - /// - public bool ReadCompleted { get; private set; } - - /// - /// Store the commits received from the stream in the collection. - /// - public virtual Task OnNextAsync(ICommit value, CancellationToken cancellationToken) - { - Commits.Add(value); - return Task.FromResult(true); - } - - /// - /// Notifies the observer that the provider has experienced an error condition. - /// - /// Preserve the stack trace and rethrow the exception that occurred while reading commits from the stream. - /// - /// - /// Override this method to log and handle the error. - /// - /// - public virtual Task OnErrorAsync(Exception ex, CancellationToken cancellationToken) - { - // Preserve the stack trace and rethrow the exception - ExceptionDispatchInfo.Capture(ex).Throw(); - return Task.CompletedTask; - } - - /// - public virtual Task OnCompletedAsync(CancellationToken cancellationToken) - { - ReadCompleted = true; - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/ConcurrencyException.cs b/src/NEventStore/ConcurrencyException.cs deleted file mode 100644 index 247e38b41..000000000 --- a/src/NEventStore/ConcurrencyException.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace NEventStore -{ - using System; - using System.Runtime.Serialization; - - /// - /// Represents an optimistic concurrency conflict between multiple writers. - /// - [Serializable] - public class ConcurrencyException : Exception - { - /// - /// Initializes a new instance of the ConcurrencyException class. - /// - public ConcurrencyException() - { } - - /// - /// Initializes a new instance of the ConcurrencyException class. - /// - /// The message that describes the error. - public ConcurrencyException(string message) - : base(message) - { } - - /// - /// Initializes a new instance of the ConcurrencyException class. - /// - /// The message that describes the error. - /// The message that is the cause of the current exception. - public ConcurrencyException(string message, Exception innerException) - : base(message, innerException) - { } - - /// - /// Initializes a new instance of the ConcurrencyException class. - /// - /// The SerializationInfo that holds the serialized object data of the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - protected ConcurrencyException(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - } -} \ No newline at end of file diff --git a/src/NEventStore/Conversion/EventUpconverterPipelineHook.cs b/src/NEventStore/Conversion/EventUpconverterPipelineHook.cs deleted file mode 100644 index 016be79d1..000000000 --- a/src/NEventStore/Conversion/EventUpconverterPipelineHook.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; -using NEventStore.Persistence; - -namespace NEventStore.Conversion -{ - /// - /// Represents a pipeline hook that upconverts events. - /// - public class EventUpconverterPipelineHook : PipelineHookBase - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(EventUpconverterPipelineHook)); - private readonly IDictionary> _converters; - - /// - /// Initializes a new instance of the EventUpconverterPipelineHook class. - /// - /// - public EventUpconverterPipelineHook(IDictionary> converters) - { - _converters = converters ?? throw new ArgumentNullException(nameof(converters)); - } - - /// - public override ICommit? SelectCommit(ICommit committed) - { - bool converted = false; - var eventMessages = committed - .Events - .Select(eventMessage => - { - object convert = Convert(eventMessage.Body); - if (ReferenceEquals(convert, eventMessage.Body)) - { - return eventMessage; - } - converted = true; - return new EventMessage { Headers = eventMessage.Headers, Body = convert }; - }) - .ToArray(); - if (!converted) - { - return committed; - } - return new Commit(committed.BucketId, - committed.StreamId, - committed.StreamRevision, - committed.CommitId, - committed.CommitSequence, - committed.CommitStamp, - committed.CheckpointToken, - committed.Headers, - eventMessages); - } - - /// - protected override void Dispose(bool disposing) - { - _converters.Clear(); - base.Dispose(disposing); - } - - private object Convert(object source) - { - Type sourceType = source.GetType(); - if (!_converters.TryGetValue(sourceType, out Func converter)) - { - return source; - } - - object target = converter(source); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.ConvertingEvent, sourceType, target.GetType()); - } - - return Convert(target); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Conversion/IUpconvertEvents.cs b/src/NEventStore/Conversion/IUpconvertEvents.cs deleted file mode 100644 index 8b4323cb5..000000000 --- a/src/NEventStore/Conversion/IUpconvertEvents.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace NEventStore.Conversion -{ - /// - /// Provides the ability to upconvert an event from one type to another. - /// - /// The source event type from which to convert. - /// The target event type. - public interface IUpconvertEvents - where TSource : class - where TTarget : class - { - /// - /// Converts an event from one type to another. - /// - /// The event to be converted. - /// The converted event. - TTarget Convert(TSource sourceEvent); - } -} \ No newline at end of file diff --git a/src/NEventStore/Conversion/MultipleConvertersFoundException.cs b/src/NEventStore/Conversion/MultipleConvertersFoundException.cs deleted file mode 100644 index 93b67cb67..000000000 --- a/src/NEventStore/Conversion/MultipleConvertersFoundException.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace NEventStore.Conversion -{ - using System; - using System.Runtime.Serialization; - - /// - /// Represents the failure that occurs when there are two or more event converters created for the same source type. - /// - [Serializable] - public class MultipleConvertersFoundException : Exception - { - /// - /// Initializes a new instance of the MultipleConvertersFoundException class. - /// - public MultipleConvertersFoundException() - { } - - /// - /// Initializes a new instance of the MultipleConvertersFoundException class. - /// - /// The message that describes the error. - public MultipleConvertersFoundException(string message) - : base(message) - { } - - /// - /// Initializes a new instance of the MultipleConvertersFoundException class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public MultipleConvertersFoundException(string message, Exception innerException) - : base(message, innerException) - { } - - /// - /// Initializes a new instance of the MultipleConvertersFoundException class. - /// - /// The serialization info. - /// The streaming context. - protected MultipleConvertersFoundException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } - } -} \ No newline at end of file diff --git a/src/NEventStore/Diagnostics/PerformanceCounterPersistenceEngine.cs b/src/NEventStore/Diagnostics/PerformanceCounterPersistenceEngine.cs deleted file mode 100644 index cfc010d50..000000000 --- a/src/NEventStore/Diagnostics/PerformanceCounterPersistenceEngine.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System.Diagnostics; -using NEventStore.Persistence; - -namespace NEventStore.Diagnostics -{ - // PerformanceCounters are not cross platform - -#if NET462 - - /// - /// Decorate an IPersistStreams implementation with performance counters. - /// - public class PerformanceCounterPersistenceEngine : IPersistStreams - { - private readonly PerformanceCounters _counters; - private readonly IPersistStreams _persistence; - - /// - /// Initializes a new instance of the PerformanceCounterPersistenceEngine class. - /// - public PerformanceCounterPersistenceEngine(IPersistStreams persistence, string instanceName) - { - _persistence = persistence; - _counters = new PerformanceCounters(instanceName); - } - - /// - public void Initialize() - { - _persistence.Initialize(); - } - - /// - public IEnumerable GetFrom(string bucketId, string streamId, int minRevision, int maxRevision) - { - return _persistence.GetFrom(bucketId, streamId, minRevision, maxRevision); - } - - /// - public ICommit? Commit(CommitAttempt attempt) - { - Stopwatch clock = Stopwatch.StartNew(); - var commit = _persistence.Commit(attempt); - clock.Stop(); - _counters.CountCommit(attempt.Events.Count, clock.ElapsedMilliseconds); - return commit; - } - - /// - public Task GetFromAsync(string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken) - { - return _persistence.GetFromAsync(bucketId, streamId, minRevision, maxRevision, observer, cancellationToken); - } - - /// - public async Task CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken) - { - Stopwatch clock = Stopwatch.StartNew(); - var commit = await _persistence.CommitAsync(attempt, cancellationToken).ConfigureAwait(false); - clock.Stop(); - _counters.CountCommit(attempt.Events.Count, clock.ElapsedMilliseconds); - return commit; - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFromTo(string bucketId, DateTime startDate, DateTime endDate) - { - return _persistence.GetFromTo(bucketId, startDate, endDate); - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFrom(Int64 checkpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFrom(string bucketId, DateTime startDate) - { - return _persistence.GetFrom(bucketId, startDate); - } - - /// - public IEnumerable GetFrom(Int64 checkpointToken) - { - return _persistence.GetFrom(checkpointToken); - } - - /// - public Task GetFromAsync(Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _persistence.GetFromAsync(checkpointToken, asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - return _persistence.GetFromTo(fromCheckpointToken, toCheckpointToken); - } - - /// - public Task GetFromToAsync(Int64 fromCheckpointToken, Int64 toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _persistence.GetFromToAsync(fromCheckpointToken, toCheckpointToken, asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFrom(string bucketId, Int64 checkpointToken) - { - return _persistence.GetFrom(bucketId, checkpointToken); - } - - /// - public Task GetFromAsync(string bucketId, Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _persistence.GetFromAsync(bucketId, checkpointToken, asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(string bucketId, Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - return _persistence.GetFromTo(bucketId, fromCheckpointToken, toCheckpointToken); - } - - /// - public Task GetFromToAsync(string bucketId, long fromCheckpointToken, long toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _persistence.GetFromToAsync(bucketId, fromCheckpointToken, toCheckpointToken, asyncObserver, cancellationToken); - } - - /// - public ISnapshot? GetSnapshot(string bucketId, string streamId, int maxRevision) - { - return _persistence.GetSnapshot(bucketId, streamId, maxRevision); - } - - /// - public bool AddSnapshot(ISnapshot snapshot) - { - bool result = _persistence.AddSnapshot(snapshot); - if (result) - { - _counters.CountSnapshot(); - } - - return result; - } - - /// - public virtual IEnumerable GetStreamsToSnapshot(string bucketId, int maxThreshold) - { - return _persistence.GetStreamsToSnapshot(bucketId, maxThreshold); - } - - /// - public Task GetSnapshotAsync(string bucketId, string streamId, int maxRevision, CancellationToken cancellationToken) - { - return _persistence.GetSnapshotAsync(bucketId, streamId, maxRevision, cancellationToken); - } - - /// - public async Task AddSnapshotAsync(ISnapshot snapshot, CancellationToken cancellationToken) - { - bool result = await _persistence.AddSnapshotAsync(snapshot, cancellationToken).ConfigureAwait(false); - if (result) - { - _counters.CountSnapshot(); - } - - return result; - } - - /// - public Task GetStreamsToSnapshotAsync(string bucketId, int maxThreshold, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _persistence.GetStreamsToSnapshotAsync(bucketId, maxThreshold, asyncObserver, cancellationToken); - } - - /// - public virtual void Purge() - { - _persistence.Purge(); - } - - /// - public void Purge(string bucketId) - { - _persistence.Purge(bucketId); - } - - /// - public Task PurgeAsync(CancellationToken cancellationToken) - { - return _persistence.PurgeAsync(cancellationToken); - } - - /// - public Task PurgeAsync(string bucketId, CancellationToken cancellationToken) - { - return _persistence.PurgeAsync(bucketId, cancellationToken); - } - - /// - public void Drop() - { - _persistence.Drop(); - } - - /// - public void DeleteStream(string bucketId, string streamId) - { - _persistence.DeleteStream(bucketId, streamId); - } - - /// - public Task DeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken) - { - return _persistence.DeleteStreamAsync(bucketId, streamId, cancellationToken); - } - - /// - public bool IsDisposed - { - get { return _persistence.IsDisposed; } - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Finalizes an instance of the PerformanceCounterPersistenceEngine class. - /// - ~PerformanceCounterPersistenceEngine() - { - Dispose(false); - } - - /// - /// Dispose the performance counter and the wrapped persistence engine. - /// - protected virtual void Dispose(bool disposing) - { - if (!disposing) - { - return; - } - - _counters.Dispose(); - _persistence.Dispose(); - } - - /// - /// Unwrap the performance counter and return the wrapped persistence engine. - /// - public IPersistStreams UnwrapPersistenceEngine() - { - return _persistence; - } - } -#endif -} \ No newline at end of file diff --git a/src/NEventStore/Diagnostics/PerformanceCounters.cs b/src/NEventStore/Diagnostics/PerformanceCounters.cs deleted file mode 100644 index acd420332..000000000 --- a/src/NEventStore/Diagnostics/PerformanceCounters.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Diagnostics; - -namespace NEventStore.Diagnostics -{ - // PerformanceCounters are not cross platform - -#if NET462 - internal class PerformanceCounters : IDisposable - { - private const string CategoryName = "NEventStore"; - private const string TotalCommitsName = "Total Commits"; - private const string CommitsRateName = "Commits/Sec"; - private const string AvgCommitDuration = "Average Commit Duration"; - private const string AvgCommitDurationBase = "Average Commit Duration Base"; - private const string TotalEventsName = "Total Events"; - private const string EventsRateName = "Events/Sec"; - private const string TotalSnapshotsName = "Total Snapshots"; - private const string SnapshotsRateName = "Snapshots/Sec"; - private readonly PerformanceCounter _avgCommitDuration; - private readonly PerformanceCounter _avgCommitDurationBase; - private readonly PerformanceCounter _commitsRate; - private readonly PerformanceCounter _eventsRate; - private readonly PerformanceCounter _snapshotsRate; - private readonly PerformanceCounter _totalCommits; - private readonly PerformanceCounter _totalEvents; - private readonly PerformanceCounter _totalSnapshots; - - static PerformanceCounters() - { - if (PerformanceCounterCategory.Exists(CategoryName)) - { - return; - } - - var counters = new CounterCreationDataCollection - { - new CounterCreationData(TotalCommitsName, "Total number of commits persisted", PerformanceCounterType.NumberOfItems32), - new CounterCreationData(CommitsRateName, "Rate of commits persisted per second", PerformanceCounterType.RateOfCountsPerSecond32), - new CounterCreationData(AvgCommitDuration, "Average duration for each commit", PerformanceCounterType.AverageTimer32), - new CounterCreationData(AvgCommitDurationBase, "Average duration base for each commit", PerformanceCounterType.AverageBase), - new CounterCreationData(TotalEventsName, "Total number of events persisted", PerformanceCounterType.NumberOfItems32), - new CounterCreationData(EventsRateName, "Rate of events persisted per second", PerformanceCounterType.RateOfCountsPerSecond32), - new CounterCreationData(TotalSnapshotsName, "Total number of snapshots persisted", PerformanceCounterType.NumberOfItems32), - new CounterCreationData(SnapshotsRateName, "Rate of snapshots persisted per second", PerformanceCounterType.RateOfCountsPerSecond32), - }; - - // TODO: add other useful counts such as: - // - // * Total Commit Bytes - // * Average Commit Bytes - // * Total Queries - // * Queries Per Second - // * Average Query Duration - // * Commits per Query (Total / average / per second) - // * Events per Query (Total / average / per second) - // - // Some of these will involve hooking into other parts of the NEventStore - - PerformanceCounterCategory.Create(CategoryName, "NEventStore Event-Sourcing Persistence", PerformanceCounterCategoryType.MultiInstance, counters); - } - - public PerformanceCounters(string instanceName) - { - _totalCommits = new PerformanceCounter(CategoryName, TotalCommitsName, instanceName, false); - _commitsRate = new PerformanceCounter(CategoryName, CommitsRateName, instanceName, false); - _avgCommitDuration = new PerformanceCounter(CategoryName, AvgCommitDuration, instanceName, false); - _avgCommitDurationBase = new PerformanceCounter(CategoryName, AvgCommitDurationBase, instanceName, false); - _totalEvents = new PerformanceCounter(CategoryName, TotalEventsName, instanceName, false); - _eventsRate = new PerformanceCounter(CategoryName, EventsRateName, instanceName, false); - _totalSnapshots = new PerformanceCounter(CategoryName, TotalSnapshotsName, instanceName, false); - _snapshotsRate = new PerformanceCounter(CategoryName, SnapshotsRateName, instanceName, false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - public void CountCommit(int eventsCount, long elapsedMilliseconds) - { - _totalCommits.Increment(); - _commitsRate.Increment(); - _avgCommitDuration.IncrementBy(elapsedMilliseconds); - _avgCommitDurationBase.Increment(); - _totalEvents.IncrementBy(eventsCount); - _eventsRate.IncrementBy(eventsCount); - } - - public void CountSnapshot() - { - _totalSnapshots.Increment(); - _snapshotsRate.Increment(); - } - - ~PerformanceCounters() - { - Dispose(false); - } - - protected virtual void Dispose(bool disposing) - { - _totalCommits.Dispose(); - _commitsRate.Dispose(); - _avgCommitDuration.Dispose(); - _avgCommitDurationBase.Dispose(); - _totalEvents.Dispose(); - _eventsRate.Dispose(); - _totalSnapshots.Dispose(); - _snapshotsRate.Dispose(); - } - } -#endif -} \ No newline at end of file diff --git a/src/NEventStore/DuplicateCommitException.cs b/src/NEventStore/DuplicateCommitException.cs deleted file mode 100644 index 58763d4af..000000000 --- a/src/NEventStore/DuplicateCommitException.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace NEventStore -{ - using System; - using System.Runtime.Serialization; - - /// - /// Represents an attempt to commit the same information more than once. - /// - [Serializable] - public class DuplicateCommitException : Exception - { - /// - /// Initializes a new instance of the DuplicateCommitException class. - /// - public DuplicateCommitException() - {} - - /// - /// Initializes a new instance of the DuplicateCommitException class. - /// - /// The message that describes the error. - public DuplicateCommitException(string message) - : base(message) - {} - - /// - /// Initializes a new instance of the DuplicateCommitException class. - /// - /// The message that describes the error. - /// The message that is the cause of the current exception. - public DuplicateCommitException(string message, Exception innerException) - : base(message, innerException) - {} - - /// - /// Initializes a new instance of the DuplicateCommitException class. - /// - /// The SerializationInfo that holds the serialized object data of the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - protected DuplicateCommitException(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - } -} \ No newline at end of file diff --git a/src/NEventStore/EventMessage.cs b/src/NEventStore/EventMessage.cs deleted file mode 100644 index 58ead0a32..000000000 --- a/src/NEventStore/EventMessage.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace NEventStore -{ - using System; - using System.Collections.Generic; - using System.Runtime.Serialization; - - /// - /// Represents a single element in a stream of events. - /// - [Serializable] - [DataContract] - public sealed class EventMessage - { - /// - /// Initializes a new instance of the EventMessage class. - /// - public EventMessage() - { - Headers = []; - } - - /// - /// Gets the metadata which provides additional, unstructured information about this message. - /// - [DataMember] - public Dictionary Headers { get; set; } - - /// - /// Gets or sets the actual event message body. - /// - [DataMember] - public object Body { get; set; } - } -} \ No newline at end of file diff --git a/src/NEventStore/EventUpconverterWireup.cs b/src/NEventStore/EventUpconverterWireup.cs deleted file mode 100644 index baa6cfb22..000000000 --- a/src/NEventStore/EventUpconverterWireup.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Reflection; -using Microsoft.Extensions.Logging; -using NEventStore.Conversion; -using NEventStore.Logging; - -namespace NEventStore -{ - /// - /// Represents the configuration for event upconverters. - /// - public class EventUpconverterWireup : Wireup - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(EventUpconverterWireup)); - private readonly List _assembliesToScan = new List(); - private readonly Dictionary> _registered = new Dictionary>(); - - /// - /// Initializes a new instance of the EventUpconverterWireup class. - /// - /// - public EventUpconverterWireup(Wireup wireup) : base(wireup) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.EventUpconverterRegistered); - } - - Container.Register(_ => - { - if (_registered.Count > 0) - { - return new EventUpconverterPipelineHook(_registered); - } - - if (_assembliesToScan.Count == 0) - { - _assembliesToScan.AddRange(GetAllAssemblies()); - } - - var converters = GetConverters(_assembliesToScan); - if (converters.Count > 0) - { - return new EventUpconverterPipelineHook(converters); - } - return null; - }); - } - - private static IEnumerable GetAllAssemblies() - { - return Assembly.GetCallingAssembly() - .GetReferencedAssemblies() - .Select(Assembly.Load) - .Concat(new[] { Assembly.GetCallingAssembly() }); - } - - private static Dictionary> GetConverters(IEnumerable toScan) - { - IEnumerable>> c = from a in toScan - from t in a.GetTypes() - where !t.IsAbstract - let i = t.GetInterface(typeof(IUpconvertEvents<,>).FullName) - where i != null - let sourceType = i.GetGenericArguments().First() - let convertMethod = i.GetMethods(BindingFlags.Public | BindingFlags.Instance).First() - let instance = Activator.CreateInstance(t) - select new KeyValuePair>( - sourceType, e => convertMethod.Invoke(instance, new[] { e })); - try - { - return c.ToDictionary(x => x.Key, x => x.Value); - } - catch (ArgumentException e) - { - throw new MultipleConvertersFoundException(e.Message, e); - } - } - - /// - /// Scans the specified assemblies for event upconverters. - /// - public virtual EventUpconverterWireup WithConvertersFrom(params Assembly[] assemblies) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.EventUpconvertersLoadedFrom, - string.Join(", ", assemblies.Select(a => $"{a.GetName().Name} {a.GetName().Version}"))); - } - _assembliesToScan.AddRange(assemblies); - return this; - } - - /// - /// Scans the assemblies containing the converters for event upconverters. - /// - public virtual EventUpconverterWireup WithConvertersFromAssemblyContaining(params Type[] converters) - { - IEnumerable assemblies = converters.Select(c => c.Assembly).Distinct(); - return this.WithConvertersFrom(assemblies.ToArray()); - } - - /// - /// Adds a converter to the pipeline. - /// - /// - public virtual EventUpconverterWireup AddConverter( - IUpconvertEvents converter) - where TSource : class - where TTarget : class - { - if (converter == null) - { - throw new ArgumentNullException(nameof(converter)); - } - - _registered[typeof(TSource)] = @event => converter.Convert((TSource)@event); - - return this; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/EventUpconverterWireupExtensions.cs b/src/NEventStore/EventUpconverterWireupExtensions.cs deleted file mode 100644 index 68024e15a..000000000 --- a/src/NEventStore/EventUpconverterWireupExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides support for upconverting events during the commit phase. - /// - public static class EventUpconverterWireupExtensions - { - /// - /// Configures the event store to upconvert events during the commit phase. - /// - public static EventUpconverterWireup UsingEventUpconversion(this Wireup wireup) - { - return new EventUpconverterWireup(wireup); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/ExtensionMethods.cs b/src/NEventStore/ExtensionMethods.cs deleted file mode 100644 index b2dcebd11..000000000 --- a/src/NEventStore/ExtensionMethods.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Globalization; - -namespace NEventStore -{ - /// - /// A set of common methods used through the NEventStore. - /// - public static class ExtensionMethods - { - /// - /// Formats the string provided using the values specified. - /// - /// The string to be formatted. - /// The values to be embedded into the string. - /// The formatted string. - public static string FormatWith(this string format, params object[] values) - { - return string.Format(CultureInfo.InvariantCulture, format ?? string.Empty, values); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Guard.cs b/src/NEventStore/Guard.cs deleted file mode 100644 index afbf03429..000000000 --- a/src/NEventStore/Guard.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Linq.Expressions; - -namespace NEventStore -{ - internal static class Guard - { - internal static void NotFalse(bool condition, Func createException) - { - if (!condition) - { - throw createException(); - } - } - - internal static void NotNullOrWhiteSpace(Expression> reference, string value) - { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentException(GetParameterName(reference)); - } - } - - internal static void NotNull(Expression> reference, T value) - { - if (value == null) - { - throw new ArgumentNullException(GetParameterName(reference)); - } - } - - internal static void NotLessThanOrEqualTo(Expression> reference, T value, T compareTo) - where T: IComparable - { - NotNull(reference, value); - if (value.CompareTo(compareTo) <= 0) - { - throw new ArgumentOutOfRangeException("{0} has value {1} which is less than or equal to {2}".FormatWith(GetParameterName(reference), value, compareTo)); - } - } - - internal static void NotLessThan(Expression> reference, T value, T compareTo) - where T : IComparable - { - NotNull(reference, value); - if (value.CompareTo(compareTo) < 0) - { - throw new ArgumentOutOfRangeException("{0} has value {1} which is less than {2}".FormatWith(GetParameterName(reference), value, compareTo)); - } - } - - internal static void NotDefault(Expression> reference, T value) - where T : IComparable - { - NotNull(reference, value); - if (value.CompareTo(default(T)) == 0) - { - throw new ArgumentException("{0} has value {1} which cannot be equal to it's default value {2}".FormatWith(GetParameterName(reference), value, default(T)!)); - } - } - - internal static void NotEmpty(Expression>> reference, IEnumerable value) - { - NotNull(reference, value); - if (!value.Any()) - { - throw new ArgumentException("{0} cannot be empty".FormatWith(GetParameterName(reference), value, default(T)!)); - } - } - - private static string GetParameterName(LambdaExpression reference) - { - return ((MemberExpression) reference.Body).Member.Name; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Helpers/DateTimeService.cs b/src/NEventStore/Helpers/DateTimeService.cs deleted file mode 100644 index 3514c4682..000000000 --- a/src/NEventStore/Helpers/DateTimeService.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace NEventStore.Helpers -{ - /// - /// Provides a way to get the current date and time. - /// Useful for testing. - /// - public static class DateTimeService - { - private static Func _nowFunc = () => DateTime.Now; - private static Func _utcNowFunc = () => DateTime.UtcNow; - - /// - /// Gets the current date and time. - /// - public static DateTime Now - { - get - { - return _nowFunc(); - } - } - - /// - /// Gets the current date and time in UTC. - /// - public static DateTime UtcNow - { - get - { - return _utcNowFunc(); - } - } - - #region "test function" - - internal static DisposableAction Override(Func functor) - { - _nowFunc = functor; - _utcNowFunc = () => functor().ToUniversalTime(); - return new DisposableAction(() => - { - _nowFunc = () => DateTime.Now; - _utcNowFunc = () => DateTime.UtcNow; - }); - } - - internal static DisposableAction Override(DateTime overrideNowDate) - { - return Override(() => overrideNowDate); - } - - #endregion - } -} diff --git a/src/NEventStore/Helpers/DisposableAction.cs b/src/NEventStore/Helpers/DisposableAction.cs deleted file mode 100644 index 79c52d8f6..000000000 --- a/src/NEventStore/Helpers/DisposableAction.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace NEventStore.Helpers -{ - /// - /// Provides a way to execute an action when disposed. - /// - internal sealed class DisposableAction : IDisposable - { - private Action? _disposeAction; - - public DisposableAction(Action disposeAction) - { - _disposeAction = disposeAction; - } - - public void Dispose() - { - // Interlocked allows the continuation to be executed only once - var dispose = Interlocked.Exchange(ref _disposeAction, null); - dispose?.Invoke(); - } - } -} diff --git a/src/NEventStore/IAccessSnapshots.cs b/src/NEventStore/IAccessSnapshots.cs deleted file mode 100644 index eedc4945e..000000000 --- a/src/NEventStore/IAccessSnapshots.cs +++ /dev/null @@ -1,43 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to get or retrieve a snapshot for a given stream. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IAccessSnapshots - { - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - ISnapshot? GetSnapshot(string bucketId, string streamId, int maxRevision); - - /// - /// Adds the snapshot provided to the stream indicated. - /// - /// The snapshot to save. - /// If the snapshot was added, returns true; otherwise false. - /// - /// - bool AddSnapshot(ISnapshot snapshot); - - /// - /// Gets identifiers for all streams whose head and last snapshot revisions differ by at least the threshold specified. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The maximum difference between the head and most recent snapshot revisions. - /// The streams for which the head and snapshot revisions differ by at least the threshold specified. - /// - /// - IEnumerable GetStreamsToSnapshot(string bucketId, int maxThreshold); - } -} \ No newline at end of file diff --git a/src/NEventStore/IAccessSnapshotsAsync.cs b/src/NEventStore/IAccessSnapshotsAsync.cs deleted file mode 100644 index 84c5f1111..000000000 --- a/src/NEventStore/IAccessSnapshotsAsync.cs +++ /dev/null @@ -1,49 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to get or retrieve a snapshot for a given stream. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IAccessSnapshotsAsync - { - /// - /// Gets the most recent snapshot which was taken on or before the revision indicated. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream to be searched for a snapshot. - /// The maximum revision possible for the desired snapshot. - /// The token to monitor for cancellation requests. - /// If found, it returns the snapshot; otherwise null is returned. - /// - /// - Task GetSnapshotAsync(string bucketId, string streamId, int maxRevision, CancellationToken cancellationToken = default); - - /// - /// Adds the snapshot provided to the stream indicated. - /// - /// The snapshot to save. - /// The token to monitor for cancellation requests. - /// If the snapshot was added, returns true; otherwise false. - /// - /// - Task AddSnapshotAsync(ISnapshot snapshot, CancellationToken cancellationToken = default); - - /// - /// Gets identifiers for all streams whose head and last snapshot revisions differ by at least the threshold specified. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The maximum difference between the head and most recent snapshot revisions. - /// The observer to receive the streams. - /// The token to monitor for cancellation requests. - /// - /// - /// - /// In Observer.OnErrorAsync and Observer.OnCompletedAsync the checkpoint will always be 0. - /// - Task GetStreamsToSnapshotAsync(string bucketId, int maxThreshold, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/src/NEventStore/IAsyncObserver.cs b/src/NEventStore/IAsyncObserver.cs deleted file mode 100644 index c11b6b3e3..000000000 --- a/src/NEventStore/IAsyncObserver.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace NEventStore -{ - /// - /// Represents an async observer that can receive notifications of objects. - /// - public interface IAsyncObserver - { - /// - /// Provides the observer with new data. - /// - /// The current notification information. - /// the cancellation token of the original request. - /// - /// true = continue reading, false = stop reading - /// - Task OnNextAsync(T value, CancellationToken cancellationToken = default); - /// - /// Notifies the observer that the provider has experienced an error condition. - /// - /// The error that has occurred. - /// the cancellation token of the original request. - Task OnErrorAsync(Exception ex, CancellationToken cancellationToken = default); - /// - /// Notifies the observer that the provider has finished sending push-based notifications. - /// It can happen because: - /// - the source has completed sending push-based notifications successfully. - /// - the reading operation has been cancelled. - /// - /// the cancellation token of the original request. - Task OnCompletedAsync(CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/src/NEventStore/ICommit.cs b/src/NEventStore/ICommit.cs deleted file mode 100644 index 04c731143..000000000 --- a/src/NEventStore/ICommit.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace NEventStore -{ - /// - /// Represents a series of events which have been fully committed as a single unit and which apply to the stream indicated. - /// - public interface ICommit - { - /// - /// Gets the value which identifies bucket to which the stream and the commit belongs. - /// - string BucketId { get; } - - /// - /// Gets the value which uniquely identifies the stream to which the commit belongs. - /// - string StreamId { get; } - - /// - /// Gets the value which indicates the revision of the most recent event in the stream to which this commit applies. - /// - int StreamRevision { get; } - - /// - /// Gets the value which uniquely identifies the commit within the stream. - /// - Guid CommitId { get; } - - /// - /// Gets the value which indicates the sequence (or position) in the stream to which this commit applies. - /// - int CommitSequence { get; } - - /// - /// Gets the point in time at which the commit was persisted. - /// - DateTime CommitStamp { get; } - - /// - /// Gets the metadata which provides additional, unstructured information about this commit. - /// - IDictionary Headers { get; } - - /// - /// Gets the collection of event messages to be committed as a single unit. - /// - ICollection Events { get; } - - /// - /// The checkpoint that represents the storage level order. - /// - Int64 CheckpointToken { get; } - } -} \ No newline at end of file diff --git a/src/NEventStore/ICommitEvents.cs b/src/NEventStore/ICommitEvents.cs deleted file mode 100644 index 69ff1fce0..000000000 --- a/src/NEventStore/ICommitEvents.cs +++ /dev/null @@ -1,39 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to commit events and access events to and from a given stream. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface ICommitEvents - { - /// - /// Gets the corresponding commits from the stream indicated starting at the revision specified until the - /// end of the stream sorted in ascending order--from oldest to newest. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events from the stream specified sorted in ascending order. - /// - /// - IEnumerable GetFrom(string bucketId, string streamId, int minRevision, int maxRevision); - - /// - /// Writes the to-be-committed events provided to the underlying persistence mechanism. - /// - /// The series of events and associated metadata to be committed. - /// - /// - /// - /// - /// This interface returns a nullable ICommit object because it's implemented by - /// that can return null if the pipeline hooks decide to abort the commit. - /// - ICommit? Commit(CommitAttempt attempt); - } -} \ No newline at end of file diff --git a/src/NEventStore/ICommitEventsAsync.cs b/src/NEventStore/ICommitEventsAsync.cs deleted file mode 100644 index 2fa4edca4..000000000 --- a/src/NEventStore/ICommitEventsAsync.cs +++ /dev/null @@ -1,47 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to commit events and access events to and from a given stream. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface ICommitEventsAsync - { - /// - /// Gets the corresponding commits (possibly using an async cursor) from the stream indicated - /// starting at the revision specified until the end of the stream sorted - /// in ascending order--from oldest to newest. - /// Each commit will be passed to an observer. - /// Reading operation will stop: - /// - when the maxRevision is reached. - /// - if CancellationToken is set. - /// - when there are no more commits to read. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// Observer to receive the commits. - /// The token to monitor for cancellation requests. - /// - /// - Task GetFromAsync(string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken = default); - - /// - /// Writes the to-be-committed events provided to the underlying persistence mechanism. - /// - /// The series of events and associated metadata to be committed. - /// The token to monitor for cancellation requests. - /// - /// - /// - /// - /// This interface returns a nullable ICommit object because it's implemented by - /// that can return null if the pipeline hooks decide to abort the commit. - /// - Task CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/src/NEventStore/IEventStream.cs b/src/NEventStore/IEventStream.cs deleted file mode 100644 index c4132e279..000000000 --- a/src/NEventStore/IEventStream.cs +++ /dev/null @@ -1,87 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to track a series of events and commit them to durable storage. - /// - /// - /// Instances of this class are single threaded and should not be shared between threads. - /// - public interface IEventStream : IDisposable - { - /// - /// Gets the value which identifies bucket to which the stream belongs. - /// - string BucketId { get; } - - /// - /// Gets the value which uniquely identifies the stream to which the stream belongs. - /// - string StreamId { get; } - - /// - /// Gets the value which indicates the most recent committed revision of event stream. - /// - int StreamRevision { get; } - - /// - /// Gets the value which indicates the most recent committed sequence identifier of the event stream. - /// - int CommitSequence { get; } - - /// - /// Gets the collection of events which have been successfully persisted to durable storage. - /// - ICollection CommittedEvents { get; } - - /// - /// Gets the collection of committed headers associated with the stream. - /// - IDictionary CommittedHeaders { get; } - - /// - /// Gets the collection of yet-to-be-committed events that have not yet been persisted to durable storage. - /// - ICollection UncommittedEvents { get; } - - /// - /// Gets the collection of yet-to-be-committed headers associated with the uncommitted events. - /// - IDictionary UncommittedHeaders { get; } - - /// - /// Adds the event messages provided to the session to be tracked. - /// - /// The event to be tracked. - void Add(EventMessage uncommittedEvent); - - /// - /// Commits the changes to durable storage. - /// - /// The value which uniquely identifies the commit. - /// The commit which has been persisted to durable storage. - /// - /// - /// - /// - ICommit? CommitChanges(Guid commitId); - - /// - /// Commits the changes to durable storage. - /// - /// The value which uniquely identifies the commit. - /// The token to monitor for cancellation requests. - /// The commit which has been persisted to durable storage. - /// - /// - /// - /// - Task CommitChangesAsync(Guid commitId, CancellationToken cancellationToken = default); - - /// - /// Clears the uncommitted changes. - /// - void ClearChanges(); - } -} \ No newline at end of file diff --git a/src/NEventStore/IPipelineHook.cs b/src/NEventStore/IPipelineHook.cs deleted file mode 100644 index b85dd3a24..000000000 --- a/src/NEventStore/IPipelineHook.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides the ability to hook into the pipeline of persisting a commit. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPipelineHook : IDisposable - { - /// - /// Hooks into the selection pipeline just prior to the commit being returned to the caller. - /// - /// The commit to be filtered. - /// If successful, returns a populated commit; otherwise returns null. - ICommit? SelectCommit(ICommit committed); - - /// - /// Hooks into the commit pipeline prior to persisting the commit to durable storage. - /// - /// The attempt to be committed. - /// If processing should continue, returns true; otherwise returns false. - bool PreCommit(CommitAttempt attempt); - - /// - /// Hooks into the commit pipeline just after the commit has been *successfully* committed to durable storage. - /// - /// The commit which has been persisted. - void PostCommit(ICommit committed); - - /// - /// Invoked when a bucket has been purged. If buckedId is null, then all buckets have been purged. - /// - /// The bucket Id that has been purged. Null when all buckets have been purged. - void OnPurge(string? bucketId); - - /// - /// Invoked when a stream has been deleted. - /// - /// The bucket Id from which the stream which has been deleted. - /// The stream Id of the stream which has been deleted. - void OnDeleteStream(string bucketId, string streamId); - } -} \ No newline at end of file diff --git a/src/NEventStore/IPipelineHookAsync.cs b/src/NEventStore/IPipelineHookAsync.cs deleted file mode 100644 index 601d273b1..000000000 --- a/src/NEventStore/IPipelineHookAsync.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides the ability to hook into the pipeline of persisting a commit. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPipelineHookAsync : IDisposable - { - /// - /// Hooks into the selection pipeline just prior to the commit being returned to the caller. - /// - /// The commit to be filtered. - /// The token to monitor for cancellation requests. - /// If successful, returns a populated commit; otherwise returns null. - Task SelectCommitAsync(ICommit committed, CancellationToken cancellationToken); - - /// - /// Hooks into the commit pipeline prior to persisting the commit to durable storage. - /// - /// The attempt to be committed. - /// The token to monitor for cancellation requests. - /// If processing should continue, returns true; otherwise returns false. - Task PreCommitAsync(CommitAttempt attempt, CancellationToken cancellationToken); - - /// - /// Hooks into the commit pipeline just after the commit has been *successfully* committed to durable storage. - /// - /// The commit which has been persisted. - /// The token to monitor for cancellation requests. - Task PostCommitAsync(ICommit committed, CancellationToken cancellationToken); - - /// - /// Invoked when a bucket has been purged. If buckedId is null, then all buckets have been purged. - /// - /// The bucket Id that has been purged. Null when all buckets have been purged. - /// The token to monitor for cancellation requests. - Task OnPurgeAsync(string? bucketId, CancellationToken cancellationToken); - - /// - /// Invoked when a stream has been deleted. - /// - /// The bucket Id from which the stream which has been deleted. - /// The stream Id of the stream which has been deleted. - /// The token to monitor for cancellation requests. - Task OnDeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken); - } -} \ No newline at end of file diff --git a/src/NEventStore/ISnapshot.cs b/src/NEventStore/ISnapshot.cs deleted file mode 100644 index 178f0bc70..000000000 --- a/src/NEventStore/ISnapshot.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace NEventStore -{ - /// - /// Represents a materialized view of a stream at specific revision. - /// - public interface ISnapshot - { - /// - /// Gets the value which uniquely identifies the bucket to which the snapshot applies. - /// - string BucketId { get; } - - /// - /// Gets the value which uniquely identifies the stream to which the snapshot applies. - /// - string StreamId { get; } - - /// - /// Gets the position at which the snapshot applies. - /// - int StreamRevision { get; } - - /// - /// Gets the snapshot or materialized view of the stream at the revision indicated. - /// - object Payload { get; } - } -} \ No newline at end of file diff --git a/src/NEventStore/IStoreEvents.cs b/src/NEventStore/IStoreEvents.cs deleted file mode 100644 index db4c27b5c..000000000 --- a/src/NEventStore/IStoreEvents.cs +++ /dev/null @@ -1,76 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Indicates the ability to store and retrieve a stream of events. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IStoreEvents : IDisposable - { - /// - /// Gets a reference to the underlying persistence engine which allows direct access to persistence operations. - /// - IPersistStreams Advanced { get; } - - /// - /// Creates a new stream. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream within the bucket to be created. - /// An empty stream. - IEventStream CreateStream(string bucketId, string streamId); - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream in the bucket from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events represented as a stream. - /// - /// - /// - IEventStream OpenStream(string bucketId, string streamId, int minRevision, int maxRevision); - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream in the bucket from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// The token to monitor for cancellation requests. - /// A series of committed events represented as a stream. - /// - /// - /// - Task OpenStreamAsync(string bucketId, string streamId, int minRevision, int maxRevision, CancellationToken cancellationToken = default); - - /// - /// Reads the stream indicated from the point of the snapshot forward until the maximum revision specified. - /// - /// The snapshot of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events represented as a stream. - /// - /// - IEventStream OpenStream(ISnapshot snapshot, int maxRevision); - - /// - /// Reads the stream indicated from the point of the snapshot forward until the maximum revision specified. - /// - /// The snapshot of the stream to be read. - /// The maximum revision of the stream to be read. - /// The token to monitor for cancellation requests. - /// A series of committed events represented as a stream. - /// - /// - Task OpenStreamAsync(ISnapshot snapshot, int maxRevision, CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/src/NEventStore/ImmutableCollection.cs b/src/NEventStore/ImmutableCollection.cs deleted file mode 100644 index 2f1cb05e8..000000000 --- a/src/NEventStore/ImmutableCollection.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Collections; - -namespace NEventStore -{ - internal sealed class ImmutableCollection : ICollection, ICollection - { - private readonly ICollection _inner; - - public ImmutableCollection(ICollection inner) - { - _inner = inner; - } - - public object SyncRoot { get; } = new object(); - - public bool IsSynchronized - { - get { return false; } - } - - public void CopyTo(Array array, int index) - { - CopyTo(array.Cast().ToArray(), index); - } - - public int Count - { - get { return _inner.Count; } - } - - public bool IsReadOnly - { - get { return true; } - } - - public IEnumerator GetEnumerator() - { - return _inner.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public void Add(T item) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - public bool Remove(T item) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - public void Clear() - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - public bool Contains(T item) - { - return _inner.Contains(item); - } - - public void CopyTo(T[] array, int arrayIndex) - { - _inner.CopyTo(array, arrayIndex); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/ImmutableDictionary.cs b/src/NEventStore/ImmutableDictionary.cs deleted file mode 100644 index 7133698bf..000000000 --- a/src/NEventStore/ImmutableDictionary.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Collections; - -namespace NEventStore -{ - /// - /// Represents an immutable dictionary. - /// - public sealed class ImmutableDictionary : IDictionary - { - private readonly IDictionary _inner; - - /// - /// Initializes a new instance of the ImmutableDictionary class. - /// - public ImmutableDictionary(IDictionary inner) - { - _inner = inner; - } - - /// - /// Gets the value associated with the specified key. - /// - /// - public TValue this[TKey key] { get => _inner[key]; set => throw new NotSupportedException(Resources.ReadOnlyCollection); } - - /// - /// Gets the keys in the dictionary. - /// - public ICollection Keys => _inner.Keys; - - /// - /// Gets the values in the dictionary. - /// - public ICollection Values => _inner.Values; - - /// - /// Gets the number of elements in the dictionary. - /// - public int Count => _inner.Count; - - /// - /// Gets a value indicating whether the dictionary is read-only. - /// - public bool IsReadOnly => true; - - /// - /// Adds an element with the provided key and value to the dictionary. - /// - /// - public void Add(TKey key, TValue value) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - /// - /// Adds an item to the dictionary. - /// - /// - public void Add(KeyValuePair item) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - /// - /// Removes all items from the dictionary. - /// - /// - public void Clear() - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - /// - /// Determines whether the dictionary contains a specific value. - /// - public bool Contains(KeyValuePair item) - { - return _inner.Contains(item); - } - - /// - /// Determines whether the dictionary contains a specific key. - /// - public bool ContainsKey(TKey key) - { - return _inner.ContainsKey(key); - } - - /// - /// Copies the elements of the dictionary to an array, starting at a particular array index. - /// - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - _inner.CopyTo(array, arrayIndex); - } - - /// - /// Removes the element with the specified key from the dictionary. - /// - /// - public bool Remove(TKey key) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - /// - /// Removes the first occurrence of a specific object from the dictionary. - /// - /// - public bool Remove(KeyValuePair item) - { - throw new NotSupportedException(Resources.ReadOnlyCollection); - } - - /// - /// Gets the value associated with the specified key. - /// - public bool TryGetValue(TKey key, out TValue value) - { - return _inner.TryGetValue(key, out value); - } - - /// - /// Returns an enumerator that iterates through the dictionary. - /// - public IEnumerator> GetEnumerator() - { - return _inner.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/LambdaAsyncObserver.cs b/src/NEventStore/LambdaAsyncObserver.cs deleted file mode 100644 index 4dcff26ea..000000000 --- a/src/NEventStore/LambdaAsyncObserver.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace NEventStore -{ - /// - /// Represents an async observer that can receive notifications of commits. - /// - public class LambdaAsyncObserver : IAsyncObserver - { - private readonly Func> _onNextAsync; - private readonly Func? _onErrorAsync; - private readonly Func? _onCompletedAsync; - - /// - /// Initializes a new instance of the LambdaAsyncObserver class. - /// - /// - public LambdaAsyncObserver( - Func> onNextAsync, - Func? onErrorAsync = null, - Func? onCompletedAsync = null) - { - _onNextAsync = onNextAsync ?? throw new ArgumentNullException(nameof(onNextAsync)); - _onErrorAsync = onErrorAsync; - _onCompletedAsync = onCompletedAsync; - } - - /// - public Task OnCompletedAsync(CancellationToken cancellationToken) - { - return _onCompletedAsync?.Invoke(cancellationToken) ?? Task.CompletedTask; - } - - /// - public Task OnErrorAsync(Exception ex, CancellationToken cancellationToken) - { - return _onErrorAsync?.Invoke(ex, cancellationToken) ?? Task.CompletedTask; - } - - /// - public Task OnNextAsync(T value, CancellationToken cancellationToken) - { - return _onNextAsync(value, cancellationToken); - } - } -} diff --git a/src/NEventStore/Logging/LogFactory.cs b/src/NEventStore/Logging/LogFactory.cs deleted file mode 100644 index 630e4965b..000000000 --- a/src/NEventStore/Logging/LogFactory.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; - -namespace NEventStore.Logging -{ - /// - /// Provides the ability to get a new instance of the configured logger. - /// - public static class LogFactory - { - /// - /// Initializes static members of the LogFactory class. - /// - static LogFactory() - { - BuildLogger = _ => NullLogger.Instance; - } - - /// - /// Gets or sets the log builder of the configured logger. - /// This should be invoked to return a new logging instance. - /// - public static Func BuildLogger { get; set; } - } -} \ No newline at end of file diff --git a/src/NEventStore/LoggingWireupExtensions.cs b/src/NEventStore/LoggingWireupExtensions.cs deleted file mode 100644 index e13c4ad80..000000000 --- a/src/NEventStore/LoggingWireupExtensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore -{ - /// - /// Provides extension methods to configure logging. - /// - public static class LoggingWireupExtensions - { - /// - /// Configures NEventStore to use the specified logger factory. - /// - public static Wireup WithLoggerFactory(this Wireup wireup, ILoggerFactory loggerFactory) - { - return wireup.LogTo(type => loggerFactory.CreateLogger(type)); - } - - /// - /// Configures NEventStore to use the specified logger. - /// - public static Wireup LogTo(this Wireup wireup, Func logger) - { - LogFactory.BuildLogger = logger; - return wireup; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Messages.Designer.cs b/src/NEventStore/Messages.Designer.cs deleted file mode 100644 index 1bbad3627..000000000 --- a/src/NEventStore/Messages.Designer.cs +++ /dev/null @@ -1,396 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Adding wireup registration callback.. - /// - internal static string AddingWireupCallback { - get { - return ResourceManager.GetString("AddingWireupCallback", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adding wireup registration for an object instance of type '{0}'.. - /// - internal static string AddingWireupRegistration { - get { - return ResourceManager.GetString("AddingWireupRegistration", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attempting to resolve existing instance.. - /// - internal static string AttemptingToResolveInstance { - get { - return ResourceManager.GetString("AttemptingToResolveInstance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring SQL engine to auto-detect dialect.. - /// - internal static string AutoDetectDialect { - get { - return ResourceManager.GetString("AutoDetectDialect", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Building (and storing) new instance for later calls.. - /// - internal static string BuildingAndStoringNewInstance { - get { - return ResourceManager.GetString("BuildingAndStoringNewInstance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Building the persistence engine.. - /// - internal static string BuildingEngine { - get { - return ResourceManager.GetString("BuildingEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Building new instance.. - /// - internal static string BuildingNewInstance { - get { - return ResourceManager.GetString("BuildingNewInstance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Head CommitSequence [{0}] greater or equal than Attempt BucketId [{1}] - CommitSequence [{2}] - StreamId {3} - StreamRevision {4} - Events Count {5}. - /// - internal static string ConcurrencyExceptionCommitSequence { - get { - return ResourceManager.GetString("ConcurrencyExceptionCommitSequence", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Head StreamRevision [{0}] greater or equal than Attempt BucketId [{1}] - StreamId {2} - StreamRevision {3} - Events Count {4}. - /// - internal static string ConcurrencyExceptionStreamRevision { - get { - return ResourceManager.GetString("ConcurrencyExceptionStreamRevision", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring serializer to compress the serialized payload.. - /// - internal static string ConfiguringCompression { - get { - return ResourceManager.GetString("ConfiguringCompression", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring serializer to encrypt the serialized payload.. - /// - internal static string ConfiguringEncryption { - get { - return ResourceManager.GetString("ConfiguringEncryption", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring persistence engine to enlist in ambient transactions using TransactionScope.. - /// - internal static string ConfiguringEngineEnlistment { - get { - return ResourceManager.GetString("ConfiguringEngineEnlistment", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring persistence engine to initialize.. - /// - internal static string ConfiguringEngineInitialization { - get { - return ResourceManager.GetString("ConfiguringEngineInitialization", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring persistence engine to track performance. - /// - internal static string ConfiguringEnginePerformanceTracking { - get { - return ResourceManager.GetString("ConfiguringEnginePerformanceTracking", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registration configured to resolve a new instance per call.. - /// - internal static string ConfiguringInstancePerCall { - get { - return ResourceManager.GetString("ConfiguringInstancePerCall", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Using SQL connection factory of type '{0}'.. - /// - internal static string ConnectionFactorySpecified { - get { - return ResourceManager.GetString("ConnectionFactorySpecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering SQL dialect of type '{0}'.. - /// - internal static string DialectSpecified { - get { - return ResourceManager.GetString("DialectSpecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Stream: {0} Bucket: {1} Duplicate commit id {2}.. - /// - internal static string DuplicateCommitIdException { - get { - return ResourceManager.GetString("DuplicateCommitIdException", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configuring the store to upconvert events when fetched.. - /// - internal static string EventUpconverterRegistered { - get { - return ResourceManager.GetString("EventUpconverterRegistered", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Will scan for event upconverters from the following assemblies: '{0}'. - /// - internal static string EventUpconvertersLoadedFrom { - get { - return ResourceManager.GetString("EventUpconvertersLoadedFrom", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot only compare {0} with {1}.. - /// - internal static string FailedToCompareCheckpoint { - get { - return ResourceManager.GetString("FailedToCompareCheckpoint", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Initializing the configured persistence engine.. - /// - internal static string InitializingEngine { - get { - return ResourceManager.GetString("InitializingEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The instance provided cannot be null.. - /// - internal static string InstanceCannotBeNull { - get { - return ResourceManager.GetString("InstanceCannotBeNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Persistence engine configured to page every '{0}' records.. - /// - internal static string PagingSpecified { - get { - return ResourceManager.GetString("PagingSpecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering persistence engine of type '{0}'.. - /// - internal static string RegisteringPersistenceEngine { - get { - return ResourceManager.GetString("RegisteringPersistenceEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering wireup instance for service of type '{0}'.. - /// - internal static string RegisteringServiceInstance { - get { - return ResourceManager.GetString("RegisteringServiceInstance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering wireup resolver for service of type '{0}'.. - /// - internal static string RegisteringWireupCallback { - get { - return ResourceManager.GetString("RegisteringWireupCallback", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Resolving instance.. - /// - internal static string ResolvingInstance { - get { - return ResourceManager.GetString("ResolvingInstance", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attempting to resolve instance for service of type '{0}'.. - /// - internal static string ResolvingService { - get { - return ResourceManager.GetString("ResolvingService", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Head CommitSequence [{0}] lesser than Attempt BucketId [{1}] - CommitSequence [{2}] - StreamId {3} - StreamRevision {4} - Events Count {5}. - /// - internal static string StorageExceptionCommitSequence { - get { - return ResourceManager.GetString("StorageExceptionCommitSequence", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Stream EOF: head.StreamRevision [{0}] < attempt.StreamRevision [{1}] - attempt.Events.Count [{2}] - BucketId {3} - StreamId {4} - StreamRevision {5} . - /// - internal static string StorageExceptionEndOfStream { - get { - return ResourceManager.GetString("StorageExceptionEndOfStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Registering stream ID hasher of type '{0}'. - /// - internal static string StreamIdHasherSpecified { - get { - return ResourceManager.GetString("StreamIdHasherSpecified", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Stream not found: StreamId {0} bucket {1}.. - /// - internal static string StreamNotFoundException { - get { - return ResourceManager.GetString("StreamNotFoundException", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The type provided must be registered as an interface rather than as a concrete type, e.g. "container.Register<ISomeService>(instance);".. - /// - internal static string TypeMustBeInterface { - get { - return ResourceManager.GetString("TypeMustBeInterface", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unable to resolve requested instance of type '{0}'.. - /// - internal static string UnableToResolve { - get { - return ResourceManager.GetString("UnableToResolve", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Wrapping serializer of type '{0}' in RijndaelSerializer.. - /// - internal static string WrappingSerializerEncryption { - get { - return ResourceManager.GetString("WrappingSerializerEncryption", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Wrapping serializer of type '{0}' in GZipSerializer.. - /// - internal static string WrappingSerializerGZip { - get { - return ResourceManager.GetString("WrappingSerializerGZip", resourceCulture); - } - } - } -} diff --git a/src/NEventStore/Messages.resx b/src/NEventStore/Messages.resx deleted file mode 100644 index eef77689c..000000000 --- a/src/NEventStore/Messages.resx +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The instance provided cannot be null. - - - The type provided must be registered as an interface rather than as a concrete type, e.g. "container.Register<ISomeService>(instance);". - - - Adding wireup registration for an object instance of type '{0}'. - - - Adding wireup registration callback. - - - Registration configured to resolve a new instance per call. - - - Resolving instance. - - - Building new instance. - - - Attempting to resolve existing instance. - - - Building (and storing) new instance for later calls. - - - Registering wireup resolver for service of type '{0}'. - - - Registering wireup instance for service of type '{0}'. - - - Attempting to resolve instance for service of type '{0}'. - - - Unable to resolve requested instance of type '{0}'. - - - Registering persistence engine of type '{0}'. - - - Configuring persistence engine to initialize. - - - Configuring persistence engine to enlist in ambient transactions using TransactionScope. - - - Building the persistence engine. - - - Initializing the configured persistence engine. - - - Configuring serializer to compress the serialized payload. - - - Wrapping serializer of type '{0}' in GZipSerializer. - - - Configuring serializer to encrypt the serialized payload. - - - Wrapping serializer of type '{0}' in RijndaelSerializer. - - - Configuring SQL engine to auto-detect dialect. - - - Persistence engine configured to page every '{0}' records. - - - Registering SQL dialect of type '{0}'. - - - Using SQL connection factory of type '{0}'. - - - Configuring the store to upconvert events when fetched. - - - Will scan for event upconverters from the following assemblies: '{0}' - - - Configuring persistence engine to track performance - - - Cannot only compare {0} with {1}. - - - Registering stream ID hasher of type '{0}' - - - Head CommitSequence [{0}] greater or equal than Attempt BucketId [{1}] - CommitSequence [{2}] - StreamId {3} - StreamRevision {4} - Events Count {5} - - - Head StreamRevision [{0}] greater or equal than Attempt BucketId [{1}] - StreamId {2} - StreamRevision {3} - Events Count {4} - - - Stream: {0} Bucket: {1} Duplicate commit id {2}. - - - Head CommitSequence [{0}] lesser than Attempt BucketId [{1}] - CommitSequence [{2}] - StreamId {3} - StreamRevision {4} - Events Count {5} - - - Stream EOF: head.StreamRevision [{0}] < attempt.StreamRevision [{1}] - attempt.Events.Count [{2}] - BucketId {3} - StreamId {4} - StreamRevision {5} - - - Stream not found: StreamId {0} bucket {1}. - - \ No newline at end of file diff --git a/src/NEventStore/NEventStore.Core.csproj b/src/NEventStore/NEventStore.Core.csproj deleted file mode 100644 index 521e7d9b4..000000000 --- a/src/NEventStore/NEventStore.Core.csproj +++ /dev/null @@ -1,95 +0,0 @@ - - - netstandard2.0;net462 - false - NEventStore - NEventStore - false - TRACE;DEBUG - - - NEventStore - NEventStore - NEventStore Dev Team - http://neventstore.org - false - The purpose of the EventStore is to represent a series of events as a stream. NEventStore is a persistence agnostic event sourcing library for .NET. The primary use is most often associated with CQRS. - events, event sourcing, cqrs, storage, persistence, database - - True - true - true - snupkg - true - true - True - True - NEventStore Dev Team - icon.png - Readme.md - https://github.com/NEventStore/NEventStore - git - license.txt - True - True - latest-recommended - - - - - - - - - True - \ - - - True - \ - - - True - \ - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - True - True - Messages.resx - - - True - True - Resources.resx - - - True - True - Messages.resx - - - - - ResXFileCodeGenerator - Messages.Designer.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - - - ResXFileCodeGenerator - Messages.Designer.cs - - - \ No newline at end of file diff --git a/src/NEventStore/NanoContainer.cs b/src/NEventStore/NanoContainer.cs deleted file mode 100644 index 2d19ed3f0..000000000 --- a/src/NEventStore/NanoContainer.cs +++ /dev/null @@ -1,175 +0,0 @@ -using NEventStore.Logging; -using Microsoft.Extensions.Logging; - -namespace NEventStore -{ - /// - /// Represents a simple IoC container. - /// - public class NanoContainer - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(NanoContainer)); - - private readonly Dictionary _registrations = []; - - /// - /// Registers a service with the container. - /// - public virtual ContainerRegistration Register(Func resolve) - where TService : class - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.RegisteringWireupCallback, typeof(TService)); - } - var registration = new ContainerRegistration(c => resolve(c)); - _registrations[typeof(TService)] = registration; - return registration; - } - - /// - /// Registers a service instance with the container. - /// - /// - /// - public virtual ContainerRegistration Register(TService instance) - { - if (Equals(instance, null)) - { - throw new ArgumentNullException(nameof(instance), Messages.InstanceCannotBeNull); - } - - if (!typeof(TService).IsValueType && !typeof(TService).IsInterface) - { - throw new ArgumentException(Messages.TypeMustBeInterface, nameof(instance)); - } - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.RegisteringServiceInstance, typeof(TService)); - } - var registration = new ContainerRegistration(instance); - _registrations[typeof(TService)] = registration; - return registration; - } - - /// - /// Resolves a service from the container. - /// - public virtual TService? Resolve() - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.ResolvingService, typeof(TService)); - } - - if (_registrations.TryGetValue(typeof(TService), out ContainerRegistration registration)) - { - var obj = registration.Resolve(this); - return obj != null ? (TService)obj : default; - } - - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.UnableToResolve, typeof(TService)); - } - return default; - } - } - - /// - /// Represents a registration in the container. - /// - public class ContainerRegistration - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(ContainerRegistration)); - private readonly Func? _resolve; - private object? _instance; - private bool _instancePerCall; - - /// - /// Initializes a new instance of the ContainerRegistration class. - /// - public ContainerRegistration(Func resolve) - { - if (resolve is null) - { - throw new ArgumentNullException(nameof(resolve)); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.AddingWireupCallback); - } - _resolve = resolve; - } - - /// - /// Initializes a new instance of the ContainerRegistration class. - /// - public ContainerRegistration(object instance) - { - if (instance is null) - { - throw new ArgumentNullException(nameof(instance)); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.AddingWireupRegistration, instance.GetType()); - } - _instance = instance; - } - - /// - /// Configures the registration to be resolved once per call. - /// - public virtual ContainerRegistration InstancePerCall() - { - if (_resolve == null) - { - throw new InvalidOperationException("Cannot configure InstancePerCall() on instance registrations."); - } - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.ConfiguringInstancePerCall); - } - _instancePerCall = true; - return this; - } - - /// - /// Resolves the registration. - /// - public virtual object? Resolve(NanoContainer container) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.ResolvingInstance); - } - if (_instancePerCall) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.BuildingNewInstance); - } - return _resolve!(container); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.AttemptingToResolveInstance); - } - - if (_instance != null) - { - return _instance; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.BuildingAndStoringNewInstance); - } - return _instance = _resolve!(container); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/OptimisticEventStore.cs b/src/NEventStore/OptimisticEventStore.cs deleted file mode 100644 index 6a81ed99e..000000000 --- a/src/NEventStore/OptimisticEventStore.cs +++ /dev/null @@ -1,297 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// An implementation of a store that supports optimistic concurrency. - /// - public class OptimisticEventStore : IStoreEvents, ICommitEvents, ICommitEventsAsync - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(OptimisticEventStore)); - private readonly IPersistStreams _persistence; - private readonly IEnumerable _pipelineHooks; - private readonly IEnumerable _pipelineHooksAsync; - - /// - public virtual IPersistStreams Advanced { get => _persistence; } - - /// - /// Initializes a new instance of the OptimisticEventStore class. - /// - /// - public OptimisticEventStore(IPersistStreams persistence, IEnumerable? pipelineHooks, IEnumerable? pipelineHooksAsync) - { - if (persistence == null) - { - throw new ArgumentNullException(nameof(persistence)); - } - - _pipelineHooks = pipelineHooks ?? []; - _pipelineHooksAsync = pipelineHooksAsync ?? []; - if (_pipelineHooks.Any() || _pipelineHooksAsync.Any()) - { - _persistence = new PipelineHooksAwarePersistStreamsDecorator(persistence, _pipelineHooks, _pipelineHooksAsync); - } - else - { - _persistence = persistence; - } - } - - /// - public virtual IEnumerable GetFrom(string bucketId, string streamId, int minRevision, int maxRevision) - { - return _persistence.GetFrom(bucketId, streamId, minRevision, maxRevision); - } - - /// - /// - /// Pipeline hooks can prevent commits to be persisted by returning false from the PreCommit method. - /// If the pipeline hook prevents the commit from being persisted, the commit will not be persisted and null will be returned. - /// - public virtual ICommit? Commit(CommitAttempt attempt) - { - Guard.NotNull(() => attempt, attempt); - foreach (var hook in _pipelineHooks) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType()); - } - if (hook.PreCommit(attempt)) - { - continue; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId); - } - return null; - } - foreach (var hook in _pipelineHooksAsync) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType()); - } - if (hook.PreCommitAsync(attempt, CancellationToken.None).GetAwaiter().GetResult()) - { - continue; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId); - } - return null; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.CommittingAttempt, attempt.CommitId, attempt.Events?.Count ?? 0); - } - var commit = _persistence.Commit(attempt); - - if (commit != null) - { - foreach (var hook in _pipelineHooks) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType()); - } - hook.PostCommit(commit); - } - foreach (var hook in _pipelineHooksAsync) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType()); - } - hook.PostCommitAsync(commit, CancellationToken.None).GetAwaiter().GetResult(); - } - } - return commit; - } - - /// - public virtual Task GetFromAsync(string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken) - { - return _persistence.GetFromAsync(bucketId, streamId, minRevision, maxRevision, observer, cancellationToken); - } - - /// - /// - /// Pipeline hooks can prevent commits to be persisted by returning false from the PreCommit method. - /// If the pipeline hook prevents the commit from being persisted, the commit will not be persisted and null will be returned. - /// - public async Task CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken) - { - Guard.NotNull(() => attempt, attempt); - foreach (var hook in _pipelineHooks) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType()); - } - if (hook.PreCommit(attempt)) - { - continue; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId); - } - return null; - } - foreach (var hook in _pipelineHooksAsync) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPreCommitHooks, attempt.CommitId, hook.GetType()); - } - if (await hook.PreCommitAsync(attempt, cancellationToken).ConfigureAwait(false)) - { - continue; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.CommitRejectedByPipelineHook, hook.GetType(), attempt.CommitId); - } - return null; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.CommittingAttempt, attempt.CommitId, attempt.Events?.Count ?? 0); - } - var commit = await _persistence.CommitAsync(attempt, cancellationToken).ConfigureAwait(false); - - if (commit != null) - { - foreach (var hook in _pipelineHooks) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType()); - } - hook.PostCommit(commit); - } - foreach (var hook in _pipelineHooksAsync) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.InvokingPostCommitPipelineHooks, attempt.CommitId, hook.GetType()); - } - await hook.PostCommitAsync(commit, cancellationToken).ConfigureAwait(false); - } - } - return commit; - } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - public virtual IEventStream CreateStream(string bucketId, string streamId) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.CreatingStream, streamId, bucketId); - } - return new OptimisticEventStream(bucketId, streamId, this, this); - } - - /// - public virtual IEventStream OpenStream(string bucketId, string streamId, int minRevision, int maxRevision) - { - maxRevision = maxRevision <= 0 ? int.MaxValue : maxRevision; - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.OpeningStreamAtRevision, streamId, bucketId, minRevision, maxRevision); - } - var stream = new OptimisticEventStream(bucketId, streamId, this, this); - stream.Initialize(minRevision, maxRevision); - return stream; - } - - /// - public async Task OpenStreamAsync(string bucketId, string streamId, int minRevision, int maxRevision, CancellationToken cancellationToken) - { - maxRevision = maxRevision <= 0 ? int.MaxValue : maxRevision; - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.OpeningStreamAtRevision, streamId, bucketId, minRevision, maxRevision); - } - var stream = new OptimisticEventStream(bucketId, streamId, this, this); - await stream.InitializeAsync(minRevision, maxRevision, cancellationToken).ConfigureAwait(false); - return stream; - } - - /// - public virtual IEventStream OpenStream(ISnapshot snapshot, int maxRevision) - { - if (snapshot == null) - { - throw new ArgumentNullException(nameof(snapshot)); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.OpeningStreamWithSnapshot, snapshot.StreamId, snapshot.BucketId, snapshot.StreamRevision, maxRevision); - } - maxRevision = maxRevision <= 0 ? int.MaxValue : maxRevision; - var stream = new OptimisticEventStream(snapshot.BucketId, snapshot.StreamId, this, this); - stream.Initialize(snapshot, maxRevision); - return stream; - } - - /// - public async Task OpenStreamAsync(ISnapshot snapshot, int maxRevision, CancellationToken cancellationToken) - { - if (snapshot == null) - { - throw new ArgumentNullException(nameof(snapshot)); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.OpeningStreamWithSnapshot, snapshot.StreamId, snapshot.BucketId, snapshot.StreamRevision, maxRevision); - } - maxRevision = maxRevision <= 0 ? int.MaxValue : maxRevision; - var stream = new OptimisticEventStream(snapshot.BucketId, snapshot.StreamId, this, this); - await stream.InitializeAsync(snapshot, maxRevision, cancellationToken).ConfigureAwait(false); - return stream; - } - - /// - protected virtual void Dispose(bool disposing) - { - if (!disposing) - { - return; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.ShuttingDownStore); - } - _persistence.Dispose(); - foreach (var hook in _pipelineHooks) - { - hook.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/OptimisticEventStream.cs b/src/NEventStore/OptimisticEventStream.cs deleted file mode 100644 index a6de10733..000000000 --- a/src/NEventStore/OptimisticEventStream.cs +++ /dev/null @@ -1,481 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore -{ - /// - /// Represents a stream of events that can be committed and appended to. - /// - [SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix", - Justification = "This behaves like a stream--not a .NET 'Stream' object, but a stream nonetheless.")] - public sealed class OptimisticEventStream : IEventStream - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(OptimisticEventStream)); - private readonly ICollection _committed = new LinkedList(); - private readonly ImmutableCollection _committedImmutableWrapper; - private readonly Dictionary _committedHeaders = []; - private readonly ImmutableDictionary _committedHeadersImmutableWrapper; - private readonly ICollection _events = new LinkedList(); - private readonly ImmutableCollection _eventsImmutableWrapper; - private readonly HashSet _identifiers = []; - private readonly ICommitEvents _persistence; - private readonly ICommitEventsAsync _persistenceAsync; - private bool _disposed; - // a stream is considered partial if we haven't read all the events in a commit - private bool _isPartialStream; - - /// - public string BucketId { get; } - /// - public string StreamId { get; } - /// - public int StreamRevision { get; private set; } - /// - public int CommitSequence { get; private set; } - /// - public ICollection CommittedEvents { get => _committedImmutableWrapper; } - /// - public IDictionary CommittedHeaders { get => _committedHeadersImmutableWrapper; } - /// - public ICollection UncommittedEvents { get => _eventsImmutableWrapper; } - /// - public IDictionary UncommittedHeaders { get; } = new Dictionary(); - - /// - /// Create a new instance of the OptimisticEventStream class. - /// - public OptimisticEventStream(string bucketId, string streamId, ICommitEvents persistence, ICommitEventsAsync persistenceAsync) - { - if (string.IsNullOrWhiteSpace(bucketId)) - { - throw new ArgumentException($"'{nameof(bucketId)}' cannot be null or whitespace.", nameof(bucketId)); - } - - if (string.IsNullOrWhiteSpace(streamId)) - { - throw new ArgumentException($"'{nameof(streamId)}' cannot be null or whitespace.", nameof(streamId)); - } - - BucketId = bucketId; - StreamId = streamId; - _persistence = persistence ?? throw new ArgumentNullException(nameof(persistence)); - _persistenceAsync = persistenceAsync ?? throw new ArgumentNullException(nameof(persistenceAsync)); - _committedImmutableWrapper = new ImmutableCollection(_committed); - _eventsImmutableWrapper = new ImmutableCollection(_events); - _committedHeadersImmutableWrapper = new ImmutableDictionary(_committedHeaders); - } - - private void EnsureStreamIsNew() - { - if (_committed.Count > 0 || _events.Count > 0) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Cannot call Initialize on a stream already used: Bucked: {0}, Stream: {1}, Committed Events: {2}, New Events: {3}", BucketId, StreamId, _committed.Count, _events.Count)); - } - } - - /// - /// Initializes a new instance of the OptimisticEventStream class. - /// - /// - /// - public void Initialize(int minRevision, int maxRevision) - { - EnsureStreamIsNew(); - IEnumerable commits = _persistence.GetFrom(BucketId, StreamId, minRevision, maxRevision); - PopulateStream(minRevision, maxRevision, commits); - - if (minRevision > 0 && _committed.Count == 0) - { - throw new StreamNotFoundException(String.Format(CultureInfo.InvariantCulture, Messages.StreamNotFoundException, StreamId, BucketId)); - } - } - - /// - /// Initializes a new instance of the OptimisticEventStream class. - /// - /// - /// - public async Task InitializeAsync(int minRevision, int maxRevision, CancellationToken cancellationToken) - { - EnsureStreamIsNew(); - _isPartialStream = false; - var observer = new LambdaAsyncObserver( - onNextAsync: (commit, _) => - { - InnerPopulateStream(minRevision, maxRevision, commit); - return Task.FromResult(true); - }); - await _persistenceAsync.GetFromAsync(BucketId, StreamId, minRevision, maxRevision, observer, cancellationToken).ConfigureAwait(false); - - if (minRevision > 0 && _committed.Count == 0) - { - throw new StreamNotFoundException(String.Format(CultureInfo.InvariantCulture, Messages.StreamNotFoundException, StreamId, BucketId)); - } - } - - private void EnsureSnapshotIsForThisStream(ISnapshot snapshot) - { - if (BucketId != snapshot.BucketId || StreamId != snapshot.StreamId) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "The snapshot is for a different stream. Stream BucketId: {0}, StreamId: {1}; Snapshot BucketId: {2}, StreamId: {3}", BucketId, StreamId, snapshot.BucketId, snapshot.StreamId)); - } - } - - /// - /// Initializes a new instance of the OptimisticEventStream class. - /// - /// - /// - public void Initialize(ISnapshot snapshot, int maxRevision) - { - if (snapshot is null) - { - throw new ArgumentNullException(nameof(snapshot)); - } - EnsureSnapshotIsForThisStream(snapshot); - EnsureStreamIsNew(); - IEnumerable commits = _persistence.GetFrom(snapshot.BucketId, snapshot.StreamId, snapshot.StreamRevision, maxRevision); - PopulateStream(snapshot.StreamRevision + 1, maxRevision, commits); - StreamRevision = snapshot.StreamRevision + _committed.Count; - } - - /// - /// Initializes a new instance of the OptimisticEventStream class. - /// - /// - /// - public async Task InitializeAsync(ISnapshot snapshot, int maxRevision, CancellationToken cancellationToken) - { - if (snapshot is null) - { - throw new ArgumentNullException(nameof(snapshot)); - } - EnsureSnapshotIsForThisStream(snapshot); - EnsureStreamIsNew(); - int minRevision = snapshot.StreamRevision + 1; - _isPartialStream = false; - var observer = new LambdaAsyncObserver( - onNextAsync: (commit, _) => - { - InnerPopulateStream(minRevision, maxRevision, commit); - return Task.FromResult(true); - }); - await _persistenceAsync.GetFromAsync(snapshot.BucketId, snapshot.StreamId, snapshot.StreamRevision, maxRevision, observer, cancellationToken).ConfigureAwait(false); - StreamRevision = snapshot.StreamRevision + _committed.Count; - } - - /// - public void Add(EventMessage uncommittedEvent) - { - if (uncommittedEvent == null) - { - throw new ArgumentNullException(nameof(uncommittedEvent)); - } - - if (uncommittedEvent.Body == null) - { - throw new ArgumentException(nameof(uncommittedEvent.Body)); - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.AppendingUncommittedToStream, uncommittedEvent.Body.GetType(), StreamId, BucketId); - } - _events.Add(uncommittedEvent); - } - - /// - public ICommit? CommitChanges(Guid commitId) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.AttemptingToCommitChanges, StreamId, BucketId); - } - - if (_isPartialStream) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.CannotAddCommitsToPartiallyLoadedStream, StreamId, BucketId, StreamRevision); - } - - RefreshStreamAfterConcurrencyException(); - - throw new ConcurrencyException(string.Format( - CultureInfo.InvariantCulture, - Resources.CannotAddCommitsToPartiallyLoadedStream, - StreamId, - BucketId, - StreamRevision - )); - } - - if (_identifiers.Contains(commitId)) - { - throw new DuplicateCommitException(String.Format(CultureInfo.InvariantCulture, Messages.DuplicateCommitIdException, StreamId, BucketId, commitId)); - } - - if (!HasChanges()) - { - return null; - } - - try - { - return PersistChanges(commitId); - } - catch (ConcurrencyException cex) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.UnderlyingStreamHasChanged, StreamId, BucketId, cex.Message); - } - - RefreshStreamAfterConcurrencyException(); - - throw; - } - } - - /// - public async Task CommitChangesAsync(Guid commitId, CancellationToken cancellationToken) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.AttemptingToCommitChanges, StreamId, BucketId); - } - - if (_isPartialStream) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.CannotAddCommitsToPartiallyLoadedStream, StreamId, BucketId, StreamRevision); - } - - await RefreshStreamAfterConcurrencyExceptionAsync(cancellationToken).ConfigureAwait(false); - - throw new ConcurrencyException(string.Format( - CultureInfo.InvariantCulture, - Resources.CannotAddCommitsToPartiallyLoadedStream, - StreamId, - BucketId, - StreamRevision - )); - } - - if (_identifiers.Contains(commitId)) - { - throw new DuplicateCommitException(String.Format(CultureInfo.InvariantCulture, Messages.DuplicateCommitIdException, StreamId, BucketId, commitId)); - } - - if (!HasChanges()) - { - return null; - } - - try - { - return await PersistChangesAsync(commitId, cancellationToken).ConfigureAwait(false); - } - catch (ConcurrencyException cex) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.UnderlyingStreamHasChanged, StreamId, BucketId, cex.Message); - } - - await RefreshStreamAfterConcurrencyExceptionAsync(cancellationToken).ConfigureAwait(false); - - throw; - } - } - - private void RefreshStreamAfterConcurrencyException() - { - int refreshFromRevision = StreamRevision + 1; - IEnumerable commits = _persistence.GetFrom(BucketId, StreamId, refreshFromRevision, int.MaxValue); - PopulateStream(refreshFromRevision, int.MaxValue, commits); - } - - private Task RefreshStreamAfterConcurrencyExceptionAsync(CancellationToken cancellationToken) - { - int refreshFromRevision = StreamRevision + 1; - const int maxRevision = int.MaxValue; - _isPartialStream = false; - var observer = new LambdaAsyncObserver( - onNextAsync: (commit, _) => - { - InnerPopulateStream(refreshFromRevision, maxRevision, commit); - return Task.FromResult(true); - }); - return _persistenceAsync.GetFromAsync(BucketId, StreamId, refreshFromRevision, maxRevision, observer, cancellationToken); - } - - /// - public void ClearChanges() - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.ClearingUncommittedChanges, StreamId, BucketId); - } - _events.Clear(); - UncommittedHeaders.Clear(); - } - - private void PopulateStream(int minRevision, int maxRevision, ICommit commit) - { - _isPartialStream = false; - InnerPopulateStream(minRevision, maxRevision, commit); - } - - private void PopulateStream(int minRevision, int maxRevision, IEnumerable commits) - { - _isPartialStream = false; - foreach (var commit in commits ?? []) - { - InnerPopulateStream(minRevision, maxRevision, commit); - } - } - - private void InnerPopulateStream(int minRevision, int maxRevision, ICommit commit) - { - _identifiers.Add(commit.CommitId); - - int currentRevision = commit.StreamRevision - commit.Events.Count + 1; - // just in case the persistence returned more commits than it should be - if (currentRevision > maxRevision) - { - _isPartialStream = true; - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.IgnoringBeyondRevision, commit.CommitId, StreamId, maxRevision); - } - return; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.AddingCommitsToStream, commit.CommitId, commit.Events.Count, StreamId, BucketId); - } - - CommitSequence = commit.CommitSequence; - - CopyToCommittedHeaders(commit); - CopyToEvents(minRevision, maxRevision, currentRevision, commit); - } - - private void CopyToCommittedHeaders(ICommit commit) - { - foreach (var key in commit.Headers.Keys) - { - _committedHeaders[key] = commit.Headers[key]; - } - } - - private void CopyToEvents(int minRevision, int maxRevision, int currentRevision, ICommit commit) - { - foreach (var @event in commit.Events) - { - if (currentRevision > maxRevision) - { - _isPartialStream = true; - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.IgnoringBeyondRevision, commit.CommitId, StreamId, maxRevision); - } - break; - } - - if (currentRevision++ < minRevision) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.IgnoringBeforeRevision, commit.CommitId, StreamId, maxRevision); - } - continue; - } - - _committed.Add(@event); - StreamRevision = currentRevision - 1; - } - } - - private bool HasChanges() - { - if (_disposed) - { - throw new ObjectDisposedException(Resources.AlreadyDisposed); - } - - if (_events.Count > 0) - { - return true; - } - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.NoChangesToCommit, StreamId, BucketId); - } - return false; - } - - private ICommit? PersistChanges(Guid commitId) - { - CommitAttempt attempt = BuildCommitAttempt(commitId); - - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.PersistingCommit, commitId, StreamId, BucketId, attempt.Events?.Count ?? 0); - } - var commit = _persistence.Commit(attempt); - if (commit != null) - { - PopulateStream(StreamRevision + 1, attempt.StreamRevision, commit); - ClearChanges(); - } - return commit; - } - - private async Task PersistChangesAsync(Guid commitId, CancellationToken cancellationToken) - { - CommitAttempt attempt = BuildCommitAttempt(commitId); - - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.PersistingCommit, commitId, StreamId, BucketId, attempt.Events?.Count ?? 0); - } - var commit = await _persistenceAsync.CommitAsync(attempt, cancellationToken).ConfigureAwait(false); - if (commit != null) - { - PopulateStream(StreamRevision + 1, attempt.StreamRevision, commit); - ClearChanges(); - } - return commit; - } - - private CommitAttempt BuildCommitAttempt(Guid commitId) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.BuildingCommitAttempt, commitId, StreamId, BucketId); - } - return new CommitAttempt( - BucketId, - StreamId, - StreamRevision + _events.Count, - commitId, - CommitSequence + 1, - SystemTime.UtcNow, - UncommittedHeaders.ToDictionary(x => x.Key, x => x.Value), - _events.ToArray()); // check this for performance: pre-allocate the array size. - } - - /// - public void Dispose() - { - _disposed = true; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/OptimisticPipelineHook.cs b/src/NEventStore/OptimisticPipelineHook.cs deleted file mode 100644 index 75338a36a..000000000 --- a/src/NEventStore/OptimisticPipelineHook.cs +++ /dev/null @@ -1,303 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; -using NEventStore.Persistence; -using System.Globalization; - -namespace NEventStore -{ - /// - /// Tracks the heads of streams to reduce latency by avoiding roundtrips to storage. - /// - public class OptimisticPipelineHook : PipelineHookBase - { - internal const int MaxStreamsToTrack = 100; - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(OptimisticPipelineHook)); - private readonly Dictionary _heads = []; //TODO use concurrent collections - private readonly LinkedList _maxItemsToTrack = new(); - private readonly int _maxStreamsToTrack; - - /// - /// Initializes a new instance of the OptimisticPipelineHook class. - /// - public OptimisticPipelineHook() - : this(MaxStreamsToTrack) - { } - - /// - /// Initializes a new instance of the OptimisticPipelineHook class. - /// - public OptimisticPipelineHook(int maxStreamsToTrack) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.TrackingStreams, maxStreamsToTrack); - } - _maxStreamsToTrack = maxStreamsToTrack; - } - - /// - public override ICommit? SelectCommit(ICommit committed) - { - Track(committed); - return committed; - } - - /// - public override bool PreCommit(CommitAttempt attempt) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.OptimisticConcurrencyCheck, attempt.StreamId); - } - - ICommit head = GetStreamHead(GetHeadKey(attempt)); - if (head == null) - { - return true; - } - - if (head.CommitSequence >= attempt.CommitSequence) - { - throw new ConcurrencyException(String.Format( - CultureInfo.InvariantCulture, - Messages.ConcurrencyExceptionCommitSequence, - head.CommitSequence, - attempt.BucketId, - attempt.CommitSequence, - attempt.StreamId, - attempt.StreamRevision, - attempt.Events.Count - )); - } - - if (head.StreamRevision >= attempt.StreamRevision) - { - throw new ConcurrencyException(String.Format( - CultureInfo.InvariantCulture, - Messages.ConcurrencyExceptionStreamRevision, - head.StreamRevision, - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.Events.Count - )); - } - - if (head.CommitSequence < attempt.CommitSequence - 1) - { - throw new StorageException(String.Format( - CultureInfo.InvariantCulture, - Messages.StorageExceptionCommitSequence, - head.CommitSequence, - attempt.BucketId, - attempt.CommitSequence, - attempt.StreamId, - attempt.StreamRevision, - attempt.Events.Count - )); // beyond the end of the stream - } - - if (head.StreamRevision < attempt.StreamRevision - attempt.Events.Count) - { - throw new StorageException(String.Format( - CultureInfo.InvariantCulture, - Messages.StorageExceptionEndOfStream, - head.StreamRevision, - attempt.StreamRevision, - attempt.Events.Count, - attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision - )); // beyond the end of the stream - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.NoConflicts, attempt.StreamId, attempt.BucketId); - } - return true; - } - - /// - public override void PostCommit(ICommit committed) - { - Track(committed); - } - - /// - public override void OnPurge(string? bucketId) - { - lock (_maxItemsToTrack) - { - if (bucketId == null) - { - _heads.Clear(); - _maxItemsToTrack.Clear(); - return; - } - HeadKey[] headsInBucket = _heads.Keys.Where(k => k.BucketId == bucketId).ToArray(); - foreach (var head in headsInBucket) - { - RemoveHead(head); - } - } - } - - /// - public override void OnDeleteStream(string bucketId, string streamId) - { - lock (_maxItemsToTrack) - { - RemoveHead(new HeadKey(bucketId, streamId)); - } - } - - /// - protected override void Dispose(bool disposing) - { - _heads.Clear(); - _maxItemsToTrack.Clear(); - base.Dispose(disposing); - } - - /// - public void Track(ICommit committed) - { - if (committed == null) - { - return; - } - - lock (_maxItemsToTrack) - { - UpdateStreamHead(committed); - TrackUpToCapacity(committed); - } - } - - private void UpdateStreamHead(ICommit committed) - { - HeadKey headKey = GetHeadKey(committed); - ICommit head = GetStreamHead(headKey); - if (AlreadyTracked(head)) - { - _maxItemsToTrack.Remove(headKey); - } - - head ??= committed; - head = head.StreamRevision > committed.StreamRevision ? head : committed; - - _heads[headKey] = head; - } - - private void RemoveHead(HeadKey head) - { - _heads.Remove(head); - LinkedListNode node = _maxItemsToTrack.Find(head); // There should only be ever one or none - if (node != null) - { - _maxItemsToTrack.Remove(node); - } - } - - private static bool AlreadyTracked(ICommit head) - { - return head != null; - } - - private void TrackUpToCapacity(ICommit committed) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.TrackingCommit, committed.CommitSequence, committed.StreamId, committed.BucketId); - } - _maxItemsToTrack.AddFirst(GetHeadKey(committed)); - if (_maxItemsToTrack.Count <= _maxStreamsToTrack) - { - return; - } - - HeadKey expired = _maxItemsToTrack.Last.Value; - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Resources.NoLongerTrackingStream, expired.StreamId, expired.BucketId); - } - - _heads.Remove(expired); - _maxItemsToTrack.RemoveLast(); - } - - /// - public bool Contains(ICommit attempt) - { - return GetStreamHead(GetHeadKey(attempt)) != null; - } - - private ICommit GetStreamHead(HeadKey headKey) - { - lock (_maxItemsToTrack) - { - _heads.TryGetValue(headKey, out ICommit head); - return head; - } - } - - private static HeadKey GetHeadKey(ICommit commit) - { - return new HeadKey(commit.BucketId, commit.StreamId); - } - - private static HeadKey GetHeadKey(CommitAttempt commitAttempt) - { - return new HeadKey(commitAttempt.BucketId, commitAttempt.StreamId); - } - - private sealed class HeadKey : IEquatable - { - public string BucketId { get; } - - public string StreamId { get; } - - public HeadKey(string bucketId, string streamId) - { - BucketId = bucketId; - StreamId = streamId; - } - - public bool Equals(HeadKey other) - { - if (other is null) - { - return false; - } - if (ReferenceEquals(this, other)) - { - return true; - } - return String.Equals(BucketId, other.BucketId, StringComparison.Ordinal) - && String.Equals(StreamId, other.StreamId, StringComparison.Ordinal); - } - - public override bool Equals(object obj) - { - if (obj is null) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return obj is HeadKey headKey && Equals(headKey); - } - - public override int GetHashCode() - { - unchecked - { - return (BucketId.GetHashCode() * 397) ^ StreamId.GetHashCode(); - } - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/Commit.cs b/src/NEventStore/Persistence/Commit.cs deleted file mode 100644 index ee7ab08e6..000000000 --- a/src/NEventStore/Persistence/Commit.cs +++ /dev/null @@ -1,67 +0,0 @@ -#pragma warning disable RCS1170 // Use read-only auto-implemented property. - -namespace NEventStore.Persistence -{ - /// - /// Represents a commit to the event store. - /// - public class Commit : ICommit - { - /// - /// Initializes a new instance of the Commit class. - /// - public Commit( - string bucketId, - string streamId, - int streamRevision, - Guid commitId, - int commitSequence, - DateTime commitStamp, - Int64 checkpointToken, - IDictionary? headers, - ICollection? events) - { - BucketId = bucketId; - StreamId = streamId; - StreamRevision = streamRevision; - CommitId = commitId; - CommitSequence = commitSequence; - CommitStamp = commitStamp; - CheckpointToken = checkpointToken; - Headers = headers ?? new Dictionary(); - Events = events ?? Array.Empty(); - //Events = events == null ? - // new ReadOnlyCollection(new List()) : - // new ReadOnlyCollection(new List(events)); - } - - /// - public string BucketId { get; private set; } - - /// - public string StreamId { get; private set; } - - /// - public int StreamRevision { get; private set; } - - /// - public Guid CommitId { get; private set; } - - /// - public int CommitSequence { get; private set; } - - /// - public DateTime CommitStamp { get; private set; } - - /// - public IDictionary Headers { get; private set; } - - /// - public ICollection Events { get; private set; } - - /// - public Int64 CheckpointToken { get; private set; } - } -} - -#pragma warning restore RCS1170 // Use read-only auto-implemented property. \ No newline at end of file diff --git a/src/NEventStore/Persistence/IPersistStreams.cs b/src/NEventStore/Persistence/IPersistStreams.cs deleted file mode 100644 index a8d3b93c6..000000000 --- a/src/NEventStore/Persistence/IPersistStreams.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Indicates the ability to adapt the underlying persistence infrastructure to behave like a stream of events. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPersistStreams : IDisposable - , IPersistStreamsSync - , IPersistStreamsAsync - { - /// - /// Gets a value indicating whether this instance has been disposed of. - /// - bool IsDisposed { get; } - - /// - /// Initializes and prepares the storage for use, if not already performed. - /// - /// - /// Store initialization will be synchronous and should be completed before the method returns. - /// This is to ensure that the storage is ready for use before the built storage instance is registered in a container. - /// Another option will be: remove the Wireup.InitializeStorageEngine() method and let the user call Initialize() or InitializeAsync() explicitly. - /// - /// - /// - void Initialize(); - - /// - /// Completely DESTROYS the contents and schema (if applicable) containing ANY and ALL streams that have been - /// successfully persisted. - /// Use with caution. - /// - void Drop(); - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/IPersistStreamsAsync.cs b/src/NEventStore/Persistence/IPersistStreamsAsync.cs deleted file mode 100644 index 9cef3cceb..000000000 --- a/src/NEventStore/Persistence/IPersistStreamsAsync.cs +++ /dev/null @@ -1,80 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Asynchronous Interface: Indicates the ability to adapt the underlying persistence infrastructure to behave like a stream of events. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPersistStreamsAsync : ICommitEventsAsync, IAccessSnapshotsAsync - { - /// - /// Gets all commits (from all the buckets) after the specified checkpoint (excluded). Use 0 to get from the beginning. - /// - /// The checkpoint token: all the commits after this one will be returned. - /// The observer to receive the commits. - /// The token to monitor for cancellation requests. - /// An enumerable of Commits. - /// - /// - Task GetFromAsync(Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default); - - /// - /// Gets all commits (from all the buckets) after the specified checkpoint token (excluded) up to the specified end checkpoint token (included). - /// - /// The checkpoint token: all the commits after this one will be returned - /// The checkpoint token: all the commits tp to this one (included) will be returned - /// The observer to receive the commits. - /// The token to monitor for cancellation requests. - /// All commits that have occurred on or after the specified checkpoint token up to the specified end checkpoint token. - /// - /// - Task GetFromToAsync(Int64 fromCheckpointToken, Int64 toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default); - - /// - /// Gets all commits after the specified checkpoint (excluded) for a specific bucket. Use 0 to get from the beginning. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The checkpoint token: all the commits after this one will be returned - /// The observer to receive the commits. - /// The token to monitor for cancellation requests. - /// An enumerable of Commits. - /// - /// - Task GetFromAsync(string bucketId, Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default); - - /// - /// Gets all commits after the specified checkpoint token (excluded) up to the specified end checkpoint token (included). - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The checkpoint token: all the commits after this one will be returned - /// The checkpoint token: all the commits tp to this one (included) will be returned - /// The observer to receive the commits. - /// The token to monitor for cancellation requests. - /// All commits that have occurred on or after the specified checkpoint token up to the specified end checkpoint token. - /// - /// - Task GetFromToAsync(string bucketId, Int64 fromCheckpointToken, Int64 toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken = default); - - /// - /// Completely DESTROYS the contents of ANY and ALL streams that have been successfully persisted. - /// Use with caution. - /// - Task PurgeAsync(CancellationToken cancellationToken = default); - - /// - /// Completely DESTROYS the contents of ANY and ALL streams that have been successfully persisted - /// in the specified bucket. - /// Use with caution. - /// - Task PurgeAsync(string bucketId, CancellationToken cancellationToken = default); - - /// - /// Deletes a stream. - /// - /// The bucket Id from which the stream is to be deleted. - /// The stream Id of the stream that is to be deleted. - /// The token to monitor for cancellation requests. - Task DeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken = default); - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/IPersistStreamsSync.cs b/src/NEventStore/Persistence/IPersistStreamsSync.cs deleted file mode 100644 index b6f504ded..000000000 --- a/src/NEventStore/Persistence/IPersistStreamsSync.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Synchronous Interface: Indicates the ability to adapt the underlying persistence infrastructure to behave like a stream of events. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPersistStreamsSync : ICommitEvents, IAccessSnapshots - { - /// - /// Gets all commits on or after the specified starting time. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The point in time at which to start. - /// All commits that have occurred on or after the specified starting time. - /// - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFrom(Int64 checkpointToken) instead. This method will be removed in a later version.")] - IEnumerable GetFrom(string bucketId, DateTime startDate); - - /// - /// Gets all commits on or after the specified starting time and before the specified end time. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The point in time at which to start. - /// The point in time at which to end. - /// All commits that have occurred on or after the specified starting time and before the end time. - /// - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) instead. This method will be removed in a later version.")] - IEnumerable GetFromTo(string bucketId, DateTime startDate, DateTime endDate); - - /// - /// Gets all commits (from all the buckets) after the specified checkpoint (excluded). Use 0 to get from the beginning. - /// - /// The checkpoint token: all the commits after this one will be returned. - /// An enumerable of Commits. - /// - /// - IEnumerable GetFrom(Int64 checkpointToken); - - /// - /// Gets all commits (from all the buckets) after the specified checkpoint token (excluded) up to the specified end checkpoint token (included). - /// - /// The checkpoint token: all the commits after this one will be returned - /// The checkpoint token: all the commits tp to this one (included) will be returned - /// All commits that have occurred on or after the specified checkpoint token up to the specified end checkpoint token. - /// - /// - IEnumerable GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken); - - /// - /// Gets all commits after the specified checkpoint (excluded) for a specific bucket. Use 0 to get from the beginning. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The checkpoint token: all the commits after this one will be returned - /// An enumerable of Commits. - /// - /// - IEnumerable GetFrom(string bucketId, Int64 checkpointToken); - - /// - /// Gets all commits after the specified checkpoint token (excluded) up to the specified end checkpoint token (included). - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The checkpoint token: all the commits after this one will be returned - /// The checkpoint token: all the commits tp to this one (included) will be returned - /// All commits that have occurred on or after the specified checkpoint token up to the specified end checkpoint token. - /// - /// - IEnumerable GetFromTo(string bucketId, Int64 fromCheckpointToken, Int64 toCheckpointToken); - - /// - /// Completely DESTROYS the contents of ANY and ALL streams that have been successfully persisted. - /// Use with caution. - /// - void Purge(); - - /// - /// Completely DESTROYS the contents of ANY and ALL streams that have been successfully persisted - /// in the specified bucket. - /// Use with caution. - /// - void Purge(string bucketId); - - /// - /// Deletes a stream. - /// - /// The bucket Id from which the stream is to be deleted. - /// The stream Id of the stream that is to be deleted. - void DeleteStream(string bucketId, string streamId); - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/IPersistenceFactory.cs b/src/NEventStore/Persistence/IPersistenceFactory.cs deleted file mode 100644 index eb4eff4b1..000000000 --- a/src/NEventStore/Persistence/IPersistenceFactory.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Indicates the ability to build a ready-to-use persistence engine. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IPersistenceFactory - { - /// - /// Builds a persistence engine. - /// - /// A ready-to-use persistence engine. - IPersistStreams Build(); - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/IStreamHead.cs b/src/NEventStore/Persistence/IStreamHead.cs deleted file mode 100644 index c70a329ed..000000000 --- a/src/NEventStore/Persistence/IStreamHead.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Indicates the most recent information representing the head of a given stream. - /// - public interface IStreamHead - { - /// - /// Gets the value which uniquely identifies the stream where the last snapshot exceeds the allowed threshold. - /// - string BucketId { get; } - - /// - /// Gets the value which uniquely identifies the stream where the last snapshot exceeds the allowed threshold. - /// - string StreamId { get; } - - /// - /// Gets the value which indicates the revision, length, or number of events committed to the stream. - /// - int HeadRevision { get; } - - /// - /// Gets the value which indicates the revision at which the last snapshot was taken. - /// - int SnapshotRevision { get; } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/InMemory/InMemoryPersistenceEngine.cs b/src/NEventStore/Persistence/InMemory/InMemoryPersistenceEngine.cs deleted file mode 100644 index fbfe3fef9..000000000 --- a/src/NEventStore/Persistence/InMemory/InMemoryPersistenceEngine.cs +++ /dev/null @@ -1,720 +0,0 @@ -using System.Collections.Concurrent; -using System.Globalization; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Persistence.InMemory -{ - /// - /// Represents an in-memory persistence engine. - /// - public class InMemoryPersistenceEngine : IPersistStreams - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(InMemoryPersistenceEngine)); - private readonly ConcurrentDictionary _buckets = new(); - private bool _disposed; - private int _checkpoint; - - private Bucket this[string bucketId] - { - get { return _buckets.GetOrAdd(bucketId, _ => new Bucket()); } - } - - /// - /// Disposes the engine. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Initializes the engine. - /// - public void Initialize() - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.InitializingEngine); - } - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFrom(Int64 checkpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFrom(string bucketId, DateTime startDate) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingAllCommitsFromTime, bucketId, startDate); - } - return this[bucketId].GetFrom(startDate); - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFromTo(string bucketId, DateTime startDate, DateTime endDate) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingAllCommitsFromToTime, startDate, endDate); - } - return this[bucketId].GetFromTo(startDate, endDate); - } - - /// - public IEnumerable GetFrom(Int64 checkpointToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingAllCommitsFromCheckpoint, checkpointToken); - } - return _buckets - .Values - .SelectMany(b => b.GetCommits()) - .Where(c => c.CheckpointToken.CompareTo(checkpointToken) > 0) - .OrderBy(c => c.CheckpointToken) - .ToArray(); - } - - /// - public Task GetFromAsync(Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return ObserveDataStream(() => GetFrom(checkpointToken), asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingCommitsFromToCheckpoint, fromCheckpointToken, toCheckpointToken); - } - return _buckets - .Values - .SelectMany(b => b.GetCommits()) - .Where(c => c.CheckpointToken.CompareTo(fromCheckpointToken) > 0 && c.CheckpointToken.CompareTo(toCheckpointToken) <= 0) - .OrderBy(c => c.CheckpointToken) - .ToArray(); - } - - /// - public Task GetFromToAsync(Int64 fromCheckpointToken, Int64 toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return ObserveDataStream(() => GetFromTo(fromCheckpointToken, toCheckpointToken), asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFrom(string bucketId, Int64 checkpointToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingAllCommitsFromBucketAndCheckpoint, bucketId, checkpointToken); - } - return this[bucketId].GetFrom(checkpointToken); - } - - /// - public Task GetFromAsync(string bucketId, Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return ObserveDataStream(() => GetFrom(bucketId, checkpointToken), asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(string bucketId, Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingCommitsFromBucketAndFromToCheckpoint, bucketId, fromCheckpointToken, toCheckpointToken); - } - return this[bucketId].GetFromTo(fromCheckpointToken, toCheckpointToken); - } - - /// - public Task GetFromToAsync(string bucketId, long fromCheckpointToken, long toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return ObserveDataStream(() => GetFromTo(bucketId, fromCheckpointToken, toCheckpointToken), asyncObserver, cancellationToken); - } - - /// - public IEnumerable GetFrom(string bucketId, string streamId, int minRevision, int maxRevision) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingAllCommitsFromRevision, streamId, bucketId, minRevision, maxRevision); - } - return this[bucketId].GetFrom(streamId, minRevision, maxRevision); - } - - /// - public ICommit? Commit(CommitAttempt attempt) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.AttemptingToCommit, attempt.CommitId, attempt.StreamId, attempt.BucketId, attempt.CommitSequence); - } - return this[attempt.BucketId].Commit(attempt, Interlocked.Increment(ref _checkpoint)); - } - - /// - public Task GetFromAsync(string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken) - { - return ObserveDataStream(() => GetFrom(bucketId, streamId, minRevision, maxRevision), observer, cancellationToken); - } - - private static async Task ObserveDataStream(Func> dataProvider, IAsyncObserver observer, CancellationToken cancellationToken) - { - try - { - var data = dataProvider(); - if (data?.Any() == true) - { - foreach (var commit in data) - { - if (cancellationToken.IsCancellationRequested) - { - throw new OperationCanceledException("Operation Cancellation Requested"); - } - var goOn = await observer.OnNextAsync(commit, cancellationToken).ConfigureAwait(false); - if (!goOn) - { - break; - } - if (cancellationToken.IsCancellationRequested) - { - throw new OperationCanceledException("Operation Cancellation Requested"); - } - } - } - await observer.OnCompletedAsync(cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - await observer.OnErrorAsync(ex, cancellationToken).ConfigureAwait(false); - } - } - - /// - public Task CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken) - { - return Task.FromResult(Commit(attempt)); - } - - /// - public ISnapshot? GetSnapshot(string bucketId, string streamId, int maxRevision) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingSnapshotForStream, bucketId, streamId, maxRevision); - } - return this[bucketId].GetSnapshot(streamId, maxRevision); - } - - /// - public bool AddSnapshot(ISnapshot snapshot) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.AddingSnapshot, snapshot.BucketId, snapshot.StreamId, snapshot.StreamRevision); - } - return this[snapshot.BucketId].AddSnapshot(snapshot); - } - - /// - public IEnumerable GetStreamsToSnapshot(string bucketId, int maxThreshold) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingStreamsToSnapshot, bucketId, maxThreshold); - } - return this[bucketId].GetStreamsToSnapshot(maxThreshold); - } - - /// - public Task GetSnapshotAsync(string bucketId, string streamId, int maxRevision, CancellationToken cancellationToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.GettingSnapshotForStream, bucketId, streamId, maxRevision); - } - return Task.FromResult(this[bucketId].GetSnapshot(streamId, maxRevision)); - } - - /// - public Task AddSnapshotAsync(ISnapshot snapshot, CancellationToken cancellationToken) - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.AddingSnapshot, snapshot.BucketId, snapshot.StreamId, snapshot.StreamRevision); - } - return Task.FromResult(this[snapshot.BucketId].AddSnapshot(snapshot)); - } - - /// - public async Task GetStreamsToSnapshotAsync(string bucketId, int maxThreshold, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - try - { - var data = GetStreamsToSnapshot(bucketId, maxThreshold); - if (data?.Any() == true) - { - foreach (var commit in data) - { - if (cancellationToken.IsCancellationRequested) - { - throw new OperationCanceledException("Operation Cancellation Requested"); - } - var goOn = await asyncObserver.OnNextAsync(commit, cancellationToken).ConfigureAwait(false); - if (!goOn) - { - break; - } - if (cancellationToken.IsCancellationRequested) - { - throw new OperationCanceledException("Operation Cancellation Requested"); - } - } - } - await asyncObserver.OnCompletedAsync(cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - await asyncObserver.OnErrorAsync(ex, cancellationToken).ConfigureAwait(false); - } - } - - /// - public void Purge() - { - ThrowWhenDisposed(); - if (Logger.IsEnabled(LogLevel.Warning)) - { - Logger.LogWarning(Resources.PurgingStore); - } - - foreach (var bucket in _buckets.Values) - { - bucket.Purge(); - } - } - - /// - public void Purge(string bucketId) - { - _buckets.TryRemove(bucketId, out var _); - } - - /// - public Task PurgeAsync(CancellationToken cancellationToken) - { - Purge(); - return Task.CompletedTask; - } - - /// - public Task PurgeAsync(string bucketId, CancellationToken cancellationToken) - { - Purge(bucketId); - return Task.CompletedTask; - } - - /// - public void Drop() - { - _buckets.Clear(); - } - - /// - public void DeleteStream(string bucketId, string streamId) - { - if (Logger.IsEnabled(LogLevel.Warning)) - { - Logger.LogWarning(Resources.DeletingStream, streamId, bucketId); - } - if (!_buckets.TryGetValue(bucketId, out Bucket bucket)) - { - return; - } - bucket.DeleteStream(streamId); - } - - /// - public Task DeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken) - { - DeleteStream(bucketId, streamId); - return Task.CompletedTask; - } - - /// - public bool IsDisposed - { - get { return _disposed; } - } - -#pragma warning disable RCS1163 // Unused parameter. -#pragma warning disable IDE0060 // Remove unused parameter - private void Dispose(bool disposing) -#pragma warning restore IDE0060 // Remove unused parameter -#pragma warning restore RCS1163 // Unused parameter. - { - _disposed = true; - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.DisposingEngine); - } - } - - private void ThrowWhenDisposed() - { - if (!_disposed) - { - return; - } - if (Logger.IsEnabled(LogLevel.Warning)) - { - Logger.LogWarning(Resources.AlreadyDisposed); - } - throw new ObjectDisposedException(Resources.AlreadyDisposed); - } - - private class InMemoryCommit : Commit - { - public InMemoryCommit( - string bucketId, - string streamId, - int streamRevision, - Guid commitId, - int commitSequence, - DateTime commitStamp, - Int64 checkpointToken, - IDictionary headers, - ICollection events) - : base(bucketId, streamId, streamRevision, commitId, commitSequence, commitStamp, checkpointToken, headers, events) - { } - } - - private class IdentityForConcurrencyConflictDetection - { - protected bool Equals(IdentityForConcurrencyConflictDetection other) - { - return string.Equals(this.streamId, other.streamId, StringComparison.Ordinal) - && string.Equals(this.bucketId, other.bucketId, StringComparison.Ordinal) - && this.commitSequence == other.commitSequence; - } - - public override bool Equals(object obj) - { - if (obj is null) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - if (obj.GetType() != this.GetType()) - { - return false; - } - return Equals((IdentityForConcurrencyConflictDetection)obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = this.streamId.GetHashCode(); - hashCode = (hashCode * 397) ^ this.bucketId.GetHashCode(); - return (hashCode * 397) ^ this.commitSequence; - } - } - - private readonly int commitSequence; - - private readonly string bucketId; - - private readonly string streamId; - - public IdentityForConcurrencyConflictDetection(CommitAttempt commitAttempt) - { - bucketId = commitAttempt.BucketId; - streamId = commitAttempt.StreamId; - commitSequence = commitAttempt.CommitSequence; - } - - public IdentityForConcurrencyConflictDetection(Commit commit) - { - bucketId = commit.BucketId; - streamId = commit.StreamId; - commitSequence = commit.CommitSequence; - } - } - - private class IdentityForDuplicationDetection - { - protected bool Equals(IdentityForDuplicationDetection other) - { - return string.Equals(this.streamId, other.streamId, StringComparison.Ordinal) - && string.Equals(this.bucketId, other.bucketId, StringComparison.Ordinal) - && this.commitId.Equals(other.commitId); - } - - public override bool Equals(object obj) - { - if (obj is null) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - if (obj.GetType() != this.GetType()) - { - return false; - } - return Equals((IdentityForDuplicationDetection)obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = this.streamId.GetHashCode(); - hashCode = (hashCode * 397) ^ this.bucketId.GetHashCode(); - return (hashCode * 397) ^ this.commitId.GetHashCode(); - } - } - - private readonly Guid commitId; - - private readonly string bucketId; - - private readonly string streamId; - - public IdentityForDuplicationDetection(CommitAttempt commitAttempt) - { - bucketId = commitAttempt.BucketId; - streamId = commitAttempt.StreamId; - commitId = commitAttempt.CommitId; - } - - public IdentityForDuplicationDetection(Commit commit) - { - bucketId = commit.BucketId; - streamId = commit.StreamId; - commitId = commit.CommitId; - } - } - - private class Bucket - { - private readonly List _commits = []; - private readonly HashSet _potentialDuplicates = []; - private readonly HashSet _potentialConflicts = []; - - public IEnumerable GetCommits() - { - lock (_commits) - { - return _commits.ToArray(); - } - } - - private readonly ICollection _heads = new LinkedList(); - private readonly ICollection _snapshots = new LinkedList(); - private readonly Dictionary _stamps = []; - - public IEnumerable GetFrom(string streamId, int minRevision, int maxRevision) - { - lock (_commits) - { - return _commits - .Where(x => x.StreamId == streamId && x.StreamRevision >= minRevision && (x.StreamRevision - x.Events.Count + 1) <= maxRevision) - .OrderBy(c => c.CommitSequence) - .ToArray(); - } - } - - public IEnumerable GetFrom(DateTime start) - { - Guid commitId = _stamps.Where(x => x.Value >= start).Select(x => x.Key).FirstOrDefault(); - if (commitId == Guid.Empty) - { - return []; - } - - InMemoryCommit startingCommit = _commits.FirstOrDefault(x => x.CommitId == commitId); - return _commits.Skip(_commits.IndexOf(startingCommit)); - } - - public IEnumerable GetFrom(Int64 checkpoint) - { - InMemoryCommit startingCommit = _commits.FirstOrDefault(x => x.CheckpointToken.CompareTo(checkpoint) == 0); - return _commits.Skip(_commits.IndexOf(startingCommit) + 1 /* GetFrom => after the checkpoint*/); - } - - public IEnumerable GetFromTo(Int64 from, Int64 to) - { - InMemoryCommit startingCommit = _commits.FirstOrDefault(x => x.CheckpointToken.CompareTo(from) == 0); - return _commits.Skip(_commits.IndexOf(startingCommit) + 1 /* GetFrom => after the checkpoint*/) - .TakeWhile(c => c.CheckpointToken <= to); - } - - public IEnumerable GetFromTo(DateTime start, DateTime end) - { - IEnumerable selectedCommitIds = _stamps.Where(x => x.Value >= start && x.Value < end).Select(x => x.Key).ToArray(); - Guid firstCommitId = selectedCommitIds.FirstOrDefault(); - Guid lastCommitId = selectedCommitIds.LastOrDefault(); - if (lastCommitId == Guid.Empty && lastCommitId == Guid.Empty) - { - return []; - } - InMemoryCommit startingCommit = _commits.FirstOrDefault(x => x.CommitId == firstCommitId); - InMemoryCommit endingCommit = _commits.FirstOrDefault(x => x.CommitId == lastCommitId); - int startingCommitIndex = (startingCommit == null) ? 0 : _commits.IndexOf(startingCommit); - int endingCommitIndex = (endingCommit == null) ? _commits.Count - 1 : _commits.IndexOf(endingCommit); - int numberToTake = endingCommitIndex - startingCommitIndex + 1; - - return _commits.Skip(startingCommitIndex).Take(numberToTake); - } - - public Commit Commit(CommitAttempt attempt, Int64 checkpoint) - { - lock (_commits) - { - DetectDuplicate(attempt); - var commit = new InMemoryCommit(attempt.BucketId, - attempt.StreamId, - attempt.StreamRevision, - attempt.CommitId, - attempt.CommitSequence, - attempt.CommitStamp, - checkpoint, - attempt.Headers, - attempt.Events); - if (_potentialConflicts.Contains(new IdentityForConcurrencyConflictDetection(commit))) - { - throw new ConcurrencyException(); - } - _stamps[commit.CommitId] = commit.CommitStamp; - _commits.Add(commit); - _potentialDuplicates.Add(new IdentityForDuplicationDetection(commit)); - _potentialConflicts.Add(new IdentityForConcurrencyConflictDetection(commit)); - IStreamHead head = _heads.FirstOrDefault(x => x.StreamId == commit.StreamId); - _heads.Remove(head); - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Resources.UpdatingStreamHead, commit.StreamId, commit.BucketId); - } - int snapshotRevision = head?.SnapshotRevision ?? 0; - _heads.Add(new StreamHead(commit.BucketId, commit.StreamId, commit.StreamRevision, snapshotRevision)); - return commit; - } - } - - private void DetectDuplicate(CommitAttempt attempt) - { - if (_potentialDuplicates.Contains(new IdentityForDuplicationDetection(attempt))) - { - throw new DuplicateCommitException(String.Format( - CultureInfo.InvariantCulture, - Messages.DuplicateCommitIdException, attempt.StreamId, attempt.BucketId, attempt.CommitId)); - } - } - - public IEnumerable GetStreamsToSnapshot(int maxThreshold) - { - lock (_commits) - { - return _heads - .Where(x => x.HeadRevision >= x.SnapshotRevision + maxThreshold) - .Select(stream => new StreamHead(stream.BucketId, stream.StreamId, stream.HeadRevision, stream.SnapshotRevision)); - } - } - - public ISnapshot? GetSnapshot(string streamId, int maxRevision) - { - lock (_commits) - { - return _snapshots - .Where(x => x.StreamId == streamId && x.StreamRevision <= maxRevision) - .OrderByDescending(x => x.StreamRevision) - .FirstOrDefault(); - } - } - - public bool AddSnapshot(ISnapshot snapshot) - { - lock (_commits) - { - IStreamHead currentHead = _heads.FirstOrDefault(h => h.StreamId == snapshot.StreamId); - if (currentHead == null) - { - return false; - } - - // if the snapshot is already there do NOT add it (follow the SQL implementation) - // and the original GetSnapshot behavior which was to return the first one that was - // added to the collection - if (_snapshots.Any(s => s.StreamId == snapshot.StreamId && s.StreamRevision == snapshot.StreamRevision)) - { - return false; - } - - _snapshots.Add(snapshot); - _heads.Remove(currentHead); - _heads.Add(new StreamHead(currentHead.BucketId, currentHead.StreamId, currentHead.HeadRevision, snapshot.StreamRevision)); - } - return true; - } - - public void Purge() - { - lock (_commits) - { - _commits.Clear(); - _snapshots.Clear(); - _heads.Clear(); - _potentialConflicts.Clear(); - _potentialDuplicates.Clear(); - } - } - - public void DeleteStream(string streamId) - { - lock (_commits) - { - InMemoryCommit[] commits = _commits.Where(c => c.StreamId == streamId).ToArray(); - foreach (var commit in commits) - { - _commits.Remove(commit); - } - ISnapshot[] snapshots = _snapshots.Where(s => s.StreamId == streamId).ToArray(); - foreach (var snapshot in snapshots) - { - _snapshots.Remove(snapshot); - } - IStreamHead streamHead = _heads.SingleOrDefault(s => s.StreamId == streamId); - if (streamHead != null) - { - _heads.Remove(streamHead); - } - } - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/InMemory/InMemoryPersistenceFactory.cs b/src/NEventStore/Persistence/InMemory/InMemoryPersistenceFactory.cs deleted file mode 100644 index 54e1d3d53..000000000 --- a/src/NEventStore/Persistence/InMemory/InMemoryPersistenceFactory.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace NEventStore.Persistence.InMemory -{ - /// - /// Represents a factory for creating in-memory persistence engines. - /// - public class InMemoryPersistenceFactory : IPersistenceFactory - { - /// - /// Builds a new in-memory persistence engine. - /// - public virtual IPersistStreams Build() - { - return new InMemoryPersistenceEngine(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/PersistStreamsExtensions.cs b/src/NEventStore/Persistence/PersistStreamsExtensions.cs deleted file mode 100644 index 1e6233805..000000000 --- a/src/NEventStore/Persistence/PersistStreamsExtensions.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace NEventStore.Persistence -{ - /// - /// Provides a set of extension methods for the interface. - /// - public static class PersistStreamsExtensions - { - /// - /// Deletes a stream from the default bucket. - /// - /// The IPersistStreams instance. - /// The stream id to be deleted. - public static void DeleteStream(this IPersistStreams persistStreams, string streamId) - { - persistStreams.DeleteStream(Bucket.Default, streamId); - } - - /// - /// Deletes a stream from the default bucket. - /// - /// The IPersistStreams instance. - /// The stream id to be deleted. - /// The token to monitor for cancellation requests. - public static Task DeleteStreamAsync(this IPersistStreams persistStreams, string streamId, CancellationToken cancellationToken = default) - { - return persistStreams.DeleteStreamAsync(Bucket.Default, streamId, cancellationToken); - } - - /// - /// Returns a single commit from any bucket. - /// Wrapper for the function in order to - /// return a single commit. - /// - /// The IPersistStreams instance. - /// The checkpoint token that mark the commit to read. - /// A single commit. - public static ICommit GetCommit(this IPersistStreams persistStreams, Int64 checkpointToken) - { - return persistStreams.GetFromTo(checkpointToken - 1, checkpointToken).SingleOrDefault(); - } - - /// - /// Returns a single commit from any bucket. - /// Wrapper for the function in order to - /// return a single commit. - /// - /// The IPersistStreams instance. - /// The checkpoint token that mark the commit to read. - /// The token to monitor for cancellation requests. - /// A single commit. - public static async Task GetCommitAsync(this IPersistStreams persistStreams, Int64 checkpointToken, CancellationToken cancellationToken = default) - { - var observer = new CommitStreamObserver(); - await persistStreams.GetFromToAsync(checkpointToken - 1, checkpointToken, observer, cancellationToken).ConfigureAwait(false); - return observer.Commits.SingleOrDefault(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/PipelineHooksAwarePersistStreamsDecorator.cs b/src/NEventStore/Persistence/PipelineHooksAwarePersistStreamsDecorator.cs deleted file mode 100644 index 113f1491c..000000000 --- a/src/NEventStore/Persistence/PipelineHooksAwarePersistStreamsDecorator.cs +++ /dev/null @@ -1,390 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Persistence -{ - /// - /// Represents a persistence decorator that allows for hooks to be injected into the pipeline. - /// - public sealed class PipelineHooksAwarePersistStreamsDecorator : IPersistStreams - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(PipelineHooksAwarePersistStreamsDecorator)); - private readonly IPersistStreams _original; - private readonly IEnumerable _pipelineHooks; - private readonly IEnumerable _pipelineHooksAsync; - - /// - /// Initializes a new instance of the PipelineHooksAwarePersistStreamsDecorator class. - /// - /// - public PipelineHooksAwarePersistStreamsDecorator(IPersistStreams original, IEnumerable pipelineHooks, IEnumerable pipelineHooksAsync) - { - _original = original ?? throw new ArgumentNullException(nameof(original)); - _pipelineHooks = pipelineHooks ?? throw new ArgumentNullException(nameof(pipelineHooks)); - _pipelineHooksAsync = pipelineHooksAsync ?? throw new ArgumentNullException(nameof(pipelineHooksAsync)); - } - - /// - public void Dispose() - { - _original.Dispose(); - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFrom(Int64 checkpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFrom(string bucketId, DateTime startDate) - { - return ExecuteSelectCommitsHooks(_original.GetFrom(bucketId, startDate)); - } - - /// - [Obsolete("DateTime is problematic in distributed systems. Use GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) instead. This method will be removed in a later version.")] - public IEnumerable GetFromTo(string bucketId, DateTime startDate, DateTime endDate) - { - return ExecuteSelectCommitsHooks(_original.GetFromTo(bucketId, startDate, endDate)); - } - - /// - public IEnumerable GetFrom(Int64 checkpointToken) - { - return ExecuteSelectCommitsHooks(_original.GetFrom(checkpointToken)); - } - - /// - public Task GetFromAsync(Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - var pipelineHookObserver = new PipelineHookObserver(_pipelineHooks, _pipelineHooksAsync, asyncObserver); - return _original.GetFromAsync(checkpointToken, pipelineHookObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - return ExecuteSelectCommitsHooks(_original.GetFromTo(fromCheckpointToken, toCheckpointToken)); - } - - /// - public Task GetFromToAsync(Int64 fromCheckpointToken, Int64 toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - var pipelineHookObserver = new PipelineHookObserver(_pipelineHooks, _pipelineHooksAsync, asyncObserver); - return _original.GetFromToAsync(fromCheckpointToken, toCheckpointToken, pipelineHookObserver, cancellationToken); - } - - /// - public IEnumerable GetFrom(string bucketId, Int64 checkpointToken) - { - return ExecuteSelectCommitsHooks(_original.GetFrom(bucketId, checkpointToken)); - } - - /// - public Task GetFromAsync(string bucketId, Int64 checkpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - var pipelineHookObserver = new PipelineHookObserver(_pipelineHooks, _pipelineHooksAsync, asyncObserver); - return _original.GetFromAsync(bucketId, checkpointToken, pipelineHookObserver, cancellationToken); - } - - /// - public IEnumerable GetFromTo(string bucketId, Int64 fromCheckpointToken, Int64 toCheckpointToken) - { - return ExecuteSelectCommitsHooks(_original.GetFromTo(bucketId, fromCheckpointToken, toCheckpointToken)); - } - - /// - public Task GetFromToAsync(string bucketId, long fromCheckpointToken, long toCheckpointToken, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - var pipelineHookObserver = new PipelineHookObserver(_pipelineHooks, _pipelineHooksAsync, asyncObserver); - return _original.GetFromToAsync(bucketId, fromCheckpointToken, toCheckpointToken, pipelineHookObserver, cancellationToken); - } - - /// - public IEnumerable GetFrom(string bucketId, string streamId, int minRevision, int maxRevision) - { - return ExecuteSelectCommitsHooks(_original.GetFrom(bucketId, streamId, minRevision, maxRevision)); - } - - /// - public ICommit? Commit(CommitAttempt attempt) - { - return _original.Commit(attempt); - } - - /// - public Task GetFromAsync(string bucketId, string streamId, int minRevision, int maxRevision, IAsyncObserver observer, CancellationToken cancellationToken) - { - var pipelineHookObserver = new PipelineHookObserver(_pipelineHooks, _pipelineHooksAsync, observer); - return _original.GetFromAsync(bucketId, streamId, minRevision, maxRevision, pipelineHookObserver, cancellationToken); - } - - /// - public Task CommitAsync(CommitAttempt attempt, CancellationToken cancellationToken) - { - return _original.CommitAsync(attempt, cancellationToken); - } - - /// - public ISnapshot? GetSnapshot(string bucketId, string streamId, int maxRevision) - { - return _original.GetSnapshot(bucketId, streamId, maxRevision); - } - - /// - public bool AddSnapshot(ISnapshot snapshot) - { - return _original.AddSnapshot(snapshot); - } - - /// - public IEnumerable GetStreamsToSnapshot(string bucketId, int maxThreshold) - { - return _original.GetStreamsToSnapshot(bucketId, maxThreshold); - } - - /// - public Task GetSnapshotAsync(string bucketId, string streamId, int maxRevision, CancellationToken cancellationToken) - { - return _original.GetSnapshotAsync(bucketId, streamId, maxRevision, cancellationToken); - } - - /// - public Task AddSnapshotAsync(ISnapshot snapshot, CancellationToken cancellationToken) - { - return _original.AddSnapshotAsync(snapshot, cancellationToken); - } - - /// - public Task GetStreamsToSnapshotAsync(string bucketId, int maxThreshold, IAsyncObserver asyncObserver, CancellationToken cancellationToken) - { - return _original.GetStreamsToSnapshotAsync(bucketId, maxThreshold, asyncObserver, cancellationToken); - } - - /// - public void Initialize() - { - _original.Initialize(); - } - - /// - public void Purge() - { - _original.Purge(); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnPurge(); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - pipelineHook.OnPurgeAsync(CancellationToken.None).GetAwaiter().GetResult(); - } - } - - /// - public void Purge(string bucketId) - { - _original.Purge(bucketId); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnPurge(bucketId); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - pipelineHook.OnPurgeAsync(bucketId, CancellationToken.None).GetAwaiter().GetResult(); - } - } - - /// - public async Task PurgeAsync(CancellationToken cancellationToken) - { - await _original.PurgeAsync(cancellationToken).ConfigureAwait(false); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnPurge(); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - await pipelineHook.OnPurgeAsync(cancellationToken).ConfigureAwait(false); - } - } - - /// - public async Task PurgeAsync(string bucketId, CancellationToken cancellationToken) - { - await _original.PurgeAsync(bucketId, cancellationToken).ConfigureAwait(false); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnPurge(bucketId); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - await pipelineHook.OnPurgeAsync(bucketId, cancellationToken).ConfigureAwait(false); - } - } - - /// - public void Drop() - { - _original.Drop(); - } - - /// - public void DeleteStream(string bucketId, string streamId) - { - _original.DeleteStream(bucketId, streamId); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnDeleteStream(bucketId, streamId); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - pipelineHook.OnDeleteStreamAsync(bucketId, streamId, CancellationToken.None).GetAwaiter().GetResult(); - } - } - - /// - public async Task DeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken) - { - await _original.DeleteStreamAsync(bucketId, streamId, cancellationToken).ConfigureAwait(false); - foreach (var pipelineHook in _pipelineHooks) - { - pipelineHook.OnDeleteStream(bucketId, streamId); - } - foreach (var pipelineHook in _pipelineHooksAsync) - { - await pipelineHook.OnDeleteStreamAsync(bucketId, streamId, cancellationToken).ConfigureAwait(false); - } - } - - /// - public bool IsDisposed - { - get { return _original.IsDisposed; } - } - - private IEnumerable ExecuteSelectCommitsHooks(IEnumerable commits) - { - foreach (var commit in commits) - { - ICommit? filtered = commit; - foreach (var hook in _pipelineHooks) - { - filtered = hook.SelectCommit(filtered); - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookSkippedCommit, hook.GetType(), commit.CommitId); - } - break; - } - } - if (filtered != null) - { - foreach (var hook in _pipelineHooksAsync) - { - filtered = hook.SelectCommitAsync(filtered, CancellationToken.None).GetAwaiter().GetResult(); - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookSkippedCommit, hook.GetType(), commit.CommitId); - } - break; - } - } - } - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookFilteredCommit); - } - } - else - { - yield return filtered; - } - } - } - - internal class PipelineHookObserver : IAsyncObserver - { - private readonly IEnumerable _pipelineHooks; - private readonly IEnumerable _pipelineHooksAsync; - private readonly IAsyncObserver _observer; - - public PipelineHookObserver( - IEnumerable pipelineHooks, - IEnumerable pipelineHooksAsync, - IAsyncObserver observer - ) - { - _pipelineHooks = pipelineHooks; - _pipelineHooksAsync = pipelineHooksAsync; - _observer = observer; - } - - public Task OnCompletedAsync(CancellationToken cancellationToken) - { - return _observer.OnCompletedAsync(cancellationToken); - } - - public Task OnErrorAsync(Exception error, CancellationToken cancellationToken) - { - return _observer.OnErrorAsync(error, cancellationToken); - } - - public async Task OnNextAsync(ICommit value, CancellationToken cancellationToken) - { - var commit = await ExecuteSelectCommitHooksAsync(value, cancellationToken).ConfigureAwait(false); - if (commit != null) - { - return await _observer.OnNextAsync(commit, cancellationToken).ConfigureAwait(false); - } - return true; - } - - private async Task ExecuteSelectCommitHooksAsync(ICommit commit, CancellationToken cancellationToken) - { - ICommit? filtered = commit; - foreach (var hook in _pipelineHooks) - { - filtered = hook.SelectCommit(filtered); - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookSkippedCommit, hook.GetType(), commit.CommitId); - } - break; - } - } - if (filtered != null) - { - foreach (var hook in _pipelineHooksAsync) - { - filtered = await hook.SelectCommitAsync(filtered, cancellationToken).ConfigureAwait(false); - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookSkippedCommit, hook.GetType(), commit.CommitId); - } - break; - } - } - } - if (filtered == null) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.PipelineHookFilteredCommit); - } - return null; - } - else - { - return filtered; - } - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/StorageException.cs b/src/NEventStore/Persistence/StorageException.cs deleted file mode 100644 index da555ed42..000000000 --- a/src/NEventStore/Persistence/StorageException.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Runtime.Serialization; - -namespace NEventStore.Persistence -{ - /// - /// Represents a general failure of the storage engine or persistence infrastructure. - /// - [Serializable] - public class StorageException : Exception - { - /// - /// Initializes a new instance of the StorageException class. - /// - public StorageException() - { } - - /// - /// Initializes a new instance of the StorageException class. - /// - /// The message that describes the error. - public StorageException(string message) - : base(message) - { } - - /// - /// Initializes a new instance of the StorageException class. - /// - /// The message that describes the error. - /// The message that is the cause of the current exception. - public StorageException(string message, Exception innerException) - : base(message, innerException) - { } - - /// - /// Initializes a new instance of the StorageException class. - /// - /// The SerializationInfo that holds the serialized object data of the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - protected StorageException(SerializationInfo info, StreamingContext context) - : base(info, context) - { } - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/StorageUnavailableException.cs b/src/NEventStore/Persistence/StorageUnavailableException.cs deleted file mode 100644 index 483d6668c..000000000 --- a/src/NEventStore/Persistence/StorageUnavailableException.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Runtime.Serialization; - -namespace NEventStore.Persistence -{ - /// - /// Indicates that the underlying persistence medium is unavailable or offline. - /// - [Serializable] - public class StorageUnavailableException : StorageException - { - /// - /// Initializes a new instance of the StorageUnavailableException class. - /// - public StorageUnavailableException() - {} - - /// - /// Initializes a new instance of the StorageUnavailableException class. - /// - /// The message that describes the error. - public StorageUnavailableException(string message) - : base(message) - {} - - /// - /// Initializes a new instance of the StorageUnavailableException class. - /// - /// The message that describes the error. - /// The message that is the cause of the current exception. - public StorageUnavailableException(string message, Exception innerException) - : base(message, innerException) - {} - - /// - /// Initializes a new instance of the StorageUnavailableException class. - /// - /// The SerializationInfo that holds the serialized object data of the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - protected StorageUnavailableException(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - } -} \ No newline at end of file diff --git a/src/NEventStore/Persistence/StreamHead.cs b/src/NEventStore/Persistence/StreamHead.cs deleted file mode 100644 index 01204f83d..000000000 --- a/src/NEventStore/Persistence/StreamHead.cs +++ /dev/null @@ -1,72 +0,0 @@ -#pragma warning disable RCS1170 // Use read-only auto-implemented property. - -namespace NEventStore.Persistence -{ - /// - /// Indicates the most recent information representing the head of a given stream. - /// - public class StreamHead : IStreamHead - { - /// - /// Initializes a new instance of the StreamHead class. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream in the bucket where the last snapshot exceeds the allowed threshold. - /// The value which indicates the revision, length, or number of events committed to the stream. - /// The value which indicates the revision at which the last snapshot was taken. - public StreamHead(string bucketId, string streamId, int headRevision, int snapshotRevision) - { - BucketId = bucketId; - StreamId = streamId; - HeadRevision = headRevision; - SnapshotRevision = snapshotRevision; - } - - /// - /// Stream Head Equality Comparer - /// - public static IEqualityComparer StreamIdBucketIdComparer { get; } = new StreamHeadEqualityComparer(); - - /// - /// Gets the value which uniquely identifies the stream where the last snapshot exceeds the allowed threshold. - /// - public string BucketId { get; private set; } - - /// - /// Gets the value which uniquely identifies the stream where the last snapshot exceeds the allowed threshold. - /// - public string StreamId { get; private set; } - - /// - /// Gets the value which indicates the revision, length, or number of events committed to the stream. - /// - public int HeadRevision { get; private set; } - - /// - /// Gets the value which indicates the revision at which the last snapshot was taken. - /// - public int SnapshotRevision { get; private set; } - - /// - /// Determines whether the specified object is equal to the current object. - /// - /// The object to compare with the current object. - /// If the two objects are equal, returns true; otherwise false. - public override bool Equals(object obj) - { - return obj is StreamHead commit - && commit.StreamId == StreamId; - } - - /// - /// Returns the hash code for this instance. - /// - /// The hash code for this instance. - public override int GetHashCode() - { - return StreamId.GetHashCode(); - } - } -} - -#pragma warning restore RCS1170 // Use read-only auto-implemented property. \ No newline at end of file diff --git a/src/NEventStore/Persistence/StreamHeadEqualityComparer.cs b/src/NEventStore/Persistence/StreamHeadEqualityComparer.cs deleted file mode 100644 index b533c638d..000000000 --- a/src/NEventStore/Persistence/StreamHeadEqualityComparer.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace NEventStore.Persistence { - /// - /// Represents a strategy for comparing stream heads. - /// - public sealed class StreamHeadEqualityComparer : IEqualityComparer { - /// - public bool Equals(IStreamHead x, IStreamHead y) { - if (ReferenceEquals(x, y)) { - return true; - } - if (x is null) { - return false; - } - if (y is null) { - return false; - } - if (x.GetType() != y.GetType()) { - return false; - } - return string.Equals(x.StreamId, y.StreamId, StringComparison.Ordinal) - && string.Equals(x.BucketId, y.BucketId, StringComparison.Ordinal); - } - - /// - public int GetHashCode(IStreamHead obj) { - unchecked { - return ((obj.StreamId?.GetHashCode() ?? 0) * 397) ^ (obj.BucketId?.GetHashCode() ?? 0); - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/PersistenceWireup.cs b/src/NEventStore/PersistenceWireup.cs deleted file mode 100644 index 4988d20cf..000000000 --- a/src/NEventStore/PersistenceWireup.cs +++ /dev/null @@ -1,144 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Diagnostics; -using NEventStore.Logging; -using NEventStore.Persistence; -using NEventStore.Serialization; - -namespace NEventStore -{ - /// - /// Represents the persistence wireup. - /// - public class PersistenceWireup : Wireup - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(PersistenceWireup)); - private bool _initialize; -#if NET462 - private bool _tracking; - private string? _trackingInstanceName; -#endif - - /// - /// Initializes a new instance of the PersistenceWireup class. - /// - public PersistenceWireup(Wireup inner) - : base(inner) - { -#pragma warning disable S125 // Sections of code should not be commented out - /* EnlistInAmbientTransaction: Will be moved to the specific Persistence driver or completely removed letting the clients handle that - Container.Register(TransactionScopeOption.Suppress); - */ -#pragma warning restore S125 // Sections of code should not be commented out - } - - /// - /// Configures the persistence engine to use the specified serializer. - /// - public virtual PersistenceWireup WithPersistence(IPersistStreams instance) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.RegisteringPersistenceEngine, instance.GetType()); - } - Register(instance); - return this; - } - - /// - /// Configures the persistence engine to use the specified serializer. - /// - protected virtual SerializationWireup WithSerializer(ISerialize serializer) - { - return new SerializationWireup(this, serializer); - } - - /// - /// Initializes the storage engine. - /// - public virtual PersistenceWireup InitializeStorageEngine() - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.ConfiguringEngineInitialization); - } - _initialize = true; - return this; - } - -#if NET462 - /// - /// Configures the persistence engine to track performance counters. - /// - /// - public virtual PersistenceWireup TrackPerformanceInstance(string instanceName) - { - _tracking = true; - _trackingInstanceName = instanceName - ?? throw new ArgumentNullException(nameof(instanceName), Messages.InstanceCannotBeNull); - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.ConfiguringEnginePerformanceTracking); - } - return this; - } -#endif - -#pragma warning disable S125 // Sections of code should not be commented out - /* EnlistInAmbientTransaction: Will be moved to the specific Persistence driver or completely removed letting the clients handle that - /// - /// Enables two-phase commit. - /// By default NEventStore will suppress surrounding TransactionScopes - /// (All the Persistence drivers that support transactions will create a - /// private nested TransactionScope with for each operation) - /// so that all of its operations run in a dedicated, separate transaction. - /// This option changes the behavior so that NEventStore enlists in a surrounding TransactionScope, - /// if there is any (All the Persistence drivers that support transactions will create a - /// private nested TransactionScope with for each operation). - /// - /// - /// Enabling the two-phase commit will also disable the - /// that provide some additionl concurrency checks to avoid useless roundtrips to the databases. - /// - /// - public virtual PersistenceWireup EnlistInAmbientTransaction() - { - if (Logger.IsInfoEnabled) Logger.Info(Messages.ConfiguringEngineEnlistment); - Container.Register(TransactionScopeOption.Required); - return this; - } - */ -#pragma warning restore S125 // Sections of code should not be commented out - - /// - /// Builds the persistence engine. - /// - public override IStoreEvents Build() - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.BuildingEngine); - } - - var engine = Container.Resolve() - ?? throw new InvalidOperationException("IPersistStreams not registered"); - - if (_initialize) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.InitializingEngine); - } - engine.Initialize(); - } - -#if NET462 - if (_tracking) - { - Container.Register(new PerformanceCounterPersistenceEngine(engine, _trackingInstanceName!)); - } -#endif - return base.Build(); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/PersistenceWireupExtensions.cs b/src/NEventStore/PersistenceWireupExtensions.cs deleted file mode 100644 index 3a17e4342..000000000 --- a/src/NEventStore/PersistenceWireupExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using NEventStore.Logging; -using Microsoft.Extensions.Logging; -using NEventStore.Persistence; -using NEventStore.Persistence.InMemory; - -namespace NEventStore -{ - /// - /// Persistence wireup extensions. - /// - public static class PersistenceWireupExtensions - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(OptimisticPipelineHook)); - - /// - /// Configures the persistence engine to use the in-memory persistence engine. - /// - public static PersistenceWireup UsingInMemoryPersistence(this Wireup wireup) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.WireupSetPersistenceEngine, "InMemoryPersistenceEngine"); - } - wireup.Register(new InMemoryPersistenceEngine()); - - return new PersistenceWireup(wireup); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/PipelineHookAsyncBase.cs b/src/NEventStore/PipelineHookAsyncBase.cs deleted file mode 100644 index 1e33f80b5..000000000 --- a/src/NEventStore/PipelineHookAsyncBase.cs +++ /dev/null @@ -1,52 +0,0 @@ - -namespace NEventStore -{ - /// - /// Provides a base implementation of the interface. - /// - public abstract class PipelineHookAsyncBase : IPipelineHookAsync - { - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - protected virtual void Dispose(bool disposing) - { - // Cleanup - } - - /// - public virtual Task OnDeleteStreamAsync(string bucketId, string streamId, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - /// - public virtual Task OnPurgeAsync(string? bucketId, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - /// - public virtual Task PostCommitAsync(ICommit committed, CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - /// - public virtual Task PreCommitAsync(CommitAttempt attempt, CancellationToken cancellationToken) - { - return Task.FromResult(true); - } - - /// - public virtual Task SelectCommitAsync(ICommit committed, CancellationToken cancellationToken) - { - return Task.FromResult(committed); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/PipelineHookBase.cs b/src/NEventStore/PipelineHookBase.cs deleted file mode 100644 index 350746c0f..000000000 --- a/src/NEventStore/PipelineHookBase.cs +++ /dev/null @@ -1,46 +0,0 @@ - -namespace NEventStore -{ - /// - /// Provides a base implementation of the interface. - /// - public abstract class PipelineHookBase : IPipelineHook - { - /// - public virtual ICommit? SelectCommit(ICommit committed) - { - return committed; - } - - /// - public virtual bool PreCommit(CommitAttempt attempt) - { - return true; - } - - /// - public virtual void PostCommit(ICommit committed) - { } - - /// - public virtual void OnPurge(string? bucketId) - { } - - /// - public virtual void OnDeleteStream(string bucketId, string streamId) - { } - - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - protected virtual void Dispose(bool disposing) - { - // Cleanup - } - } -} \ No newline at end of file diff --git a/src/NEventStore/PipelineHookExtensions.cs b/src/NEventStore/PipelineHookExtensions.cs deleted file mode 100644 index 9f351fd31..000000000 --- a/src/NEventStore/PipelineHookExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides extension methods for . - /// - public static class PipelineHookExtensions - { - /// - /// Invoked when all buckets have been purged. - /// - /// The pipeline hook. - public static void OnPurge(this IPipelineHook pipelineHook) - { - pipelineHook.OnPurge(null); - } - - /// - /// Invoked when all buckets have been purged. - /// - /// The pipeline hook. - /// The token to monitor for cancellation requests. - public static Task OnPurgeAsync(this IPipelineHookAsync pipelineHook, CancellationToken cancellationToken) - { - return pipelineHook.OnPurgeAsync(null, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Properties/ProjectAssemblyInfo.cs b/src/NEventStore/Properties/ProjectAssemblyInfo.cs deleted file mode 100644 index 94ee3b119..000000000 --- a/src/NEventStore/Properties/ProjectAssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("NEventStore")] -[assembly: AssemblyDescription("")] -[assembly: Guid("9cb4668f-d7b2-4ad9-8f9b-2af9903d2db2")] \ No newline at end of file diff --git a/src/NEventStore/Resources.Designer.cs b/src/NEventStore/Resources.Designer.cs deleted file mode 100644 index 53e1afe31..000000000 --- a/src/NEventStore/Resources.Designer.cs +++ /dev/null @@ -1,531 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Adding commit '{0}' with {1} events to stream '{2}' bucket'{3}'.. - /// - internal static string AddingCommitsToStream { - get { - return ResourceManager.GetString("AddingCommitsToStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Adding a snapshot for bucket '{0}' stream '{1}' at revision '{2}'.. - /// - internal static string AddingSnapshot { - get { - return ResourceManager.GetString("AddingSnapshot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The object has already been disposed.. - /// - internal static string AlreadyDisposed { - get { - return ResourceManager.GetString("AlreadyDisposed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Appending uncommitted event '{0}' to stream '{1}' bucket '{2}'. - /// - internal static string AppendingUncommittedToStream { - get { - return ResourceManager.GetString("AppendingUncommittedToStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attempting to append commit '{0}' to stream '{1}' bucket '{2}' at position '{3}'.. - /// - internal static string AttemptingToCommit { - get { - return ResourceManager.GetString("AttemptingToCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attempting to commit all changes on stream '{0}' bucket '{1}' to the underlying store.. - /// - internal static string AttemptingToCommitChanges { - get { - return ResourceManager.GetString("AttemptingToCommitChanges", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Building a commit attempt '{0}' on stream '{1}' bucket '{2}'.. - /// - internal static string BuildingCommitAttempt { - get { - return ResourceManager.GetString("BuildingCommitAttempt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The stream '{0}' bucket '{1}' was partially loaded up to revision {1}. Cannot append commits to a partially loaded stream, refreshing the stream.. - /// - internal static string CannotAddCommitsToPartiallyLoadedStream { - get { - return ResourceManager.GetString("CannotAddCommitsToPartiallyLoadedStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Clearing all uncommitted changes on stream '{0}' bucket '{1}'.. - /// - internal static string ClearingUncommittedChanges { - get { - return ResourceManager.GetString("ClearingUncommittedChanges", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Pipeline hook of type '{0}' rejected attempt '{1}'.. - /// - internal static string CommitRejectedByPipelineHook { - get { - return ResourceManager.GetString("CommitRejectedByPipelineHook", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Committing attempt '{0}' which contains {1} events to the underlying persistence engine.. - /// - internal static string CommittingAttempt { - get { - return ResourceManager.GetString("CommittingAttempt", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Converting an Event from '{0}' to '{1}'.. - /// - internal static string ConvertingEvent { - get { - return ResourceManager.GetString("ConvertingEvent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Creating stream '{0}' in bucket '{1}'.. - /// - internal static string CreatingStream { - get { - return ResourceManager.GetString("CreatingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Deleting stream '{0}' from bucket '{1}'.. - /// - internal static string DeletingStream { - get { - return ResourceManager.GetString("DeletingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Disposing engine.. - /// - internal static string DisposingEngine { - get { - return ResourceManager.GetString("DisposingEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits from bucket '{0}' since checkpoint '{1}' (excluded).. - /// - internal static string GettingAllCommitsFromBucketAndCheckpoint { - get { - return ResourceManager.GetString("GettingAllCommitsFromBucketAndCheckpoint", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits since checkpoint '{0}' (excluded).. - /// - internal static string GettingAllCommitsFromCheckpoint { - get { - return ResourceManager.GetString("GettingAllCommitsFromCheckpoint", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits for stream '{0}' bucket '{1}' between '{2}' and '{3}'.. - /// - internal static string GettingAllCommitsFromRevision { - get { - return ResourceManager.GetString("GettingAllCommitsFromRevision", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits from bucket '{0}' from '{1}' forward.. - /// - internal static string GettingAllCommitsFromTime { - get { - return ResourceManager.GetString("GettingAllCommitsFromTime", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits from bucket '{0}' from '{1}' to '{2}'.. - /// - internal static string GettingAllCommitsFromToTime { - get { - return ResourceManager.GetString("GettingAllCommitsFromToTime", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits from bucket '{0}' from checkpoint '{1}' (excluded) up to '{2}' (included).. - /// - internal static string GettingCommitsFromBucketAndFromToCheckpoint { - get { - return ResourceManager.GetString("GettingCommitsFromBucketAndFromToCheckpoint", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting all commits from checkpoint '{0}' (excluded) up to '{1}' (included).. - /// - internal static string GettingCommitsFromToCheckpoint { - get { - return ResourceManager.GetString("GettingCommitsFromToCheckpoint", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting the most recent snapshot from bucket '{0}' for stream '{1}' on/since revision '{2}'.. - /// - internal static string GettingSnapshotForStream { - get { - return ResourceManager.GetString("GettingSnapshotForStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Getting the set of all streams to be snapshot from bucket '{0}' which exceed {1} revisions without a snapshot.. - /// - internal static string GettingStreamsToSnapshot { - get { - return ResourceManager.GetString("GettingStreamsToSnapshot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Ignoring some events on commit '{0}' of stream '{1}' because they starting before revision {2}.. - /// - internal static string IgnoringBeforeRevision { - get { - return ResourceManager.GetString("IgnoringBeforeRevision", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Ignoring some events on commit '{0}' of stream '{1}' because they go beyond revision {2}.. - /// - internal static string IgnoringBeyondRevision { - get { - return ResourceManager.GetString("IgnoringBeyondRevision", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Initializing engine.. - /// - internal static string InitializingEngine { - get { - return ResourceManager.GetString("InitializingEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Initializing persistence engine.. - /// - internal static string InitializingPersistence { - get { - return ResourceManager.GetString("InitializingPersistence", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Pushing commit '{0}' to post-commit hook of type '{1}'.. - /// - internal static string InvokingPostCommitPipelineHooks { - get { - return ResourceManager.GetString("InvokingPostCommitPipelineHooks", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Pushing commit '{0}' to pre-commit hook of type '{1}'.. - /// - internal static string InvokingPreCommitHooks { - get { - return ResourceManager.GetString("InvokingPreCommitHooks", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to There are no outstanding changes to be committed stream '{0}' bucket '{1}'.. - /// - internal static string NoChangesToCommit { - get { - return ResourceManager.GetString("NoChangesToCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No other commits have been discovered that conflict for stream '{0}' bucket '{1}'.. - /// - internal static string NoConflicts { - get { - return ResourceManager.GetString("NoConflicts", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Purging all commits on stream '{0}' bucket '{1}' from tracking.. - /// - internal static string NoLongerTrackingStream { - get { - return ResourceManager.GetString("NoLongerTrackingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The stream revision must be a positive number.. - /// - internal static string NonPositiveRevisionNumber { - get { - return ResourceManager.GetString("NonPositiveRevisionNumber", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The commit sequence must be a positive number.. - /// - internal static string NonPositiveSequenceNumber { - get { - return ResourceManager.GetString("NonPositiveSequenceNumber", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Opening stream '{0}' from bucket '{1}' between revisions {2} and {3}.. - /// - internal static string OpeningStreamAtRevision { - get { - return ResourceManager.GetString("OpeningStreamAtRevision", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Opening stream '{0}' from bucket '{1}' with snapshot at {2} up to revision {3}.. - /// - internal static string OpeningStreamWithSnapshot { - get { - return ResourceManager.GetString("OpeningStreamWithSnapshot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Verifying that no other commits have succeed on the stream '{0}'.. - /// - internal static string OptimisticConcurrencyCheck { - get { - return ResourceManager.GetString("OptimisticConcurrencyCheck", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Pushing attempt '{0}' on stream '{1}' bucket '{2}' with '{3}' events to the underlying store.. - /// - internal static string PersistingCommit { - get { - return ResourceManager.GetString("PersistingCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to One or more pipeline hooks filtered out the commit.. - /// - internal static string PipelineHookFilteredCommit { - get { - return ResourceManager.GetString("PipelineHookFilteredCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Pipeline hook of type '{0}' skipped over commit '{1}'.. - /// - internal static string PipelineHookSkippedCommit { - get { - return ResourceManager.GetString("PipelineHookSkippedCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Purging all data from storage.. - /// - internal static string PurgingStore { - get { - return ResourceManager.GetString("PurgingStore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The collection is read only and cannot be modified.. - /// - internal static string ReadOnlyCollection { - get { - return ResourceManager.GetString("ReadOnlyCollection", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The stream revision must always be greater than or equal to the commit sequence.. - /// - internal static string RevisionTooSmall { - get { - return ResourceManager.GetString("RevisionTooSmall", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Shutting down event store.. - /// - internal static string ShuttingDownStore { - get { - return ResourceManager.GetString("ShuttingDownStore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Tracking commit {0} on stream '{1}' bucket '{2}'.. - /// - internal static string TrackingCommit { - get { - return ResourceManager.GetString("TrackingCommit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Tracking up to {0} streams.. - /// - internal static string TrackingStreams { - get { - return ResourceManager.GetString("TrackingStreams", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The underlying stream '{0}' bucket '{1}' has changed since the last known commit, refreshing the stream. Exception Message: {2}. - /// - internal static string UnderlyingStreamHasChanged { - get { - return ResourceManager.GetString("UnderlyingStreamHasChanged", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Updating stream head for stream '{0}' bucket '{1}'.. - /// - internal static string UpdatingStreamHead { - get { - return ResourceManager.GetString("UpdatingStreamHead", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Hook into pipeline with hooks: {0}. - /// - internal static string WireupHookIntoPipeline { - get { - return ResourceManager.GetString("WireupHookIntoPipeline", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configured Persistence Engine: {0}. - /// - internal static string WireupSetPersistenceEngine { - get { - return ResourceManager.GetString("WireupSetPersistenceEngine", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Configured serializer: {0}. - /// - internal static string WireupSetSerializer { - get { - return ResourceManager.GetString("WireupSetSerializer", resourceCulture); - } - } - } -} diff --git a/src/NEventStore/Resources.resx b/src/NEventStore/Resources.resx deleted file mode 100644 index 4e39441c4..000000000 --- a/src/NEventStore/Resources.resx +++ /dev/null @@ -1,276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The collection is read only and cannot be modified. - - - The object has already been disposed. - - - The commit sequence must be a positive number. - - - The stream revision must be a positive number. - - - The stream revision must always be greater than or equal to the commit sequence. - - - Initializing persistence engine. - - - Disposing engine. - - - Initializing engine. - - - Getting all commits for stream '{0}' bucket '{1}' between '{2}' and '{3}'. - - - Getting all commits from bucket '{0}' from '{1}' forward. - - - Getting all commits from bucket '{0}' from '{1}' to '{2}'. - - - Attempting to append commit '{0}' to stream '{1}' bucket '{2}' at position '{3}'. - - - Updating stream head for stream '{0}' bucket '{1}'. - - - Getting the set of all streams to be snapshot from bucket '{0}' which exceed {1} revisions without a snapshot. - - - Getting the most recent snapshot from bucket '{0}' for stream '{1}' on/since revision '{2}'. - - - Adding a snapshot for bucket '{0}' stream '{1}' at revision '{2}'. - - - Purging all data from storage. - - - Tracking up to {0} streams. - - - Verifying that no other commits have succeed on the stream '{0}'. - - - No other commits have been discovered that conflict for stream '{0}' bucket '{1}'. - - - Tracking commit {0} on stream '{1}' bucket '{2}'. - - - Purging all commits on stream '{0}' bucket '{1}' from tracking. - - - Creating stream '{0}' in bucket '{1}'. - - - Opening stream '{0}' from bucket '{1}' between revisions {2} and {3}. - - - Opening stream '{0}' from bucket '{1}' with snapshot at {2} up to revision {3}. - - - Pipeline hook of type '{0}' skipped over commit '{1}'. - - - One or more pipeline hooks filtered out the commit. - - - Pushing commit '{0}' to pre-commit hook of type '{1}'. - - - Pipeline hook of type '{0}' rejected attempt '{1}'. - - - Committing attempt '{0}' which contains {1} events to the underlying persistence engine. - - - Pushing commit '{0}' to post-commit hook of type '{1}'. - - - Adding commit '{0}' with {1} events to stream '{2}' bucket'{3}'. - - - Ignoring some events on commit '{0}' of stream '{1}' because they go beyond revision {2}. - - - Ignoring some events on commit '{0}' of stream '{1}' because they starting before revision {2}. - - - Appending uncommitted event '{0}' to stream '{1}' bucket '{2}' - - - Attempting to commit all changes on stream '{0}' bucket '{1}' to the underlying store. - - - There are no outstanding changes to be committed stream '{0}' bucket '{1}'. - - - The underlying stream '{0}' bucket '{1}' has changed since the last known commit, refreshing the stream. Exception Message: {2} - - - Pushing attempt '{0}' on stream '{1}' bucket '{2}' with '{3}' events to the underlying store. - - - Building a commit attempt '{0}' on stream '{1}' bucket '{2}'. - - - Clearing all uncommitted changes on stream '{0}' bucket '{1}'. - - - Shutting down event store. - - - Converting an Event from '{0}' to '{1}'. - - - Getting all commits since checkpoint '{0}' (excluded). - - - Getting all commits from bucket '{0}' since checkpoint '{1}' (excluded). - - - Deleting stream '{0}' from bucket '{1}'. - - - Hook into pipeline with hooks: {0} - - - Configured Persistence Engine: {0} - - - Configured serializer: {0} - - - The stream '{0}' bucket '{1}' was partially loaded up to revision {1}. Cannot append commits to a partially loaded stream, refreshing the stream. - - - Getting all commits from bucket '{0}' from checkpoint '{1}' (excluded) up to '{2}' (included). - - - Getting all commits from checkpoint '{0}' (excluded) up to '{1}' (included). - - \ No newline at end of file diff --git a/src/NEventStore/Serialization/ByteStreamDocumentSerializer.cs b/src/NEventStore/Serialization/ByteStreamDocumentSerializer.cs deleted file mode 100644 index e001e03fc..000000000 --- a/src/NEventStore/Serialization/ByteStreamDocumentSerializer.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Serialization -{ - /// - /// A document serializer that uses a serializer to serialize and deserialize objects to and from byte arrays. - /// - public class ByteStreamDocumentSerializer : IDocumentSerializer - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(ByteStreamDocumentSerializer)); - private readonly ISerialize _serializer; - - /// - /// Initializes a new instance of the ByteStreamDocumentSerializer class. - /// - public ByteStreamDocumentSerializer(ISerialize serializer) - { - _serializer = serializer; - } - - /// - /// Serializes the object graph in a byte array - public object Serialize(T graph) where T : notnull - { - if (graph == null) - { - throw new ArgumentNullException(nameof(graph)); - } - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - return _serializer.Serialize(graph); - } - - /// - /// - /// Accepts a byte array (in the form of a byte array or a base64 encoded string) - /// and deserialize it to an object graph. - /// - public T? Deserialize(object document) - { - var bytes = (FromBase64(document as string) ?? document as byte[]) - ?? throw new NotSupportedException("document must be byte[] or a string representing base64 encoded byte[]"); - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - return _serializer.Deserialize(bytes); - } - - private static byte[]? FromBase64(string? value) - { - if (string.IsNullOrEmpty(value)) - { - return null; - } - - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.InspectingTextStream); - } - - try - { - return Convert.FromBase64String(value); - } - catch (FormatException) - { - return null; - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/DocumentObjectSerializer.cs b/src/NEventStore/Serialization/DocumentObjectSerializer.cs deleted file mode 100644 index d050849fe..000000000 --- a/src/NEventStore/Serialization/DocumentObjectSerializer.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace NEventStore.Serialization -{ - /// - /// A simple serializer that does not perform any serialization. - /// - public class DocumentObjectSerializer : IDocumentSerializer - { - /// - public object Serialize(T graph) where T : notnull - { - if (graph == null) - { - throw new ArgumentNullException(nameof(graph)); - } - return graph; - } - - /// - public T? Deserialize(object document) - { - return (T?)document; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/GzipSerializer.cs b/src/NEventStore/Serialization/GzipSerializer.cs deleted file mode 100644 index d2dd6edcd..000000000 --- a/src/NEventStore/Serialization/GzipSerializer.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.IO.Compression; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Serialization -{ - /// - /// Represents a serializer that compresses the serialized object using GZip. - /// - public class GzipSerializer : ISerialize - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(GzipSerializer)); - private readonly ISerialize _inner; - - /// - /// Initializes a new instance of the GzipSerializer class. - /// - public GzipSerializer(ISerialize inner) - { - _inner = inner; - } - - /// - public virtual void Serialize(Stream output, T graph) where T : notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - using var compress = new DeflateStream(output, CompressionMode.Compress, true); - _inner.Serialize(compress, graph); - } - - /// - public virtual T? Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - using var decompress = new DeflateStream(input, CompressionMode.Decompress, true); - return _inner.Deserialize(decompress); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/IDocumentSerializer.cs b/src/NEventStore/Serialization/IDocumentSerializer.cs deleted file mode 100644 index 74c51782d..000000000 --- a/src/NEventStore/Serialization/IDocumentSerializer.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace NEventStore.Serialization -{ - /// - /// Provides the ability to serialize an object graph to and from a document. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface IDocumentSerializer - { - /// - /// Serializes the object graph provided into a document. - /// - /// The type of object to be serialized - /// The object graph to be serialized. - /// The document form of the graph provided. - object Serialize(T graph) where T : notnull; - - /// - /// Deserializes the document provided into an object graph. - /// - /// The type of object graph. - /// The document to be deserialized. - /// An object graph of the specified type. - T? Deserialize(object document); - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/ISerialize.cs b/src/NEventStore/Serialization/ISerialize.cs deleted file mode 100644 index ba00cf418..000000000 --- a/src/NEventStore/Serialization/ISerialize.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace NEventStore.Serialization -{ - using System.IO; - - /// - /// Provides the ability to serialize and deserialize an object graph. - /// - /// - /// Instances of this class must be designed to be multi-thread safe such that they can be shared between threads. - /// - public interface ISerialize - { - /// - /// Serializes the object graph provided and writes a serialized representation to the output stream provided. - /// - /// The type of object to be serialized - /// The stream into which the serialized object graph should be written. - /// The object graph to be serialized. - void Serialize(Stream output, T graph) where T : notnull; - - /// - /// Deserializes the stream provided and reconstructs the corresponding object graph. - /// - /// The type of object to be deserialized. - /// The stream of bytes from which the object will be reconstructed. - /// The reconstructed object. - T? Deserialize(Stream input); - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/Messages.Designer.cs b/src/NEventStore/Serialization/Messages.Designer.cs deleted file mode 100644 index 5bd835077..000000000 --- a/src/NEventStore/Serialization/Messages.Designer.cs +++ /dev/null @@ -1,99 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NEventStore.Serialization { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Messages { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Messages() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NEventStore.Serialization.Messages", typeof(Messages).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Deserializing stream to object of type '{0}'.. - /// - internal static string DeserializingStream { - get { - return ResourceManager.GetString("DeserializingStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Inspecting text-based stream contents.. - /// - internal static string InspectingTextStream { - get { - return ResourceManager.GetString("InspectingTextStream", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The encryption key must be exactly 16 bytes.. - /// - internal static string InvalidKeyLength { - get { - return ResourceManager.GetString("InvalidKeyLength", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Serializing object graph of type '{0}'.. - /// - internal static string SerializingGraph { - get { - return ResourceManager.GetString("SerializingGraph", resourceCulture); - } - } - } -} diff --git a/src/NEventStore/Serialization/Messages.resx b/src/NEventStore/Serialization/Messages.resx deleted file mode 100644 index 87a2e1f68..000000000 --- a/src/NEventStore/Serialization/Messages.resx +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Deserializing stream to object of type '{0}'. - - - Serializing object graph of type '{0}'. - - - The encryption key must be exactly 16 bytes. - - - Inspecting text-based stream contents. - - \ No newline at end of file diff --git a/src/NEventStore/Serialization/NonDisposableStream.cs b/src/NEventStore/Serialization/NonDisposableStream.cs deleted file mode 100644 index 4d9ffaf7a..000000000 --- a/src/NEventStore/Serialization/NonDisposableStream.cs +++ /dev/null @@ -1,83 +0,0 @@ -namespace NEventStore.Serialization -{ - using System.IO; - - /// - /// Represents a stream that wraps another stream and prevents it from being disposed. - /// - internal class NonDisposableStream : Stream - { - private readonly Stream _stream; - - /// - /// Initializes a new instance of the NonDisposableStream class. - /// - public NonDisposableStream(Stream stream) - { - _stream = stream; - } - - public override bool CanRead - { - get { return _stream.CanRead; } - } - - public override bool CanSeek - { - get { return _stream.CanSeek; } - } - - public override bool CanWrite - { - get { return _stream.CanWrite; } - } - - public override long Length - { - get { return _stream.Length; } - } - - public override long Position - { - get { return _stream.Position; } - set { _stream.Position = value; } - } - -#pragma warning disable CA2215 // Dispose methods should call base class dispose - protected override void Dispose(bool disposing) -#pragma warning restore CA2215 // Dispose methods should call base class dispose - { - // no-op - } - - public override void Close() - { - // no-op - } - - public override void Flush() - { - _stream.Flush(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return _stream.Seek(offset, origin); - } - - public override void SetLength(long value) - { - _stream.SetLength(value); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return _stream.Read(buffer, offset, count); - } - - public override void Write(byte[] buffer, int offset, int count) - { - _stream.Write(buffer, offset, count); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/RijndaelSerializer.cs b/src/NEventStore/Serialization/RijndaelSerializer.cs deleted file mode 100644 index 6bd1e615b..000000000 --- a/src/NEventStore/Serialization/RijndaelSerializer.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections; -using System.Security.Cryptography; -using Microsoft.Extensions.Logging; -using NEventStore.Logging; - -namespace NEventStore.Serialization -{ - /// - /// Represents a serializer that encrypts the serialized data using the Rijndael algorithm. - /// - public class RijndaelSerializer : ISerialize - { - private const int KeyLength = 16; // bytes - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(RijndaelSerializer)); - private readonly byte[] _encryptionKey; - private readonly ISerialize _inner; - - /// - /// Initializes a new instance of the RijndaelSerializer class. - /// - /// - public RijndaelSerializer(ISerialize inner, byte[] encryptionKey) - { - if (!KeyIsValid(encryptionKey, KeyLength)) - { - throw new ArgumentException(Messages.InvalidKeyLength, nameof(encryptionKey)); - } - - _encryptionKey = encryptionKey; - _inner = inner; - } - - /// - public virtual void Serialize(Stream output, T graph) where T: notnull - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.SerializingGraph, typeof(T)); - } - - using var rijndael = new RijndaelManaged(); - rijndael.Key = _encryptionKey; - rijndael.Mode = CipherMode.CBC; - rijndael.GenerateIV(); - - using ICryptoTransform encryptor = rijndael.CreateEncryptor(); - using var wrappedOutput = new NonDisposableStream(output); - using var encryptionStream = new CryptoStream(wrappedOutput, encryptor, CryptoStreamMode.Write); - wrappedOutput.Write(rijndael.IV, 0, rijndael.IV.Length); - _inner.Serialize(encryptionStream, graph); - encryptionStream.Flush(); - encryptionStream.FlushFinalBlock(); - } - - /// - public virtual T? Deserialize(Stream input) - { - if (Logger.IsEnabled(LogLevel.Trace)) - { - Logger.LogTrace(Messages.DeserializingStream, typeof(T)); - } - - using var rijndael = new RijndaelManaged(); - rijndael.Key = _encryptionKey; - rijndael.IV = GetInitVectorFromStream(input, rijndael.IV.Length); - rijndael.Mode = CipherMode.CBC; - - using ICryptoTransform decrypter = rijndael.CreateDecryptor(); - using var decryptedStream = new CryptoStream(input, decrypter, CryptoStreamMode.Read); - return _inner.Deserialize(decryptedStream); - } - - private static bool KeyIsValid(ICollection key, int length) - { - return key != null && key.Count == length; - } - - private static byte[] GetInitVectorFromStream(Stream encrypted, int initVectorSizeInBytes) - { - var buffer = new byte[initVectorSizeInBytes]; - encrypted.Read(buffer, 0, buffer.Length); - return buffer; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Serialization/SerializationExtensions.cs b/src/NEventStore/Serialization/SerializationExtensions.cs deleted file mode 100644 index 6e7e7cb93..000000000 --- a/src/NEventStore/Serialization/SerializationExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ - -namespace NEventStore.Serialization -{ - /// - /// Implements extension methods that make call to the serialization infrastructure more simple. - /// - public static class SerializationExtensions - { - /// - /// Serializes the object provided. - /// - /// The type of object to be serialized - /// The serializer to use. - /// The object graph to be serialized. - /// A serialized representation of the object graph provided. - public static byte[] Serialize(this ISerialize serializer, T value) where T : notnull - { - using var stream = new MemoryStream(); - serializer.Serialize(stream, value); - return stream.ToArray(); - } - - /// - /// Deserializes the array of bytes provided. - /// - /// The type of object to be deserialized. - /// The serializer to use. - /// The serialized array of bytes. - /// The reconstituted object, if any. - public static T? Deserialize(this ISerialize serializer, byte[] serialized) - { - // add null or empty check - if (serialized == null || serialized.Length == 0) - { - throw new ArgumentNullException(nameof(serialized), "cannot be null or empty."); - } - - using var stream = new MemoryStream(serialized); - return serializer.Deserialize(stream); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/SerializationWireup.cs b/src/NEventStore/SerializationWireup.cs deleted file mode 100644 index e98f8f591..000000000 --- a/src/NEventStore/SerializationWireup.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.Extensions.Logging; -using NEventStore.Logging; -using NEventStore.Serialization; - -namespace NEventStore -{ - /// - /// Represents the configuration for serialization. - /// - public class SerializationWireup : Wireup - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(SerializationWireup)); - - /// - /// Initializes a new instance of the SerializationWireup class. - /// - public SerializationWireup(Wireup inner, ISerialize serializer) - : base(inner) - { - Container.Register(serializer); - } - - /// - /// Enable GZip compression on the serialized stream. - /// - public SerializationWireup Compress() - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.ConfiguringCompression); - } - var wrapped = Container.Resolve() - ?? throw new InvalidOperationException("Serialize not configured."); - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.WrappingSerializerGZip, wrapped.GetType()); - } - Container.Register(new GzipSerializer(wrapped)); - return this; - } - - /// - /// Enable Rijndael encryption on the serialized stream. - /// - public SerializationWireup EncryptWith(byte[] encryptionKey) - { - if (Logger.IsEnabled(LogLevel.Debug)) - { - Logger.LogDebug(Messages.ConfiguringEncryption); - } - var wrapped = Container.Resolve() - ?? throw new InvalidOperationException("Serialize not configured."); - - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Messages.WrappingSerializerEncryption, wrapped.GetType()); - } - Container.Register(new RijndaelSerializer(wrapped, encryptionKey)); - return this; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/SerializationWireupExtensions.cs b/src/NEventStore/SerializationWireupExtensions.cs deleted file mode 100644 index faa39c577..000000000 --- a/src/NEventStore/SerializationWireupExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using NEventStore.Logging; -using Microsoft.Extensions.Logging; -using NEventStore.Serialization; - -namespace NEventStore -{ - /// - /// Represents the configuration for serialization. - /// - public static class SerializationWireupExtensions - { - private static readonly ILogger Logger = LogFactory.BuildLogger(typeof(PersistenceWireup)); - - /// - /// Configure custom serialization. - /// - public static SerializationWireup UsingCustomSerialization(this PersistenceWireup wireup, ISerialize serializer) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.WireupSetSerializer, serializer.GetType()); - } - return new SerializationWireup(wireup, serializer); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Snapshot.cs b/src/NEventStore/Snapshot.cs deleted file mode 100644 index 6fb768167..000000000 --- a/src/NEventStore/Snapshot.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Runtime.Serialization; - -namespace NEventStore -{ - /// - /// Represents a materialized view of a stream at specific revision. - /// - [DataContract] - [Serializable] - public class Snapshot : ISnapshot - { - /// - /// Initializes a new instance of the Snapshot class for the default bucket. - /// - /// The value which uniquely identifies the stream to which the snapshot applies. - /// The position at which the snapshot applies. - /// The snapshot or materialized view of the stream at the revision indicated. - public Snapshot(string streamId, int streamRevision, object payload) - : this(Bucket.Default, streamId, streamRevision, payload) - {} - - /// - /// Initializes a new instance of the Snapshot class. - /// - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream to which the snapshot applies. - /// The position at which the snapshot applies. - /// The snapshot or materialized view of the stream at the revision indicated. - public Snapshot(string bucketId, string streamId, int streamRevision, object payload) - : this() - { - BucketId = bucketId; - StreamId = streamId; - StreamRevision = streamRevision; - Payload = payload; - } - - /// - /// Initializes a new instance of the Snapshot class. - /// - protected Snapshot() - {} - - /// - [DataMember] - public virtual string BucketId { get; private set; } - - /// - /// Gets the value which uniquely identifies the stream to which the snapshot applies. - /// - [DataMember] - public virtual string StreamId { get; private set; } - - /// - /// Gets the position at which the snapshot applies. - /// - [DataMember] - public virtual int StreamRevision { get; private set; } - - /// - /// Gets the snapshot or materialized view of the stream at the revision indicated. - /// - [DataMember] - public virtual object Payload { get; private set; } - } -} \ No newline at end of file diff --git a/src/NEventStore/StoreEventsExtensions.cs b/src/NEventStore/StoreEventsExtensions.cs deleted file mode 100644 index bbd8a8d5d..000000000 --- a/src/NEventStore/StoreEventsExtensions.cs +++ /dev/null @@ -1,167 +0,0 @@ -using NEventStore.Persistence; - -namespace NEventStore -{ - /// - /// Provides extension methods for . - /// - public static class StoreEventsExtensions - { - /// - /// Creates a new stream. - /// - /// The store events instance. - /// The value which uniquely identifies the stream to be created. - /// An empty stream. - public static IEventStream CreateStream(this IStoreEvents storeEvents, Guid streamId) - { - return CreateStream(storeEvents, Bucket.Default, streamId); - } - - /// - /// Creates a new stream. - /// - /// The store events instance. - /// The value which uniquely identifies the stream to be created. - /// An empty stream. - public static IEventStream CreateStream(this IStoreEvents storeEvents, string streamId) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.CreateStream(Bucket.Default, streamId); - } - - /// - /// Creates a new stream. - /// - /// The store events instance. - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream within the bucket to be created. - /// An empty stream. - public static IEventStream CreateStream(this IStoreEvents storeEvents, string bucketId, Guid streamId) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.CreateStream(bucketId, streamId.ToString()); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies the stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events represented as a stream. - /// - /// - /// - public static IEventStream OpenStream(this IStoreEvents storeEvents, Guid streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue) - { - EnsureStoreEventsNotNull(storeEvents); - return OpenStream(storeEvents, Bucket.Default, streamId, minRevision, maxRevision); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies the stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events represented as a stream. - /// - /// - /// - public static IEventStream OpenStream(this IStoreEvents storeEvents, string streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.OpenStream(Bucket.Default, streamId, minRevision, maxRevision); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream within the bucket to be created. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// A series of committed events represented as a stream. - /// - /// - /// - public static IEventStream OpenStream(this IStoreEvents storeEvents, string bucketId, Guid streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.OpenStream(bucketId, streamId.ToString(), minRevision, maxRevision); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies the stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// The token to monitor for cancellation requests. - /// A series of committed events represented as a stream. - /// - /// - /// - public static Task OpenStreamAsync(this IStoreEvents storeEvents, Guid streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue, CancellationToken cancellationToken = default) - { - EnsureStoreEventsNotNull(storeEvents); - return OpenStreamAsync(storeEvents, Bucket.Default, streamId, minRevision, maxRevision, cancellationToken); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies the stream from which the events will be read. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// The token to monitor for cancellation requests. - /// A series of committed events represented as a stream. - /// - /// - /// - public static Task OpenStreamAsync(this IStoreEvents storeEvents, string streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue, CancellationToken cancellationToken = default) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.OpenStreamAsync(Bucket.Default, streamId, minRevision, maxRevision, cancellationToken); - } - - /// - /// Reads the stream indicated from the minimum revision specified up to the maximum revision specified or creates - /// an empty stream if no commits are found and a minimum revision of zero is provided. - /// - /// The store events instance. - /// The value which uniquely identifies bucket the stream belongs to. - /// The value which uniquely identifies the stream within the bucket to be created. - /// The minimum revision of the stream to be read. - /// The maximum revision of the stream to be read. - /// The token to monitor for cancellation requests. - /// A series of committed events represented as a stream. - /// - /// - /// - public static Task OpenStreamAsync(this IStoreEvents storeEvents, string bucketId, Guid streamId, int minRevision = int.MinValue, int maxRevision = int.MaxValue, CancellationToken cancellationToken = default) - { - EnsureStoreEventsNotNull(storeEvents); - return storeEvents.OpenStreamAsync(bucketId, streamId.ToString(), minRevision, maxRevision, cancellationToken); - } - - private static void EnsureStoreEventsNotNull(IStoreEvents storeEvents) - { - if (storeEvents == null) - { - throw new ArgumentNullException(nameof(storeEvents)); - } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/StreamHeadObserver.cs b/src/NEventStore/StreamHeadObserver.cs deleted file mode 100644 index 1c30129cf..000000000 --- a/src/NEventStore/StreamHeadObserver.cs +++ /dev/null @@ -1,54 +0,0 @@ -using NEventStore.Persistence; -using System.Runtime.ExceptionServices; - -namespace NEventStore -{ - /// - /// Represents an async observer that can receive and stores commits from a stream. - /// Can be used as base class for other observers. - /// - public class StreamHeadObserver : IAsyncObserver - { - /// - /// The list of commits read from the stream - /// - public IList StreamHeads { get; } = []; - - /// - /// Indicates if the read operation has completed - /// - public bool ReadCompleted { get; private set; } - - /// - /// Store the commits received from the stream - /// - public virtual Task OnNextAsync(IStreamHead value, CancellationToken cancellationToken) - { - StreamHeads.Add(value); - return Task.FromResult(true); - } - - /// - /// Notifies the observer that the provider has experienced an error condition. - /// - /// Preserve the stack trace and rethrow the exception that occurred while reading commits from the stream. - /// - /// - /// Override this method to log and handle the error. - /// - /// - public virtual Task OnErrorAsync(Exception ex, CancellationToken cancellationToken) - { - // Preserve the stack trace and rethrow the exception - ExceptionDispatchInfo.Capture(ex).Throw(); - return Task.CompletedTask; - } - - /// - public virtual Task OnCompletedAsync(CancellationToken cancellationToken) - { - ReadCompleted = true; - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/src/NEventStore/StreamNotFoundException.cs b/src/NEventStore/StreamNotFoundException.cs deleted file mode 100644 index 25478862d..000000000 --- a/src/NEventStore/StreamNotFoundException.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Runtime.Serialization; - -namespace NEventStore -{ - /// - /// Represents an attempt to retrieve a nonexistent event stream. - /// - [Serializable] - public class StreamNotFoundException : Exception - { - /// - /// Initializes a new instance of the StreamNotFoundException class. - /// - public StreamNotFoundException() - {} - - /// - /// Initializes a new instance of the StreamNotFoundException class. - /// - /// The message that describes the error. - public StreamNotFoundException(string message) - : base(message) - {} - - /// - /// Initializes a new instance of the StreamNotFoundException class. - /// - /// The message that describes the error. - /// The message that is the cause of the current exception. - public StreamNotFoundException(string message, Exception innerException) - : base(message, innerException) - {} - - /// - /// Initializes a new instance of the StreamNotFoundException class. - /// - /// The SerializationInfo that holds the serialized object data of the exception being thrown. - /// The StreamingContext that contains contextual information about the source or destination. - protected StreamNotFoundException(SerializationInfo info, StreamingContext context) - : base(info, context) - {} - } -} \ No newline at end of file diff --git a/src/NEventStore/SystemTime.cs b/src/NEventStore/SystemTime.cs deleted file mode 100644 index ad5cb4ae4..000000000 --- a/src/NEventStore/SystemTime.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace NEventStore -{ - /// - /// Provides the ability to override the current moment in time to facilitate testing. - /// Original idea by Ayende Rahien: - /// http://ayende.com/Blog/archive/2008/07/07/Dealing-with-time-in-tests.aspx - /// - public static class SystemTime - { - /// - /// The callback to be used to resolve the current moment in time. - /// - public static Func? Resolver { get; set; } - - /// - /// Gets the current moment in time. - /// - public static DateTime UtcNow - { - get { return Resolver == null ? DateTime.UtcNow : Resolver(); } - } - } -} \ No newline at end of file diff --git a/src/NEventStore/TaskHelpers.cs b/src/NEventStore/TaskHelpers.cs deleted file mode 100644 index 173ead8e4..000000000 --- a/src/NEventStore/TaskHelpers.cs +++ /dev/null @@ -1,78 +0,0 @@ -namespace NEventStore -{ - internal static class TaskHelpers - { - internal static Task Delay(double milliseconds, CancellationToken cancellationToken) - { - var tcs = new TaskCompletionSource(); - TimerCallback callback = (_) => tcs.TrySetResult(true); -#pragma warning disable IDE0067 // Dispose objects before losing scope - var timer = new Timer(callback, null, 0, Convert.ToInt32(milliseconds)); -#pragma warning restore IDE0067 // Dispose objects before losing scope - CancellationTokenRegistration cancellationTokenRegistration = cancellationToken.Register(() => - { - timer.Dispose(); - tcs.TrySetCanceled(); - }); - return tcs.Task.ContinueWith(_ => - { - cancellationTokenRegistration.Dispose(); - timer.Dispose(); - }, TaskContinuationOptions.ExecuteSynchronously); - } - - public static void WhenCompleted(this Task task, Action> onComplete, Action> onFaulted, bool execSync = false) - { - if (task.IsCompleted) - { - if (task.IsFaulted) - { - onFaulted.Invoke(task); - return; - } - - onComplete.Invoke(task); - return; - } - - task.ContinueWith( - onComplete, - execSync ? - TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion : - TaskContinuationOptions.OnlyOnRanToCompletion); - - task.ContinueWith( - onFaulted, - execSync ? - TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted : - TaskContinuationOptions.OnlyOnFaulted); - } - - public static void WhenCompleted(this Task task, Action onComplete, Action onFaulted, bool execSync = false) - { - if (task.IsCompleted) - { - if (task.IsFaulted) - { - onFaulted.Invoke(task); - return; - } - - onComplete.Invoke(task); - return; - } - - task.ContinueWith( - onComplete, - execSync ? - TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnRanToCompletion : - TaskContinuationOptions.OnlyOnRanToCompletion); - - task.ContinueWith( - onFaulted, - execSync ? - TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted : - TaskContinuationOptions.OnlyOnFaulted); - } - } -} \ No newline at end of file diff --git a/src/NEventStore/Wireup.cs b/src/NEventStore/Wireup.cs deleted file mode 100644 index 5a6cbdd00..000000000 --- a/src/NEventStore/Wireup.cs +++ /dev/null @@ -1,157 +0,0 @@ -using NEventStore.Conversion; -using NEventStore.Persistence; -using NEventStore.Persistence.InMemory; -using NEventStore.Logging; -using Microsoft.Extensions.Logging; - -namespace NEventStore -{ - /// - /// Represents the configuration for the event store. - /// - public class Wireup - { - private readonly NanoContainer? _container; - private readonly Wireup? _inner; - private readonly ILogger Logger = LogFactory.BuildLogger(typeof(Wireup)); - - /// - /// Initializes a new instance of the Wireup class. - /// - protected Wireup(NanoContainer container) - { - _container = container ?? throw new ArgumentNullException(nameof(container)); - } - - /// - /// Initializes a new instance of the Wireup class. - /// - protected Wireup(Wireup inner) - { - _inner = inner ?? throw new ArgumentNullException(nameof(inner)); - } - - /// - /// Gets the container. - /// - protected NanoContainer Container - { - get { return _container ?? _inner!.Container; } - } - - /// - /// Initializes a new instance of the Wire-up class. - /// - public static Wireup Init() - { - var container = new NanoContainer(); - - container.Register(new InMemoryPersistenceEngine()); - container.Register(BuildEventStore); - - return new Wireup(container); - } - - /// - /// Registers a service with the container. - /// - public virtual Wireup Register(T instance) where T : class - { - Container.Register(instance); - return this; - } - - /// - /// Add pipeline hooks to the processing pipeline. - /// - public virtual Wireup HookIntoPipelineUsing(IEnumerable hooks) - { - return HookIntoPipelineUsing((hooks ?? []).ToArray()); - } - - /// - /// Add pipeline hooks to the processing pipeline. - /// - public virtual Wireup HookIntoPipelineUsing(params IPipelineHook[] hooks) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.WireupHookIntoPipeline, string.Join(", ", hooks.Select(h => h.GetType()))); - } - ICollection collection = (hooks ?? []).Where(x => x != null).ToArray(); - Container.Register(collection); - return this; - } - - /// - /// Add pipeline hooks to the processing pipeline. - /// - public virtual Wireup HookIntoPipelineUsing(IEnumerable hooks) - { - return HookIntoPipelineUsing((hooks ?? []).ToArray()); - } - - /// - /// Add pipeline hooks to the processing pipeline. - /// Asynchronous hooks are executed after the synchronous hooks. - /// - public virtual Wireup HookIntoPipelineUsing(params IPipelineHookAsync[] hooks) - { - if (Logger.IsEnabled(LogLevel.Information)) - { - Logger.LogInformation(Resources.WireupHookIntoPipeline, string.Join(", ", hooks.Select(h => h.GetType()))); - } - ICollection collection = (hooks ?? []).Where(x => x != null).ToArray(); - Container.Register(collection); - return this; - } - - /// - /// Builds the configured event store. - /// - public virtual IStoreEvents Build() - { - if (_inner != null) - { - return _inner.Build(); - } - - return Container.Resolve() - ?? throw new InvalidOperationException("IStoreEvents was not registered."); - } - - /// - /// - /// Provide some additional concurrency checks to avoid useless roundtrips to the databases in a non-transactional environment. - /// - /// - /// If you enable any sort of two-phase commit and/or transactional behavior on the Persistence drivers - /// you should not use the module. - /// - /// - public Wireup UseOptimisticPipelineHook(int maxStreamsToTrack = OptimisticPipelineHook.MaxStreamsToTrack) - { - Container.Register(_ => new OptimisticPipelineHook(maxStreamsToTrack)); - return this; - } - - private static IStoreEvents BuildEventStore(NanoContainer context) - { - var concurrency = context.Resolve(); - var upconverter = context.Resolve(); - - ICollection hooks = context.Resolve>() ?? []; - var pipelineHooks = new List(hooks); - if (concurrency != null) - { - pipelineHooks.Add(concurrency); - } - if (upconverter != null) - { - pipelineHooks.Add(upconverter); - } - ICollection hooksAsync = context.Resolve>() ?? []; - return new OptimisticEventStore(context.Resolve()!, pipelineHooks, hooksAsync); - } - } -} \ No newline at end of file diff --git a/src/packages.config b/src/packages.config deleted file mode 100644 index e37e764ee..000000000 --- a/src/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/tests_dotnetcore.runsettings b/src/tests_dotnetcore.runsettings deleted file mode 100644 index a14d14a9a..000000000 --- a/src/tests_dotnetcore.runsettings +++ /dev/null @@ -1,6 +0,0 @@ - - - - true - - \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css new file mode 100644 index 000000000..e65cedff6 --- /dev/null +++ b/stylesheets/pygment_trac.css @@ -0,0 +1,70 @@ +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f0f3f3; } +.highlight .c { color: #0099FF; font-style: italic } /* Comment */ +.highlight .err { color: #AA0000; background-color: #FFAAAA } /* Error */ +.highlight .k { color: #006699; font-weight: bold } /* Keyword */ +.highlight .o { color: #555555 } /* Operator */ +.highlight .cm { color: #0099FF; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #009999 } /* Comment.Preproc */ +.highlight .c1 { color: #0099FF; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #0099FF; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { background-color: #FFCCCC; border: 1px solid #CC0000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #003300; font-weight: bold } /* Generic.Heading */ +.highlight .gi { background-color: #CCFFCC; border: 1px solid #00CC00 } /* Generic.Inserted */ +.highlight .go { color: #AAAAAA } /* Generic.Output */ +.highlight .gp { color: #000099; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #003300; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #99CC66 } /* Generic.Traceback */ +.highlight .kc { color: #006699; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #006699; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #006699; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #006699 } /* Keyword.Pseudo */ +.highlight .kr { color: #006699; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #007788; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #FF6600 } /* Literal.Number */ +.highlight .s { color: #CC3300 } /* Literal.String */ +.highlight .na { color: #330099 } /* Name.Attribute */ +.highlight .nb { color: #336666 } /* Name.Builtin */ +.highlight .nc { color: #00AA88; font-weight: bold } /* Name.Class */ +.highlight .no { color: #336600 } /* Name.Constant */ +.highlight .nd { color: #9999FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CC0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #CC00FF } /* Name.Function */ +.highlight .nl { color: #9999FF } /* Name.Label */ +.highlight .nn { color: #00CCFF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #330099; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #003333 } /* Name.Variable */ +.highlight .ow { color: #000000; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #FF6600 } /* Literal.Number.Float */ +.highlight .mh { color: #FF6600 } /* Literal.Number.Hex */ +.highlight .mi { color: #FF6600 } /* Literal.Number.Integer */ +.highlight .mo { color: #FF6600 } /* Literal.Number.Oct */ +.highlight .sb { color: #CC3300 } /* Literal.String.Backtick */ +.highlight .sc { color: #CC3300 } /* Literal.String.Char */ +.highlight .sd { color: #CC3300; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #CC3300 } /* Literal.String.Double */ +.highlight .se { color: #CC3300; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #CC3300 } /* Literal.String.Heredoc */ +.highlight .si { color: #AA0000 } /* Literal.String.Interpol */ +.highlight .sx { color: #CC3300 } /* Literal.String.Other */ +.highlight .sr { color: #33AAAA } /* Literal.String.Regex */ +.highlight .s1 { color: #CC3300 } /* Literal.String.Single */ +.highlight .ss { color: #FFCC33 } /* Literal.String.Symbol */ +.highlight .bp { color: #336666 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #003333 } /* Name.Variable.Class */ +.highlight .vg { color: #003333 } /* Name.Variable.Global */ +.highlight .vi { color: #003333 } /* Name.Variable.Instance */ +.highlight .il { color: #FF6600 } /* Literal.Number.Integer.Long */ + +.type-csharp .highlight .k { color: #0000FF } +.type-csharp .highlight .kt { color: #0000FF } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css new file mode 100644 index 000000000..d067c80d2 --- /dev/null +++ b/stylesheets/stylesheet.css @@ -0,0 +1,428 @@ +/******************************************************************************* +Slate Theme for GitHub Pages +by Jason Costello, @jsncostello +*******************************************************************************/ + +@import url(pygment_trac.css); + +/******************************************************************************* +MeyerWeb Reset +*******************************************************************************/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +ol, ul { + list-style: none; +} + +blockquote, q { +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +a:focus { + outline: none; +} + +/******************************************************************************* +Theme Styles +*******************************************************************************/ + +body { + box-sizing: border-box; + color:#373737; + background: #212121; + font-size: 16px; + font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +h1, h2, h3, h4, h5, h6 { + margin: 10px 0; + font-weight: 700; + color:#222222; + font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; + letter-spacing: -1px; +} + +h1 { + font-size: 36px; + font-weight: 700; +} + +h2 { + padding-bottom: 10px; + font-size: 32px; + background: url('../images/bg_hr.png') repeat-x bottom; +} + +h3 { + font-size: 24px; +} + +h4 { + font-size: 21px; +} + +h5 { + font-size: 18px; +} + +h6 { + font-size: 16px; +} + +p { + margin: 10px 0 15px 0; +} + +footer p { + color: #f2f2f2; +} + +a { + text-decoration: none; + color: #007edf; + text-shadow: none; + + transition: color 0.5s ease; + transition: text-shadow 0.5s ease; + -webkit-transition: color 0.5s ease; + -webkit-transition: text-shadow 0.5s ease; + -moz-transition: color 0.5s ease; + -moz-transition: text-shadow 0.5s ease; + -o-transition: color 0.5s ease; + -o-transition: text-shadow 0.5s ease; + -ms-transition: color 0.5s ease; + -ms-transition: text-shadow 0.5s ease; +} + +#main_content a:hover { + color: #0069ba; + text-shadow: #0090ff 0px 0px 2px; +} + +footer a:hover { + color: #43adff; + text-shadow: #0090ff 0px 0px 2px; +} + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + +img { + position: relative; + margin: 0 auto; + max-width: 739px; + padding: 5px; + margin: 10px 0 10px 0; + border: 1px solid #ebebeb; + + box-shadow: 0 0 5px #ebebeb; + -webkit-box-shadow: 0 0 5px #ebebeb; + -moz-box-shadow: 0 0 5px #ebebeb; + -o-box-shadow: 0 0 5px #ebebeb; + -ms-box-shadow: 0 0 5px #ebebeb; +} + +pre, code { + width: 100%; + color: #222; + background-color: #fff; + + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + font-size: 14px; + + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + + + +} + +pre { + width: 100%; + padding: 10px; + box-shadow: 0 0 10px rgba(0,0,0,.1); + overflow: auto; +} + +code { + padding: 3px; + margin: 0 3px; + box-shadow: 0 0 10px rgba(0,0,0,.1); +} + +pre code { + display: block; + box-shadow: none; +} + +blockquote { + color: #666; + margin-bottom: 20px; + padding: 0 0 0 20px; + border-left: 3px solid #bbb; +} + +ul, ol, dl { + margin-bottom: 15px +} + +ul li { + list-style: inside; + padding-left: 20px; +} + +ol li { + list-style: decimal inside; + padding-left: 20px; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + height: 1px; + margin-bottom: 5px; + border: none; + background: url('../images/bg_hr.png') repeat-x center; +} + +table { + border: 1px solid #373737; + margin-bottom: 20px; + text-align: left; + } + +th { + font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; + padding: 10px; + background: #373737; + color: #fff; + } + +td { + padding: 10px; + border: 1px solid #373737; + } + +form { + background: #f2f2f2; + padding: 20px; +} + + + +/******************************************************************************* +Full-Width Styles +*******************************************************************************/ + +.outer { + width: 100%; +} + +.inner { + position: relative; + max-width: 640px; + padding: 20px 10px; + margin: 0 auto; +} + +#forkme_banner { + display: block; + position: absolute; + top:0; + right: 10px; + z-index: 10; + padding: 10px 50px 10px 10px; + color: #fff; + background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; + font-weight: 700; + box-shadow: 0 0 10px rgba(0,0,0,.5); + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +#header_wrap { + background: #212121; + background: -moz-linear-gradient(top, #373737, #212121); + background: -webkit-linear-gradient(top, #373737, #212121); + background: -ms-linear-gradient(top, #373737, #212121); + background: -o-linear-gradient(top, #373737, #212121); + background: linear-gradient(top, #373737, #212121); +} + +#header_wrap .inner { + padding: 50px 10px 30px 10px; +} + +#project_title { + margin: 0; + color: #fff; + font-size: 42px; + font-weight: 700; + text-shadow: #111 0px 0px 10px; +} + +#project_tagline { + color: #fff; + font-size: 24px; + font-weight: 300; + background: none; + text-shadow: #111 0px 0px 10px; +} + +#downloads { + position: absolute; + width: 210px; + z-index: 10; + bottom: -40px; + right: 0; + height: 70px; + background: url('../images/icon_download.png') no-repeat 0% 90%; +} + +.zip_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom left; +} + +.tar_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom right; + margin-left: 10px; +} + +.zip_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top left; +} + +.tar_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top right; +} + +#main_content_wrap { + background: #f2f2f2; + border-top: 1px solid #111; + border-bottom: 1px solid #111; +} + +#main_content { + padding-top: 40px; +} + +#footer_wrap { + background: #212121; +} + + + +/******************************************************************************* +Small Device Styles +*******************************************************************************/ + +@media screen and (max-width: 480px) { + body { + font-size:14px; + } + + #downloads { + display: none; + } + + .inner { + min-width: 320px; + max-width: 480px; + } + + #project_title { + font-size: 32px; + } + + h1 { + font-size: 28px; + } + + h2 { + font-size: 24px; + } + + h3 { + font-size: 21px; + } + + h4 { + font-size: 18px; + } + + h5 { + font-size: 14px; + } + + h6 { + font-size: 12px; + } + + code, pre { + min-width: 320px; + max-width: 480px; + font-size: 11px; + } + +}