Message label in Rabbitmq - rabbitmq

MSMQ messages have a Label property. It can contain an application-defined string describing the message. Does Rabbitmq have such a concept? Maybe it's called differently - haven't found anything similar yet.

I would use custom message headers. They are a lot more flexible than the MSMQ label. You can store string, number or boolean, or a list of those values.
Add custom headers to the IBasicProperties (C# example)
var properties = channel.CreateBasicProperties();
properties.Headers = new Dictionary<string, object>();
properties.Headers.Add("Label", "some text");
When you consume, extract them from the IBasicProperties.

Related

problem with masstransit dynamic event publish ( json event )

we need publish multiple event as json string from DB. publish this json event by masstransit like this:
using var scope = _serviceScopeFactory.CreateScope();
var sendEndpointProvider = scope.ServiceProvider.GetService<ISendEndpointProvider>();
var endpoint = await sendEndpointProvider.GetSendEndpoint(new System.Uri("exchange:IntegrationEvents.DynamicEvent:DynamicEvent"))
var json = JsonConvert.SerializeObject(dynamicObject, Newtonsoft.Json.Formatting.None);// sample
var obj = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { });
await endpoint.Send(obj,i=>i.Serializer.ContentType.MediaType= "application/json");
and in config we use this config:
cfg.UseRawJsonSerializer();
when use this config, json event is successful published but we have strange problem : "all" event consumer is called by empty message data ! ... in Rabbitmq jsut published our "Dynamic Event", but in masstrasit all consumers called !!
Thank you for letting us know if we made a mistake
You don't need all of that JSON manipulation, just send the message object using the endpoint with the serializer configured for RawJson. I cover JSON interoperability in this video.
Also, MassTransit does not allow anonymous types to be published. You might be able to publish dynamic or Expando objects.
I used ExpandoObject like this and get this exception "Messages types must not be in the System namespace: System.Dynamic.ExpandoObject" :
dynamic dynamicObject = new ExpandoObject();
dynamicObject.Id = 1;
dynamicObject.Name = "NameForName";
await endpoint.Send(dynamicObject);
and using like this we get same result as "all consumers called":
var dynamicObject = new ExpandoObject() as IDictionary<string, object>;
dynamicObject.Add("Id", 1);
dynamicObject.Add("Name", "NameForName");
I watch your great video, you used from rabbitmq directly .. how "send the message object using the endpoint with the serializer configured for RawJson" in C# code.

WCF Change message encoding from Utf-16 to Utf-8

I have a WCF connected service in a .net core application. I'm using the code that is autogenerated taken the wsdl definition.
Currently at the top of the request xml is including this line:
<?xml version="1.0" encoding="utf-16"?>
I can't find a simple way to change this encoding to UTF-8 when sending the request.
Since I could find a configuration option a the request/client objects, I've tried to change the message with following code at IClientMessageInspector.BeforeSendRequest
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
// Load a new xml document from current request
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(request.ToString());
((XmlDeclaration)xmlDocument.FirstChild).Encoding = Encoding.UTF8.HeaderName;
// Create streams to copy
var memoryStream = new MemoryStream();
var xmlWriter = XmlWriter.Create(memoryStream);
xmlDocument.Save(xmlWriter);
xmlWriter.Flush();
xmlWriter.Close();
memoryStream.Position = 0;
var xmlReader = XmlReader.Create(memoryStream);
// Create a new message
var newMessage = Message.CreateMessage(request.Version, null, xmlReader);
newMessage.Headers.CopyHeadersFrom(request);
newMessage.Properties.CopyProperties(request.Properties);
return null;
}
But the newMessage object still writes the xml declaration using utf-16. I can see it while debugging at the watch window since.
Any idea on how to accomplish this (should be) simple change will be very apreciated.
Which binding do you use to create the communication channel? The textmessageencoding element which has been contained in the CustomBinding generally contains TextEncoding property.
https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/textmessageencoding
WriteEncoding property specifies the character set encoding to be used for emitting messages on the binding. Valid values are
UnicodeFffeTextEncoding: Unicode BigEndian encoding
Utf16TextEncoding: Unicode encoding
Utf8TextEncoding: 8-bit encoding
The default is Utf8TextEncoding. This attribute is of type Encoding.
As for the specific binding, it contains the textEncoding property too.
https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.basichttpbinding.textencoding?view=netframework-4.0
Feel free to let me know if there is anything I can help with.

Hybris DataHub INVALID_LOCALE Exception

I have localized raw data item baseName. I want to send localized raw data item to DataHub. I read many documents, it writes send localized raw attribute value but I couldn't find the format of the localized attribute value. In the composition, it throws INVALID_LOCALE exception.
I am sending value for baseName, but how can I localized "XYZ"?
RawFragmentData rawFragmentData = new RawFragmentData();
final Map<String, String> line = new HashMap<>();
........
line.put("baseName", "XYZ");
........
rawFragmentData.setValueMap(line);
rawFragmentData.setType(type);
rawFragmentData.setDataFeedName(feedName);
rawFragmentData.setExtensionSource(Constants.DATAHUB_EXTENSION_SOURCE);
return rawFragmentData;
e.g OOTB :
DefaultPartnerContributor.Java :-
row.put(PartnerCsvColumns.COUNTRY_ISO_CODE, address.getCountry());
Same way you might have languageColumn for it, so just pass language value to it.

ServiceStack.RabbitMq - how to set custom attributes on messages

We use ServiceStack.RabbitMq and I could not find a way to put a custom attribute on the rabbit mq message. I want the publisher to set the attribute on the message and the worker to read it.
A variant is to move that attribute as part of request body but I have a lot of requests and in all honesty the request should not know at all about this kind of information - as that is metadata of the message.
Any idea how this can be achieved?
You can use the Message Filters in RabbitMqServer to add and introspect message properties, e.g:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};
You could either add the custom attribute to the object you are pushing down the queue or add that attribute to the rabbit message metadata header table. RabbitMQ messages have various metadata attributes that can be set when a message is published.
Check this

Read the soap message body contents in WCF custom message filter

I've been working with WCF routing and implemented a custom message filter,
public override bool Match(Message message)
{
MessageBuffer buffer = message.CreateBufferedCopy(Int32.MaxValue);
var msg = buffer.CreateMessage();
XmlDictionaryReader reader = msg.GetReaderAtBodyContents();
string paramsXml = reader.ReadOuterXml();
....
....
return serviceType.Equals(service);
}
I'm getting the following exception "This message cannot support the operation because it has been copied." eventhough I'm creating a buffered copy. Can anyone help me on this?
This is apparently the problem with VS debugger. does not happen with soap ui or other clients. hope this will be useful for somebody struggling with same issue.
You need to set routeOnHeadersOnly = false in the routing behavior
Then you implement the operations that take message buffers