Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
65bc4b9
Plan for in-memory-emulator with its own http(s) endpoint
FabianMeiswinkel Jul 14, 2026
3ce86e8
Update plan.md
FabianMeiswinkel Jul 14, 2026
ee5fc91
Update plan.md
FabianMeiswinkel Jul 14, 2026
7720563
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
9dc8ec4
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
8863aa9
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
3c2b1a3
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
ca92a9f
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
6795fe1
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
9fcdda9
docs: require HTTPS for auth modes and define JWT trust inputs in ADR…
Copilot Jul 14, 2026
67bc248
Use Gateway 2.0 naming
Copilot Jul 14, 2026
80b550e
docs: normalize Gateway 2.0 naming
Copilot Jul 14, 2026
2399f36
Adjust split/merge plan contract
Copilot Jul 14, 2026
bf4c5df
Normalize Gateway 2.0 plan naming
Copilot Jul 14, 2026
909c6cd
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
e15a002
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
b81eb51
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
e006e99
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
67e5fb2
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
2ecd0e0
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
94af359
Potential fix for pull request finding
FabianMeiswinkel Jul 14, 2026
2dd214a
Updating ADRs
FabianMeiswinkel Jul 14, 2026
5be250e
Unlinking links
FabianMeiswinkel Jul 14, 2026
f3577b8
Updating ADRs
FabianMeiswinkel Jul 15, 2026
37f0049
Addressing code review comments
FabianMeiswinkel Jul 15, 2026
6332052
Update 007_gateway_v2_rntbd.md
FabianMeiswinkel Jul 15, 2026
d9e1ad8
Addressing code review feedback
FabianMeiswinkel Jul 15, 2026
7216572
Update 002_separate_host_crate.md
FabianMeiswinkel Jul 15, 2026
a168d02
Iterating on doc fixes
FabianMeiswinkel Jul 15, 2026
561c820
Merge branch 'main' into users/fabianm/ExternalInMemoryEmulator
FabianMeiswinkel Jul 15, 2026
bb83bd2
Initial implementation
FabianMeiswinkel Jul 15, 2026
797262f
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-rust in…
FabianMeiswinkel Jul 15, 2026
477b15f
Addressing code review comments
FabianMeiswinkel Jul 17, 2026
017d746
Merge branch 'main' into users/fabianm/ExternalInMemoryEmulator_02
FabianMeiswinkel Jul 17, 2026
cabc4aa
Reacting to offline code review comments
FabianMeiswinkel Jul 17, 2026
da5b1cc
Merge branch 'users/fabianm/ExternalInMemoryEmulator_02' of https://g…
FabianMeiswinkel Jul 17, 2026
d4571f8
Fix emulator CI readiness
FabianMeiswinkel Jul 17, 2026
1868146
Fix link verification issues
FabianMeiswinkel Jul 17, 2026
c1dc127
Update gateway_v2_dispatch.rs
FabianMeiswinkel Jul 17, 2026
37d4801
Merge branch 'main' into users/fabianm/ExternalInMemoryEmulator_02
FabianMeiswinkel Jul 17, 2026
eeab9cf
Update validation.rs
FabianMeiswinkel Jul 17, 2026
b8007ca
Merge branch 'main' into users/fabianm/ExternalInMemoryEmulator_02
FabianMeiswinkel Jul 17, 2026
3197287
Fix build issue
FabianMeiswinkel Jul 17, 2026
b5c9413
Fixes rntbd response tokens
FabianMeiswinkel Jul 17, 2026
99498e0
Update validation.rs
FabianMeiswinkel Jul 17, 2026
95eda00
Fix accidental yml changes
FabianMeiswinkel Jul 17, 2026
33b985e
Update gateway_v2_dispatch.rs
FabianMeiswinkel Jul 18, 2026
ce144b2
Update dual_backend.rs
FabianMeiswinkel Jul 18, 2026
e59c8a1
Update test_client.rs
FabianMeiswinkel Jul 18, 2026
32cc9bc
Update validation.rs
FabianMeiswinkel Jul 20, 2026
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
123 changes: 120 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"sdk/cosmos/azure_data_cosmos",
"sdk/cosmos/azure_data_cosmos_benchmarks",
"sdk/cosmos/azure_data_cosmos_driver",
"sdk/cosmos/azure_data_cosmos_emulator",
"sdk/cosmos/azure_data_cosmos_driver_native",
"sdk/cosmos/azure_data_cosmos_macros",
"sdk/cosmos/azure_data_cosmos_perf",
Expand Down Expand Up @@ -90,6 +91,7 @@ version = "1.0.0"
async-lock = "3.4"
async-stream = { version = "0.3.6" }
async-trait = "0.1"
axum = { version = "0.8", features = ["http2", "json", "macros"] }
base64 = "0.22"
arc-swap = "1.7"
backtrace = "0.3"
Expand Down
1 change: 1 addition & 0 deletions eng/dict/crates.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ azure_data_cosmos
azure_data_cosmos_benchmarks
azure_data_cosmos_driver
azure_data_cosmos_driver_native
azure_data_cosmos_emulator
azure_data_cosmos_macros
azure_data_cosmos_perf
azure_identity
Expand Down
2 changes: 1 addition & 1 deletion sdk/cosmos/azure_data_cosmos/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
fn main() {
// Allow `#[cfg_attr(not(test_category = "..."), ignore)]` in `tests/*.rs`.
println!(
"cargo:rustc-check-cfg=cfg(test_category, values(\"emulator\", \"emulator_vnext\", \"multi_write\", \"split\", \"gateway_v2\", \"gateway_v2_multi_region\"))"
"cargo:rustc-check-cfg=cfg(test_category, values(\"emulator\", \"emulator_vnext\", \"emulator_inmemory\", \"emulator_inmemory_gateway_v2\", \"multi_write\", \"split\", \"gateway_v2\", \"gateway_v2_multi_region\"))"
);
}
92 changes: 50 additions & 42 deletions sdk/cosmos/azure_data_cosmos/docs/in-memory-emulator-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ An **in-memory emulator** that intercepts requests at the `HttpClient` transport
### Non-Goals (This Phase)

