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

SDK 3.40.0-preview.1: Adds version bump and changelog. #4436

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ClientOfficialVersion>3.39.0</ClientOfficialVersion>
<ClientOfficialVersion>3.39.1</ClientOfficialVersion>
<ClientPreviewVersion>3.40.0</ClientPreviewVersion>
<ClientPreviewSuffixVersion>preview.0</ClientPreviewSuffixVersion>
<ClientPreviewSuffixVersion>preview.1</ClientPreviewSuffixVersion>
<DirectVersion>3.33.1</DirectVersion>
<EncryptionOfficialVersion>2.0.4</EncryptionOfficialVersion>
<EncryptionPreviewVersion>2.1.0</EncryptionPreviewVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,37 +85,33 @@ public void ChangeFeedModeSwitchingCheck(

DocumentServiceLease documentServiceLease = documentServiceLeases[0];

// Mode attribute exists on lease document, but it is not set. legacy is always LatestVersion because
// AllVersionsAndDeletes does not exist. There should not be any legacy lease documents that are
// AllVersionsAndDeletes. If the ChangeFeedProcessor's mode is not legacy, an exception should thrown.
// If the ChangeFeedProcessor mode is not the mode in the lease document, an exception should be thrown.

bool shouldThrowException = this.VerifyChangeFeedProcessorMode(
changeFeedMode:
string.IsNullOrEmpty(documentServiceLease.Mode)
? ChangeFeedMode.LatestVersion
: changeFeedLeaseOptionsMode,
leaseChangeFeedMode: documentServiceLease.Mode,
normalizedProcessorChangeFeedMode: out string normalizedProcessorChangeFeedMode);

// If shouldThrowException is true, throw the exception.

if (shouldThrowException)
{
throw new ArgumentException(message: $"Switching {nameof(ChangeFeedMode)} {documentServiceLease.Mode} to {normalizedProcessorChangeFeedMode} is not allowed.");
}
this.VerifyChangeFeedProcessorMode(
changeFeedMode: changeFeedLeaseOptionsMode,
leaseChangeFeedMode: documentServiceLease.Mode);
}

private bool VerifyChangeFeedProcessorMode(
/// <summary>
/// Mode attribute exists on lease document, but it is not set. Legacy is always LatestVersion/IncrementalFeed
/// because AllVersionsAndDeletes does not exist. There should not be any legacy lease documents that are
/// AllVersionsAndDeletes. If the ChangeFeedProcessor's mode is not legacy, an exception should thrown.
/// If the ChangeFeedProcessor mode is not the mode in the lease document, an exception should be thrown.
/// </summary>
/// <param name="changeFeedMode">The current change feed mode.</param>
/// <param name="leaseChangeFeedMode">The change feed mode on the lease document.</param>
private void VerifyChangeFeedProcessorMode(
ChangeFeedMode changeFeedMode,
string leaseChangeFeedMode,
out string normalizedProcessorChangeFeedMode)
string leaseChangeFeedMode)
{
normalizedProcessorChangeFeedMode = changeFeedMode == ChangeFeedMode.AllVersionsAndDeletes
leaseChangeFeedMode ??= HttpConstants.A_IMHeaderValues.IncrementalFeed;

string normalizedProcessorChangeFeedMode = changeFeedMode == ChangeFeedMode.AllVersionsAndDeletes
? HttpConstants.A_IMHeaderValues.FullFidelityFeed
: HttpConstants.A_IMHeaderValues.IncrementalFeed;

return string.Compare(leaseChangeFeedMode, normalizedProcessorChangeFeedMode, StringComparison.OrdinalIgnoreCase) != 0;
if (string.Compare(leaseChangeFeedMode, normalizedProcessorChangeFeedMode, StringComparison.OrdinalIgnoreCase) != 0)
{
throw new ArgumentException(message: $"Switching {nameof(ChangeFeedMode)} {leaseChangeFeedMode} to {normalizedProcessorChangeFeedMode} is not allowed.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests.ChangeFeed
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.ChangeFeed.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;

[TestClass]
[TestCategory("ChangeFeedProcessor")]
Expand Down Expand Up @@ -107,8 +108,6 @@ public async Task WhenADocumentIsCreatedThenUpdatedThenDeletedTestsAsync()
Assert.IsTrue(condition: createChange.Metadata.Lsn < replaceChange.Metadata.Lsn, message: "The create operation must happen before the replace operation.");
Assert.IsTrue(condition: createChange.Metadata.Lsn < replaceChange.Metadata.Lsn, message: "The replace operation must happen before the delete operation.");

Debug.WriteLine("Assertions completed.");

return Task.CompletedTask;
})
.WithInstanceName(Guid.NewGuid().ToString())
Expand All @@ -117,9 +116,6 @@ public async Task WhenADocumentIsCreatedThenUpdatedThenDeletedTestsAsync()
{
exception = error.InnerException;

Debug.WriteLine("WithErrorNotification");
Debug.WriteLine(error.ToString());

return Task.CompletedTask;
})
.Build();
Expand Down Expand Up @@ -176,11 +172,46 @@ await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed));

