-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[event-hubs] Created a v2 -> v5 migration guide #6501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
richardpark-msft
merged 44 commits into
Azure:master
from
richardpark-msft:richardpark-eh-migration-guide
Dec 11, 2019
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
29858fe
starting the migration guide
richardpark-msft 45065e3
Update event hubs migration guide.md
richardpark-msft a1c6ebd
Change wording to 'receiving'
richardpark-msft e7b1def
AAD line
richardpark-msft 7ca4971
* Checked against code - casing for AAD was incorrect (should have be…
richardpark-msft c1855a0
Merge branch 'richardpark-eh-migration-guide' of https://github.com/r…
richardpark-msft 5d7dceb
Applying Ramya's changes
richardpark-msft 686dc6a
Took part of a description from our REST documentation and tailored i…
richardpark-msft e6e89bd
Merge branch 'richardpark-eh-migration-guide' of https://github.com/r…
richardpark-msft 8edaf44
Updating migration guide sample for sending.
richardpark-msft 52bce99
Add in a description of EventProcessorHost
richardpark-msft 79fdac1
Removed the 'as well'
richardpark-msft 39f6a44
Adding example for EventProcessorHost => EventHubConsumerClient migra…
richardpark-msft 339ba8c
* Don't use $Default anywhere if we can avoid it. Guide the user choo…
richardpark-msft 7fe7dea
There were two packages, not one.
richardpark-msft 20492ab
Document the multiple types of message receiving we can handle.
richardpark-msft 78138d4
We only construct clients, not empires.
richardpark-msft 8992aee
It's a function. Be proud of it and call it theoretically in the table.
richardpark-msft 58bdcb1
Parens.
richardpark-msft 07fb17c
Removed!
richardpark-msft b6286da
Updated with in-person feedback
de2de90
Remove backtick from the toc links
55e8480
send example was incorrect (should have been sendBatch)
de034b9
The user is in control of the batch size...
richardpark-msft 93e8259
Merge branch 'richardpark-eh-migration-guide' of https://github.com/r…
8e74f24
Let's assume they're already full events and not just data.
richardpark-msft bb92f68
Tenatitively fixing sample
9b37716
Merge branch 'richardpark-eh-migration-guide' of https://github.com/r…
2c25e0e
Merge remote-tracking branch 'upstream/master' into richardpark-eh-mi…
96d7a5b
Advertise the goodness that was EPH and that is now part of the Event…
richardpark-msft 0db9b43
* Make sample a bit more interesting by allowing them to specify the …
richardpark-msft e9de8a0
EventHubs V2 implies something else...
richardpark-msft 91755dc
Same deal here - EventHubs V5 implies something different.
richardpark-msft 433ddaf
A little more context goes a long way
richardpark-msft 6ee889c
Update the "new users should go to readme.md" blurb.
richardpark-msft 038e662
createFromConnectionString is really a constructor. Put it in the rig…
richardpark-msft eec6e97
Love it.
richardpark-msft d59f209
Merge branch 'richardpark-eh-migration-guide' of https://github.com/r…
richardpark-msft 9d95885
Sync sample change with readme change
richardpark-msft 7574c08
Updated to mention the change is a combination of calling subscribe()…
richardpark-msft 5b97049
Adding in EventPosition as well since those methods have also been re…
richardpark-msft 3d5ea48
Make mention of the package since everything is now unified.
richardpark-msft d170dc2
Provide examples on what those different sources of errors are.
richardpark-msft 121adff
Updated to not mention SubscriptionEventHandlers, which is really jus…
richardpark-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,216 @@ | ||
| # Migration Guide (EventHubs v2 to v5) | ||
|
|
||
| This document is intended for users that are familiar with V2 of the JavaScript SDK for Event Hubs library (`@azure/event-hubs@2.x.x` & `@azure/event-processor-host@2.x.x`) and wish | ||
| to migrate their application to V5 of the same library. | ||
|
|
||
| For users new to the JavaScript SDK for Event Hubs, please see the [readme file for the @azure/event-hubs package](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/README.md). | ||
|
|
||
| ## General changes | ||
|
|
||
| In the interest of simplifying the API surface we've made two distinct | ||
| clients, rather than having a single `EventHubClient`: | ||
| * [EventHubProducerClient](https://docs.microsoft.com/en-us/javascript/api/@azure/event-hubs/eventhubproducerclient?view=azure-node-preview) | ||
| for sending messages. | ||
| * [EventHubConsumerClient](https://docs.microsoft.com/en-us/javascript/api/@azure/event-hubs/eventhubconsumerclient?view=azure-node-preview) | ||
| for receiving messages. | ||
|
|
||
| We've also merged the functionality from `EventProcessorHost` in the `@azure/event-processor-host` package into | ||
| `EventHubConsumerClient` in the `@azure/event-hubs` package, allowing `EventHubConsumerClient` to be the single | ||
| point of entry for receiving of any type (from single partition, all partitions, or with load balancing and checkpointing features) within Event Hubs. | ||
|
|
||
|
|
||
| ### Client constructors | ||
|
|
||
| | In v2 | Equivalent in v5 | Sample | | ||
| |------------------------------------------------|------------------------------------------------------------------|--------| | ||
| | `EventHubClient.createFromConnectionString()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts), [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | ||
| | `EventHubClient.createFromAadTokenCredentials()` | `new EventHubProducerClient()` or `new EventHubConsumerClient()` | [usingAadAuth](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/usingAadAuth.ts) | ||
| | `EventProcessorHost.createFromConnectionString()` | `new EventHubConsumerClient(..., checkpointStore)` | [receiveEventsUsingCheckpointStore](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEventsUsingCheckpointStore.ts) | | ||
|
|
||
| ### Receiving events | ||
|
|
||
| | In v2 | Equivalent in v5 | Sample | | ||
| |------------------------------------------------|------------------------------------------------------------------|--------| | ||
| | `EventHubClient.receive()` and `EventHubClient.receiveBatch()` | `EventHubConsumerClient.subscribe()` | [receiveEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | | ||
|
|
||
| ### Sending events | ||
|
|
||
| | In v2 | Equivalent in v5 | Sample | | ||
| |------------------------------------------------|------------------------------------------------------------------|--------| | ||
| | `EventHubClient.send()` | `EventHubConsumerClient.sendBatch()` | [sendEvents](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/sendEvents.ts) | | ||
|
|
||
| ### Minor renames | ||
|
|
||
| | In v2 | Equivalent in v5 | | ||
| |------------------------------------------------|-----------------------------| | ||
| | `EventPosition.fromStart()` | `EventPosition.earliest()` | | ||
| | `EventPosition.fromEnd()` | `EventPosition.latest()` | | ||
|
|
||
| ## Migration samples | ||
|
|
||
| * [Receiving events](#migrating-code-from-eventhubclient-to-eventhubconsumerclient-for-receiving-events) | ||
| * [Receiving events with checkpointing](#migrating-code-from-eventprocessorhost-to-eventhubconsumerclient-for-receiving-events) | ||
| * [Sending events](#migrating-code-from-eventhubclient-to-eventhubproducerclient-for-sending-events) | ||
|
|
||
| ### Migrating code from `EventHubClient` to `EventHubConsumerClient` for receiving events | ||
|
|
||
| In V2, event handlers were passed as positional arguments to `receive`. | ||
|
|
||
| In V5, event handlers are passed as part of a `SubscriptionEventHandlers` shaped object. | ||
|
|
||
| For example, this code which receives from a partition in V2: | ||
|
|
||
| ```typescript | ||
| const client = EventHubClient.createFromConnectionString(connectionString); | ||
| const rcvHandler = client.receive(partitionId, onMessageHandler, onErrorHandler, { | ||
| eventPosition: EventPosition.fromStart(), | ||
| consumerGroup: consumerGroupName | ||
| }); | ||
| await rcvHandler.stop(); | ||
| ``` | ||
|
|
||
| Becomes this in V5: | ||
|
|
||
| ```typescript | ||
| const eventHubConsumerClient = new EventHubConsumerClient(consumerGroupName, connectionString); | ||
|
|
||
| const subscription = eventHubConsumerClient.subscribe( | ||
| partitionId, { | ||
| processInitialize: (initContext) => { | ||
| initContext.setStartingPosition(EventPosition.fromStart()); | ||
| }, | ||
| processEvents: onMessageHandler, | ||
| processError: onErrorHandler | ||
| }); | ||
|
|
||
| await subscription.close(); | ||
| ``` | ||
|
|
||
| See [`receiveEvents.ts`](https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/eventhub/event-hubs/samples/receiveEvents.ts) | ||
| for a sample program demonstrating this. | ||
|
|
||
| ### Migrating code from `EventHubClient` to `EventHubProducerClient` for sending events | ||
|
|
||
| In V2, there were multiple options on how to send data. | ||
|
|
||
| In V5, this has been consolidated into a more efficient `sendBatch` method. | ||
| Batching merges information from multiple messages into a single send, reducing | ||
| the amount of network communication needed vs sending messages one at a time. | ||
|
|
||
| So in V2: | ||
| ```typescript | ||
| const eventsToSend = [ | ||
| // events go here | ||
| ]; | ||
|
|
||
| const client = EventHubClient.createFromConnectionString(connectionString); | ||
|
|
||
| // Would fail if the total size of events exceed the max size supported by the library. | ||
| await client.sendBatch(eventsToSend, partitionId); | ||
| ``` | ||
|
|
||
| In V5: | ||
| ```typescript | ||
| const producer = new EventHubProducerClient(connectionString); | ||
|
|
||
| const eventsToSend = [ | ||
| // events go here | ||
| ]; | ||
|
|
||
| let batch = await producer.createBatch(); | ||
| let i = 0; | ||
|
|
||
| while (i < eventsToSend.length) { | ||
| // messages can fail to be added to the batch if they exceed the maximum size configured for | ||
| // the EventHub. | ||
| const isAdded = batch.tryAdd(eventsToSend[i]); | ||
|
|
||
| if (isAdded) { | ||
| console.log(`Added event number ${i} to the batch`); | ||
| ++i; | ||
| continue; | ||
| } | ||
|
|
||
| if (batch.count === 0) { | ||
| // If we can't add it and the batch is empty that means the message we're trying to send | ||
| // is too large, even when it would be the _only_ message in the batch. | ||
| // | ||
| // At this point you'll need to decide if you're okay with skipping this message entirely | ||
| // or find some way to shrink it. | ||
| console.log(`Message was too large and can't be sent until it's made smaller. Skipping...`); | ||
| ++i; | ||
| continue; | ||
| } | ||
|
|
||
| // otherwise this just signals a good spot to send our batch | ||
| console.log(`Batch is full - sending ${batch.count} messages as a single batch.`); | ||
| await producer.sendBatch(batch); | ||
|
|
||
| // and create a new one to house the next set of messages | ||
| batch = await producer.createBatch(); | ||
| } | ||
|
|
||
| // send any remaining messages, if any. | ||
| if (batch.count > 0) { | ||
| console.log(`Sending remaining ${batch.count} messages as a single batch.`) | ||
| await producer.sendBatch(batch); | ||
| } | ||
| ``` | ||
|
|
||
| ### Migrating code from `EventProcessorHost` to `EventHubConsumerClient` for receiving events | ||
|
|
||
| In V2, `EventProcessorHost` allowed you to balance the load between multiple instances of | ||
| your program when receiving events. | ||
|
|
||
| In V5, `EventHubConsumerClient` allows you to do the same with the `subscribe()` method if you | ||
| pass a `CheckpointStore` to the constructor. | ||
|
|
||
| So in V2: | ||
| ```typescript | ||
| const eph = EventProcessorHost.createFromConnectionString( | ||
| EventProcessorHost.createHostName(ephName), | ||
| storageConnectionString, | ||
| storageContainerName, | ||
| ehConnectionString, | ||
| { | ||
| eventHubPath: eventHubName, | ||
| onEphError: (error: any) => { | ||
| console.log("[%s] Error: %O", ephName, error); | ||
| } | ||
| } | ||
| ); | ||
|
|
||
| const onMessage: OnReceivedMessage = async (context: PartitionContext, event: EventData) => { } | ||
|
|
||
| const onError: OnReceivedError = (error: any) => { | ||
| console.log("[%s] Received Error: %O", ephName, error); | ||
| }; | ||
|
|
||
| await eph.start(onMessage, onError); | ||
| ``` | ||
|
|
||
| And in V5: | ||
| ```typescript | ||
| import { EventHubConsumerClient, CheckpointStore } from "@azure/event-hubs"; | ||
| import { ContainerClient } from "@azure/storage-blob"; | ||
| import { BlobCheckpointStore } from "@azure/eventhubs-checkpointstore-blob"; | ||
|
|
||
| const containerClient = new ContainerClient(storageConnectionString, storageContainerName); | ||
| const checkpointStore : CheckpointStore = new BlobCheckpointStore(containerClient); | ||
| const eventHubConsumerClient = new EventHubConsumerClient(consumerGroupName, ehConnectionString, eventHubName); | ||
|
|
||
| const subscription = eventHubConsumerClient.subscribe( | ||
| partitionId, { | ||
| // In V5 we deliver messages in batches, rather than a single message | ||
| // at a time. You can control the batch size via the options passed to the client. | ||
| processEvents: (messages, context) => {}, | ||
|
|
||
| // Prior to V5 errors were handled by separate callbacks depending | ||
| // on where they were thrown i.e when managing different partitions vs receiving from each partition. | ||
| // | ||
| // In V5 you only need a single error handler for all of those cases. | ||
| processError: onErrorHandler | ||
| }); | ||
|
|
||
| await subscription.close(); | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.