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

[Client encryption]: Implement EncryptionContainerStream #4848

Draft
wants to merge 114 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
d6f89ea
Add baseline benchmarks for `Microsoft.Azure.Cosmos.Encryption.Custom`
juraj-blazek Sep 12, 2024
8928b88
Cleanup
juraj-blazek Sep 12, 2024
9dc7d54
Use set of static test data for benchmarks
juraj-blazek Sep 12, 2024
368dc25
Merge branch 'master' into users/juraj-blazek/encryption-benchmark-ba…
juraj-blazek Sep 12, 2024
38a198a
Add non-allocating APIs to encryptors
juraj-blazek Sep 16, 2024
e0bb8bf
WIP
juraj-blazek Sep 16, 2024
9c3c276
Revert solution update
juraj-blazek Sep 16, 2024
c37a092
Merge branch 'users/juraj-blazek/encryption-benchmark-baseline' of ht…
juraj-blazek Sep 16, 2024
f4db1c6
Merge branch 'master' into users/juraj-blazek/encryption-benchmark-ba…
juraj-blazek Sep 16, 2024
91714f9
Merge branch 'master' into users/juraj-blazek/encryption-benchmark-ba…
juraj-blazek Sep 17, 2024
2058f8b
Merge remote-tracking branch 'origin/master' into users/juraj-blazek/…
juraj-blazek Sep 17, 2024
f33538c
Add implementation, fix tests
juraj-blazek Sep 17, 2024
6923fd2
Switch to randomized encryption for benchmarks
juraj-blazek Sep 17, 2024
4ea8690
Merge branch 'master' into users/juraj-blazek/encryption-benchmark-ba…
kr-santosh Sep 18, 2024
03ef682
Some more array pooling
juraj-blazek Sep 17, 2024
1044a89
Streaming deserialization
juraj-blazek Sep 19, 2024
f1db54d
Merge remote-tracking branch 'origin/master' into users/juraj-blazek/…
juraj-blazek Sep 19, 2024
05bfc50
Cleanup
juraj-blazek Sep 20, 2024
5629f74
Update MDE and rerun benchmarks
juraj-blazek Sep 20, 2024
495d2c4
Add non-allocating APIs to encryptors
juraj-blazek Sep 16, 2024
b3f74b1
Merge branch 'master' into users/juraj-blazek/non-allocating-encryptor
Sep 30, 2024
14bce37
~ drop repeated DEK calls
Sep 30, 2024
4ff1601
! typo
Sep 30, 2024
d8a345c
~ update benchmark
Sep 30, 2024
03c06e0
~ fix tests
Sep 30, 2024
a1025c4
Merge branch 'Azure:master' into users/juraj-blazek/non-allocating-en…
JanHyka Oct 1, 2024
3bf77c8
~ cleanup
Oct 1, 2024
ceaa8b5
+ refresh benchmark
Oct 1, 2024
611b3ac
+ unit test
Oct 1, 2024
9ca89d4
~ merge predecessor PR
Oct 1, 2024
8a78fe8
~ merge fixes and initial cleanup
Oct 1, 2024
8ed2135
~ write directly to output document instead of copying
Oct 1, 2024
bbe9845
! tests
Oct 1, 2024
a107f62
~ retrieve DataEncryptionKey only once per document
Oct 1, 2024
a1ad02b
! fix tests
Oct 1, 2024
4f2f072
~ update Aes algorithm to reuse GetEncryptedByteCount
Oct 2, 2024
cbbeee2
~ refactor EncryptionProcessor
Oct 4, 2024
b6c851c
! names
Oct 4, 2024
72ccae7
~ less static
Oct 4, 2024
8ea5879
Merge branch 'master' into users/juraj-blazek/encryption-array-pooling
Oct 6, 2024
8c60e69
Merge branch 'master' into users/juraj-blazek/encryption-array-pooling
Oct 6, 2024
5554aa0
~ merge fixes
Oct 6, 2024
28620ed
~ cleanup
Oct 6, 2024
eb059c8
~ unwanted changes
Oct 6, 2024
cc2eab5
- unused method
Oct 6, 2024
c9ba300
~ updates (PR)
Oct 6, 2024
9f9cbca
~ add stable vs preview release duplicity
Oct 7, 2024
c347e71
Merge branch 'users/juraj-blazek/encryption-array-pooling' into users…
Oct 7, 2024
64172b8
~ cleanup and parent branch merge
Oct 7, 2024
ff583f9
Merge branch 'master' into users/jan-hyka/refactor-encryption-processor
Oct 7, 2024
0ba8c34
Merge branch 'master' into users/jan-hyka/refactor-encryption-processor
Oct 7, 2024
326b1be
~ master merges
Oct 7, 2024
c520e16
- duplicate
Oct 7, 2024
5c40821
~ cleanup
Oct 7, 2024
99c7a75
+ Add .NET8.0 target for Cosmos.Encryption.Custom
Oct 8, 2024
31c20e7
- remove implicit IsPreview from csproj
Oct 8, 2024
90b2cec
+ JsonNodeSqlSerializer
Oct 9, 2024
6f27d9d
+ initial commit
Oct 9, 2024
d7c06d6
! EncryptioProperties System.Text.Json annotations
Oct 9, 2024
cb9d166
+ bump benchmark
Oct 9, 2024
5fc5165
~ wip
Oct 9, 2024
c9e7f30
+ initial for JsonNode decryption
Oct 9, 2024
9215f67
~ Merge branch 'master' into users/jan-hyka/jsonnode_serializer
Oct 10, 2024
fed6a3a
~ polishing and benchmark refresh
Oct 10, 2024
38cc928
- remove explicit System.Text.Json 8.0.5
Oct 10, 2024
ba4f73b
Merge branch 'users/jan-hyka/jsonnode_serializer' into users/jan-hyka…
Oct 10, 2024
424028c
Merge branch 'master' into users/jan-hyka/jsonnode_encryptionProcessor
Oct 10, 2024
2af9ddb
~ propagate changes from master
Oct 10, 2024
30c18d0
Merge branch 'users/jan-hyka/jsonnode_encryptionProcessor' into users…
Oct 10, 2024
54b0ad9
~ fixes for preview x non-preview branching
Oct 10, 2024
69c8978
Merge branch 'master' into users/jan-hyka/jsonnode_encryptionProcessor
JanHyka Oct 11, 2024
ad15ceb
+ tests
Oct 11, 2024
a0ccd44
Merge branch 'master' into users/jan-hyka/jsonnode_encryptionProcessor
Oct 13, 2024
d9c315d
~ complete merge from master & update benchmark
Oct 13, 2024
b11db28
Merge branch 'users/jan-hyka/jsonnode_encryptionProcessor' into users…
Oct 13, 2024
996252b
+ initial
Oct 14, 2024
758e98d
+ tests, fixes and benchmark
Oct 14, 2024
420a35d
! bugfix
Oct 14, 2024
d08be05
~ benchmark update
Oct 14, 2024
0bf29b8
+ cleanup
Oct 15, 2024
2b2209f
+ stream serializer
Oct 15, 2024
f03c92d
Merge branch 'master' into users/jan-hyka/stream_deserializer
Oct 15, 2024
42462d5
~ preview branching fixes
Oct 15, 2024
703830f
+ add support for Stream deserialization of obsoleted encryption algo…
Oct 15, 2024
4319524
~ final touches
Oct 16, 2024
940d667
Merge branch 'master' into users/jan-hyka/stream_deserializer
Oct 17, 2024
da92d22
+ initial draft for new DecryptableItem
Oct 17, 2024
71c674f
+ unsaved comments
Oct 17, 2024
4bf4a6b
+ new DecryptableItem
Oct 17, 2024
03a4e9b
+EncryptableItemStream
Oct 17, 2024
0ed76e6
+ update EncryptionContainer to work with new EncryptionProcessor
Oct 18, 2024
b55a857
~ cleanup
Oct 18, 2024
46b3ca4
+ EncryptionFeedIterator
Oct 18, 2024
5ec68ba
~ update EncryptionTransactionalBatch
Oct 18, 2024
fa0020c
~ PR based changes
Oct 18, 2024
8e45769
Merge branch 'master' into users/jan-hyka/stream_deserializer
kirankumarkolli Oct 18, 2024
1428118
+ wip
Oct 21, 2024
a7a66b1
~ cleanup
Oct 21, 2024
eb1ec76
+ tests for EncryptionContainerStream
Oct 21, 2024
c98f2bf
- drop JsonNode serializer/deserializer
Oct 21, 2024
3be6843
+ rms
Oct 21, 2024
de555a8
- drop rentArrayBufferWriter
Oct 21, 2024
6c8a918
+ update Azure.Cosmos references to 3.43.1 (stable), 3.44.0-preview.1…
Oct 23, 2024
b362826
! Utf8JsonReader/Writer correctly working with escaped strings
Oct 24, 2024
428f2e1
Merge branch 'master' into users/jan-hyka/drop_jsonnode
Oct 24, 2024
8ce3622
~ fix the mess after merge
Oct 24, 2024
10ad1d4
~ fix merge mess
Oct 24, 2024
81394b2
- drop JsonNode based benchmarks
Oct 24, 2024
a439cf2
Merge branch 'users/jan-hyka/drop_jsonnode' into users/jan-hyka/drop_…
Oct 24, 2024
b4da46c
- drop files we don't need yet
Oct 24, 2024
9ce8ccd
Merge branch 'users/jan-hyka/drop_rentarraybufferwriter' into users/j…
Oct 24, 2024
147ecc8
~ bugfixes
Oct 24, 2024
86e33ec
~ more fixes
Oct 24, 2024
ffe19d1
Merge from master
juraj-blazek Oct 31, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Microsoft.Azure.Cosmos.Encryption.Custom
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;