- Bulk / Patch operations (return hard-coded errors).
- Gateway 2.0 transport mode (skip for now — will come later).
- Network hosting remains outside the in-process `HttpClient` interception contract described by
this document. The separate `azure_data_cosmos_emulator` host supports Gateway V1 and a scoped
Gateway 2.0 adapter; see `sdk/cosmos/azure_data_cosmos_emulator/docs/plan.md`.
- Change feed.
- Stored procedures / triggers / UDFs.
- Complete Cosmos SQL service parity beyond the local query evaluator and local query-plan analyzer.
Expand Down Expand Up @@ -564,48 +566,48 @@ Each physical partition is independently serialized:

### URL Path Parsing

| Pattern | Resource Type |
| ---------------------------------- | ------------------------------------------------------------ |
| `/` | Account |
| `/dbs` | DatabaseFeed (create/read/query) |
| `/dbs/{db}` | Database (read/delete) |
| `/dbs/{db}/colls` | ContainerFeed (create/read/query) |
| `/dbs/{db}/colls/{coll}` | Container (read/delete) |
| `/dbs/{db}/colls/{coll}/pkranges` | PartitionKeyRangeFeed (read feed) |
| `/dbs/{db}/colls/{coll}/docs` | DocumentFeed (create/upsert/read/query/query-plan/batch) |
| `/dbs/{db}/colls/{coll}/docs/{id}` | Document (read/replace/delete) |
| `/offers` | OfferFeed (read/query) |
| `/offers/{id}` | Offer (read/replace) |
| Pattern | Resource Type |
| ---------------------------------- | -------------------------------------------------------- |
| `/` | Account |
| `/dbs` | DatabaseFeed (create/read/query) |
| `/dbs/{db}` | Database (read/delete) |
| `/dbs/{db}/colls` | ContainerFeed (create/read/query) |
| `/dbs/{db}/colls/{coll}` | Container (read/delete) |
| `/dbs/{db}/colls/{coll}/pkranges` | PartitionKeyRangeFeed (read feed) |
| `/dbs/{db}/colls/{coll}/docs` | DocumentFeed (create/upsert/read/query/query-plan/batch) |
| `/dbs/{db}/colls/{coll}/docs/{id}` | Document (read/replace/delete) |
| `/offers` | OfferFeed (read/query) |
| `/offers/{id}` | Offer (read/replace) |

