Skip to content

Conversation

PallabPaul
Copy link
Member

@PallabPaul PallabPaul commented Aug 12, 2025

Contributing to the Azure SDK

Please see our CONTRIBUTING.md if you are not familiar with contributing to this repository or have questions.

For specific information about pull request etiquette and best practices, see this section.

Changes:

  • Added support to route to failover ledgers for the GetLedgerEntry, GetLedgerEntryAsync, GetCurrentLedgerEntry, and GetCurrentLedgerEntryAsync methods.

@PallabPaul
Copy link
Member Author

PallabPaul commented Aug 12, 2025

TODO:

  • remove log lines
  • merge /failover endpoint CP logic before merging this

@PallabPaul
Copy link
Member Author

TODO:

  • remove log lines
  • merge /failover endpoint CP logic before merging this

Done

@PallabPaul PallabPaul marked this pull request as ready for review August 14, 2025 22:22
@Copilot Copilot AI review requested due to automatic review settings August 14, 2025 22:22
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This pull request adds failover endpoint support to the Azure Confidential Ledger SDK, enabling automatic routing to backup ledger instances when the primary endpoint fails. The implementation provides a new failover service that can discover and attempt operations against backup ledger endpoints.

Key changes include:

  • Introduction of a new ConfidentialLedgerFailoverService class that handles failover endpoint discovery and execution
  • Integration of the failover service into the main ConfidentialLedgerClient
  • Version bump from 1.4.1-beta.3 to 1.5.0-beta.1

Reviewed Changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

File Description
ConfidentialLedgerFailoverService.cs New service class implementing failover endpoint discovery and operation execution logic
ConfidentialLedgerClient.cs Integration of the failover service into the main client
Azure.Security.ConfidentialLedger.csproj Version increment to reflect new failover functionality
CHANGELOG.md Documentation of the new failover routing feature

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

{
List<Uri> endpoints = await GetFailoverEndpointsAsync(primaryEndpoint, cancellationToken).ConfigureAwait(false);
Exception last = null;
foreach (var ep in endpoints)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a minor suggestion, probably not worth doing for this PR since this customer only has one failover: switch to Task.WhenAny or similar for the async failovers method. That should also simplify handling of the requestfailed exceptions.

var jsonWriterOptions = new System.Text.Json.JsonWriterOptions
{
Indented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious - what breaks if we use the regular utf8 encoder?

}
ms.Position = 0;
// Wrap in a synthetic Response that mimics the original status/headers but with new content.
return new SyntheticResponse(currentResponse, ms.ToArray());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Azure Response ContentStream is settable. I'm wondering if we can just set the currentResponse.contentStream with your memorystream to avoid wrapping and creating the SyntheticResponse.

public abstract Stream? ContentStream { get; set; }


if (!string.IsNullOrEmpty(failoverLedgerId))
{
Uri endpoint = new UriBuilder(primaryEndpoint) { Host = $"{failoverLedgerId}.{LedgerDomainSuffix}" }.Uri;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is passing the primaryEndpoint needed here?

{
// Include 404 and specific UnknownLedgerEntry error code.
return ex.Status == 404 ||
string.Equals(ex.ErrorCode, "UnknownLedgerEntry", StringComparison.OrdinalIgnoreCase) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should UnknownLedgerEntry be retriable? That's a guarantee that no key was written in that transaction right?

Copy link

@msftsettiy msftsettiy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, please explore the option to set the service identity cert for the fail over endpoints in the transport options object.

try
{
using HttpMessage primaryMessage = CreateGetLedgerEntryRequest(_ledgerEndpoint, transactionId, collectionId, context);
return await _pipeline.ProcessMessageAsync(primaryMessage, context).ConfigureAwait(false);
Copy link
Member

@taicchoumsft taicchoumsft Aug 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgetting a little: does the pipeline account for Not Ready state? I only remember that the python SDK does not.

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

Successfully merging this pull request may close these issues.

3 participants