Debug.WriteLine(exception.ToString());

Assert.AreEqual(expected: "Switching ChangeFeedMode Incremental Feed to Full-Fidelity Feed is not allowed.", actual: exception.Message);
}


/// <summary>
/// This is based on an issue located at <see href="https://github.com/Azure/azure-cosmos-dotnet-v3/issues/4308"/>.
/// </summary>
[TestMethod]
[Owner("philipthomas-MSFT")]
[Description("Scenario: For Legacy lease documents with no Mode property, When ChangeFeedMode on ChangeFeedProcessor, switches from LatestVersion to AllVersionsAndDeletes," +
"an exception is expected. LatestVersion's WithStartFromBeginning can be set, or not set.")]
[DataRow(false)]
[DataRow(true)]
public async Task WhenLegacyLatestVersionSwitchToAllVersionsAndDeletesExpectsAexceptionTestAsync(bool withStartFromBeginning)
{
ContainerInternal monitoredContainer = await this.CreateMonitoredContainer(ChangeFeedMode.LatestVersion);
ManualResetEvent allDocsProcessed = new(false);

await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.BuildChangeFeedProcessorWithLatestVersionAsync(
monitoredContainer: monitoredContainer,
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed,
withStartFromBeginning: withStartFromBeginning);

// Read lease documents, remove the Mode, and update the lease documents, so that it mimics a legacy lease document.

await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.RevertLeaseDocumentsToLegacyWithNoMode(
leaseContainer: this.LeaseContainer,
leaseDocumentCount: 2);

ArgumentException exception = await Assert.ThrowsExceptionAsync<ArgumentException>(
() => GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.BuildChangeFeedProcessorWithAllVersionsAndDeletesAsync(
monitoredContainer: monitoredContainer,
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed));

Debug.WriteLine("Assertions completed.");
Assert.AreEqual(expected: "Switching ChangeFeedMode Incremental Feed to Full-Fidelity Feed is not allowed.", actual: exception.Message);
}

/// <summary>
Expand Down Expand Up @@ -211,11 +242,7 @@ await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
allDocsProcessed: allDocsProcessed,
withStartFromBeginning: withStartFromBeginning));

Debug.WriteLine(exception.ToString());

Assert.AreEqual(expected: "Switching ChangeFeedMode Full-Fidelity Feed to Incremental Feed is not allowed.", actual: exception.Message);

Debug.WriteLine("Assertions completed.");
}

/// <summary>
Expand Down Expand Up @@ -243,8 +270,6 @@ await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
monitoredContainer: monitoredContainer,
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed);

Debug.WriteLine("No exceptions occurred.");
}
catch
{
Expand Down Expand Up @@ -281,15 +306,87 @@ await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed,
withStartFromBeginning: withStartFromBeginning);

Debug.WriteLine("No exceptions occurred.");
}
catch
{
Assert.Fail("An exception occurred when one was not expceted."); ;
}
}

