Skip to content

Add support for Cosmos DB and other NoSQL databases #1103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
887a153
Add NoSqlResourceService
ThomasBarnekow Nov 6, 2021
c6db07d
Fix ambiguous reference in cref attribute
ThomasBarnekow Nov 7, 2021
37ac8f2
Fix warnings
ThomasBarnekow Nov 7, 2021
05b1163
Fix code style-related errors
ThomasBarnekow Nov 7, 2021
fd237a0
Fix false-positive warning on possible multiple enumeration
ThomasBarnekow Nov 7, 2021
71e437d
Remove isIncluded parameter
ThomasBarnekow Nov 7, 2021
19a6dd5
Manually perform JADNC Full Cleanup
ThomasBarnekow Nov 7, 2021
50bb3ec
Manually edit files to comply with formatting rules
ThomasBarnekow Nov 8, 2021
8c438b6
Enhance NoSqlQueryLayerComposer
ThomasBarnekow Nov 9, 2021
7396735
Enhance FilterExpressionVisitor
ThomasBarnekow Nov 10, 2021
7fc31f3
Add JsonApiDotNetCoreExample.Cosmos
ThomasBarnekow Nov 10, 2021
e65face
Fix comment
ThomasBarnekow Nov 10, 2021
755fac3
Fix layout of appsettings.json
ThomasBarnekow Nov 10, 2021
443aa98
Rename example to CosmosDbExample
ThomasBarnekow Nov 11, 2021
1ef4f50
Enhance NoSqlResourceService
ThomasBarnekow Nov 12, 2021
fedad68
Implement integration tests
ThomasBarnekow Nov 12, 2021
5c02d46
Add build scripts for Cosmos DB
ThomasBarnekow Nov 13, 2021
1bff1cc
Start process with nohup
ThomasBarnekow Nov 13, 2021
8863296
Fix build on Linux
ThomasBarnekow Nov 15, 2021
245fb67
Fix permission issue with Start-Process
ThomasBarnekow Nov 15, 2021
ab8dd8a
Drill down into appveyor issue
ThomasBarnekow Nov 15, 2021
1e2fa47
Enhance appveyor.yml and build scripts
ThomasBarnekow Nov 15, 2021
f00121c
Change appveyor.yml
ThomasBarnekow Nov 15, 2021
097bd4d
Remove postgresql13 from Ubuntu list of servicesDefine appveyor.yml b…
ThomasBarnekow Nov 15, 2021
f1a096e
Use sudo to run bash scripts
ThomasBarnekow Nov 15, 2021
63bfa79
Try to fix before_build script
ThomasBarnekow Nov 15, 2021
606e2f7
Try to build on Windows only
ThomasBarnekow Nov 15, 2021
ddc822c
Launch Cosmos DB Emulator in build_script
ThomasBarnekow Nov 15, 2021
d5b8dcf
Next attempt
ThomasBarnekow Nov 15, 2021
c21fad6
Disable CosmosDbTests on appveyor Ubuntu image
ThomasBarnekow Nov 15, 2021
4c907f0
Remove using statement
ThomasBarnekow Nov 15, 2021
c94851a
Fix Docker config and enable tests on Linux
ThomasBarnekow Nov 16, 2021
7add1c6
Explicitly configure DbContextOptions
ThomasBarnekow Nov 16, 2021
063b04f
Use default timeout and optimize build on Linux
ThomasBarnekow Nov 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,10 @@ CheckLastExitCode
dotnet build -c Release
CheckLastExitCode

RunInspectCode
RunCleanupCode
if ($isWindows) {
RunInspectCode
RunCleanupCode
}

