Skip to content

Commit b4ed227

Browse files
committed
chore(conformance): vendor the canonical Kafka (§6) binding block
1 parent 45acb01 commit b4ed227

1 file changed

Lines changed: 25 additions & 0 deletions

File tree

tests/conformance/manifest.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,30 @@
148148
{ "name": "native-equals-body", "body_attempts": 3, "redelivery_count": 3, "expected_attempts": 3 }
149149
]
150150
}
151+
},
152+
"kafka": {
153+
"description": "Apache Kafka binding conformance (broker-bindings.md §6). Every SDK that ships a Kafka transport must satisfy these. The record value is the byte-identical envelope (the 'cases' above); these lock the bq- header projection + the bq-attempts-authoritative reconciliation the binding adds. Per-message values reuse fixtures/order-created.json so the expected projection is deterministic.",
154+
"property_projection": {
155+
"description": "On produce, the transport MUST project these native Kafka record headers from the envelope, all UTF-8 byte strings (Kafka headers are bytes, so integers are stringified): bq-job = job (the URN), bq-trace-id = trace_id, bq-message-id = meta.id, bq-schema-version = str(meta.schema_version), bq-source-lang = meta.lang, bq-attempts = str(attempts). The record value is the byte-identical envelope and the record timestamp mirrors meta.created_at (Unix ms). Applies to every Kafka-producing SDK.",
156+
"envelope_file": "fixtures/order-created.json",
157+
"headers": {
158+
"bq-job": "urn:babel:orders:created",
159+
"bq-trace-id": "7b3f9c2a-e41d-4f88-9b2a-1c0d5e6f7a8b",
160+
"bq-message-id": "f1e2d3c4-b5a6-4789-90ab-cdef01234567",
161+
"bq-schema-version": "1",
162+
"bq-source-lang": "php",
163+
"bq-attempts": "0"
164+
}
165+
},
166+
"attempts_reconciliation": {
167+
"description": "On consume, attempts = the bq-attempts header when present (AUTHORITATIVE — Kafka has no native delivery count), else the body's own attempts (the fallback for a non-BabelQueue producer). This is NOT a max: the header overrides the body even when lower. A null header_attempts means the header is absent. The rule is identical across all five Kafka SDKs.",
168+
"cases": [
169+
{ "name": "header-matches-body", "body_attempts": 0, "header_attempts": 0, "expected_attempts": 0 },
170+
{ "name": "header-present", "body_attempts": 0, "header_attempts": 2, "expected_attempts": 2 },
171+
{ "name": "header-absent-falls-back", "body_attempts": 3, "header_attempts": null, "expected_attempts": 3 },
172+
{ "name": "header-authoritative-overrides", "body_attempts": 5, "header_attempts": 1, "expected_attempts": 1 },
173+
{ "name": "header-higher-than-body", "body_attempts": 1, "header_attempts": 4, "expected_attempts": 4 }
174+
]
175+
}
151176
}
152177
}

0 commit comments

Comments
 (0)