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

Fix: Rabbitmq7 header injection overwrites user supplied basic properties #6730

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

johang88
Copy link

Note: Created as draft as I have not actually run or tested the changes 😶

Summary of changes

Fixes the header injection so that basic properties are preserved from the supplied argument list in case PopulateBasicPropertiesHeaders returns null which happens if the basic properties argument is writable or if no changes had to be made to it.

Reason for change

Fixes a bug that would remove all user supplied basic properties.

Implementation details

Stores the basicproperties argument in the active scope and retrieves it a null return value is encountered. Changed CachedBasicPropertiesHelper to call the copy constructor that takes a IReadOnlyBasicProperties as argument.

Test coverage

Added basic properties to one of the rabbitmq7 test methods as well as assertions.

Other details

Fixes #6723

@johang88 johang88 requested review from a team as code owners February 28, 2025 13:15
@lucaspimentel
Copy link
Member

@johang88: Thanks for this! We'll take a look, run all tests, and merge it if all goes well.

Copy link
Contributor

@bouwkast bouwkast left a comment

Choose a reason for hiding this comment

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

Hey thanks a lot @johang88

I ran the CI against this and am seeing test failures for 7.1.0 related to the new Activator code

Comment on lines 22 to 38
var targetType = typeof(TBasicProperties).Assembly.GetType("RabbitMQ.Client.BasicProperties")!;
var parameterType = typeof(TBasicProperties).Assembly.GetType("RabbitMQ.Client.IReadOnlyBasicProperties")!;

var constructor = targetType.GetConstructor([parameterType])!;

var createBasicPropertiesMethod = new DynamicMethod(
$"TypeActivator_{targetType.Name}_{parameterType.Name}",
targetType,
[parameterType],
typeof(DuckType).Module,
true);

var il = createBasicPropertiesMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, constructor);
il.Emit(OpCodes.Ret);
Activator = (Func<object, object>)createBasicPropertiesMethod.CreateDelegate(typeof(Func<object, object>), targetType);
Copy link
Contributor

Choose a reason for hiding this comment

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

Unfortunately it looks like this is throwing an exception when attempting to run the tests / sample

[ERR] Exception occurred when calling the CallTarget integration continuation. System.TypeInitializationException: The type initializer for 'Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.CachedBasicPropertiesHelper`1' threw an exception.
 ---> System.ArgumentException: Cannot bind to the target method because its signature is not compatible with that of the delegate type.
   at System.Delegate.CreateDelegateNoSecurityCheck(Type type, Object target, RuntimeMethodHandle method)
   at System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType, Object target)
   at Datadog.Trace.ClrProfiler.AutoInstrumentation.RabbitMQ.CachedBasicPropertiesHelper`1..cctor() 

}
else if (state.State.DuckIs<IReadOnlyBasicProperties>())
{
returnValue = CachedBasicPropertiesHelper<TReturn>.CreateHeaders(state.State!);
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we need to preserve / copy headers here?
Haven't tested it out if that is necessary though

Copy link
Author

Choose a reason for hiding this comment

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

I'll take a look and see if I can sort it out. We definitely need to copy the basic properties and headers as they will be dropped completely from the message otherwise. For example the current implementation completely breaks our rabbitmq message sender if instrumentation is enabled as the messageid, timestame, persistance settings will be removed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you!
And let us know if need help on this as we definitely want to fix this

Copy link
Author

Choose a reason for hiding this comment

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

I have added a commit that should fix the activator, not super happy about the cast but also not sure how to get rid of it. But I suppose optimizations can come after it's working properly :)

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

Successfully merging this pull request may close these issues.

[BUG]: RabbitMQ Basic Properties overwritten to default values
3 participants