Open stephanjohnson opened 7 months ago
I am going to create a couple of new projects with the following settings
Type: Clean Architecture Turn off Entity Framework Turn on Cosmos DB
I will experiment with different solutions for implementing this feature and discuss with the team.
One project will explore applying the etag as part of the method call for the Cosmos DB library that we use. An early problem with this was that the optional parameter is only available on Update methods, and not the Delete methods.
Another project will explore applying the etag to the document object when projecting from the entity. Cosmos DB should honor the existence of the etag on the document as it is received.
Ran into an issue while testing the Intent Generated code with the etag dictionary.
When reading an item, it is added to the dictionary based on its Id, but if you read the same item twice, you get an error because an item with the same key has been added already.
var customerA = await _customerRepository.FindByIdAsync(id, cancellationToken);
if (customerA is null)
{
throw new NotFoundException($"Could not find CustomerA '{id}'");
}
var customerB = await _customerRepository.FindByIdAsync(id, cancellationToken);
if (customerB is null)
{
throw new NotFoundException($"Could not find CustomerB '{id}'");
}
customerA.Name = "CustomerA";
_customerRepository.Update(customerA);
await _customerRepository.UnitOfWork.SaveChangesAsync(cancellationToken);
customerB.Name = "CustomerB";
_customerRepository.Update(customerB);
await _customerRepository.UnitOfWork.SaveChangesAsync(cancellationToken);
I completed the change, committed to the repo, just have to test the resulting generated code, and turn on the setting in one of the test projects
Testing the output completed. Next step is to modify one of the test projects to use this mode, and get it ready for CI SF tests
hmmm, one small problem is that the default value for "Use Optimistic Concurrency Default" is "On". This means that I have to update the version of the Intent.CosmosDB
in all of the CosmosDB test projects, and turn it off for all except one.
This might have an unseen impact on other test projects that use the module that I am unaware of as just yet, and as I do not have visibility into the AzureDevOps pipelines, I won't know if a build fails.
I am going to have to search all of the modules.config
files and update those projects too.
This is going to include the following other projects
C:\dev\Intent.Modules.NET\Tests\AdvancedMappingCrud.Cosmos.Tests\modules.config C:\dev\Intent.Modules.NET\Tests\CleanArchitecture.OnlyModeledDomainEvents\modules.config C:\dev\Intent.Modules.NET\Tests\CleanArchitecture.SingleFiles\modules.config C:\dev\Intent.Modules.NET\Tests\MultipleDocumentStores\modules.config
The only remaining issue that I have is the Settings implementation itself. Currently it looks like this:
I would imagine, and prefer, to have the Use Optimistic Concurrency Default
in the Document Database
setting group. I could not figure out how to reference the module from the Intent.Modules.NET
to theIntent.Modules
projects without potentially breaking the build.
Maybe there will be some help in the PR tomorrow 😄
After some feedback on the PR:
So the integration testing has opened a bit of a can of worms.
I had to upgrade the Microsoft.Extensions.Http
nuget package version in the Intent.Modules.Integration.HttpClients.Shared
shared code project, and update all of the version numbers and release-notes for each of those, and in doing so i have uncovered an edge case while using the AdvancedMappingCrud.Cosmos.Tests
project regarding the Intent.CosmosDB.CosmosDBValueObjectDocument
and Intent.CosmosDB.CosmosDBDocument
templates.
What is required?
Add a setting called something like "Use Optimistic Concurrency Default" which is by default set to "On".
Will probably need repositories / Unit of work to keep track of Etags per document Id so that when we save, we send it back over.
this is a option which can be passed into the Cosmos operations like update and delete. Simple change, should it be a setting or the default behaviour.
new ItemRequestOptions { IfMatchETag = entity._etag }
Database transactions and optimistic concurrency control in Azure Cosmos DB | Microsoft Learn