dotnet test -c Release --no-build --collect:"XPlat Code Coverage"
CheckLastExitCode
Expand Down
54 changes: 42 additions & 12 deletions JsonApiDotNetCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiDbContextTests", "test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestBuildingBlocks", "test\TestBuildingBlocks\TestBuildingBlocks.csproj", "{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CosmosDbExample", "src\Examples\CosmosDbExample\CosmosDbExample.csproj", "{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CosmosDbTests", "test\CosmosDbTests\CosmosDbTests.csproj", "{2E387408-8689-4335-A7C4-363DDB28E701}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -54,6 +58,18 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x64.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x64.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x86.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x86.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|Any CPU.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x64.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x64.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.Build.0 = Release|Any CPU
{CAF331F8-9255-4D72-A1A8-A54141E99F1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAF331F8-9255-4D72-A1A8-A54141E99F1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAF331F8-9255-4D72-A1A8-A54141E99F1E}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -162,18 +178,6 @@ Global
{21D27239-138D-4604-8E49-DCBE41BCE4C8}.Release|x64.Build.0 = Release|Any CPU
{21D27239-138D-4604-8E49-DCBE41BCE4C8}.Release|x86.ActiveCfg = Release|Any CPU
{21D27239-138D-4604-8E49-DCBE41BCE4C8}.Release|x86.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x64.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x64.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x86.ActiveCfg = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Debug|x86.Build.0 = Debug|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|Any CPU.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x64.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x64.Build.0 = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.ActiveCfg = Release|Any CPU
{067FFD7A-C66B-473D-8471-37F5C95DF61C}.Release|x86.Build.0 = Release|Any CPU
{6CAFDDBE-00AB-4784-801B-AB419C3C3A26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CAFDDBE-00AB-4784-801B-AB419C3C3A26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CAFDDBE-00AB-4784-801B-AB419C3C3A26}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -210,6 +214,30 @@ Global
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x64.Build.0 = Release|Any CPU
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x86.ActiveCfg = Release|Any CPU
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21}.Release|x86.Build.0 = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|x64.ActiveCfg = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|x64.Build.0 = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|x86.ActiveCfg = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Debug|x86.Build.0 = Debug|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|Any CPU.Build.0 = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|x64.ActiveCfg = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|x64.Build.0 = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|x86.ActiveCfg = Release|Any CPU
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2}.Release|x86.Build.0 = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|x64.ActiveCfg = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|x64.Build.0 = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|x86.ActiveCfg = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Debug|x86.Build.0 = Debug|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|Any CPU.Build.0 = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|x64.ActiveCfg = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|x64.Build.0 = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|x86.ActiveCfg = Release|Any CPU
{2E387408-8689-4335-A7C4-363DDB28E701}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -228,6 +256,8 @@ Global
{6CAFDDBE-00AB-4784-801B-AB419C3C3A26} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
{EC3202C6-1D4C-4B14-A599-B9D3F27FE3BA} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
{210FD61E-FF5D-4CEE-8E0D-C739ECCCBA21} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
{3AD5D1B4-8456-4639-98DB-F0D0EDAB2AD2} = {026FBC6C-AF76-4568-9B87-EC73457899FD}
{2E387408-8689-4335-A7C4-363DDB28E701} = {24B15015-62E5-42E1-9BA0-ECE6BE7AA15F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A2421882-8F0A-4905-928F-B550B192F9A4}
Expand Down
40 changes: 38 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ image:

version: '{build}'

stack: postgresql 13.4
stack: postgresql 13.4, docker

environment:
PGUSER: postgres
Expand All @@ -29,7 +29,7 @@ matrix:
fast_finish: true

for:
-
- # Visual Studio 2019
matrix:
only:
- image: Visual Studio 2019
Expand All @@ -48,6 +48,11 @@ for:
if ($lastexitcode -ne 0) {
throw "docfx install failed with exit code $lastexitcode."
}
- pwsh: |
# Start Azure Cosmos Emulator on Windows
if ($isWindows) {
& .\start-cosmos-db-emulator.ps1
}
after_build:
- pwsh: |
CD ./docs
Expand Down Expand Up @@ -95,6 +100,37 @@ for:
on:
branch: /release\/.+/
appveyor_repo_tag: true
- # Ubuntu
matrix:
only:
- image: Ubuntu
services:
- docker
before_build:
- sh: |
# Start Azure Cosmos Emulator on Linux
# Pull Azure Cosmos Emulator Docker image
echo "Pulling Azure Cosmos Emulator Docker image for Linux ..."
bash ./pull-docker-azure-cosmos-emulator-linux.sh

# Start Azure Cosmos Emulator container
echo "Running Azure Cosmos Emulator Docker container ..."
nohup bash ./run-docker-azure-cosmos-emulator-linux.sh &

# Wait for Docker container being started in the background
echo "Waiting 60 seconds before trying to download Azure Cosmos Emulator SSL certificate ..."
sleep 60

# Print the background process output to see whether there are any errors
if [ -f "./nohup.out" ]; then
echo "--- BEGIN CONTENTS OF NOHUP.OUT ---"
cat ./nohup.out
echo "--- END CONTENTS OF NOHUP.OUT ---"
fi

# Install SSL certificate to be able to access the emulator
echo "Installing Azure Cosmos Emulator SSL certificate ..."
sudo bash ./install-azure-cosmos-emulator-linux-certificates.sh

build_script:
- pwsh: |
Expand Down
30 changes: 30 additions & 0 deletions install-azure-cosmos-emulator-linux-certificates.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

certfile=~/emulatorcert.crt
echo "Certificate file: ${certfile}"

result=1
count=0

while [[ "$result" != "0" && "$count" < "5" ]]; do
echo "Trying to download certificate ..."
curl -k https://localhost:8081/_explorer/emulator.pem > $certfile
result=$?
let "count++"

if [[ "$result" != "0" && "$count" < "5" ]]
then
echo "Could not download certificate. Waiting 10 seconds before trying again ..."
sleep 10
fi
done

if [[ $result -eq 0 ]]
then
echo "Updating CA certificates ..."
sudo cp $certfile /usr/local/share/ca-certificates
sudo update-ca-certificates
else
echo "Could not download CA certificate!"
false
fi
4 changes: 4 additions & 0 deletions pull-docker-azure-cosmos-emulator-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

