Basis.IntegrationPlatform.MessageStore
0.3.1
Prefix Reserved
dotnet add package Basis.IntegrationPlatform.MessageStore --version 0.3.1
NuGet\Install-Package Basis.IntegrationPlatform.MessageStore -Version 0.3.1
<PackageReference Include="Basis.IntegrationPlatform.MessageStore" Version="0.3.1" />
<PackageVersion Include="Basis.IntegrationPlatform.MessageStore" Version="0.3.1" />
<PackageReference Include="Basis.IntegrationPlatform.MessageStore" />
paket add Basis.IntegrationPlatform.MessageStore --version 0.3.1
#r "nuget: Basis.IntegrationPlatform.MessageStore, 0.3.1"
#:package Basis.IntegrationPlatform.MessageStore@0.3.1
#addin nuget:?package=Basis.IntegrationPlatform.MessageStore&version=0.3.1
#tool nuget:?package=Basis.IntegrationPlatform.MessageStore&version=0.3.1
Basis .NET Message Store Adapter
Implements message-store contract v1.0.0-rc2 (basis-no/integration-platform-contract — spec, JSON Schemas, canonical SQL, and the certification suite both runtime adapters must pass).
NuGet package source for .NET integrations that need the Basis platform
message-store contract.
Package (NuGet.org):
Basis.IntegrationPlatform.MessageStore
The adapter owns platform mechanics for .NET integrations:
- consumes the platform input topic
APP_KAFKA_INPUT_TOPIC(defaultbip.<APP_NAME>.in) - calls application code through
IPlatformMessageHandler - takes the platform attempt number from the
x-bip-attemptheader (absent means attempt 1) and upserts the(message_id, attempt)row so infrastructure redeliveries re-record the same attempt - records terminal status in
bip_message_logandbip_message_attempt - records per-attempt step observations (
DELIVERED/FAILED/SKIPPED) inbip_message_attempt.steps_json - records idempotent external step outcomes in
bip_step_outcome - stores replayable payload bytes in Postgres under the payload policy
(
replayable= payload captured, not expired, not deleted — independent of message status) - retries handler failures before terminal
COMPLETEDorDLQ - publishes failed messages to
APP_KAFKA_DLQ_TOPIC(defaultbip.message.dlq) withx-bip-errorandx-bip-dlq-at - exposes
POST /admin/messages/{messageId}/resend - republishes replay payloads back to the integration input topic
(
bip.<integration>.in), committing theREQUESTEDaudit row before the Kafka produce - verifies the provisioned contract major in
bip_contractat startup and refuses to start on a mismatch (missing table logs a loud warning during the v1.0 rollout)
Integration Usage
builder.Services.AddBasisMessageStoreAdapter<MyMessageHandler>();
app.MapBasisMessageStoreAdminEndpoints();
Application code implements:
public sealed class MyMessageHandler : IPlatformMessageHandler
{
private readonly IPlatformStepExecutor steps;
public MyMessageHandler(IPlatformStepExecutor steps)
{
this.steps = steps;
}
public async Task<PlatformMessageResult> HandleAsync(
PlatformMessage message,
CancellationToken cancellationToken)
{
await steps.ExecuteAsync(
message,
stepId: "target-system",
endpointUri: "https://target.example/api/orders",
targetRef: message.TargetSystem,
operation: async ct =>
{
await SendToTargetSystem(message, ct);
},
cancellationToken);
return PlatformMessageResult.Completed();
}
}
Required Runtime Environment
The shared integration-app chart injects these when the catalog enables both
Kafka and Postgres:
APP_NAME
APP_ENVIRONMENT
APP_TENANT
KAFKA_BOOTSTRAP_SERVERS
APP_KAFKA_INPUT_TOPIC
APP_KAFKA_DLQ_TOPIC
POSTGRES_JDBC_URL
POSTGRES_USERNAME
POSTGRES_PASSWORD
BASIS_MESSAGE_STORE_SINK
BASIS_MESSAGE_STORE_STEP_OUTCOME_STORE
BASIS_MESSAGE_STORE_REPLAY_INPUT_TOPIC_PATTERN
Payload policy
Identical semantics across runtime adapters (contract v1 §6):
| Environment variable | Default | Meaning |
|---|---|---|
BASIS_MESSAGE_STORE_PAYLOAD_MODE |
postgres_inline |
postgres_inline or metadata_only |
BASIS_MESSAGE_STORE_PAYLOAD_MAX_BYTES |
1048576 |
Payloads larger than this degrade to metadata_only with a replay_disabled_reason |
BASIS_MESSAGE_STORE_PAYLOAD_RETENTION_DAYS |
30 |
Sets payload_expires_at on captured payloads |
metadata_only rows store no payload_bytes and are replayable=false with
a reason. Replayability is a property of payload availability, never of the
message outcome: COMPLETED messages are resendable as long as the payload
is captured, unexpired, and undeleted.
Publish
Releases are published to NuGet.org as Basis.IntegrationPlatform.MessageStore
by .github/workflows/publish-nuget.yml (tag-driven, NuGet Trusted
Publishing). The workflow builds, tests against the vendored contract bip_*
schema in tests/fixtures/postgres/, packs with the version derived from the
tag, and pushes. Per ADR-003 the public registry is the canonical channel;
tenant-registry fan-out remains an opt-in overlay for restricted environments
and is operated from the platform's internal infrastructure.
License and support
Apache-2.0. The adapter is developed as part of the Basis integration platform; production use is supported for platform customers through their platform agreement. Issues and pull requests from other users are welcome and handled best-effort.
Managed payload capture profile
The managed runtime keeps the v1 Kafka consumer, Postgres lifecycle journal,
step-outcome ledger, retry/DLQ handling and admin adapter active independently
of payload storage. BASIS_MESSAGE_STORE_PAYLOAD_MODE=metadata-only processes
messages but records no replay payload: lifecycle rows remain, with
replayable=false and a reason. postgres-inline restores payload capture
for subsequent deliveries subject to the existing size and retention policy.
This is not a no-storage mode: Kafka input/DLQ records retain their payloads under Kafka retention, and Postgres retains lifecycle and step metadata. Switching modes neither purges earlier history nor captures messages retroactively. Existing replayable history is evaluated per message by the adapter; a replay processed with capture off records a metadata-only new attempt. Earlier attempts and the replay audit remain historical evidence. The latest lifecycle row follows the latest attempt's capture policy.
Runtime stop/start remains deployment replica state. Do not disable the sink or step ledger to implement payload capture off: durable recording before commit remains mandatory. Missing or failed journal persistence must still prevent successful acknowledgement. No new adapter package or database schema is required for this profile; published .NET 0.3.0 and Camel 0.3.1 already implement the required payload modes. A coordinated managed projection release is required; do not infer fleet adoption from this documentation change.
Operator-owned runtime security
Existing deployments keep plaintext Kafka unless configured. For authenticated TLS, inject these settings through the platform's secret/runtime bindings:
| Environment variable | Default / purpose |
|---|---|
BASIS_MESSAGE_STORE_KAFKA_SECURITY_PROTOCOL |
PLAINTEXT; use SASL_SSL for authenticated TLS (SSL, SASL_PLAINTEXT also recognized) |
BASIS_MESSAGE_STORE_KAFKA_SASL_MECHANISM |
SCRAM-SHA-512; also SCRAM-SHA-256 or PLAIN |
BASIS_MESSAGE_STORE_KAFKA_SASL_USERNAME |
Required for SASL; inject approved principal |
BASIS_MESSAGE_STORE_KAFKA_SASL_PASSWORD |
Required for SASL; secret binding only |
BASIS_MESSAGE_STORE_KAFKA_SSL_CA_LOCATION |
Mounted broker CA file; system trust if unset |
BASIS_MESSAGE_STORE_POSTGRES_MAX_POOL_SIZE |
Optional bounded pool size for JDBC-derived settings; previous Npgsql default if unset |
BASIS_MESSAGE_STORE_POSTGRES_SSL_MODE |
Optional Npgsql TLS mode, e.g. VerifyFull |
BASIS_MESSAGE_STORE_POSTGRES_ROOT_CERTIFICATE |
Mounted PostgreSQL CA file |
The same Kafka client configuration covers consumption, DLQ and replay. TLS
certificate and hostname verification stay enabled. Missing SASL credentials
fail validation; the client never silently falls back to plaintext. Keep
credentials out of source, endpoint URLs and logs. An explicit
POSTGRES_CONNECTION_STRING takes precedence and must carry its own pool/TLS
settings. Plaintext modes are retained for trusted local compatibility.
Business persistence belongs in a separate application database. The adapter
uses its keyed datasource PlatformMessageStoreExtensions.MessageStoreDataSourceKey
for both journal and step persistence. A default datasource is still registered
for backwards compatibility; registering another application datasource will
not redirect adapter writes. Keep application schema migrations in a separate
execution with a scoped migration login, never the Message Store login.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Confluent.Kafka (>= 2.8.0)
- Npgsql (>= 9.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.