Skip to content

[FEAT] Event Hubs: partition support ($management READ + partitioned consumer path) #239

Description

@deyanp

Service

Event Hubs (AMQP data plane + management plane)

API Action / Feature

Partition support: the $management READ operations (com.microsoft:eventhub, com.microsoft:partition) and the partitioned consumer path they feed.

Azure Documentation

Why is this needed?

Consuming from Event Hubs does not work at all today, for any SDK. Every consumer starts by asking the management node which partitions exist, and nothing answers:

get_eventhub_properties failed: Transport Implementation Error: StatusCode is nor found

With #237 (CBS + the Artemis library patches) publishing works end to end, so this is the last thing between floci-az and a working Event Hubs round-trip.

There is also a smaller correctness point: the entity config syntax accepts a partition count — floci.az.services.event-hub.entities is documented as "name:partitions", e.g. eh1:4 — and ArtemisConfigGenerator.parseEntities then discards it:

"The partition count in the entities string is accepted but ignored (Artemis handles routing)."

So a hub configured with four partitions is emulated as one undivided stream, silently.

Current state

grep -ri partition src/main/java/io/floci/az/services/eventhub/ returns exactly one hit — the comment above. There are no partition ids, no partition addresses, no partition properties. A hub becomes an Artemis address with one durable queue per consumer group.

The consumer path needs three things that do not exist yet:

  1. Management replies. com.microsoft:eventhub READ must return name, created_at, partition_count and partition_ids; com.microsoft:partition READ must return begin_sequence_number, last_enqueued_sequence_number, last_enqueued_offset, last_enqueued_time_utc, is_partition_empty. A missing field fails the call outright.
  2. Per-partition addresses. SDKs attach the receiver to amqps://{namespace}/{hub}/ConsumerGroups/{group}/Partitions/{id}. The generated topology has no /Partitions/ segment. Because Event Hubs sets auto-create-addresses=true, an attach today succeeds against an empty auto-created address and the consumer reads nothing — a silent wrong answer rather than an error.
  3. Start positions. Earliest / latest / from-offset / from-sequence-number / from-enqueued-time arrive as AMQP selector filters over x-opt-* annotations, so those values have to exist on messages and be filterable.

Proposed implementation

Real N-partition emulation, using machinery that is already in the repo.

Topology — a durable queue per (consumer group, partition), named to match the address SDKs attach to:

<hub>/ConsumerGroups/<group>/Partitions/<n>

Routing and stamping — an Artemis broker plugin, the same mechanism as the Service Bus plugins already shipped in servicebus-artemis-extension.jar. On route it would:

  1. choose the partition — an explicitly pinned partition id if present, else a stable hash of the partition key, else round-robin;
  2. assign per-partition monotonic x-opt-sequence-number and x-opt-offset, and stamp x-opt-enqueued-time;
  3. set the partition as an ordinary message property so each partition queue can select its own messages with a native Artemis filter.

Management responder — the $cbs pattern reused: a $management$management-intercept divert plus a proton-j responder modelled on ServiceBusCbsResponder, answering both READ types from the counters the plugin maintains.

Start positions — once the annotations are real, filterable properties, Artemis selectors can serve all five forms.

Config — stop discarding the count in parseEntities and thread it through to topology and management.

This also lines the AMQP arm up with the Kafka arm, where Redpanda already has native partitions: a hub declared eh1:4 would mean the same thing over both protocols.

Design questions

Worth settling before any code, since these change the shape of it:

  1. Is real multi-partition the direction you want? The cheaper option is to emulate a single partition and report partition_ids: ["0"], following the floci-az is always single-partition precedent in CosmosHandler. It would unblock consumers for far less work, but partitions are central to Event Hubs' consumer model — partition keys, per-partition ordering, per-partition checkpoints, EventProcessor distributing partitions across instances — so a single-partition emulator would make all of that pass against behaviour that cannot occur in production. My preference is real partitions for exactly that reason, but it is your call.
  2. Validation of the configured count. It becomes load-bearing, and today it has no bounds at all — parseEntities splits on : and discards the number, so eh1:0, eh1:abc and eh1:10000 are silently equivalent. Reject zero and non-numeric (Azure requires at least one), and what upper bound? Each partition costs a durable queue per consumer group, so the count multiplies: eh1:10000 with five groups would be 50,000 queues. Azure caps at 32 per hub outside dedicated clusters, which seems a reasonable limit to borrow — cap, warn, or reject beyond it?
  3. Broker plugin vs. an AMQP proxy for routing and stamping — the plugin looks right given the Service Bus precedent, but is there a reason you would avoid one here?
  4. Persistence — in-memory per-namespace counters, consistent with storage: memory, or must sequence numbers and offsets survive a restart?
  5. Partition assignment — does the hash need to match Azure's real assignment for a given partition key, or is any stable hash acceptable?

Are you willing to contribute a PR?

  • Yes
  • No

Happy to implement this once the direction above is settled — I would rather agree the semantics first than send a few hundred lines of Java that encodes the wrong model. Context: #227 reported the CBS gap, and #237 fixes CBS plus the max-message-size library patches, which is what made publishing work; this is the remaining half.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesteventhubAzure Event Hubs

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions