Skip to content

[V4] Support Native AOT trimming for DynamoDB DataModel #3606

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

Merged
merged 5 commits into from
Jan 16, 2025
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
18 changes: 18 additions & 0 deletions generator/.DevConfigs/7FE49E8F-93BF-419E-B3B2-265D9D6F35E3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"core": {
"changeLogMessages": [
"Backport the .NET trimming attributes like DynamicallyAccessedMembersAttribute into ThirdParty.RuntimeBackports namespace for Target Frameworks before .NET 8. This simplifies the SDK's codebase by removing compilation conditional checks when using the attributes."
],
"type": "patch",
"updateMinimum": true
},
"services": [
{
"serviceName": "DynamoDBv2",
"type": "patch",
"changeLogMessages": [
"Add NativeAOT support for the DataModel namespace also known as the Object Persistence high level library."
]
}
]
}
6 changes: 3 additions & 3 deletions sdk/src/Core/Amazon.Runtime/ClientContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,18 @@
using Amazon.Util.Internal;
using Amazon.Util.Internal.PlatformServices;
using Amazon.Runtime;
using System.Diagnostics.CodeAnalysis;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime.Internal
{
/// <summary>
/// This class composes Client Context header for Amazon Web Service client.
/// It contains information like app title, version code, version name, client id, OS platform etc.
/// </summary>
#if NET8_0_OR_GREATER
// This class wasn't updated to use source generators because the object to JSON method uses the non generic IDictionary. Usage of this class is probably very low since it is not used directly
// by the SDK and it is in an internal namespace.
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("ClientContext has not been updated to support producing JSON using source generators. For requests that need client context JSON the JSON must be created manually.")]
#endif
[RequiresUnreferencedCode("ClientContext has not been updated to support producing JSON using source generators. For requests that need client context JSON the JSON must be created manually.")]
public partial class ClientContext
{
//client related keys
Expand Down
11 changes: 1 addition & 10 deletions sdk/src/Core/Amazon.Runtime/ConstantClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@
using System.Text;

using Amazon.Util.Internal;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime
{
/// <summary>
/// Base class for constant class that holds the value that will be sent to AWS for the static constants.
/// </summary>
#if NET8_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
#endif
public class ConstantClass
{
static readonly object staticFieldsLock = new object();
Expand Down Expand Up @@ -91,11 +90,7 @@ internal ConstantClass Intern()
return map.TryGetValue(this.Value, out foundValue) ? foundValue : this;
}

#if NET8_0_OR_GREATER
protected static T FindValue<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicConstructors)] T>(string value) where T : ConstantClass
#else
protected static T FindValue<T>(string value) where T : ConstantClass
#endif
{
if (value == null)
return null;
Expand All @@ -115,11 +110,7 @@ protected static T FindValue<T>(string value) where T : ConstantClass
return foundValue as T;
}

#if NET8_0_OR_GREATER
private static void LoadFields([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] Type type)
#else
private static void LoadFields(Type type)
#endif
{
if (staticFields.ContainsKey(type))
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
using System;
using System.Globalization;
using System.Net;
using System.Diagnostics.CodeAnalysis;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime
{
Expand Down Expand Up @@ -89,10 +91,8 @@ public AssumeRoleAWSCredentials(AWSCredentials sourceCredentials, string roleArn
PreemptExpiryTime = TimeSpan.FromMinutes(15);
}

#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
Justification = "Reflection code is only used as a fallback in case the SDK was not trimmed. Trimmed scenarios should register dependencies with Amazon.RuntimeDependencyRegistry.GlobalRuntimeDependencyRegistry")]
#endif
protected override CredentialsRefreshState GenerateNewCredentials()
{
var region = FallbackRegionFactory.GetRegionEndpoint() ?? DefaultSTSClientRegion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
using Amazon.RuntimeDependencies;
using Amazon.Util;
using Amazon.Util.Internal;
using ThirdParty.RuntimeBackports;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Net;
Expand Down Expand Up @@ -222,10 +224,8 @@ protected override async Task<CredentialsRefreshState> GenerateNewCredentialsAsy
/// Gets a client to be used for AssumeRoleWithWebIdentity requests.
/// </summary>
/// <returns>The STS client.</returns>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
Justification = "Reflection code is only used as a fallback in case the SDK was not trimmed. Trimmed scenarios should register dependencies with Amazon.RuntimeDependencyRegistry.GlobalRuntimeDependencyRegistry")]
#endif
protected virtual ICoreAmazonSTS_WebIdentity CreateClient()
{
var region = FallbackRegionFactory.GetRegionEndpoint() ?? _defaultSTSClientRegion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
using Amazon.Util;
using Amazon.RuntimeDependencies;
using Amazon.Util.Internal;
using ThirdParty.RuntimeBackports;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
Expand Down Expand Up @@ -177,10 +179,8 @@ protected override CredentialsRefreshState GenerateNewCredentials()
return newState;
}

