Skip to content
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

AMQP 1.0 Support for Service Bus SDK #1185

Closed
wants to merge 461 commits into from

Conversation

minghuaw
Copy link

@minghuaw minghuaw commented Dec 28, 2022

This PR is a partial fullfillment of service bus SDK using the AMQP 1.0 protocol (#643). The overall design follows that of the dotnet SDK.

What's added

The following key public types are added in this PR.

  • ServiceBusClient
  • ServiceBusSender
  • ServiceBusReceiver
  • ServiceBusSessionReceiver
  • ServiceBusRuleManager
  • ServiceBusMessageBatch

This PR also changes the minimum required rust version to 1.65 due to the use of generic associate types.

What's removed

The old reqwest based HTTP client (QueueClient, SubscriptionReceiver, TopicClient, and TopicSender) and the corresponding dependencies/examples/tests are removed.

What's not implemented yet

  • Transaction
  • ServiceBusProcessor
  • ServiceBusSessionProcessor
  • ServiceBusAdministrationClient

Testing

Mock testing (using the mockall crate) has been applied to some unit tests but not implemented for integration testing, and integration testing relies heavily on live testing. Because of this, the environment variables listed below must be set in order to run cargo test. For testing on a local machine, it is recommended to put these environment variables in a .env file that is placed at the root of this crate (ie. azure-sdk-for-rust/sdk/messaging_servicebus/.env).

  • SERVICE_BUS_CONNECTION_STRING - full connection string to a service bus namespace. It should look like "Endpoint=sb://<your-namespace>.servicebus.windows.net/;SharedAccessKeyName=<your-policy>;SharedAccessKey=<your-key>"
  • SERVICE_BUS_NAMESPACE - "<your-namespace>.servicebus.windows.net"
  • SERVICE_BUS_SAS_KEY_NAME - shared access key name, for example "RootManageSharedAccessKey"
  • SERVICE_BUS_SAS_KEY - shared access key value. This is essentially the field "<your-key>" in the full connection string
  • SERVICE_BUS_QUEUE - a queue that does NOT have session enabled
  • SERVICE_BUS_SESSION_QUEUE - a queue that has session enabled
  • SERVICE_BUS_TOPIC - a topic whose subscriptions will be used for non-session topic/subscription testing
  • SERVICE_BUS_SUBSCRIPTION - a subscription of SERVICE_BUS_TOPIC, and it does NOT have session enabled
  • SERVICE_BUS_SESSION_TOPIC - a topic whose subscriptions will be used for session-enabled topic/subscription testing
  • SERVICE_BUS_SESSION_SUBSCRIPTION - a subscription of SERVICE_BUS_SESSION_TOPIC, and it must have session enabled
  • SERVICE_BUS_RULE_FILTER_TEST_TOPIC - a topic whose subscription will be used to test get/delete/create rule filters. It is recommended to have a separate topic that is different from SERVICE_BUS_TOPIC and SERVICE_BUS_SESSION_TOPIC to avoid accidentally affecting the subscription testing with the rule filters.
  • SERVICE_BUS_RULE_FILTER_TEST_SUBSCRIPTION - a subscription of SERVICE_BUS_RULE_FILTER_TEST_TOPIC that will be used for get/delete/create rule filter testing. It is recommended to have a separate topic/subscription that is different from SERVICE_BUS_TOPIC/SERVICE_BUS_SUBSCRIPTION and SERVICE_BUS_SESSION_TOPIC/SERVICE_BUS_SESSION_SUBSCRIPTION to avoid accidentally affecting the subscription testing with the rule filters.

Most integration test cases assume an empty queue/subscription at the beginning of the test and should leave an empty queue/subscription at the end of the test. So it is important to make sure only one live test is running for the testing queue/topic/subscription.

There is one long test in the integration tests (fn send_to_queue_every_minute_for_two_hour() in messaging_servicebus/tests/long_tests.rs) that is ignored in the usual cargo test. This test can be explicitly executed with cargo test --test long_tests -- --ignored --exact --nocapture which will also periodically print out message sent and message received. This test could also be used for testing recovery against network interruptions.

I can provide my testing namespace/queue/topic/subscription (actually a copy of my .env file) in an email if necessary.

Documentation

The current implementation sets a rust doc flag "docsrs" to conditionally import types for intra-doc-links. To test the doc locally, the following command could be used. Please note that a nightly toolchain is needed (the nightly toolchain will used for the doc only, the crate itself doesn't need nightly at all)

cargo +nightly doc --no-deps --open -Z unstable-options --config "build.rustdocflags=[\"--cfg\", \"docsrs\"]"

Most of the documentations are ported from the dotnet SDK. More detailed explanation and/or examples might be necessary

Limitations and discussions

I have not got the time to review whether the APIs are cancel safe, but the send and recv method provided by the upstream AMQP crate have been reviewed and should be cancel safe.

There are a few design decisions that, I think, could be discussed

  1. Whether AzureNamedKeyCredential and AzureSasCredential should be moved to the azure_core crate (which is the way that is implemented in the dotnet sdk)?
  2. The current retry policy trait and implementation (ServiceBusRetryPolicy and BasicRetryPolicy) essentially mimic what the dotnet sdk does. However, there is another retry policy trait in the azure_core crate (azure_core::RetryPolicy), which is not exactly the same. Should this implementation move to use azure_core::RetryPolicy instead?

There is a known problem in the current implementation. Sometimes, upon certian network interruptions (eg. switching from one wireless network to another), the sending operation may need to wait for ServiceBusRetryOptions::delay (default to 1 minute) before it starts to try to recover the connection and retry the sending operation. The tests/long_tests.rs has been used for testing network interruptions by manually disconnecting/reconnecting or switching the network.

Another problem is logging. Both log and tracing are popular in the rust ecosystem. Would it make sense to use a feature to allow user to choose which logging crate to use? (this will likely be in the next PR). Ths current use of log also definitely has room for improvement.

@mario-guerra
Copy link
Member

Hi @minghuaw, are you still using the service bus test resource I set up for you?

@minghuaw
Copy link
Author

Hi @minghuaw, are you still using the service bus test resource I set up for you?

No. I am currently only using the ones I created under my own SB namespace

@mario-guerra
Copy link
Member

mario-guerra commented Feb 10, 2023 via email

@cataggar
Copy link
Member

@minghuaw, thank you for continuing to update this. ❤️

@cataggar
Copy link
Member

We really like seeing this work, but it is not something those of us volunteering can take on. It is probably best to create a new git repo for azservicebus.

https://crates.io/crates/azservicebus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants