public void CorrectlyHandlesDeserializationWhenAlternativeEncodingIsUsed(string encodingWebName) { // arrange var encoding = Encoding.GetEncoding(encodingWebName); var bytes = encoding.GetBytes(SerializedMessage); Console.WriteLine(@"This is how it looks as ASCII: {0}", Encoding.ASCII.GetString(bytes)); var receivedTransportMessage = new ReceivedTransportMessage { Headers = new Dictionary <string, object> { { Headers.ContentType, "text/json" }, { Headers.Encoding, encodingWebName }, }, Body = bytes, }; // act var deserializedMessage = serializer.Deserialize(receivedTransportMessage); // assert deserializedMessage.Messages.Length.ShouldBe(1); var message = deserializedMessage.Messages.Single(); message.ShouldBeOfType <SomeComplexObjectThatRequïresÜnicódeToWørk>(); ((SomeComplexObjectThatRequïresÜnicódeToWørk)message).ThisIsÜnicøde.ShouldBe("thiß ís jüst tæxt"); }
void HandleMessageFailedMaxNumberOfTimes(ReceivedTransportMessage receivedTransportMessage, string errorDetail) { var transportMessageToSend = receivedTransportMessage.ToForwardableMessage(); log.Warn("Message {0} is forwarded to error queue", transportMessageToSend.Label); transportMessageToSend.Headers[Headers.SourceQueue] = receiveMessages.InputQueueAddress; transportMessageToSend.Headers[Headers.ErrorMessage] = errorDetail; try { sendMessages.Send(errorTracker.ErrorQueueAddress, transportMessageToSend, GetTransactionContext()); } catch (Exception e) { log.Error(e, "Wanted to move message with id {0} to the error queue, but an exception occurred!", receivedTransportMessage.Id); // what to do? we need to throw again, or the message will not be rolled back and will thus be lost // - but we want to avoid thrashing, so we just log the badness and relax a little bit - that's // probably the best we can do Thread.Sleep(300); throw; } }
public void Log(ReceivedTransportMessage message) { var encoding = MessageLoggerHelper.GetEncoding(message.Headers); if (encoding == null) { _logger.WarnFormat("Unable to guess encoding for incoming message with id '{0}'?!", message.Id); return; } _logger.Log(_logLevel, () => { var messageLog = new StringBuilder(); messageLog.AppendFormat("Incoming message ({0}) headers:", message.Id); Append(messageLog, message.Id, message.Headers); return(messageLog.ToString()); }); _logger.Log(_logLevel, () => { var messageLog = new StringBuilder(); messageLog.AppendFormat("Incoming message ({0}) body:", message.Id); Append(messageLog, message.Id, message.Body, encoding); return(messageLog.ToString()); }); }
public void CorrectlyHandlesDeserializationWhenAlternativeEncodingIsUsed(string encodingWebName) { // arrange var encoding = Encoding.GetEncoding(encodingWebName); var bytes = encoding.GetBytes(SerializedMessage); Console.WriteLine(@"This is how it looks as ASCII: {0}", Encoding.ASCII.GetString(bytes)); var receivedTransportMessage = new ReceivedTransportMessage { Headers = new Dictionary<string, object> { {Headers.ContentType, "text/json"}, {Headers.Encoding, encodingWebName}, }, Body = bytes, }; // act var deserializedMessage = serializer.Deserialize(receivedTransportMessage); // assert deserializedMessage.Messages.Length.ShouldBe(1); var message = deserializedMessage.Messages.Single(); message.ShouldBeOfType<SomeComplexObjectThatRequïresÜnicódeToWørk>(); ((SomeComplexObjectThatRequïresÜnicódeToWørk)message).ThisIsÜnicøde.ShouldBe("thiß ís jüst tæxt"); }
void HandleMessageFailedMaxNumberOfTimes(ReceivedTransportMessage receivedTransportMessage, string errorDetail) { var transportMessageToSend = receivedTransportMessage.ToForwardableMessage(); log.Warn("Message {0} is forwarded to error queue", transportMessageToSend.Label); transportMessageToSend.Headers[Headers.SourceQueue] = receiveMessages.InputQueueAddress; transportMessageToSend.Headers[Headers.ErrorMessage] = errorDetail; transportMessageToSend.Headers[Headers.Bounced] = ""; try { using (var txc = ManagedTransactionContext.Get()) { sendMessages.Send(errorTracker.ErrorQueueAddress, transportMessageToSend, txc.Context); } } catch (Exception e) { log.Error(e, "An error occurred while attempting to move message with id {0} to the error queue '{1}'", receivedTransportMessage.Id, errorTracker.ErrorQueueAddress); // what to do? we need to throw again, or the message will not be rolled back and will thus be lost // - but we want to avoid thrashing, so we just log the badness and relax a little bit - that's // probably the best we can do Thread.Sleep(TimeSpan.FromSeconds(1)); throw; } }
public void ItsSymmetric() { var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary <string, object> { { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() } }, Body = Guid.NewGuid().ToByteArray(), }; transport.Send("test", toSend, new NoTransaction()); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
/// <summary> /// Deserializes the transport message using JSON.NET from a <see cref="ReceivedTransportMessage"/> and wraps it in a <see cref="Message"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { if (transportMessage == null) { throw new ArgumentNullException("transportMessage", "A transport message must be passed to this function in order to deserialize"); } using (new CultureContext(serializationCulture)) { var headers = new Dictionary <string, object>(transportMessage.Headers); var encodingToUse = GetEncodingOrThrow(headers); var serializedTransportMessage = encodingToUse.GetString(transportMessage.Body); if (!headers.ContainsKey(Headers.MessageTypes)) { throw new SerializationException(string.Format("Could not find the '{0}' header in the message", Headers.MessageTypes)); } try { var concatenatedTypeNames = headers[Headers.MessageTypes].ToString(); var typeNames = concatenatedTypeNames.Split(';'); var jsonLines = serializedTransportMessage.Split(LineSeparator); if (typeNames.Length != jsonLines.Length) { throw new SerializationException(string.Format("Number of message types in the '{0}' header does not correspond to the number of lines in the body - here's the header: '{1}' - here's the body: {2}", Headers.MessageTypes, concatenatedTypeNames, serializedTransportMessage)); } var messages = typeNames .Zip(jsonLines, (typeName, jsonLine) => { var messageType = Type.GetType(typeName); if (messageType == null) { throw new SerializationException(string.Format("Could not find message type '{0}' in the current AppDomain", typeName)); } var message = JsonConvert.DeserializeObject(jsonLine, messageType, settings); return(message); }); return(new Message { Headers = headers, Messages = messages.ToArray() }); } catch (Exception e) { throw new ArgumentException( string.Format( "An error occurred while attempting to deserialize JSON text '{0}' into an object[]", serializedTransportMessage), e); } } }
public ReceivedTransportMessage ReceiveMessage(ITransactionContext context) { var receivedTransportMessage = MessageToReceive; MessageToReceive = null; return(receivedTransportMessage); }
/// <summary> /// Deserializes the transport message using JSON.NET from a <see cref="ReceivedTransportMessage"/> and wraps it in a <see cref="Message"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { using (new CultureContext(serializationCulture)) { var headers = transportMessage.Headers.Clone(); var encodingToUse = GetEncodingOrThrow(headers); var serializedTransportMessage = encodingToUse.GetString(transportMessage.Body); try { var messages = (object[]) JsonConvert.DeserializeObject(serializedTransportMessage, settings); return new Message { Headers = headers, Messages = messages }; } catch (Exception e) { throw new ArgumentException( string.Format( "An error occurred while attempting to deserialize JSON text '{0}' into an object[]", serializedTransportMessage), e); } } }
/// <summary> /// Deserializes the transport message using JSON.NET from a <see cref="ReceivedTransportMessage"/> and wraps it in a <see cref="Message"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { if (transportMessage == null) { throw new ArgumentNullException("transportMessage", "A transport message must be passed to this function in order to deserialize"); } using (new CultureContext(serializationCulture)) { var headers = transportMessage.Headers.Clone(); var encodingToUse = GetEncodingOrThrow(headers); var serializedTransportMessage = encodingToUse.GetString(transportMessage.Body); try { var messages = (object[])JsonConvert.DeserializeObject(serializedTransportMessage, settings); return(new Message { Headers = headers, Messages = messages }); } catch (Exception e) { throw new ArgumentException( string.Format( "An error occurred while attempting to deserialize JSON text '{0}' into an object[]", serializedTransportMessage), e); } } }
public void Deserialize_StandardToposSerializedEvent_ShouldWork() { var position = new Position("hey", 1, 666); var headers = new Dictionary<string, string>(); headers.Add("tps-msg-type", "OpenFTTH.GDBIntegrator.Integrator.EventMessages.RouteNodeAdded, OpenFTTH.GDBIntegrator.Integrator"); var bodyJson = "{\"EventType\":\"RouteNodeAdded\",\"EventTs\":\"2020-07-28T08:04:37.8098439Z\",\"CmdId\":\"e3693ffe-be4b-490b-9b1d-5c2883ea3849\",\"EventId\":\"351428bc-1606-44ff-b6e4-396664ccef9b\",\"NodeId\":\"b41a377c-ebe6-4327-9f08-ff58f70c2bb1\",\"Geometry\":\"[538888.8171487605,6210640.758167612]\"}"; var bodyBytes = Encoding.UTF8.GetBytes(bodyJson); var messageToDeserialized = new ReceivedTransportMessage(position, headers, bodyBytes); var logicalMessage = new GenericEventDeserializer<DomainEvent>().Deserialize(messageToDeserialized); // Check if got a route node added object from deserializer Assert.True(logicalMessage.Body is RouteNodeAdded); var routeNodeAddedEvent = logicalMessage.Body as RouteNodeAdded; Assert.Equal("RouteNodeAdded", (routeNodeAddedEvent).EventType); // Check if event sequence number was set to 666 Assert.Equal(666, routeNodeAddedEvent.EventSequenceNumber); }
static ReceivedTransportMessage GetReceivedTransportMessage(IBasicProperties basicProperties, byte[] body) { var result = new ReceivedTransportMessage { Id = basicProperties != null ? basicProperties.MessageId ?? "(null)" : "(unknown)", Headers = basicProperties != null ? GetHeaders(basicProperties) : new Dictionary <string, object>(), Body = body, }; // As this is a recent change, I feel we should alert if a message arrives // with different transport-level and header-level IDs. (pruiz) if (result.Headers.ContainsKey(Headers.MessageId)) { var headerLevelId = result.Headers[Headers.MessageId]; if (!string.Equals(headerLevelId, result.Id)) { log.Warn("Mismatch between transport-level and header-level message's id. " + "This may indicate a software bug, or maybe due to processing of messages " + "generated by previous versions of Rebus. (TLID: {0} - HLID: {1})", result.Id, headerLevelId); } } return(result); }
public ReceivedTransportMessage ReceiveMessage() { var receivedTransportMessage = MessageToReceive; MessageToReceive = null; return(receivedTransportMessage); }
void SendMessage(ReceivedTransportMessage receivedTransportMessage) { log.Info("Trying to send message {0} to {1}", receivedTransportMessage.Id, destinationUri); var request = (HttpWebRequest)WebRequest.Create(destinationUri); request.Method = "POST"; request.ContentType = Encoding.WebName; var bytes = receivedTransportMessage.Body; request.ContentLength = bytes.Length; var headers = receivedTransportMessage.Headers.ToDictionary(d => d.Key, d => d.Value); foreach (var header in headers) { request.Headers.Add(RebusHttpHeaders.CustomHeaderPrefix + header.Key, header.Value); } request.Headers.Add(RebusHttpHeaders.Id, receivedTransportMessage.Id); request.GetRequestStream().Write(bytes, 0, bytes.Length); log.Info("Added headers to request: {0}", string.Join(", ", headers.Keys)); using (var response = (HttpWebResponse)request.GetResponse()) using (var reader = new StreamReader(response.GetResponseStream())) { log.Info("Message {0} was sent", receivedTransportMessage.Id); reader.ReadToEnd(); } }
public ReceivedLogicalMessage Deserialize(ReceivedTransportMessage message) { var headers = message.Headers.Clone(); GetValue(headers, ToposHeaders.ContentType, out var contentType); if (!string.Equals(contentType, DefaultContentType, StringComparison.OrdinalIgnoreCase)) { throw new FormatException($"Cannot decode content type '{contentType}' yet, only '{DefaultContentType}' is understood"); } var bytes = message.Body; var json = _encoding.GetString(bytes); GetValue(headers, ToposHeaders.MessageType, out var messageType); try { var type = messageType.ParseType(); var body = JsonConvert.DeserializeObject(json, type, _settings); var position = message.Position; return(new ReceivedLogicalMessage(headers, body, position)); } catch (Exception exception) { throw new FormatException($"Could not deserialize JSON text: '{json}'", exception); } }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var outputQueue = cloudQueueClient.GetQueueReference(destinationQueueName); using (var memoryStream = new MemoryStream()) { var formatter = new BinaryFormatter(); var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Headers = message.Headers, Body = message.Body, Label = message.Label, }; formatter.Serialize(memoryStream, receivedTransportMessage); memoryStream.Position = 0; var cloudQueueMessage = new CloudQueueMessage(memoryStream.ToArray()); var timeToLive = GetTimeToLive(message); if (timeToLive.HasValue) { outputQueue.AddMessage(cloudQueueMessage, timeToLive.Value); } else { outputQueue.AddMessage(cloudQueueMessage); } } }
public ReceivedLogicalMessage Deserialize(ReceivedTransportMessage message) { var headers = message.Headers.Clone(); var body = message.Body; if (!headers.TryGetValue(ToposHeaders.ContentType, out var contentType)) { throw new ArgumentException($"Could not find '{ToposHeaders.ContentType}' header on the incoming message"); } // quick path if (contentType == ContentType) { return(new ReceivedLogicalMessage(headers, Encoding.GetString(body), message.Position)); } // otherwise, we need to parse the content type var parts = contentType.Split(';').Select(t => t.Trim()).ToArray(); if (parts.Length != 2) { throw new ArgumentException($"Expected exactly 2 parts separated by ';' in content type, got this: '{contentType}'"); } if (parts[0] != "text/plain") { throw new ArgumentException($"Invalid content type '{contentType}', expected 'text/plain' and then an encoding, e.g. like '{ContentType}'"); } var encoding = GetEncoding(parts[1], contentType); return(new ReceivedLogicalMessage(headers, encoding.GetString(body), message.Position)); }
/// <summary> /// Deserializes the specified message using the BCL <see cref="BinaryFormatter"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { using (var memoryStream = new MemoryStream(transportMessage.Body)) { var formatter = new BinaryFormatter(); var message = (Message)formatter.Deserialize(memoryStream); return(message); } }
public Message Deserialize(ReceivedTransportMessage transportMessage) { using (var memoryStream = new MemoryStream(transportMessage.Body)) { var formatter = new BinaryFormatter(); var message = (Message) formatter.Deserialize(memoryStream); return message; } }
void PumpTopic(string topic) { var cancellationToken = _cancellationTokenSource.Token; _logger.Info("Starting consumer worker for topic {topic}", topic); try { var topicDirectoryPath = Path.Combine(_directoryPath, topic); var logDirectory = new LogDirectory(topicDirectoryPath, new Settings(logger: new KafkaesqueToToposLogger(_logger))); var reader = logDirectory.GetReader(); while (!cancellationToken.IsCancellationRequested) { try { var resumePosition = _positionManager.Get(topic, 0).Result; var(fileNumber, bytePosition) = resumePosition.ToKafkaesquePosition(); _logger.Debug("Resuming consumer from file {fileNumber} byte {bytePosition}", fileNumber, bytePosition); foreach (var eventData in reader.Read(fileNumber, bytePosition, cancellationToken: cancellationToken)) { var transportMessage = JsonConvert.DeserializeObject <TransportMessage>(Encoding.UTF8.GetString(eventData.Data)); var kafkaesqueEventPosition = new KafkaesquePosition(eventData.FileNumber, eventData.BytePosition); var eventPosition = kafkaesqueEventPosition.ToPosition(topic, partition: 0); var receivedTransportMessage = new ReceivedTransportMessage(eventPosition, transportMessage.Headers, transportMessage.Body); _logger.Debug("Received event {position}", eventPosition); _consumerDispatcher.Dispatch(receivedTransportMessage); } } catch (Exception exception) { _logger.Warn(exception, "Error in consumer worker for topic {topic} - waiting 10 s", topic); Task.Delay(TimeSpan.FromSeconds(10), cancellationToken) .Wait(cancellationToken); } } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // we're done } catch (Exception exception) { _logger.Error(exception, "Unhandled exception in consumer worker for topic {topic}", topic); } finally { _logger.Info("Stopped consumer worker for topic {topic}", topic); } }
public void MessageWithTimeToLiveWillDisappearFromErrorQueueAsWell() { // arrange var senderBus = CreateBus(SenderQueueName, new HandlerActivatorForTesting()).Start(1); var errorQueue = GetMessageQueue(ReceiverErrorQueueName); var deadLetterQueue = GetMessageQueueFromPath(string.Format(@"FormatName:DIRECT=OS:{0}\SYSTEM$;DEADLETTER", Environment.MachineName)); var deadLetterQueue2 = GetMessageQueueFromPath(string.Format(@"FormatName:DIRECT=OS:{0}\SYSTEM$;DEADXACT", Environment.MachineName)); var activator = new HandlerActivatorForTesting() .Handle <string>(s => { throw new OmfgExceptionThisIsBad("whoahhh!"); }); CreateBus(ReceiverQueueName, activator, new InMemorySubscriptionStorage(), new SagaDataPersisterForTesting(), ReceiverErrorQueueName).Start(1); const string message = "HELLO!"; senderBus.AttachHeader(message, Headers.TimeToBeReceived, "00:00:02"); senderBus.Routing.Send(ReceiverQueueName, message); Thread.Sleep(3.Seconds()); ReceivedTransportMessage transportMessage = null; try { transportMessage = (ReceivedTransportMessage)errorQueue.Receive(3.Seconds()).Body; } catch (Exception e) { Console.WriteLine(e); } try { transportMessage = (ReceivedTransportMessage)deadLetterQueue.Receive(3.Seconds()).Body; } catch (Exception e) { Console.WriteLine(e); } try { transportMessage = (ReceivedTransportMessage)deadLetterQueue2.Receive(3.Seconds()).Body; } catch (Exception e) { Console.WriteLine(e); } transportMessage.ShouldBe(null); }
/// <summary> /// Receives a <see cref="ReceivedTransportMessage"/> using the underlying implementation of <see cref="IReceiveMessages"/> /// decrypting the message body if necessary, and remove the additional encryption headers /// </summary> public ReceivedTransportMessage ReceiveMessage(ITransactionContext context) { var message = innerReceiveMessages.ReceiveMessage(context); if (message == null) { return(null); } var clone = new ReceivedTransportMessage { Body = message.Body, Headers = message.Headers.Clone(), Label = message.Label, Id = message.Id }; var headers = clone.Headers; if (encryptionHelper != null) { if (headers.ContainsKey(Headers.Encrypted)) { var iv = clone.GetStringHeader(Headers.EncryptionSalt); clone.Body = encryptionHelper.Decrypt(clone.Body, iv); headers.Remove(Headers.EncryptionSalt); headers.Remove(Headers.Encrypted); } } if (compressionHelper != null) { if (headers.ContainsKey(Headers.Compression)) { var compressionType = (headers[Headers.Compression] ?? "").ToString(); switch (compressionType) { case Headers.CompressionTypes.GZip: clone.Body = compressionHelper.Decompress(clone.Body); break; default: throw new ArgumentException( string.Format( "Received message has the {0} header, but the compression type is set to {1} which cannot be handled", Headers.Compression, compressionType)); } headers.Remove(Headers.Compression); } } return(clone); }
public void Deserialize_ShouldThrowArgumentNullException_OnReceivedLogicalMessageBeingNull() { var serializationMapper = A.Fake <IInfoMapper>(); var routeNodeSerializer = new RouteNetworkSerializer(serializationMapper); ReceivedTransportMessage receivedTransportMessage = null; routeNodeSerializer.Invoking(x => x.Deserialize(receivedTransportMessage)) .Should().Throw <ArgumentNullException>(); }
public void Deserialize_ShouldReturnDeserializedNodeMessage_OnValidReceivedTransportMessage(string fileData) { var serializationMapper = A.Fake <IInfoMapper>(); var routeNodeSerializer = new RouteNetworkSerializer(serializationMapper); A.CallTo(() => serializationMapper.MapDeploymentState("InService")).Returns(DeploymentStateEnum.InService); A.CallTo(() => serializationMapper.MapRouteNodeFunction("FlexPoint")).Returns(RouteNodeFunctionEnum.FlexPoint); var position = new Position(string.Empty, 0, 0); var headers = new Dictionary <string, string>(); var body = Encoding.UTF8.GetBytes(fileData); var receivedTransportMessage = new ReceivedTransportMessage(position, headers, body); var expectedRouteNodeBefore = new RouteNode { ApplicationInfo = string.Empty, ApplicationName = string.Empty, Coord = Convert.FromBase64String("AQEAACDoZAAAqxoVSPa2H8GsStinzINUQQ=="), DeleteMe = false, MarkAsDeleted = false, Mrid = new Guid("9bffa519-c672-49fd-93d0-52cd22519346"), Username = string.Empty, WorkTaskMrid = Guid.Empty, LifeCycleInfo = null, MappingInfo = null, NamingInfo = null, RouteNodeInfo = null, SafetyInfo = null }; var expectedRouteNodeAfter = new RouteNode { ApplicationInfo = string.Empty, ApplicationName = string.Empty, Coord = Convert.FromBase64String("AQEAACDoZAAAqxoVSPa2H8GsStinzINUQQ=="), DeleteMe = false, MarkAsDeleted = true, Mrid = new Guid("9bffa519-c672-49fd-93d0-52cd22519346"), Username = string.Empty, WorkTaskMrid = Guid.Empty, LifeCycleInfo = new LifecycleInfo(DeploymentStateEnum.InService, DateTime.Parse("2020-08-12 00:00:00"), DateTime.Parse("2020-08-12 00:00:00")), MappingInfo = null, NamingInfo = null, RouteNodeInfo = new RouteNodeInfo(null, RouteNodeFunctionEnum.FlexPoint), SafetyInfo = null }; var expectedBody = new RouteNodeMessage(expectedRouteNodeBefore, expectedRouteNodeAfter); var expected = new ReceivedLogicalMessage(headers, expectedBody, position); var result = routeNodeSerializer.Deserialize(receivedTransportMessage); result.Should().BeEquivalentTo(expected); }
public ReceivedLogicalMessage Deserialize(ReceivedTransportMessage message) { try { var typeList = GetEventTypes(); if (message is null) { throw new ArgumentNullException($"{nameof(ReceivedTransportMessage)} is null"); } if (message.Body is null || message.Body.Length == 0) { throw new ArgumentNullException($"{nameof(ReceivedTransportMessage)} body is null"); } var messageBody = Encoding.UTF8.GetString(message.Body, 0, message.Body.Length); Log.Debug(messageBody); var eventTypeName = GetEventTypeNameFromMessage(message); if (eventTypeName == null) { return(new ReceivedLogicalMessage(message.Headers, new EventCouldNotBeDeserialized("notset", $"Could not find {_rebusMsgTypeHeaderKey} header", messageBody), message.Position)); } if (GetEventTypes().ContainsKey(eventTypeName.ToLower())) { var eventType = GetEventTypes()[eventTypeName.ToLower()]; var eventObject = JsonConvert.DeserializeObject(messageBody, eventType); // Set event sequence number, if such attribut exitsts PropertyInfo prop = eventObject.GetType().GetProperty("EventSequenceNumber", BindingFlags.Public | BindingFlags.Instance); if (null != prop && prop.CanWrite) { prop.SetValue(eventObject, message.Position.Offset, null); } return(new ReceivedLogicalMessage(message.Headers, eventObject, message.Position)); } var errorEvent = new EventCouldNotBeDeserialized(eventTypeName, $"Deserializer did not found a class with the name: '{eventTypeName}' So, the event will not be deserialized!", messageBody); return(new ReceivedLogicalMessage(message.Headers, errorEvent, message.Position)); } catch (Exception ex) { // Make sure any exception occuring in deserialization gets logged Log.Error(ex, ex.Message); throw; } }
public void Deserialize_ShouldReturnDeserializedSegmentMessage_(string fileData) { var serializationMapper = A.Fake <IInfoMapper>(); var routeSegmentSerializer = new RouteNetworkSerializer(serializationMapper); var position = new Position(string.Empty, 0, 0); var headers = new Dictionary <string, string>(); var body = Encoding.UTF8.GetBytes(fileData); var receivedTransportMessage = new ReceivedTransportMessage(position, headers, body); var expectedRouteSegmentBefore = new RouteSegment { Mrid = new Guid("57fb87f5-093c-405d-b619-755e3f39073f"), Coord = Convert.FromBase64String("AQIAACDoZAAAAgAAAO79HyV51h/B6DWfEXKJVEGgwmxDUMkfwXuWw252iVRB"), WorkTaskMrid = Guid.Empty, ApplicationName = string.Empty, Username = string.Empty, MarkAsDeleted = false, ApplicationInfo = string.Empty, DeleteMe = false, LifeCycleInfo = null, MappingInfo = null, NamingInfo = null, RouteSegmentInfo = null, SafetyInfo = null }; var expectedRouteSegmentAfter = new RouteSegment { Mrid = new Guid("57fb87f5-093c-405d-b619-755e3f39073f"), Coord = null, WorkTaskMrid = Guid.Empty, ApplicationName = string.Empty, Username = string.Empty, MarkAsDeleted = true, ApplicationInfo = string.Empty, DeleteMe = false, LifeCycleInfo = null, MappingInfo = null, NamingInfo = null, RouteSegmentInfo = null, SafetyInfo = null }; var expectedBody = new RouteSegmentMessage(expectedRouteSegmentBefore, expectedRouteSegmentAfter); var expectedInvalidMessage = new InvalidMessage(expectedBody); var expected = new ReceivedLogicalMessage(headers, expectedInvalidMessage, position); var result = routeSegmentSerializer.Deserialize(receivedTransportMessage); result.Should().BeEquivalentTo(expected); }
/// <summary> /// Receives a <see cref="ReceivedTransportMessage"/> using the underlying implementation of <see cref="IReceiveMessages"/> /// decrypting the message body if necessary, and remove the additional encryption headers /// </summary> public ReceivedTransportMessage ReceiveMessage(ITransactionContext context) { var message = innerReceiveMessages.ReceiveMessage(context); if (message == null) return null; var clone = new ReceivedTransportMessage { Body = message.Body, Headers = message.Headers.Clone(), Label = message.Label, Id = message.Id }; var headers = clone.Headers; if (encryptionHelper != null) { if (headers.ContainsKey(Headers.Encrypted)) { var iv = clone.GetStringHeader(Headers.EncryptionSalt); clone.Body = encryptionHelper.Decrypt(clone.Body, iv); headers.Remove(Headers.EncryptionSalt); headers.Remove(Headers.Encrypted); } } if (compressionHelper != null) { if (headers.ContainsKey(Headers.Compression)) { var compressionType = (headers[Headers.Compression] ?? "").ToString(); switch (compressionType) { case Headers.CompressionTypes.GZip: clone.Body = compressionHelper.Decompress(clone.Body); break; default: throw new ArgumentException( string.Format( "Received message has the {0} header, but the compression type is set to {1} which cannot be handled", Headers.Compression, compressionType)); } headers.Remove(Headers.Compression); } } return clone; }
private ICommand GetCommandFromMessage(ReceivedTransportMessage message) { if (UseCustomSerializer) { var deserializedMessage = CustomSerializer.Deserialize(message); if (deserializedMessage != null && deserializedMessage.Messages.Length > 0) { var command = deserializedMessage.Messages[0] as ICommand; if (command != null) { return(command); } } } string body; switch (message.Headers["rebus-encoding"].ToString().ToLowerInvariant()) { case "utf-7": body = Encoding.UTF7.GetString(message.Body); break; case "utf-8": body = Encoding.UTF8.GetString(message.Body); break; case "utf-32": body = Encoding.UTF32.GetString(message.Body); break; case "ascii": body = Encoding.ASCII.GetString(message.Body); break; case "unicode": body = Encoding.Unicode.GetString(message.Body); break; default: return(null); } var msg = JsonConvert.DeserializeObject(body, _jsonSerializerSettings); var array = msg as Object[]; if (array != null) { return(array[0] as ICommand); } return(null); }
public void Deliver(Message message) { var transportMessageToSend = serializer.Serialize(message); var receivedTransportMessage = new ReceivedTransportMessage { Id = NewMessageId(), Body = transportMessageToSend.Body, Label = transportMessageToSend.Label, }; messageQueue.Enqueue(receivedTransportMessage); }
public Message Deserialize(ReceivedTransportMessage transportMessage) { using (new CultureContext(SerializationCulture)) { var messages = (object[])JsonConvert.DeserializeObject(Encoding.GetString(transportMessage.Body), Settings); return new Message { Headers = transportMessage.Headers.ToDictionary(k => k.Key, v => v.Value), Messages = messages }; } }
public Message Deserialize(ReceivedTransportMessage transportMessage) { using (new CultureContext(SerializationCulture)) { var messages = (object[])JsonConvert.DeserializeObject(Encoding.GetString(transportMessage.Body), Settings); return new Message { Headers = transportMessage.Headers.Clone(), Messages = messages }; } }
public void Deliver(Message message) { var transportMessageToSend = serializer.Serialize(message); var receivedTransportMessage = new ReceivedTransportMessage { Id = NewMessageId(), Body = transportMessageToSend.Body, Label = transportMessageToSend.Label, Headers = transportMessageToSend.Headers.Clone(), }; messageQueue.Enqueue(receivedTransportMessage); }
/// <summary> /// Deserializes the transport message using JSON.NET from a <see cref="ReceivedTransportMessage"/> and wraps it in a <see cref="Message"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { using (new CultureContext(serializationCulture)) { var messages = (object[])JsonConvert.DeserializeObject(encoding.GetString(transportMessage.Body), settings); return new Message { Headers = transportMessage.Headers.Clone(), Messages = messages }; } }
public void CanRoundtripTHisBadBoy() { var headers = new Dictionary <string, string> { ["test-header"] = "test-value" }; var logicalMessage = new LogicalMessage(headers, "hej med dig"); var transportMessage = _serializer.Serialize(logicalMessage); var receivedTransportMessage = new ReceivedTransportMessage(Position.Default("random-topic", 0), transportMessage.Headers, transportMessage.Body); var receivedLogicalMessage = _serializer.Deserialize(receivedTransportMessage); Assert.That(receivedLogicalMessage.Headers.GetValue("test-header"), Is.EqualTo("test-value")); }
void TryProcessNextMessage(IConsumer <string, byte[]> consumer, CancellationToken cancellationToken) { try { var consumeResult = consumer.Consume(cancellationToken); if (consumeResult == null) { Thread.Sleep(100); //< chill (but it should not happen) return; } var position = new Position( topic: consumeResult.Topic, partition: consumeResult.Partition.Value, offset: consumeResult.Offset.Value ); var message = new ReceivedTransportMessage( position: position, headers: GetHeaders(consumeResult.Headers), body: consumeResult.Value ); _logger.Debug("Received event {position}", position); _consumerDispatcher.Dispatch(message); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // it's alright } catch (ThreadAbortException) { _logger.Warn("Kafka consumer worker aborted!"); } catch (Exception exception) { _logger.Warn(exception, "Unhandled exception in Kafka consumer loop - waiting 30 s"); try { Task.Delay(TimeSpan.FromSeconds(30), cancellationToken) .Wait(cancellationToken); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { } } }
public void Deserialize_NoToposHeader_ShouldReturnEventCouldNotBeDeserialized() { // Create an event with no topos header information var position = new Position("hest", 1, 1); var headers = new Dictionary<string, string>(); var bodyJson = "{\"EventType\":\"RouteNodeAddedCommand\",\"EventTs\":\"2020-07-28T08:04:37.8098439Z\",\"CmdId\":\"e3693ffe-be4b-490b-9b1d-5c2883ea3849\",\"EventId\":\"351428bc-1606-44ff-b6e4-396664ccef9b\",\"NodeId\":\"b41a377c-ebe6-4327-9f08-ff58f70c2bb1\",\"Geometry\":\"[538888.8171487605,6210640.758167612]\"}"; var bodyBytes = Encoding.UTF8.GetBytes(bodyJson); var messageToDeserialized = new ReceivedTransportMessage(position, headers, bodyBytes); var logicalMessage = new GenericEventDeserializer<DomainEvent>().Deserialize(messageToDeserialized); Assert.True(logicalMessage.Body is EventCouldNotBeDeserialized); }
public void DoesntDecryptIfEncrypedHeaderIsNotPresent() { // arrange var messageWithoutEncryptedHeader = new ReceivedTransportMessage { Body = new byte[] { 128 } }; receiver.MessageToReceive = messageWithoutEncryptedHeader; // act var receivedTransportMessage = transport.ReceiveMessage(new NoTransaction()); // assert receivedTransportMessage.Body.ShouldBe(new byte[] { 128 }); }
static void PossiblyCopyToAuditQueue(string auditQueueName, Exception exceptionOrNull, IBus bus, ReceivedTransportMessage message) { // if an error occurred, don't do anything if (exceptionOrNull != null) return; // this one will always be non-null - but still if (TransactionContext.Current == null) { log.Warn("Auditor called outside of a proper transaction context!!! This must be an error."); return; } var rebusBus = bus as RebusBus; if (rebusBus == null) { log.Warn("Current IBus is not a RebusBus, it's a {0} - cannot use {0} for auditing, sorry!", bus.GetType().Name); return; } using (var txc = ManagedTransactionContext.Get()) { var messageCopy = message.ToForwardableMessage(); messageCopy.Headers[Headers.AuditReason] = Headers.AuditReasons.Handled; messageCopy.Headers[Headers.AuditSourceQueue] = rebusBus.GetInputQueueAddress(); messageCopy.Headers[Headers.AuditMessageCopyTime] = RebusTimeMachine.Now().ToString("u"); rebusBus.InternalSend(new List<string> {auditQueueName}, messageCopy, txc.Context); var rebusEvents = rebusBus.Events as RebusEvents; if (rebusEvents == null) { log.Warn( "Current IRebusEvents is not a RebusEvents, it's a {0} - cannot use {0} for raising auditing events, sorry! (the message was properly audited though, it just turned out to be impossible to raise the MessageAudited event!)"); return; } rebusEvents.RaiseMessageAudited(rebusBus, messageCopy); } }
void HandlePost(HttpListenerResponse response, HttpListenerRequest request) { using (var reader = new BinaryReader(request.InputStream)) { var receivedTransportMessage = new ReceivedTransportMessage { Id = request.Headers[RebusHttpHeaders.Id], Body = reader.ReadBytes((int) request.ContentLength64) }; var headers = new Dictionary<string, string>(); foreach (var rebusHeaderKey in request.Headers.AllKeys.Where(k => k.StartsWith(RebusHttpHeaders.CustomHeaderPrefix))) { var value = request.Headers[rebusHeaderKey]; var key = rebusHeaderKey.Substring(RebusHttpHeaders.CustomHeaderPrefix.Length); headers.Add(key, value); } log.Info("Got headers in request: {0}", string.Join(", ", headers.Keys)); receivedTransportMessage.Headers = headers; log.Info("Received message {0}", receivedTransportMessage.Id); using (var queue = MsmqMessageQueue.Sender()) { queue.Send(destinationQueue, receivedTransportMessage.ToForwardableMessage()); } log.Info("Message was sent to {0}", destinationQueue); response.StatusCode = (int) HttpStatusCode.OK; response.Close(); } }
/// <summary> /// Deserializes the transport message using JSON.NET from a <see cref="ReceivedTransportMessage"/> and wraps it in a <see cref="Message"/> /// </summary> public Message Deserialize(ReceivedTransportMessage transportMessage) { if (transportMessage == null) throw new ArgumentNullException("transportMessage", "A transport message must be passed to this function in order to deserialize"); using (new CultureContext(serializationCulture)) { var headers = new Dictionary<string, object>(transportMessage.Headers); var encodingToUse = GetEncodingOrThrow(headers); var serializedTransportMessage = encodingToUse.GetString(transportMessage.Body); if (!headers.ContainsKey(Headers.MessageTypes)) { throw new SerializationException(string.Format("Could not find the '{0}' header in the message", Headers.MessageTypes)); } try { var concatenatedTypeNames = headers[Headers.MessageTypes].ToString(); var typeNames = concatenatedTypeNames.Split(';'); var jsonLines = serializedTransportMessage.Split(LineSeparator); if (typeNames.Length != jsonLines.Length) { throw new SerializationException(string.Format("Number of message types in the '{0}' header does not correspond to the number of lines in the body - here's the header: '{1}' - here's the body: {2}", Headers.MessageTypes, concatenatedTypeNames, serializedTransportMessage)); } var messages = typeNames .Zip(jsonLines, (typeName, jsonLine) => { var messageType = Type.GetType(typeName); if (messageType == null) { throw new SerializationException(string.Format("Could not find message type '{0}' in the current AppDomain", typeName)); } var message = JsonConvert.DeserializeObject(jsonLine, messageType, settings); return message; }); return new Message { Headers = headers, Messages = messages.ToArray() }; } catch (Exception e) { throw new ArgumentException( string.Format( "An error occurred while attempting to deserialize JSON text '{0}' into an object[]", serializedTransportMessage), e); } } }
internal void RaisePoisonMessage(IBus bus, ReceivedTransportMessage transportMessage, PoisonMessageInfo poisonMessageInfo) { PoisonMessage(bus, transportMessage, poisonMessageInfo); }
void SendMessage(ReceivedTransportMessage receivedTransportMessage) { log.Info("Trying to send message {0} to {1}", receivedTransportMessage.Id, destinationUri); var request = (HttpWebRequest)WebRequest.Create(destinationUri); request.Method = "POST"; request.ContentType = Encoding.WebName; var bytes = receivedTransportMessage.Body; request.ContentLength = bytes.Length; var headers = receivedTransportMessage.Headers.ToDictionary(d => d.Key, d => d.Value); foreach (var header in headers) { request.Headers.Add(RebusHttpHeaders.CustomHeaderPrefix + header.Key, (string)header.Value); } request.Headers.Add(RebusHttpHeaders.Id, receivedTransportMessage.Id); using(var requestStream = request.GetRequestStream()) { requestStream.Write(bytes, 0, bytes.Length); } log.Info("Added headers to request: {0}", string.Join(", ", headers.Keys)); using (var response = (HttpWebResponse)request.GetResponse()) using (var reader = new StreamReader(response.GetResponseStream())) { log.Info("Message {0} was sent", receivedTransportMessage.Id); reader.ReadToEnd(); } }
public void SetUpReceive(ReceivedTransportMessage receivedTransportMessage) { MessageToReceive = receivedTransportMessage; }
public ReceivedTransportMessage ReceiveMessage(ITransactionContext context) { var receivedTransportMessage = MessageToReceive; MessageToReceive = null; return receivedTransportMessage; }
public void ItsSymmetric() { var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary<string, object> { {Guid.NewGuid().ToString(), Guid.NewGuid().ToString()} }, Body = Guid.NewGuid().ToByteArray(), }; transport.Send("test", toSend, new NoTransaction()); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
public void CanGenerateValidKey() { var key = RijndaelEncryptionTransportDecorator.GenerateKeyBase64(); var localInstance = new RijndaelEncryptionTransportDecorator(sender, receiver, key); var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary<string, object> { {Guid.NewGuid().ToString(), Guid.NewGuid().ToString()} }, Body = Guid.NewGuid().ToByteArray(), }; localInstance.Send("test", toSend, new NoTransaction()); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = localInstance.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
internal void RaisePoisonMessage(IAdvancedBus advancedBus, ReceivedTransportMessage transportMessage, PoisonMessageInfo poisonMessageInfo) { PoisonMessage(advancedBus, transportMessage, poisonMessageInfo); }
internal void RaiseAfterTransportMessage(IAdvancedBus advancedBus, Exception exception, ReceivedTransportMessage transportMessage) { AfterTransportMessage(advancedBus, exception, transportMessage); }
public ReceivedTransportMessage ReceiveMessage() { var receivedTransportMessage = MessageToReceive; MessageToReceive = null; return receivedTransportMessage; }
string ExtractContents(ReceivedTransportMessage receiveMessage) { return Encoding.UTF8.GetString(receiveMessage.Body); }
void HandlePoisonMessage(string id, ReceivedTransportMessage transportMessage) { var errorText = errorTracker.GetErrorText(id); log.Error("Handling message {0} has failed the maximum number of times - details: {1}", id, errorText); var poisonMessageInfo = errorTracker.GetPoisonMessageInfo(id); MessageFailedMaxNumberOfTimes(transportMessage, errorText); errorTracker.StopTracking(id); try { PoisonMessage(transportMessage, poisonMessageInfo); } catch (Exception exceptionWhileRaisingEvent) { log.Error("An exception occurred while raising the PoisonMessage event: {0}", exceptionWhileRaisingEvent); } }
ReceivedTransportMessage GetReceivedTransportMessage(IBasicProperties basicProperties, byte[] body) { var result = new ReceivedTransportMessage { Id = basicProperties != null ? basicProperties.MessageId ?? "(null)" : "(unknown)", Headers = basicProperties != null ? GetHeaders(basicProperties) : new Dictionary<string, object>(), Body = body, }; // As this is a recent change, I feel we should alert if a message arrives // with different transport-level and header-level IDs. (pruiz) if (result.Headers.ContainsKey(Headers.MessageId)) { var headerLevelId = result.Headers[Headers.MessageId]; if (!string.Equals(headerLevelId, result.Id)) { log.Warn("Mismatch between transport-level and header-level message's id. " + "This may indicate a software bug, or maybe due to processing of messages " + "generated by previous versions of Rebus. (TLID: {0} - HLID: {1})", result.Id, headerLevelId); } } return result; }
/// <summary> /// Receives a message from the logical queue specified as this instance's input queue. What actually /// happens, is that a row is read and locked in the messages table, whereafter it is deleted. /// </summary> public ReceivedTransportMessage ReceiveMessage(ITransactionContext context) { try { AssertNotInOneWayClientMode(); var connection = GetConnectionPossiblyFromContext(context); try { ReceivedTransportMessage receivedTransportMessage = null; using (var selectCommand = connection.Connection.CreateCommand()) { selectCommand.Transaction = connection.Transaction; // selectCommand.CommandText = // string.Format( // @" // ;with msg as ( // select top 1 [seq], [headers], [label], [body] // from [{0}] // with (updlock, readpast, rowlock) // where [recipient] = @recipient // order by [seq] asc // ) // delete msg // output deleted.seq, deleted.headers, deleted.body, deleted.label //", // messageTableName); selectCommand.CommandText = string.Format(@" select top 1 [seq], [headers], [label], [body], [priority] from [{0}] with (updlock, readpast, rowlock) where [recipient] = @recipient order by [priority] asc, [seq] asc ", messageTableName); // selectCommand.CommandText = // string.Format(@" //delete top(1) from [{0}] //output deleted.seq, deleted.headers, deleted.body, deleted.label //where [seq] = ( // select min([seq]) from [{0}] with (readpast, holdlock) where recipient = @recipient //) //", messageTableName); selectCommand.Parameters.Add("recipient", SqlDbType.NVarChar, 200) .Value = inputQueueName; var seq = 0L; var priority = -1; using (var reader = selectCommand.ExecuteReader()) { if (reader.Read()) { var headers = reader["headers"]; var label = reader["label"]; var body = reader["body"]; seq = (long) reader["seq"]; priority = (byte) reader["priority"]; var headersDictionary = DictionarySerializer.Deserialize((string) headers); var messageId = seq.ToString(CultureInfo.InvariantCulture); receivedTransportMessage = new ReceivedTransportMessage { Id = messageId, Label = (string) label, Headers = headersDictionary, Body = (byte[]) body, }; log.Debug("Received message with ID {0} from logical queue {1}.{2}", messageId, messageTableName, inputQueueName); } } if (receivedTransportMessage != null) { using (var deleteCommand = connection.Connection.CreateCommand()) { deleteCommand.Transaction = connection.Transaction; deleteCommand.CommandText = string.Format( "delete from [{0}] where [recipient] = @recipient and [priority] = @priority and [seq] = @seq", messageTableName); deleteCommand.Parameters.Add("recipient", SqlDbType.NVarChar, 200) .Value = inputQueueName; deleteCommand.Parameters.Add("seq", SqlDbType.BigInt, 8) .Value = seq; deleteCommand.Parameters.Add("priority", SqlDbType.TinyInt, 1) .Value = priority; var rowsAffected = deleteCommand.ExecuteNonQuery(); if (rowsAffected != 1) { throw new ApplicationException( string.Format( "Attempted to delete message with recipient = '{0}' and seq = {1}, but {2} rows were affected!", inputQueueName, seq, rowsAffected)); } } } } if (!context.IsTransactional) { commitAction(connection); } return receivedTransportMessage; } finally { if (!context.IsTransactional) { releaseConnection(connection); } } } catch (Exception exception) { // if we end up here, something bas has happened - no need to hurry, so we sleep Thread.Sleep(2000); throw new ApplicationException( string.Format("An error occurred while receiving message from {0}", inputQueueName), exception); } }
internal void RaiseAfterTransportMessage(IBus bus, Exception exception, ReceivedTransportMessage transportMessage) { AfterTransportMessage(bus, exception, transportMessage); }
internal void RaiseBeforeTransportMessage(IAdvancedBus advancedBus, ReceivedTransportMessage transportMessage) { BeforeTransportMessage(advancedBus, transportMessage); }
internal void RaiseBeforeTransportMessage(IBus bus, ReceivedTransportMessage transportMessage) { BeforeTransportMessage(bus, transportMessage); }