#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
Justification = "Reflection code is only used as a fallback in case the SDK was not trimmed. Trimmed scenarios should register dependencies with Amazon.RuntimeDependencyRegistry.GlobalRuntimeDependencyRegistry")]
#endif
private CredentialsRefreshState Authenticate(ICredentials userCredential)
{
CredentialsRefreshState state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using ThirdParty.Json.LitJson;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime
{
Expand Down Expand Up @@ -50,27 +52,21 @@ protected static string GetContents(Uri uri, IWebProxy proxy, Dictionary<string,
}

[Obsolete("This method is not compatible with Native AOT builds. The GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#endif
[RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
protected static T GetObjectFromResponse<T>(Uri uri)
{
return GetObjectFromResponse<T>(uri, null, null);
}

[Obsolete("This method is not compatible with Native AOT builds. The GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#endif
[RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
protected static T GetObjectFromResponse<T>(Uri uri, IWebProxy proxy)
{
return GetObjectFromResponse<T>(uri, proxy, null);
}

[Obsolete("This method is not compatible with Native AOT builds. The GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
#endif
[RequiresUnreferencedCode("GetObjectFromResponse overload using the generic parameter taking in a JsonSerializerContext should be used instead.")]
protected static T GetObjectFromResponse<T>(Uri uri, IWebProxy proxy, Dictionary<string, string> headers)
{
string json = GetContents(uri, proxy, headers);
Expand Down
14 changes: 5 additions & 9 deletions sdk/src/Core/Amazon.Runtime/Documents/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using ThirdParty.Json.LitJson;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime.Documents
{
Expand Down Expand Up @@ -410,19 +412,15 @@ public override string ToString()
/// for performance critical work. Additionally, if <paramref name="o"/> is a known primitive (ie <see cref="int"/>),
/// using a <see cref="Document"/> constructor directly will be more performant.
/// </summary>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
#endif
[RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
public static Document FromObject(object o)
{
IJsonWrapper jsonData = JsonMapper.ToObject(JsonMapper.ToJson(o));

return FromObject(jsonData);
}

#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
#endif
[RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
private static Document FromObject(IJsonWrapper jsonData)
{
switch (jsonData.GetJsonType())
Expand Down Expand Up @@ -450,9 +448,7 @@ private static Document FromObject(IJsonWrapper jsonData)
throw new NotSupportedException($"Couldn't convert {jsonData.GetJsonType()}");
}

#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
#endif
[RequiresUnreferencedCode("FromObject is not currently supported for Native AOT compilation due unbounded reflection required.")]
private static void Copy(IDictionary source, Dictionary<string, Document> target)
{
foreach (var key in source.Keys)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
using System.Threading.Tasks;
#endif

using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime.EventStreams.Internal
{
/// <summary>
Expand All @@ -49,11 +51,7 @@ namespace Amazon.Runtime.EventStreams.Internal
/// <typeparam name="TE">An implementation of EventStreamException (e.g. S3EventStreamException).</typeparam>
[SuppressMessage("Microsoft.Naming", "CA1710", Justification = "EventStreamCollection is not descriptive.")]
[SuppressMessage("Microsoft.Design", "CA1063", Justification = "IDisposable is a transient interface from IEventStream. Users need to be able to call Dispose.")]
#if NET8_0_OR_GREATER
public abstract class EnumerableEventStream<T, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TE> : EventStream<T, TE>, IEnumerableEventStream<T, TE>, IAsyncEnumerable<T> where T : IEventStreamEvent where TE : EventStreamException, new()
#else
public abstract class EnumerableEventStream<T, TE> : EventStream<T, TE>, IEnumerableEventStream<T, TE>, IAsyncEnumerable<T> where T : IEventStreamEvent where TE : EventStreamException, new()
#endif
{
private const string MutuallyExclusiveExceptionMessage = "Stream has already begun processing. Event-driven and Enumerable traversals of the stream are mutually exclusive. " +
"You can either use the event driven or enumerable interface, but not both.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading;
using ThirdParty.RuntimeBackports;

#if AWS_ASYNC_API
using System.Threading.Tasks;
Expand Down Expand Up @@ -67,11 +68,7 @@ namespace Amazon.Runtime.EventStreams.Internal
/// </summary>
/// <typeparam name="T">An implementation of IEventStreamEvent (e.g. IS3Event).</typeparam>
/// <typeparam name="TE">An implementation of EventStreamException (e.g. S3EventStreamException).</typeparam>
#if NET8_0_OR_GREATER
public abstract class EventStream<T, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TE> : IEventStream<T, TE> where T : IEventStreamEvent where TE : EventStreamException, new()
#else
public abstract class EventStream<T, TE> : IEventStream<T, TE> where T : IEventStreamEvent where TE : EventStreamException, new()
#endif
{
/// <summary>
/// "Unique" key for unknown event lookup.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
using Amazon.Util.Internal;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using ThirdParty.RuntimeBackports;

namespace Amazon.Runtime.Internal.Auth
{
Expand All @@ -46,12 +48,10 @@ public AWS4aSignerCRTWrapper() : this(true)
/// Instantiates an SigV4a signer using CRT's SigV4a implementation
/// </summary>
/// <param name="signPayload">Whether to sign the request's payload</param>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
Justification = "Reflection code is only used as a fallback in case the SDK was not trimmed. Trimmed scenarios should register dependencies with Amazon.RuntimeDependencyRegistry.GlobalRuntimeDependencyRegistry")]
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075",
Justification = "Reflection code is only used as a fallback in case the SDK was not trimmed. Trimmed scenarios should register dependencies with Amazon.RuntimeDependencyRegistry.GlobalRuntimeDependencyRegistry")]
#endif
public AWS4aSignerCRTWrapper(bool signPayload)
{
if (_awsSigV4AProvider == null)
Expand Down
Loading
Loading