/// <summary>
Expand Down Expand Up @@ -40,6 +42,18 @@ internal CosmosJsonDotNetSerializer(JsonSerializerSettings jsonSerializerSetting
/// <returns>The object representing the deserialized stream</returns>
public T FromStream<T>(Stream stream)
{
return this.FromStream<T>(stream, false);
}

/// <summary>
/// Convert a Stream to the passed in type.
/// </summary>
/// <typeparam name="T">The type of object that should be deserialized</typeparam>
/// <param name="stream">An open stream that is readable that contains JSON</param>
/// <param name="leaveOpen">True if input stream shouldn't be disposed</param>
/// <returns>The object representing the deserialized stream</returns>
public T FromStream<T>(Stream stream, bool leaveOpen)
{
#if NET8_0_OR_GREATER
ArgumentNullException.ThrowIfNull(stream);
#else
Expand All @@ -54,7 +68,7 @@ public T FromStream<T>(Stream stream)
return (T)(object)stream;
}

using (StreamReader sr = new (stream))
using (StreamReader sr = new (stream, Encoding.UTF8, true, 1024, leaveOpen))
using (JsonTextReader jsonTextReader = new (sr))
{
jsonTextReader.ArrayPool = JsonArrayPool.Instance;
Expand All @@ -72,19 +86,30 @@ public T FromStream<T>(Stream stream)
public MemoryStream ToStream<T>(T input)
{
MemoryStream streamPayload = new ();
using (StreamWriter streamWriter = new (streamPayload, encoding: CosmosJsonDotNetSerializer.DefaultEncoding, bufferSize: 1024, leaveOpen: true))
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
this.ToStreamAsync(input, streamPayload, CancellationToken.None).GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
return streamPayload;
}

public async Task ToStreamAsync<T>(T input, Stream output, CancellationToken cancellationToken)
{
using (StreamWriter streamWriter = new (output, encoding: CosmosJsonDotNetSerializer.DefaultEncoding, bufferSize: 1024, leaveOpen: true))
using (JsonTextWriter writer = new (streamWriter))
{
writer.ArrayPool = JsonArrayPool.Instance;
writer.Formatting = Newtonsoft.Json.Formatting.None;
JsonSerializer jsonSerializer = this.GetSerializer();
jsonSerializer.Serialize(writer, input);
writer.Flush();
streamWriter.Flush();
#if NET8_0_OR_GREATER
await streamWriter.FlushAsync(cancellationToken);
#else
await streamWriter.FlushAsync();
#endif
}

streamPayload.Position = 0;
return streamPayload;
output.Position = 0;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.Azure.Cosmos.Encryption.Custom
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Newtonsoft.Json;

/// <summary>
Expand Down Expand Up @@ -73,31 +74,36 @@ internal DataEncryptionKeyProperties(DataEncryptionKeyProperties source)
/// </para>
/// </remarks>
[JsonProperty(PropertyName = "id")]
[JsonPropertyName("id")]
public string Id { get; internal set; }

/// <summary>
/// Gets the Encryption algorithm that will be used along with this data encryption key to encrypt/decrypt data.
/// </summary>
[JsonProperty(PropertyName = "encryptionAlgorithm", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("encryptionAlgorithm")]
public string EncryptionAlgorithm { get; internal set; }

/// <summary>
/// Gets wrapped form of the data encryption key.
/// </summary>
[JsonProperty(PropertyName = "wrappedDataEncryptionKey", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("wrappedDataEncryptionKey")]
public byte[] WrappedDataEncryptionKey { get; internal set; }

/// <summary>
/// Gets metadata for the wrapping provider that can be used to unwrap the wrapped data encryption key.
/// </summary>
[JsonProperty(PropertyName = "keyWrapMetadata", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("keyWrapMetadata")]
public EncryptionKeyWrapMetadata EncryptionKeyWrapMetadata { get; internal set; }

/// <summary>
/// Gets the creation time of the resource from the Azure Cosmos DB service.
/// </summary>
[JsonConverter(typeof(UnixDateTimeConverter))]
[Newtonsoft.Json.JsonConverter(typeof(UnixDateTimeConverter))]
[JsonProperty(PropertyName = "createTime", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("createTime")]
public DateTime? CreatedTime { get; internal set; }

/// <summary>
Expand All @@ -110,14 +116,16 @@ internal DataEncryptionKeyProperties(DataEncryptionKeyProperties source)
/// ETags are used for concurrency checking when updating resources.
/// </remarks>
[JsonProperty(PropertyName = "_etag", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_etag")]
public string ETag { get; internal set; }

/// <summary>
/// Gets the last modified time stamp associated with the resource from the Azure Cosmos DB service.
/// </summary>
/// <value>The last modified time stamp associated with the resource.</value>
[JsonConverter(typeof(UnixDateTimeConverter))]
[Newtonsoft.Json.JsonConverter(typeof(UnixDateTimeConverter))]
[JsonProperty(PropertyName = "_ts", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_ts")]
public DateTime? LastModified { get; internal set; }

/// <summary>
Expand All @@ -129,6 +137,7 @@ internal DataEncryptionKeyProperties(DataEncryptionKeyProperties source)
/// E.g. a self-link for a document could be dbs/db_resourceid/colls/coll_resourceid/documents/doc_resourceid
/// </remarks>
[JsonProperty(PropertyName = "_self", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_self")]
public virtual string SelfLink { get; internal set; }

/// <summary>
Expand All @@ -143,6 +152,7 @@ internal DataEncryptionKeyProperties(DataEncryptionKeyProperties source)
/// These resource ids are used when building up SelfLinks, a static addressable Uri for each resource within a database account.
/// </remarks>
[JsonProperty(PropertyName = "_rid", NullValueHandling = NullValueHandling.Ignore)]
[JsonPropertyName("_rid")]
internal string ResourceId { get; set; }

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Microsoft.Azure.Cosmos.Encryption.Custom
{
using System;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
Expand Down Expand Up @@ -71,13 +73,26 @@ namespace Microsoft.Azure.Cosmos.Encryption.Custom
/// ]]>
/// </code>
/// </example>
public abstract class DecryptableItem
public abstract class DecryptableItem : IDisposable
{
/// <summary>
/// Decrypts and deserializes the content.
/// </summary>
/// <typeparam name="T">The type of item to be returned.</typeparam>
/// <returns>The requested item and the decryption related context.</returns>
public abstract Task<(T, DecryptionContext)> GetItemAsync<T>();

/// <summary>
/// Decrypts and deserializes the content.
/// </summary>
/// <param name="cancellationToken">Cancellation token.</param>
/// <typeparam name="T">The type of item to be returned.</typeparam>
/// <returns>The requested item and the decryption related context.</returns>
public abstract Task<(T, DecryptionContext)> GetItemAsync<T>(CancellationToken cancellationToken);

/// <summary>
/// Dispose unmanaged resources.
/// </summary>
public abstract void Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Microsoft.Azure.Cosmos.Encryption.Custom
{
using System;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

Expand All @@ -27,7 +28,16 @@ public DecryptableItemCore(
this.cosmosSerializer = cosmosSerializer ?? throw new ArgumentNullException(nameof(cosmosSerializer));
}

public override async Task<(T, DecryptionContext)> GetItemAsync<T>()
public override void Dispose()
{
}

public override Task<(T, DecryptionContext)> GetItemAsync<T>()
{
return this.GetItemAsync<T>(CancellationToken.None);
}

public override async Task<(T, DecryptionContext)> GetItemAsync<T>(CancellationToken cancellationToken)
{
if (this.decryptableContent is not JObject document)
{
Expand All @@ -40,7 +50,7 @@ public DecryptableItemCore(
document,
this.encryptor,
new CosmosDiagnosticsContext(),
cancellationToken: default);
cancellationToken: cancellationToken);

return (this.cosmosSerializer.FromStream<T>(EncryptionProcessor.BaseSerializer.ToStream(decryptedItem)), decryptionContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

namespace Microsoft.Azure.Cosmos.Encryption.Custom
{
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos.Encryption.Custom.Transformation;
using Newtonsoft.Json.Linq;

/// <summary>
/// Input type should implement this abstract class for lazy decryption and to retrieve the details in the write path.
/// </summary>
public abstract class EncryptableItem
public abstract class EncryptableItem : IDisposable
{
/// <summary>
/// Gets DecryptableItem
Expand All @@ -24,6 +28,15 @@ public abstract class EncryptableItem
/// <returns>Input payload in stream format</returns>
protected internal abstract Stream ToStream(CosmosSerializer serializer);

/// <summary>
/// Gets the input payload in stream format.
/// </summary>
/// <param name="serializer">Cosmos Serializer</param>
/// <param name="outputStream">Output stream</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
protected internal abstract Task ToStreamAsync(CosmosSerializer serializer, Stream outputStream, CancellationToken cancellationToken);

/// <summary>
/// Populates the DecryptableItem that can be used getting the decryption result.
/// </summary>
Expand All @@ -34,5 +47,27 @@ protected internal abstract void SetDecryptableItem(
JToken decryptableContent,
Encryptor encryptor,
CosmosSerializer cosmosSerializer);

#if ENCRYPTION_CUSTOM_PREVIEW && NET8_0_OR_GREATER
/// <summary>
/// Populates the DecryptableItem that can be used getting the decryption result.
/// </summary>
/// <param name="decryptableStream">The encrypted content stream which is yet to be decrypted.</param>
/// <param name="encryptor">Encryptor instance which will be used for decryption.</param>
/// <param name="jsonProcessor">Json processor for decryption.</param>
/// <param name="cosmosSerializer">Serializer instance which will be used for deserializing the content after decryption.</param>
/// <param name="streamManager">Stream manager providing output streams.</param>
protected internal abstract void SetDecryptableStream(
Stream decryptableStream,
Encryptor encryptor,
JsonProcessor jsonProcessor,
CosmosSerializer cosmosSerializer,
StreamManager streamManager);
#endif

/// <summary>
/// Release unmananaged resources
/// </summary>
public abstract void Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace Microsoft.Azure.Cosmos.Encryption.Custom
{
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

/// <summary>
Expand Down Expand Up @@ -69,16 +71,45 @@ protected internal override void SetDecryptableItem(
cosmosSerializer);
}

private void Dispose(bool disposing)
{
if (disposing)
{
this.StreamPayload?.Dispose();
this.DecryptableItem?.Dispose();
}
}

/// <inheritdoc/>
public void Dispose()
public override void Dispose()
{
this.StreamPayload.Dispose();
this.Dispose(true);
}

/// <inheritdoc/>
protected internal override Stream ToStream(CosmosSerializer serializer)
{
return this.StreamPayload;
}

/// <inheritdoc/>
/// <remarks>This solution is not performant with Newtonsoft.Json.</remarks>
protected internal override async Task ToStreamAsync(CosmosSerializer serializer, Stream outputStream, CancellationToken cancellationToken)
{
#if NET8_0_OR_GREATER
await this.StreamPayload.CopyToAsync(outputStream, cancellationToken);
#else
await this.StreamPayload.CopyToAsync(outputStream, 81920, cancellationToken);
#endif
}

#if NET8_0_OR_GREATER
/// <inheritdoc/>
/// <remarks>Direct stream based item is not supported with Newtonsoft.Json.</remarks>
protected internal override void SetDecryptableStream(Stream decryptableStream, Encryptor encryptor, JsonProcessor jsonProcessor, CosmosSerializer cosmosSerializer, StreamManager streamManager)
{
throw new NotImplementedException("Stream based item is only allowed for EncryptionContainerStream");
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace Microsoft.Azure.Cosmos.Encryption.Custom
{
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

/// <summary>
Expand Down Expand Up @@ -85,5 +87,32 @@ protected internal override Stream ToStream(CosmosSerializer serializer)
{
return serializer.ToStream(this.Item);
}

/// <inheritdoc/>
/// <remarks>This solution is not performant with Newtonsoft.Json.</remarks>
protected internal override async Task ToStreamAsync(CosmosSerializer serializer, Stream outputStream, CancellationToken cancellationToken)
{
Stream temp = serializer.ToStream(this.Item);
#if NET8_0_OR_GREATER
await temp.CopyToAsync(outputStream, cancellationToken);
#else
await temp.CopyToAsync(outputStream, 81920, cancellationToken);
#endif
}

#if NET8_0_OR_GREATER
/// <inheritdoc/>
/// <remarks>Direct stream based item is not supported with Newtonsoft.Json.</remarks>
protected internal override void SetDecryptableStream(Stream decryptableStream, Encryptor encryptor, JsonProcessor jsonProcessor, CosmosSerializer cosmosSerializer, StreamManager streamManager)
{
throw new NotImplementedException("Stream based item is only allowed for EncryptionContainerStream");
}
#endif

/// <inheritdoc/>
/// <remarks>Does nothing with Newtonsoft based EncryptableItem.</remarks>
public override void Dispose()
{
}
}
}
Loading