### Operation Resolution

| HTTP Method | Path | Headers | Operation |
| ----------- | --------------------------- | -------------------------------------------- | ------------------ |
| `GET` | `/` | — | ReadAccount |
| `POST` | `/dbs` | — | CreateDatabase |
| `GET` | `/dbs` | — | ReadFeedDatabases |
| `POST` | `/dbs` | `x-ms-documentdb-isquery: True` | QueryDatabases |
| `GET` | `/dbs/{db}` | — | ReadDatabase |
| `DELETE` | `/dbs/{db}` | — | DeleteDatabase |
| `POST` | `/dbs/{db}/colls` | — | CreateContainer |
| `GET` | `/dbs/{db}/colls` | — | ReadFeedContainers |
| `POST` | `/dbs/{db}/colls` | `x-ms-documentdb-isquery: True` | QueryContainers |
| `GET` | `/dbs/{db}/colls/{coll}` | — | ReadContainer |
| `DELETE` | `/dbs/{db}/colls/{coll}` | — | DeleteContainer |
| `GET` | `.../colls/{coll}/pkranges` | — | ReadPKRanges |
| `POST` | `.../docs` | — | Create |
| `POST` | `.../docs` | `x-ms-documentdb-is-upsert: True` | Upsert |
| `GET` | `.../docs` | — | ReadFeedItems |
| `POST` | `.../docs` | `x-ms-documentdb-isquery: True` | QueryItems |
| `POST` | `.../docs` | `x-ms-cosmos-is-query-plan-request: True` | QueryPlan |
| `POST` | `.../docs` | `x-ms-cosmos-is-batch-request: True` | Batch |
| `GET` | `.../docs/{id}` | — | Read |
| `PUT` | `.../docs/{id}` | — | Replace |
| `DELETE` | `.../docs/{id}` | — | Delete |
| `GET` | `/offers` | — | ReadFeedOffers |
| `POST` | `/offers` | `x-ms-documentdb-isquery: True` | QueryOffers |
| `GET` | `/offers/{id}` | — | ReadOffer |
| `PUT` | `/offers/{id}` | — | ReplaceOffer |
| HTTP Method | Path | Headers | Operation |
| ----------- | --------------------------- | ----------------------------------------- | ------------------ |
| `GET` | `/` | — | ReadAccount |
| `POST` | `/dbs` | — | CreateDatabase |
| `GET` | `/dbs` | — | ReadFeedDatabases |
| `POST` | `/dbs` | `x-ms-documentdb-isquery: True` | QueryDatabases |
| `GET` | `/dbs/{db}` | — | ReadDatabase |
| `DELETE` | `/dbs/{db}` | — | DeleteDatabase |
| `POST` | `/dbs/{db}/colls` | — | CreateContainer |
| `GET` | `/dbs/{db}/colls` | — | ReadFeedContainers |
| `POST` | `/dbs/{db}/colls` | `x-ms-documentdb-isquery: True` | QueryContainers |
| `GET` | `/dbs/{db}/colls/{coll}` | — | ReadContainer |
| `DELETE` | `/dbs/{db}/colls/{coll}` | — | DeleteContainer |
| `GET` | `.../colls/{coll}/pkranges` | — | ReadPKRanges |
| `POST` | `.../docs` | — | Create |
| `POST` | `.../docs` | `x-ms-documentdb-is-upsert: True` | Upsert |
| `GET` | `.../docs` | — | ReadFeedItems |
| `POST` | `.../docs` | `x-ms-documentdb-isquery: True` | QueryItems |
| `POST` | `.../docs` | `x-ms-cosmos-is-query-plan-request: True` | QueryPlan |
| `POST` | `.../docs` | `x-ms-cosmos-is-batch-request: True` | Batch |
| `GET` | `.../docs/{id}` | — | Read |
| `PUT` | `.../docs/{id}` | — | Replace |
| `DELETE` | `.../docs/{id}` | — | Delete |
| `GET` | `/offers` | — | ReadFeedOffers |
| `POST` | `/offers` | `x-ms-documentdb-isquery: True` | QueryOffers |
| `GET` | `/offers/{id}` | — | ReadOffer |
| `PUT` | `/offers/{id}` | — | ReplaceOffer |

