Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased
- Change the default large payload externalization threshold (`LargePayloadStorageOptions.ThresholdBytes`) from 900,000 bytes to 256 KiB (262,144 bytes)
- **BREAKING**: `EntityInstanceId` now throws if its string form exceeds 100 characters (backend limit). Migration: shorten entity name/key; if entities already exist with overlong IDs, use the truncated 100-character value when addressing them.


## v1.25.0-preview.2
Expand Down
8 changes: 8 additions & 0 deletions src/Abstractions/Entities/EntityInstanceId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace Microsoft.DurableTask.Entities;
[JsonConverter(typeof(EntityInstanceId.JsonConverter))]
public readonly record struct EntityInstanceId
{
const int MaxInstanceIdLength = 100;

/// <summary>
/// Initializes a new instance of the <see cref="EntityInstanceId"/> struct.
/// </summary>
Expand All @@ -28,6 +30,12 @@ public EntityInstanceId(string name, string key)
Check.NotNull(key);
this.Name = name.ToLowerInvariant();
this.Key = key;

int length = this.ToString().Length;
if (length > MaxInstanceIdLength)
{
throw new ArgumentException($"entity instance ids may not exceed 100 characters in length, actual length {length}.");
}
}

/// <summary>
Expand Down
64 changes: 64 additions & 0 deletions test/Abstractions.Tests/Entities/EntityInstanceIdTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.DurableTask.Entities;

namespace Microsoft.DurableTask.Abstractions.Tests.Entities;

public class EntityInstanceIdTests
{
[Fact]
public void TestValidEntityInstanceId()
{
var entityId = new EntityInstanceId("entity", "key1");
Assert.Equal("@entity@key1", entityId.ToString());
}

[Fact]
public void TestEntityNameLowercased()
{
var entityId = new EntityInstanceId("Entity", "key1");
Assert.Equal("entity", entityId.Name);
Assert.Equal("@entity@key1", entityId.ToString());
}

[Fact]
public void TestEntityNameWithAtSymbolThrows()
{
Assert.Throws<ArgumentException>(() => new EntityInstanceId("entity@name", "key1"));
}

[Fact]
public void TestEntityInstanceIdExceedsMaxLengthThrows()
{
string longName = new string('a', 50);
string longKey = new string('b', 51);
Assert.Throws<ArgumentException>(() => new EntityInstanceId(longName, longKey));
}

[Fact]
public void TestEntityInstanceIdEqualsMaxLength()
{
string longName = new string('a', 49);
string longKey = new string('b', 49);
var entityId = new EntityInstanceId(longName, longKey);
Assert.Equal($"@{longName}@{longKey}", entityId.ToString());
}

[Fact]
public void TestFromStringValid()
{
var entityId = EntityInstanceId.FromString("@entity@key1");
Assert.Equal("entity", entityId.Name);
Assert.Equal("key1", entityId.Key);
}

[Fact]
public void TestFromStringInvalidThrows()
{
Assert.Throws<ArgumentException>(() => EntityInstanceId.FromString("invalid"));
Assert.Throws<ArgumentException>(() => EntityInstanceId.FromString("@entitykey1"));
Assert.Throws<ArgumentException>(() => EntityInstanceId.FromString("@@key1"));
Assert.Throws<ArgumentException>(() => EntityInstanceId.FromString($"@entity@{new string('a', 100)}"));
}
}
Loading