/// <summary>
/// This is based on an issue located at <see href="https://github.com/Azure/azure-cosmos-dotnet-v3/issues/4423"/>.
/// </summary>
[TestMethod]
[Owner("philipthomas-MSFT")]
[Description("Scenario: For Legacy lease documents with no Mode property, When ChangeFeedMode on ChangeFeedProcessor " +
"does not switch, LatestVersion, no exception is expected. LatestVersion's WithStartFromBeginning can be set, or not set.")]
[DataRow(false)]
[DataRow(true)]
public async Task WhenLegacyNoSwitchLatestVersionDoesNotExpectAnExceptionTestAsync(bool withStartFromBeginning)
{
ContainerInternal monitoredContainer = await this.CreateMonitoredContainer(ChangeFeedMode.LatestVersion);
ManualResetEvent allDocsProcessed = new(false);

await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.BuildChangeFeedProcessorWithLatestVersionAsync(
monitoredContainer: monitoredContainer,
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed,
withStartFromBeginning: withStartFromBeginning);

// Read lease documents, remove the Mode, and update the lease documents, so that it mimics a legacy lease document.

await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.RevertLeaseDocumentsToLegacyWithNoMode(
leaseContainer: this.LeaseContainer,
leaseDocumentCount: 2);

await GetChangeFeedProcessorBuilderWithAllVersionsAndDeletesTests
.BuildChangeFeedProcessorWithLatestVersionAsync(
monitoredContainer: monitoredContainer,
leaseContainer: this.LeaseContainer,
allDocsProcessed: allDocsProcessed,
withStartFromBeginning: withStartFromBeginning);
}

private static async Task RevertLeaseDocumentsToLegacyWithNoMode(
Container leaseContainer,
int leaseDocumentCount)
{
FeedIterator iterator = leaseContainer.GetItemQueryStreamIterator(
queryText: "SELECT * FROM c",
continuationToken: null);

List<JObject> leases = new List<JObject>();
while (iterator.HasMoreResults)
{
using (ResponseMessage responseMessage = await iterator.ReadNextAsync().ConfigureAwait(false))
{
responseMessage.EnsureSuccessStatusCode();
leases.AddRange(CosmosFeedResponseSerializer.FromFeedResponseStream<JObject>(
serializerCore: CosmosContainerExtensions.DefaultJsonSerializer,
streamWithServiceEnvelope: responseMessage.Content));
}
}

int counter = 0;

foreach (JObject lease in leases)
{
if (!lease.ContainsKey("Mode"))
{
continue;
}

counter++;
lease.Remove("Mode");

_ = await leaseContainer.UpsertItemAsync(item: lease);
}

Assert.AreEqual(expected: leaseDocumentCount, actual: counter);
}

private static async Task BuildChangeFeedProcessorWithLatestVersionAsync(
ContainerInternal monitoredContainer,
Container leaseContainer,
Expand All @@ -307,9 +404,6 @@ private static async Task BuildChangeFeedProcessorWithLatestVersionAsync(
{
exception = error.InnerException;

Debug.WriteLine("WithErrorNotification");
Debug.WriteLine(error.ToString());

return Task.CompletedTask;
});

Expand All @@ -318,7 +412,6 @@ private static async Task BuildChangeFeedProcessorWithLatestVersionAsync(
processorBuilder.WithStartFromBeginning();
}


ChangeFeedProcessor processor = processorBuilder.Build();
Interlocked.Exchange(ref latestVersionProcessorAtomic, processor);

Expand Down Expand Up @@ -349,9 +442,6 @@ private static async Task BuildChangeFeedProcessorWithAllVersionsAndDeletesAsync
{
exception = error.InnerException;

Debug.WriteLine("WithErrorNotification");
Debug.WriteLine(error.ToString());

return Task.FromResult(exception);
});

Expand All @@ -376,8 +466,6 @@ private async Task<ContainerInternal> CreateMonitoredContainer(ChangeFeedMode ch

if (changeFeedMode == ChangeFeedMode.AllVersionsAndDeletes)
{
Debug.WriteLine($"{nameof(properties.ChangeFeedPolicy.FullFidelityRetention)} initialized.");

properties.ChangeFeedPolicy.FullFidelityRetention = TimeSpan.FromMinutes(5);
}

Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ Preview features are treated as a separate branch and will not be included in th
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### <a name="3.40.0-preview.1"/> [3.40.0-preview.1](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.40.0-preview.1) - 2024-04-17
### <a name="3.39.1"/> [3.39.1](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.39.1) - 2024-04-17

#### Fixed
- [4426](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/4426) ChangeFeedProcessor: Fixes ArgumentException when dealing with Legacy lease incremental documents that do not have a Mode property

### <a name="3.40.0-preview.0"/> [3.40.0-preview.0](https://www.nuget.org/packages/Microsoft.Azure.Cosmos/3.40.0-preview.0) - 2024-04-05

#### Fixed
Expand Down
Loading