# Pull the azure-cosmos-emulator Docker image for Linux from the registry.
docker pull mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
23 changes: 23 additions & 0 deletions run-docker-azure-cosmos-emulator-linux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# Run the Docker image that was previously pulled from the Docker repository, creating a container called
# "azure-cosmos-emulator-linux". Do not (!) set
#
# AZURE_COSMOS_EMULATOR_IP_ADDRESS_OVERRIDE=$ipaddr
#
# as suggested in Microsoft's documentation at https://docs.microsoft.com/en-us/azure/cosmos-db/linux-emulator.
# We would not be able to connect to the emulator at all on appveyor, regardless of the connection mode.
# To connect to the emulator, we must use Gateway mode. Direct mode will not work.

docker run \
-p 8081:8081 \
-p 10251:10251 \
-p 10252:10252 \
-p 10253:10253 \
-p 10254:10254 \
-m 3g \
--cpus=2.0 \
--name=azure-cosmos-emulator-linux \
-e AZURE_COSMOS_EMULATOR_PARTITION_COUNT=3 \
-e AZURE_COSMOS_EMULATOR_ENABLE_DATA_PERSISTENCE=true \
mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator
22 changes: 22 additions & 0 deletions shutdown-cosmos-db-emulator.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#Requires -Version 7

function ShutdownCosmosDbEmulator {
if ($PSVersionTable.Platform -eq "Unix") {
ShutdownCosmosDbEmulatorDockerContainer
}
else {
ShutdownCosmosDbEmulatorForWindows
}
}

function ShutdownCosmosDbEmulatorDockerContainer {
Write-Host "Shutting down Cosmos DB Emulator Docker container ..."
docker stop azure-cosmos-emulator-linux
}

function ShutdownCosmosDbEmulatorForWindows {
Write-Host "Shutting down Cosmos DB Emulator for Windows ..."
Start-Process -FilePath "C:\Program Files\Azure Cosmos DB Emulator\Microsoft.Azure.Cosmos.Emulator.exe" -ArgumentList "/Shutdown"
}

ShutdownCosmosDbEmulator
55 changes: 55 additions & 0 deletions src/Examples/CosmosDbExample/Controllers/NonJsonApiController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace CosmosDbExample.Controllers
{
[Route("[controller]")]
public sealed class NonJsonApiController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
string[] result =
{
"Welcome!"
};

return Ok(result);
}

[HttpPost]
public async Task<IActionResult> PostAsync()
{
string name = await new StreamReader(Request.Body).ReadToEndAsync();

if (string.IsNullOrEmpty(name))
{
return BadRequest("Please send your name.");
}

string result = $"Hello, {name}";
return Ok(result);
}

[HttpPut]
public IActionResult Put([FromBody] string name)
{
string result = $"Hi, {name}";
return Ok(result);
}

[HttpPatch]
public IActionResult Patch(string name)
{
string result = $"Good day, {name}";
return Ok(result);
}

[HttpDelete]
public IActionResult Delete()
{
return Ok("Bye.");
}
}
}
18 changes: 18 additions & 0 deletions src/Examples/CosmosDbExample/Controllers/OperationsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using JsonApiDotNetCore.AtomicOperations;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Middleware;
using JsonApiDotNetCore.Resources;
using Microsoft.Extensions.Logging;

namespace CosmosDbExample.Controllers
{
public sealed class OperationsController : JsonApiOperationsController
{
public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor,
IJsonApiRequest request, ITargetedFields targetedFields)
: base(options, resourceGraph, loggerFactory, processor, request, targetedFields)
{
}
}
}
18 changes: 18 additions & 0 deletions src/Examples/CosmosDbExample/Controllers/PeopleController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using CosmosDbExample.Models;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Services;
using Microsoft.Extensions.Logging;

namespace CosmosDbExample.Controllers
{
public sealed class PeopleController : JsonApiController<Person, Guid>
{
public PeopleController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory,
IResourceService<Person, Guid> resourceService)
: base(options, resourceGraph, loggerFactory, resourceService)
{
}
}
}
18 changes: 18 additions & 0 deletions src/Examples/CosmosDbExample/Controllers/TodoItemsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using CosmosDbExample.Models;
using JsonApiDotNetCore.Configuration;
using JsonApiDotNetCore.Controllers;
using JsonApiDotNetCore.Services;
using Microsoft.Extensions.Logging;

namespace CosmosDbExample.Controllers
{
public sealed class TodoItemsController : JsonApiController<TodoItem, Guid>
{
public TodoItemsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory,
IResourceService<TodoItem, Guid> resourceService)
: base(options, resourceGraph, loggerFactory, resourceService)
{
}
}
}
14 changes: 14 additions & 0 deletions src/Examples/CosmosDbExample/CosmosDbExample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>$(NetCoreAppVersion)</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\JsonApiDotNetCore\JsonApiDotNetCore.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.21.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Cosmos" Version="$(EFCoreVersion)" />
</ItemGroup>
</Project>
Loading