-
Notifications
You must be signed in to change notification settings - Fork 1
Integration DynamoDB Extension
The Kronikol.Extensions.DynamoDB package adds Amazon DynamoDB operation tracking to your test diagrams. Instead of showing raw HTTP requests like POST https://dynamodb.us-east-1.amazonaws.com/, your sequence diagrams show classified operations like PutItem with a clean dynamodb:///Users URI.
Using a shared library or abstraction layer? If your code doesn't use the DynamoDB SDK directly — e.g. it goes through a shared data-access library, wrapper, or custom abstraction — this extension won't be able to intercept the underlying calls. See Tracking Custom Dependencies for alternative approaches including
RequestResponseLogger.LogPair(),TrackingProxy<T>, andMessageTracker.
The AWS SDK for .NET translates all DynamoDB operations into HTTP POST requests to a single endpoint. The operation type is encoded in the X-Amz-Target header (e.g. DynamoDB_20120810.PutItem) and the table name is in the JSON request body's TableName field. DynamoDbTrackingMessageHandler is a DelegatingHandler that:
- Reads the request body to extract the table name (since it's in the JSON, not the URL)
- Classifies the operation from the
X-Amz-Targetheader - Reconstructs the request content so the inner handler can still read it
- Logs the request/response to
RequestResponseLogger
Because it logs to the same RequestResponseLogger as the standard TestTrackingMessageHandler, DynamoDB operations appear alongside your HTTP API calls in the same sequence diagram — showing the complete flow from test → API → DynamoDB.
dotnet add package Kronikol.Extensions.DynamoDBThe extension supports three verbosity levels that control how much detail appears in the diagrams:
| Level | Method shown | URI shown | Headers | Request body | Response body |
|---|---|---|---|---|---|
| Raw | HTTP method (POST) |
Full original URI | All except excluded set | Full content | Full content |
| Detailed | Classified operation (PutItem) |
dynamodb:///TableName |
Filtered (noisy AWS headers excluded) | Full content | Full content |
| Summarised | Classified operation (PutItem) |
dynamodb:///TableName |
None | None | None |
The default is Detailed.
| Operation | Raw | Detailed | Summarised |
|---|---|---|---|
| Put item | POST: https://dynamodb.us-east-1.amazonaws.com/ |
PutItem: dynamodb:///Users |
PutItem: dynamodb:///Users |
| Get item | POST: https://dynamodb.us-east-1.amazonaws.com/ |
GetItem: dynamodb:///Users |
GetItem: dynamodb:///Users |
| Query | POST: https://dynamodb.us-east-1.amazonaws.com/ |
Query: dynamodb:///Orders |
Query: dynamodb:///Orders |
| Batch write | POST: https://dynamodb.us-east-1.amazonaws.com/ |
BatchWriteItem: dynamodb:///Users, Orders |
BatchWriteItem: dynamodb:///Users, Orders |
| PartiQL | POST: https://dynamodb.us-east-1.amazonaws.com/ |
ExecuteStatement: dynamodb:/// |
ExecuteStatement: dynamodb:/// |
| Unrecognised | POST: https://dynamodb.us-east-1.amazonaws.com/ |
Other: dynamodb:/// |
(skipped) |
The classifier recognises these DynamoDB operations from the X-Amz-Target header:
| Category | Operations |
|---|---|
| CRUD |
PutItem, GetItem, UpdateItem, DeleteItem
|
| Queries |
Query, Scan
|
| Batch |
BatchWriteItem, BatchGetItem
|
| Transactions |
TransactWriteItems, TransactGetItems
|
| Table management |
CreateTable, DeleteTable, DescribeTable, ListTables, UpdateTable
|
| PartiQL |
ExecuteStatement, BatchExecuteStatement, ExecuteTransaction
|
| Fallback |
Other (unrecognised target header) |
-
Single-table operations (PutItem, GetItem, Query, etc.): Extracted from the
"TableName"field in the JSON body -
Batch operations (BatchWriteItem, BatchGetItem): Extracted from the keys of the
"RequestItems"object, producing a comma-separated list likeUsers, Orders -
PartiQL operations: The
"Statement"field is extracted for potential use in detailed logging -
Table management: Extracted from the
"TableName"field
In Summarised mode, Other operations are silently skipped.
var trackingOptions = new DynamoDbTrackingMessageHandlerOptions
{
ServiceName = "DynamoDB",
CallerName = "My API",
Verbosity = DynamoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var config = new AmazonDynamoDBConfig
{
RegionEndpoint = RegionEndpoint.USEast1
};
config.WithTestTracking(trackingOptions);
var client = new AmazonDynamoDBClient(credentials, config);WithTestTracking sets the HttpClientFactory property on AmazonDynamoDBConfig to route all HTTP requests through the tracking handler. This requires no production code changes.
If you need more control over the HTTP pipeline:
var trackingOptions = new DynamoDbTrackingMessageHandlerOptions
{
ServiceName = "DynamoDB",
CallerName = "My API",
Verbosity = DynamoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var trackingHandler = new DynamoDbTrackingMessageHandler(trackingOptions);
// Use trackingHandler with your own HttpClient / AWS pipeline customizationbuilder.ConfigureTestServices(services =>
{
services.AddSingleton<IAmazonDynamoDB>(sp =>
{
var trackingOptions = new DynamoDbTrackingMessageHandlerOptions
{
ServiceName = "DynamoDB",
CallerName = "My API",
Verbosity = DynamoDbTrackingVerbosity.Detailed,
CurrentTestInfoFetcher = CurrentTestInfo.Fetcher
};
var config = new AmazonDynamoDBConfig
{
RegionEndpoint = RegionEndpoint.USEast1,
ServiceURL = "http://localhost:8000" // e.g. DynamoDB Local
};
config.WithTestTracking(trackingOptions);
return new AmazonDynamoDBClient(new BasicAWSCredentials("test", "test"), config);
});
});| Property | Type | Default | Description |
|---|---|---|---|
ServiceName |
string |
"DynamoDB" |
The participant name shown in the diagram for the DynamoDB service |
CallerName |
string |
"Caller" |
The participant name shown for the service making DynamoDB calls |
Verbosity |
DynamoDbTrackingVerbosity |
Detailed |
Controls how much detail appears in the diagram (Raw, Detailed, Summarised) |
CurrentTestInfoFetcher |
Func<(string Name, string Id)>? |
null |
Returns the current test's name and ID. Required — if null, requests are forwarded but not logged |
CurrentStepTypeFetcher |
Func<string?>? |
null |
Optional — returns the current BDD step type (Given/When/Then) |
HttpContextAccessor |
IHttpContextAccessor? |
null |
Optional — enables dual-resolution of test identity from HTTP headers. Auto-resolved by DI extensions (v2.26.3+). See HTTP Tracking Setup#Dual-Resolution Test Identity (v2.23.0+) |
ExcludedHeaders |
HashSet<string> |
See below | Headers to exclude from diagrams in Raw/Detailed mode |
SetupVerbosity |
DynamoDbTrackingVerbosity? |
null |
Verbosity override for the Setup phase. See Phase-Aware Tracking |
ActionVerbosity |
DynamoDbTrackingVerbosity? |
null |
Verbosity override for the Action phase. See Phase-Aware Tracking |
TrackDuringSetup |
bool |
true |
When false, tracking is suppressed during Setup. See Phase-Aware Tracking
|
TrackDuringAction |
bool |
true |
When false, tracking is suppressed during Action. See Phase-Aware Tracking
|
v2.23.0+ Dual-Resolution:
DynamoDbTrackingMessageHandleraccepts an optionalIHttpContextAccessor? httpContextAccessorconstructor parameter for resolving test identity from HTTP request headers when running inside the SUT's request pipeline. v2.26.3+: SetHttpContextAccessoronDynamoDbTrackingMessageHandlerOptionsinstead — the tracker reads it automatically. See HTTP Tracking Setup#Dual-Resolution Test Identity (v2.23.0+) for details.
The following AWS headers are excluded by default (they add noise without diagnostic value):
Authorizationx-amz-datex-amz-security-tokenx-amz-content-sha256User-Agentamz-sdk-invocation-idamz-sdk-request
Override ExcludedHeaders to customise:
new DynamoDbTrackingMessageHandlerOptions
{
ExcludedHeaders = ["Authorization", "x-amz-date"] // Only exclude these two
}Unlike most HTTP tracking handlers, DynamoDB tracking needs special handling: because DynamoDB encodes the operation type in the request body (not just the URL), the handler must read the request body before forwarding. After reading and classifying, it reconstructs the request content with the original body and Content-Type header so the inner handler (the AWS SDK) can still consume it.
This is transparent — your production code and the AWS SDK continue to work normally.
DynamoDbTrackingMessageHandler implements ITrackingComponent and auto-registers with TrackingComponentRegistry. You can use this to assert that DynamoDB was (or wasn't) invoked during a test:
var handler = new DynamoDbTrackingMessageHandler(options);
// ... run test ...
Assert.True(handler.WasInvoked);
Assert.Equal(3, handler.InvocationCount);Or use TrackingComponentRegistry.GetUnusedComponents() at the end of each test to find services that were wired up but never called.
Getting Started
Common Tasks
Integration Guides
- Integration xUnit3
- Integration xUnit2
- Integration NUnit
- Integration MSTest
- Integration TUnit
- Integration BDDfy xUnit3
- Integration LightBDD xUnit2
- Integration LightBDD xUnit3
- Integration LightBDD TUnit
- Integration ReqNRoll xUnit2
- Integration ReqNRoll xUnit3
- Integration ReqNRoll TUnit
Extensions
- Integration AtlasDataApi Extension
- Integration BigQuery Extension
- Integration Bigtable Extension
- Integration BlobStorage Extension
- Integration ClickHouse Extension
- Integration CloudStorage Extension
- Integration CosmosDB Extension
- Integration Dapper Extension
- Integration DynamoDB Extension
- Integration EF Core Relational Extension
- Integration Elasticsearch Extension
- Integration EventBridge Extension
- Integration EventHubs Extension
- Integration Grpc Extension
- Integration Kafka Extension
- Integration MassTransit Extension
- Integration MongoDB Extension
- Integration MySqlConnector Extension
- Integration Npgsql Extension
- Integration Oracle Extension
- Integration PubSub Extension
- Integration Redis Extension
- Integration S3 Extension
- Integration ServiceBus Extension
- Integration SNS Extension
- Integration Spanner Extension
- Integration SqlClient Extension
- Integration Sqlite Extension
- Integration SQS Extension
- Integration StorageQueues Extension
- Integration OpenTelemetry Extension
- Integration DispatchProxy Extension
- Integration MediatR Extension
- Integration PlantUML IKVM
Configuration
- Tracking Dependencies
- Tracking Custom Dependencies
- HTTP Tracking Setup
- Report Configuration
- Diagram Customisation
- Phase-Aware Tracking
- Content Formatting
- PlantUML Server Configuration
Features
- Generated Reports
- Search Syntax
- Component Diagrams
- PlantUML Browser Rendering
- Inline SVG Rendering
- Internal Flow Tracking
- Tags and Attributes
- Excluding Requests
- Excluded Headers
- Multi-Host Test Architectures
- Event-Driven Architecture Testing
- Service Bus Tracking Patterns
- Background Thread Correlation
- Parallel-Safe Background Correlation
- Event & Message Tracking
- Assertion Tracking
- Step Tracking
- Tabular Attributes
- Large Response and Diagram Handling
- Diagnostics and Debugging
- CI Summary Integration
- CI Artifact Upload
- Merging Parallel Reports
Reference