/// <summary> /// Constructs a group and stores it in this Message object /// </summary> /// <param name="grpNoFld"></param> /// <param name="msgstr"></param> /// <param name="pos"></param> /// <param name="fieldMap"></param> /// <param name="dd"></param> /// <param name="sessionDataDictionary"></param> /// <param name="appDD"></param> /// <param name="msgFactory">if this is null, then this method will use the generic Group class constructor</param> /// <returns></returns> protected int SetGroup(StringField grpNoFld, string msgstr, int pos, FieldMap fieldMap, DataDictionary.IGroupSpec dd, DataDictionary.DataDictionary sessionDataDictionary, DataDictionary.DataDictionary appDD, IMessageFactory msgFactory) { int delim = dd.Delim; int grpPos = pos; Group grp = null; while (pos < msgstr.Length) { grpPos = pos; StringField f = ExtractField(msgstr, ref pos, sessionDataDictionary, appDD); if (f.Tag == delim) { if (grp != null) { fieldMap.AddGroup(grp, false); } if (msgFactory != null) grp = msgFactory.Create(Message.ExtractBeginString(msgstr), Message.GetMsgType(msgstr), grpNoFld.Tag); //If above failed, just use a generic Group. if (grp == null) grp = new Group(grpNoFld.Tag, delim); } else if (!dd.IsField(f.Tag)) { if (grp != null) { fieldMap.AddGroup(grp, false); } return grpPos; } grp.SetField(f); if (dd.IsGroup(f.Tag)) { if (FixMessageDescriptorEnabled) { var oldCurrField = _currentGroupField; _currentGroupField = new GroupFixFieldInfo(); _currentGroupField.Tag = f.Tag; DataDictionary.DDField field = null; if (appDD != null && appDD.FieldsByTag.TryGetValue(f.Tag, out field)) { _currentGroupField.Name = field.Name; } else if (sessionDataDictionary != null && sessionDataDictionary.FieldsByTag.TryGetValue(f.Tag, out field)) { _currentGroupField.Name = field.Name; } _currentGroupField.Value = f.getValue(); _currentGroupField.EnumValue = GetEnumValueFromField(f, field); oldCurrField.Fields.Add(_currentGroupField); } pos = SetGroup(f, msgstr, pos, grp, dd.GetGroupSpec(f.Tag), sessionDataDictionary, appDD, msgFactory); } else { if (FixMessageDescriptorEnabled) { FixFieldInfo fi = new FixFieldInfo(); fi.Tag = f.Tag; DataDictionary.DDField field = null; if (appDD != null && appDD.FieldsByTag.TryGetValue(f.Tag, out field)) { _currentGroupField.Name = field.Name; } else if (sessionDataDictionary != null && sessionDataDictionary.FieldsByTag.TryGetValue(f.Tag, out field)) { _currentGroupField.Name = field.Name; } fi.Value = f.getValue(); fi.EnumValue = GetEnumValueFromField(f, field); _currentGroupField.Fields.Add(fi); } } } return grpPos; }
/// <summary> /// Constructs a group and stores it in this Message object /// </summary> /// <param name="grpNoFld">the group's counter field</param> /// <param name="msgstr">full message string</param> /// <param name="pos">starting character position of group</param> /// <param name="fieldMap">full message as FieldMap</param> /// <param name="dd">group definition structure from dd</param> /// <param name="sessionDataDictionary"></param> /// <param name="appDD"></param> /// <param name="msgFactory">if null, then this method will use the generic Group class constructor</param> /// <returns></returns> protected int SetGroup( StringField grpNoFld, string msgstr, int pos, FieldMap fieldMap, DataDictionary.IGroupSpec dd, DataDictionary.DataDictionary sessionDataDictionary, DataDictionary.DataDictionary appDD, IMessageFactory msgFactory) { int grpEntryDelimiterTag = dd.Delim; int grpPos = pos; Group grp = null; // the group entry being constructed while (pos < msgstr.Length) { grpPos = pos; StringField f = ExtractField(msgstr, ref pos, sessionDataDictionary, appDD); if (f.Tag == grpEntryDelimiterTag) { // This is the start of a group entry. if (grp != null) { // We were already building an entry, so the delimiter means it's done. fieldMap.AddGroup(grp, false); grp = null; // prepare for new Group } // Create a new group! if (msgFactory != null) grp = msgFactory.Create(Message.ExtractBeginString(msgstr), Message.GetMsgType(msgstr), grpNoFld.Tag); //If above failed (shouldn't ever happen), just use a generic Group. if (grp == null) grp = new Group(grpNoFld.Tag, grpEntryDelimiterTag); } else if (!dd.IsField(f.Tag)) { // This field is not in the group, thus the repeating group is done. if (grp != null) { fieldMap.AddGroup(grp, false); } return grpPos; } if (grp == null) { // This means we got into the group's fields without finding a delimiter tag. throw new GroupDelimiterTagException(grpNoFld.Tag, grpEntryDelimiterTag); } // f is just a field in our group entry. Add it and iterate again. grp.SetField(f); if(dd.IsGroup(f.Tag)) { // f is a counter for a nested group. Recurse! pos = SetGroup(f, msgstr, pos, grp, dd.GetGroupSpec(f.Tag), sessionDataDictionary, appDD, msgFactory); } } return grpPos; }
/// <summary> /// Constructs a group and stores it in this Message object /// </summary> /// <param name="grpNoFld">the group's counter field</param> /// <param name="msgstr">full message string</param> /// <param name="pos">starting character position of group</param> /// <param name="fieldMap">full message as FieldMap</param> /// <param name="dd">group definition structure from dd</param> /// <param name="sessionDataDictionary"></param> /// <param name="appDD"></param> /// <param name="msgFactory">if null, then this method will use the generic Group class constructor</param> /// <returns></returns> protected int SetGroup( StringField grpNoFld, string msgstr, int pos, FieldMap fieldMap, DataDictionary.IGroupSpec dd, DataDictionary.DataDictionary sessionDataDictionary, DataDictionary.DataDictionary appDD, IMessageFactory msgFactory) { int grpEntryDelimiterTag = dd.Delim; int grpPos = pos; Group grp = null; // the group entry being constructed while (pos < msgstr.Length) { grpPos = pos; StringField f = ExtractField(msgstr, ref pos, sessionDataDictionary, appDD); if (f.Tag == grpEntryDelimiterTag) { // This is the start of a group entry. if (grp != null) { // We were already building an entry, so the delimiter means it's done. fieldMap.AddGroup(grp, false); grp = null; // prepare for new Group } // Create a new group! if (msgFactory != null) { grp = msgFactory.Create(Message.ExtractBeginString(msgstr), Message.GetMsgType(msgstr), grpNoFld.Tag); } //If above failed (shouldn't ever happen), just use a generic Group. if (grp == null) { grp = new Group(grpNoFld.Tag, grpEntryDelimiterTag); } } else if (!dd.IsField(f.Tag)) { // This field is not in the group, thus the repeating group is done. if (grp != null) { fieldMap.AddGroup(grp, false); } return(grpPos); } if (grp == null) { // This means we got into the group's fields without finding a delimiter tag. throw new GroupDelimiterTagException(grpNoFld.Tag, grpEntryDelimiterTag); } // f is just a field in our group entry. Add it and iterate again. grp.SetField(f); if (dd.IsGroup(f.Tag)) { // f is a counter for a nested group. Recurse! pos = SetGroup(f, msgstr, pos, grp, dd.GetGroupSpec(f.Tag), sessionDataDictionary, appDD, msgFactory); } } return(grpPos); }
/// <summary> /// Constructs a group and stores it in this Message object /// </summary> /// <param name="grpNoFld"></param> /// <param name="msgstr"></param> /// <param name="pos"></param> /// <param name="fieldMap"></param> /// <param name="dd"></param> /// <param name="sessionDataDictionary"></param> /// <param name="appDD"></param> /// <param name="msgFactory">if this is null, then this method will use the generic Group class constructor</param> /// <returns></returns> protected int SetGroup(StringField grpNoFld, string msgstr, int pos, FieldMap fieldMap, DataDictionary.IGroupSpec dd, DataDictionary.DataDictionary sessionDataDictionary, DataDictionary.DataDictionary appDD, IMessageFactory msgFactory) { int delim = dd.Delim; int grpPos = pos; Group grp = null; while (pos < msgstr.Length) { grpPos = pos; StringField f = ExtractField(msgstr, ref pos, sessionDataDictionary, appDD); if (f.Tag == delim) { if (grp != null) { fieldMap.AddGroup(grp, false); } if (msgFactory != null) grp = msgFactory.Create(Message.ExtractBeginString(msgstr), Message.GetMsgType(msgstr), grpNoFld.Tag); //If above failed, just use a generic Group. if (grp == null) grp = new Group(grpNoFld.Tag, delim); } else if (!dd.IsField(f.Tag)) { if (grp != null) { fieldMap.AddGroup(grp, false); } return grpPos; } grp.SetField(f); if(dd.IsGroup(f.Tag)) { pos = SetGroup(f, msgstr, pos, grp, dd.GetGroupSpec(f.Tag), sessionDataDictionary, appDD, msgFactory); } } return grpPos; }
public MessageViewModel CreateMessage(IMessageDelegate delegato, Message message) { return(_messageFactory.Create(delegato, message)); }
/// <inheritdoc /> public RedisMessage Handle(ReceiveMessageQuery query) { byte[] message = null; byte[] headers = null; string messageId; var poisonMessage = false; RedisQueueCorrelationIdSerialized correlationId = null; try { var unixTimestamp = _unixTimeFactory.Create().GetCurrentUnixTimestampMilliseconds(); RedisValue[] result = _dequeueLua.Execute(unixTimestamp); if (result == null || result.Length == 1 && !result[0].HasValue || !result[0].HasValue) { return(null); } if (!result[1].HasValue) { //at this point, the record has been de-queued, but it can't be processed. poisonMessage = true; } messageId = result[0]; var id = new RedisQueueId(messageId); query.MessageContext.SetMessageAndHeaders(id, null); if (!poisonMessage) { message = result[1]; headers = result[2]; if (result[3].HasValue) { if (result[3].TryParse(out long messageExpiration)) { if (messageExpiration - unixTimestamp < 0) { //message has expired var allHeaders = _serializer.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(headers); query.MessageContext.SetMessageAndHeaders(id, new ReadOnlyDictionary <string, object>(allHeaders)); _removeMessage.Remove(query.MessageContext, RemoveMessageReason.Expired); return(new RedisMessage(messageId, null, true)); } } } } } catch (Exception error) { throw new ReceiveMessageException("Failed to dequeue a message", error); } if (poisonMessage) { //at this point, the record has been de-queued, but it can't be processed. throw new PoisonMessageException( "An error has occurred trying to re-assemble a message de-queued from Redis; a messageId was returned, but the LUA script returned a null message. The message payload has most likely been lost.", null, new RedisQueueId(messageId), new RedisQueueCorrelationId(Guid.Empty), null, null); } try { var allHeaders = _serializer.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(headers); correlationId = (RedisQueueCorrelationIdSerialized)allHeaders[_redisHeaders.CorrelationId.Name]; var messageGraph = (MessageInterceptorsGraph)allHeaders[_redisHeaders.Headers.StandardHeaders.MessageInterceptorGraph.Name]; var messageData = _serializer.Serializer.BytesToMessage <MessageBody>(message, messageGraph, allHeaders); var newMessage = _messageFactory.Create(messageData.Body, allHeaders); query.MessageContext.SetMessageAndHeaders(query.MessageContext.MessageId, new ReadOnlyDictionary <string, object>(allHeaders)); return(new RedisMessage( messageId, _receivedMessageFactory.Create( newMessage, new RedisQueueId(messageId), new RedisQueueCorrelationId(correlationId.Id)), false)); } catch (Exception error) { //at this point, the record has been de-queued, but it can't be processed. throw new PoisonMessageException( "An error has occurred trying to re-assemble a message de-queued from redis", error, new RedisQueueId(messageId), new RedisQueueCorrelationId(correlationId), message, headers); } }
public async Task Run([ServiceBusTrigger("message", Connection = "ServiceBus")] Message mySbMsg, ILogger log) { LogDetails logDetails = new LogDetails() { Queue = "Message" }; logDetails.Started = DateTime.Now; logDetails.MessageId = mySbMsg.MessageId; logDetails.DeliveryCount = mySbMsg.SystemProperties.DeliveryCount; SendMessageRequest sendMessageRequest = null; bool emailAlreadySent = await _cosmosDbService.EmailSent(mySbMsg.MessageId); if (emailAlreadySent) { logDetails.Status = "email already sent"; } else { try { string converted = Encoding.UTF8.GetString(mySbMsg.Body, 0, mySbMsg.Body.Length); sendMessageRequest = JsonConvert.DeserializeObject <SendMessageRequest>(converted); logDetails.Job = Enum.GetName(typeof(CommunicationJobTypes), sendMessageRequest.CommunicationJobType); logDetails.RecipientUserId = sendMessageRequest.RecipientUserID; IMessage message = _messageFactory.Create(sendMessageRequest); EmailBuildData emailBuildData = await message.PrepareTemplateData(sendMessageRequest.BatchID, sendMessageRequest.RecipientUserID, sendMessageRequest.JobID, sendMessageRequest.GroupID, sendMessageRequest.RequestID, sendMessageRequest.AdditionalParameters, sendMessageRequest.TemplateName); if (emailBuildData != null) { emailBuildData.JobID = emailBuildData.JobID.HasValue ? emailBuildData.JobID : sendMessageRequest.JobID; emailBuildData.GroupID = emailBuildData.GroupID.HasValue ? emailBuildData.GroupID : sendMessageRequest.GroupID; emailBuildData.RecipientUserID = sendMessageRequest.RecipientUserID; emailBuildData.RequestID = emailBuildData.RequestID.HasValue ? emailBuildData.RequestID : sendMessageRequest.RequestID; var result = await _connectSendGridService.SendDynamicEmail(mySbMsg.MessageId, sendMessageRequest.TemplateName, message.GetUnsubscriptionGroupName(sendMessageRequest.RecipientUserID), emailBuildData); logDetails.Status = $"SendDynamicEmail: {result}"; } else { logDetails.Status = "no emailBuildData"; } } catch (AggregateException exc) { RetryHandler(mySbMsg, sendMessageRequest, exc.InnerException, log); } catch (Exception ex) { log.LogInformation($"Calling retry handler..."); // Manage retries using our message retry handler RetryHandler(mySbMsg, sendMessageRequest, ex, log); } } logDetails.Finished = DateTime.Now; string json = JsonConvert.SerializeObject(logDetails); log.LogInformation(json); }
/// <summary> /// Creates an empty message /// </summary> /// <param name="opCode"></param> /// <returns></returns> public static IMessage Create(short opCode) { return(_factory.Create(opCode)); }
internal IReceivedMessageInternal HandleMessage(IDbConnection connection, IDbTransaction transaction, IDataReader reader, CommandString commandString) { if (!reader.Read()) { return(null); } //load up the message from the DB long id = 0; var correlationId = Guid.Empty; byte[] headerPayload = null; byte[] messagePayload = null; try { id = (long)reader["QueueID"]; var cId = (string)reader["CorrelationID"]; headerPayload = (byte[])reader["Headers"]; messagePayload = (byte[])reader["Body"]; //before we continue, run the commands and commit the transaction //otherwise, poison messages will conflict foreach (var additionalCommand in commandString.AdditionalCommands) { using (var command = connection.CreateCommand()) { command.Transaction = transaction; command.CommandText = additionalCommand; command.ExecuteNonQuery(); } } transaction.Commit(); correlationId = new Guid(cId); var headers = _serialization.InternalSerializer .ConvertBytesTo <IDictionary <string, object> >( headerPayload); var messageGraph = (MessageInterceptorsGraph) headers[_headers.StandardHeaders.MessageInterceptorGraph.Name]; var message = _serialization.Serializer.BytesToMessage <MessageBody>( messagePayload, messageGraph, headers).Body; var newMessage = _messageFactory.Create(message, headers); return(_receivedMessageFactory.Create(newMessage, new MessageQueueId <long>(id), new MessageCorrelationId <Guid>(correlationId))); } catch (Exception err) { //at this point, the record has been de-queued, but it can't be processed. throw new PoisonMessageException( "An error has occurred trying to re-assemble a message de-queued from SQLite", err, new MessageQueueId <long>(id), new MessageCorrelationId <Guid>(correlationId), messagePayload, headerPayload); } }
public virtual void Cancel() { _eventAggregator.PublishOnUIThreadAsync(_messageFactory.Create(typeof(DeviceSelectedMessage))); }
/// <inheritdoc /> public IReceivedMessageInternal Handle(ReceiveMessageQuery <NpgsqlConnection, NpgsqlTransaction> query) { using (var selectCommand = query.Connection.CreateCommand()) { selectCommand.Transaction = query.Transaction; if (query.MessageId != null && query.MessageId.HasValue) { selectCommand.CommandText = ReceiveMessage.GetDeQueueCommand(_commandCache, _tableNameHelper, _options.Value, true, query.Routes); selectCommand.Parameters.Add("@QueueID", NpgsqlDbType.Bigint); selectCommand.Parameters["@QueueID"].Value = query.MessageId.Id.Value; } else { selectCommand.CommandText = ReceiveMessage.GetDeQueueCommand(_commandCache, _tableNameHelper, _options.Value, false, query.Routes); } selectCommand.Parameters.Add("@CurrentDate", NpgsqlDbType.Bigint); selectCommand.Parameters["@CurrentDate"].Value = _getTime.GetCurrentUtcDate().Ticks; if (_options.Value.EnableRoute && query.Routes != null && query.Routes.Count > 0) { var routeCounter = 1; foreach (var route in query.Routes) { selectCommand.Parameters.Add("@Route" + routeCounter, NpgsqlDbType.Varchar); selectCommand.Parameters["@Route" + routeCounter].Value = route; routeCounter++; } } using (var reader = selectCommand.ExecuteReader()) { if (!reader.Read()) { return(null); } //load up the message from the DB long id = 0; var correlationId = Guid.Empty; byte[] headerPayload = null; byte[] messagePayload = null; try { id = (long)reader["queueid"]; correlationId = (Guid)reader["CorrelationID"]; headerPayload = (byte[])reader["Headers"]; messagePayload = (byte[])reader["body"]; var headers = _serialization.InternalSerializer.ConvertBytesTo <IDictionary <string, object> >(headerPayload); var messageGraph = (MessageInterceptorsGraph)headers[_headers.StandardHeaders.MessageInterceptorGraph.Name]; var message = _serialization.Serializer.BytesToMessage <MessageBody>(messagePayload, messageGraph).Body; var newMessage = _messageFactory.Create(message, headers); return(_receivedMessageFactory.Create(newMessage, new MessageQueueId(id), new MessageCorrelationId(correlationId))); } catch (Exception error) { //at this point, the record has been de-queued, but it can't be processed. throw new PoisonMessageException( "An error has occurred trying to re-assemble a message de-queued from the server ", error, new MessageQueueId(id), new MessageCorrelationId(correlationId), messagePayload, headerPayload); } } } }
public async ValueTask <IMessage <TMessage> > Receive(CancellationToken cancellationToken) { using (await _lock.Lock(cancellationToken).ConfigureAwait(false)) { while (true) { if (_sendWhenZero == 0) { await SendFlow(cancellationToken).ConfigureAwait(false); } _sendWhenZero--; var message = _batchHandler.GetNext(); if (message is not null) { return(message); } var messagePackage = await _queue.Dequeue(cancellationToken).ConfigureAwait(false); if (!messagePackage.ValidateMagicNumberAndChecksum()) { await RejectPackage(messagePackage, CommandAck.ValidationErrorType.ChecksumMismatch, cancellationToken).ConfigureAwait(false); continue; } var metadataSize = messagePackage.GetMetadataSize(); var metadata = messagePackage.ExtractMetadata(metadataSize); var data = messagePackage.ExtractData(metadataSize); if (metadata.Compression != CompressionType.None) { var decompressor = _decompressors[(int)metadata.Compression]; if (decompressor is null) { throw new CompressionException($"Support for {metadata.Compression} compression was not found"); } try { data = decompressor.Decompress(data, (int)metadata.UncompressedSize); } catch { await RejectPackage(messagePackage, CommandAck.ValidationErrorType.DecompressionError, cancellationToken).ConfigureAwait(false); continue; } } var messageId = messagePackage.MessageId; var redeliveryCount = messagePackage.RedeliveryCount; if (metadata.ShouldSerializeNumMessagesInBatch()) { try { return(_batchHandler.Add(messageId, redeliveryCount, metadata, data)); } catch { await RejectPackage(messagePackage, CommandAck.ValidationErrorType.BatchDeSerializeError, cancellationToken).ConfigureAwait(false); continue; } } return(_messageFactory.Create(messageId.ToMessageId(), redeliveryCount, data, metadata)); } } }
/// <inheritdoc /> public IReceivedMessageInternal GetNextMessage(List <string> routes, TimeSpan timeout) { if (_complete) { return(null); } if (routes != null && routes.Count > 0) { throw new NotSupportedException("The in-memory transport does not support routes"); } using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_cancelToken.CancelWorkToken, _cancelToken.StopWorkToken)) { Guid id = Guid.Empty; try { if (!Queues[_connectionInformation].TryTake(out id, Convert.ToInt32(timeout.TotalMilliseconds), linkedCts.Token)) { return(null); } } catch (OperationCanceledException) { return(null); } if (!QueueData[_connectionInformation].TryRemove(id, out var item)) { return(null); } var hasError = false; try { var newMessage = _messageFactory.Create(item.Body, item.Headers); if (!string.IsNullOrEmpty(item.JobName)) { var key = GenerateKey(item.JobName); //add it to the cache JobLastEventCache.Execute(context => item.JobEventTime, new Context(key)); } Interlocked.Increment(ref DequeueCounts[_connectionInformation].ProcessedCount); return(_receivedMessageFactory.Create(newMessage, new MessageQueueId(id), new MessageCorrelationId(item.CorrelationId))); } catch (Exception error) { hasError = true; //at this point, the record has been de-queued, but it can't be processed. throw new PoisonMessageException( "An error has occurred trying to re-assemble a message", error, new MessageQueueId(id), null, null, null); } finally { if (!hasError) { QueueWorking[_connectionInformation].TryAdd(item.Id, item); } } } }