### Region Routing

Expand Down Expand Up @@ -768,7 +770,10 @@ One-shot: next read to the physical partition containing the given partition key
## 10. ETag & Optimistic Concurrency

- New quoted UUID ETag generated on every write.
- **If-Match**: Compared on Replace/Delete → 412 on mismatch.
- **If-Match**: Compared on Replace/Delete → 412 on mismatch. Also enforced on Upsert
when the target item already exists; an Upsert against a non-existent item ignores
`If-Match` and creates the item (mirrors real Cosmos DB — preconditions only apply
to items that already exist).
- **If-None-Match**: Reserved for future use (create-if-not-exists pattern).
- ETag returned in both `etag` header and `_etag` body property.

Expand Down Expand Up @@ -1124,7 +1129,10 @@ The `GET /dbs/{db}/colls/{coll}/pkranges` feed reflects the updated topology:

## 18. Unsupported Operations

Bulk, Patch, ChangeFeed, stored procedures, triggers, UDFs, and Gateway 2.0 transport mode remain unsupported and return **501 Not Implemented** or the closest service-shaped error for that route.
Bulk, Patch, ChangeFeed, stored procedures, triggers, and UDFs remain unsupported and return
**501 Not Implemented** or the closest service-shaped error for that route. The in-process client
does not select a network transport, while the separate hosted emulator supports the documented
subset of Gateway 2.0 over HTTP/2.

Query support is intentionally scoped to the local SQL evaluator and local query-plan analyzer used by the SDK tests. Transactional batch supports document operations within one logical partition and rolls back the whole batch on failure.

Expand Down
24 changes: 20 additions & 4 deletions sdk/cosmos/azure_data_cosmos/tests/emulator_tests/cosmos_aad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,16 @@ struct AadTestItem {
/// invoked for the Cosmos scope, guarding against silently exercising key auth.
#[tokio::test]
#[cfg_attr(
not(any(test_category = "emulator", test_category = "emulator_vnext")),
ignore = "requires test_category 'emulator' or 'emulator_vnext'"
not(any(
test_category = "emulator",
test_category = "emulator_vnext",
test_category = "emulator_inmemory"
)),
ignore = "requires test_category 'emulator', 'emulator_vnext', or 'emulator_inmemory'"
)]
#[cfg_attr(
test_category = "emulator_inmemory",
ignore = "hosted in-memory emulator authentication is deferred to PR3"
)]
pub async fn aad_item_crud_roundtrip() -> Result<(), Box<dyn Error>> {
TestClient::run_with_unique_db(
Expand Down Expand Up @@ -149,8 +157,16 @@ pub async fn aad_item_crud_roundtrip() -> Result<(), Box<dyn Error>> {
/// the `readMetadata` data action the SDK requires on its first request.
#[tokio::test]
#[cfg_attr(
not(any(test_category = "emulator", test_category = "emulator_vnext")),
ignore = "requires test_category 'emulator' or 'emulator_vnext'"
not(any(
test_category = "emulator",
test_category = "emulator_vnext",
test_category = "emulator_inmemory"
)),
ignore = "requires test_category 'emulator', 'emulator_vnext', or 'emulator_inmemory'"
)]
#[cfg_attr(
test_category = "emulator_inmemory",
ignore = "hosted in-memory emulator authentication is deferred to PR3"
)]
pub async fn aad_read_container_metadata() -> Result<(), Box<dyn Error>> {
TestClient::run_with_unique_db(
Expand Down
Loading
Loading