/// <summary> /// Sends a message /// </summary> /// <param name="message"></param> /// <param name="queueName"></param> /// <param name="applicationId"></param> /// <param name="basicProperties"></param> /// <returns>Null on success or the text of an error message</returns> public string Send(IRawMessage message, string queueName, string applicationId, IBasicProperties basicProperties) { Verify.RequireNotNull(message, "message"); Verify.RequireStringNotNullOrWhitespace(queueName, "queueName"); Verify.RequireStringNotNullOrWhitespace(applicationId, "applicationId"); try { var application = settings.Applications.FirstOrDefault(x => x.ApplicationId == applicationId); if (application == null) { return(string.Format("Could not find configuration for application id {0}", applicationId)); } using ( var connection = rabbitConnectionFactory.Create(application.RabbitConnectionString).CreateConnection()) { using (var channel = connection.CreateModel()) { var sendData = message.GetEelementsForRabbitPublish(); basicProperties.Headers = sendData.Item2; channel.BasicPublish(queueName, "", basicProperties, sendData.Item1); return(null); } } } catch (Exception err) { logger.ErrorException("Failed to send message for retry", err); return(string.Format("Failed to send message for retry. Error is {0}. See error log for details", err.Message)); } }
/// <summary> /// Creates and populates a new Message from and IRawMessage /// </summary> /// <param name="rawMessage">Received message</param> /// <returns></returns> public IMessage Create(IRawMessage rawMessage) => new Message() { Payload = rawMessage.Payload, ID = Guid.NewGuid(), TimestampReceived = DateTimeOffset.Now };
private static void CaptureHeaders(IRawMessage rawMessage, MessageDocument document) { foreach (var header in rawMessage.Headers) { document.Headers.Add(header.Key, header.Value); } }
public long Store(IRawMessage message, IQueueSettings queueSettings) { var retry = new MessageDocument { ApplicationId = queueSettings.ApplicationId }; headerParser.AddHeaderInformation(message, retry); retry.Body = message.Body; var expiry = DateTime.UtcNow.AddHours(retry.IsError ? queueSettings.ErrorDocumentExpirationInHours : queueSettings.DocumentExpirationInHours); long originalId = -1; long.TryParse(message.Headers[Headers.Retry], out originalId); long documentIdToReturn = -1; //deal with rare transients that happen under load var policy = Policy.Handle <Exception>().WaitAndRetry(new TimeSpan[] { TimeSpan.FromMilliseconds(5), TimeSpan.FromMilliseconds(10) }, (exception, retryDelay, context) => { logger.ErrorException($"Retrying storage of message document with delay {retryDelay} after exception", exception); }); policy.Execute(() => { documentIdToReturn = SaveDocument(queueSettings, originalId, retry, expiry); }); return(documentIdToReturn); }
public static IMessageState Resolve(IRawMessage rawMessage) { IMessage ircMessage = new ProtocolMessage(rawMessage); string commandWord = ircMessage.CommandWord.ToUpperInvariant(); return new MessageState(MessageHandlerFactory.messageHandlers[commandWord], ircMessage); }
public void AddHeaderInformation(IRawMessage rawMessage, MessageDocument document) { Verify.RequireNotNull(rawMessage, "rawMessage"); Verify.RequireNotNull(document, "document"); CaptureHeaders(rawMessage, document); CaptureMessageTypes(document); CaptureSagaInfo(document); CaptureTimeSent(document); CaptureContentType(document); CaptureProcessingTime(document); CaptureIsError(document); if (document.IsError) { if (document.Headers.ContainsKey(Headers.TimeOfFailure) && document.Headers.ContainsKey(Headers.TimeSent)) { document.TotalTime = Helpers.ToUniversalDateTime(document.Headers[Headers.TimeOfFailure]) - Helpers.ToUniversalDateTime(document.Headers[Headers.TimeSent]); } } else { if (document.Headers.ContainsKey(Headers.ProcessingEnded) && document.Headers.ContainsKey(Headers.TimeSent)) { document.TotalTime = Helpers.ToUniversalDateTime(document.Headers[Headers.ProcessingEnded]) - Helpers.ToUniversalDateTime(document.Headers[Headers.TimeSent]); } } }
public void Setup() { _rawMessage = new RawMessage() { Content = _content, CreatedAt = _createdAt, Categories = _categories }; }
private static void RemoveDiagnosticHeaders(IRawMessage rawMessage) { var keysToRemove = rawMessage.Headers.Where(x => x.Key.StartsWith("$.diagnostics")).Select(x => x.Key).ToList(); foreach (var key in keysToRemove) { rawMessage.Headers.Remove(key); } }
/// <summary> /// Creates a Message from a given rawMessage and publishing time. /// </summary> /// <param name="rawMessage"> /// The raw message to construct the message from. /// </param> /// <param name="publishTime">The time of publishing</param> public Message(IRawMessage rawMessage, DateTime publishTime) { if (publishTime < rawMessage.CreatedAt) { throw new ArgumentException("publishTime must not be older than the time of creating the message.", "publishTime"); } _content = rawMessage.Content; _created = rawMessage.CreatedAt; _published = publishTime; }
private static void RemoveTimeoutHeaders(IRawMessage rawMessage) { var keysToRemove = rawMessage.Headers.Where(x => x.Key.StartsWith("NServiceBus.Timeout")).Select(x => x.Key).ToList(); foreach (var key in keysToRemove) { rawMessage.Headers.Remove(key); } }
public void PrepareMessageForRetry(IRawMessage rawMessage) { Verify.RequireNotNull(rawMessage, "rawMessage"); RemoveDiagnosticHeaders(rawMessage); RemoveExceptionHeaders(rawMessage); RemoveTimeoutHeaders(rawMessage); RemoveRetryHeaders(rawMessage); RemoveProcessingHeaders(rawMessage); SetTimeSent(rawMessage); }
private string GetHeaderValueIfExists(IRawMessage rawMessage, string key) { string val = null; if (rawMessage.Headers.ContainsKey(key)) { val = rawMessage.Headers[key]; } return(val); }
public IBasicProperties Create(IRawMessage rawMessage) { var basicProperties = new BasicProperties(); basicProperties.ContentType = GetHeaderValueIfExists(rawMessage, "NServiceBus.ContentType"); basicProperties.MessageId = GetHeaderValueIfExists(rawMessage, "NServiceBus.MessageId"); basicProperties.CorrelationId = GetHeaderValueIfExists(rawMessage, "NServiceBus.CorrelationId"); SetTypeIfHeaderExists(rawMessage, basicProperties); basicProperties.DeliveryMode = persistentDelivery; return(basicProperties); }
public void Handle(IRawMessage rawMessage) { try { _rawMessageHandler.Handle(rawMessage); } catch (Exception ex) { var encodedMessage = Convert.ToBase64String(rawMessage.Payload); var format = "Failed to process message: {message}"; _logger.LogError(0, ex, format, encodedMessage); } }
private string GetRawMessage(SlackSocketMessage message) { IRawMessage rawMessage = message as IRawMessage; if (rawMessage == null) { throw new InvalidCastException($"'{message.GetType().FullName}' is not a proxy class and cannot be casted to IRawMessage"); } else { return(rawMessage.Data); } }
public IStoreMessages MessageStorageServiceFor(IRawMessage message) { if (message.Headers.ContainsKey(Headers.Retry)) { return (ServiceLocator.Container.Resolve <IStoreMessages>( typeof(StoreMessagesThatAreRetriesService).ToString())); } return (ServiceLocator.Container.Resolve <IStoreMessages>( typeof(StoreMessagesThatAreNotRetriesService).ToString())); }
private void SetTypeIfHeaderExists(IRawMessage rawMessage, BasicProperties basicProperties) { string types = GetHeaderValueIfExists(rawMessage, "NServiceBus.EnclosedMessageTypes"); if (types != null) { var typeList = types.Split(';').Select(pt => { return(new TypeName(pt)); }).ToList(); if (typeList.Count > 0) { basicProperties.Type = string.Format("{0}.{1}", typeList[0].Namespace, typeList[0].ClassName); } } }
public void Handle(IRawMessage rawMessage) { if (rawMessage == null) { throw new ArgumentNullException(nameof(rawMessage)); } if (rawMessage.Payload == null) { throw new ArgumentException("Message Payload must be provided", nameof(rawMessage)); } var message = _syslogMessageParser.Parse(rawMessage.Payload); _syslogMessageHandler.Handle(message); }
public string GetRetryDestination(IRawMessage rawMessage, string userSuppliedRetryDestination) { Verify.RequireNotNull(rawMessage, "rawMessage"); if (!string.IsNullOrWhiteSpace(userSuppliedRetryDestination)) { return(userSuppliedRetryDestination); } if (rawMessage.Headers.ContainsKey("NServiceBus.FailedQ")) { var failedQ = rawMessage.Headers["NServiceBus.FailedQ"]; return(failedQ.Split('@')[0]); } return(null); }
private static void RemoveProcessingHeaders(IRawMessage rawMessage) { var keysToRemove = rawMessage.Headers.Select(x => x.Key) .Intersect(new[] { "NServiceBus.ProcessingStarted", "NServiceBus.ProcessingEnded", "NServiceBus.ProcessingEndpoint", "NServiceBus.ProcessingMachine" }).ToList(); foreach (var key in keysToRemove) { rawMessage.Headers.Remove(key); } }
public void ReadReceivedMessageSimple() { // prepare test messate string payloadStr = "{\"TEST\":123456789}"; byte[] msgBytes = TcpServiceCom.CreateMessage(Interface.Communication.Raw.RawMessageFormat.JSON, payloadStr); RawMessage sharedMsg = new RawMessage(Interface.Communication.Raw.RawMessageFormat.JSON, new byte[20], 0, 0); IRawMessage pendingMsg = null; int startIndex = 0; TcpServiceCom serviceCommTest = new TcpServiceCom(); IRawMessage resultMsg = serviceCommTest.ReadRawMessage(msgBytes, ref startIndex, msgBytes.Length, sharedMsg, ref pendingMsg); Assert.NotNull(resultMsg); string resultPayloadStr = Encoding.UTF8.GetString(resultMsg.Data, 0, resultMsg.Length); Assert.Equal(payloadStr, resultPayloadStr); }
public IMessage Parse(IRawMessage source) { if (!(source is MockRawMessage)) { throw new ApplicationException("MockSourceText only knows how to deal with MockSourceText"); } // mockRawMessage saves you the trouble of parsing because - hey! its already parsed! MockRawMessage mockRaw = (MockRawMessage) source; OfferMessage msg = new OfferMessage(); msg.CreatedBy = mockRaw.CreatedBy; msg.Location = mockRaw.Location; msg.MoreInfoURL = mockRaw.MoreInfoURL; msg.CreatedBy = mockRaw.CreatedBy; msg.MessageText = mockRaw.OfferText; if (mockRaw.EndBy.HasValue) { msg.SetEndBy(mockRaw.EndByText, mockRaw.EndBy.Value); } else { msg.ClearEndBy(); } foreach (ITag tag in mockRaw.Tags) { msg.AddTag(tag); } //if (CONVERT_MOCK_TO_REAL) //{ // RawMessage realRawMessage = new RawMessage(source.Text, source.Pointer, source.CreatedBy, source.Timestamp); // msg.Source = realRawMessage; //} //FIXME1 this all has to go - don't keep the source around! //msg.Source = mockRaw; msg.RawText = mockRaw.Text; msg.Timestamp = mockRaw.Timestamp; msg.MessagePointer = mockRaw.Pointer; return msg; }
private static void ProcessReceivedMessageOverlappingTcpFrameHandling(int restLength) { // prepare test messate string payloadStr = "{\"TEST\":123456789}"; byte[] msgBytes = TcpServiceCom.CreateMessage(Interface.Communication.Raw.RawMessageFormat.JSON, payloadStr); // separate in parts int firstPartLength = msgBytes.Length - restLength; byte[] firstPart = new byte[firstPartLength]; Array.Copy(msgBytes, 0, firstPart, 0, firstPartLength); int secondPartLength = msgBytes.Length - firstPartLength; byte[] secondPart = new byte[secondPartLength]; Array.Copy(msgBytes, firstPartLength, secondPart, 0, secondPartLength); RawMessage sharedMsg = new RawMessage(Interface.Communication.Raw.RawMessageFormat.IncompleteControlDataSlice, null, 0, 0); IRawMessage pendingMsg = null; int startIndex = 0; TcpServiceCom serviceCommTest = new TcpServiceCom(); IRawMessage resultMsg = serviceCommTest.ReadRawMessage(firstPart, ref startIndex, firstPart.Length, sharedMsg, ref pendingMsg); // 1. expect only pending Assert.Null(resultMsg); Assert.NotNull(pendingMsg); // 2. read rest and expect result msg startIndex = 0; // reset read index resultMsg = serviceCommTest.ReadRawMessage(secondPart, ref startIndex, secondPart.Length, sharedMsg, ref pendingMsg); Assert.NotNull(resultMsg); string resultPayloadStr = Encoding.UTF8.GetString(resultMsg.Data, 0, resultMsg.Length); Assert.Equal(payloadStr, resultPayloadStr); }
private static void RemoveRetryHeaders(IRawMessage rawMessage) { var keysToRemove = rawMessage.Headers.Where(x => x.Key.StartsWith("NServiceBus.Retries")).Select(x => x.Key).ToList(); foreach (var key in keysToRemove) { rawMessage.Headers.Remove(key); } keysToRemove = rawMessage.Headers.Select(x => x.Key) .Intersect(new[] { "NServiceBus.FLRetries", "NServiceBus.FailedQ", "NServiceBus.TimeOfFailure" }) .ToList(); foreach (var key in keysToRemove) { rawMessage.Headers.Remove(key); } }
/// <summary> /// Creates a Message from a given rawMessage, setting the /// <see cref="Published"/> property to the actual time. /// </summary> /// <param name="rawMessage"> /// The raw message to construct the message from. /// </param> public Message(IRawMessage rawMessage) : this(rawMessage,DateTime.Now) { }
private async Task SendToQueue(IRawMessage message) { IMessagePublisher publisher = new AzureServiceBusPublisher(); await publisher.Publish(message); }
public ProtocolMessage(IRawMessage rawMessage) { this.Text = rawMessage.Text; this.Direction = rawMessage.Direction; }
public static void NotifyRawMessage(IRawMessage message) { Kernel.Get<IRawMessageReceiver>().Notify(message); }
public void Notify(IRawMessage updatedMessage) { // pass to above method Notify(new[] { updatedMessage }); }
public IMessage Parse(IRawMessage rawMessage) { string sourceText = rawMessage.Text; IEnumerable<ITag> tags = ParseTags(sourceText, rawMessage); BaseMarketMessage msg; switch (GetMessageType(sourceText, tags)) { case MessageType.need: case MessageType.needed: case MessageType.want: case MessageType.wanted: msg = new WantedMessage(); break; case MessageType.offer: case MessageType.available: default: msg = new OfferMessage(); break; } msg.CreatedBy = rawMessage.CreatedBy; msg.Timestamp = rawMessage.Timestamp; msg.MessagePointer = rawMessage.Pointer; msg.RawText = rawMessage.Text; bool containsGroup = false; foreach (ITag tag in tags) { if (tag.Type == TagType.msg_type) continue; //skip tags of this Type if(tag.Type==TagType.group) containsGroup = true; msg.AddTag(tag); } if (!containsGroup) { ITag possibleGroup = CheckForAtSymbolGroup(sourceText); if(possibleGroup != null) { //remove the @chchneeds tag from the messages sourceText=sourceText.Replace("@" + possibleGroup.Text, ""); msg.AddTag(possibleGroup); } } if (msg.HasValidTags()) { // for efficiency don't even both trying to parse the google address // unless it at least has some valid tags ILocation location = ParseLocation(sourceText); if (location != null) { msg.Location = location; foreach (ITag s in location.Tags) { msg.AddTag(s); } } } msg.MessageText = sourceText; msg.MoreInfoURL = GetMoreInfoUrl(sourceText); string untilText; DateTime until; if (ParseUntil(sourceText, out untilText, out until)) { msg.SetEndBy(untilText, until); } msg.AddThumbnail(GetImageUrl(sourceText)); return msg; }
public bool Validate(IRawMessage rawMessage) => !string.IsNullOrWhiteSpace(rawMessage.Payload);
void Send(IRawMessage message);
/// <summary> /// Called when [raw message received]. /// </summary> /// <param name="rawMessage">The raw message.</param> public async ValueTask OnRawMessageReceived(IRawMessage rawMessage) { var tuple = new Tuple <int, byte[]>(rawMessage.SessionId, rawMessage.Data); await receiverQueue.Writer.WriteAsync(tuple); }
/// <summary> /// Reads the raw message. /// </summary> /// <param name="source">The source.</param> /// <param name="startIndex">The start index.</param> /// <param name="length">The length.</param> /// <param name="unusedSharedMessage">The unused shared message.</param> /// <param name="pendingMessage">The pending message.</param> /// <returns></returns> public IRawMessage ReadRawMessage(byte[] source, ref int startIndex, int length, IRawMessage unusedSharedMessage, ref IRawMessage pendingMessage) { try { if (pendingMessage != null) { if (pendingMessage.MessageFormat == RawMessageFormat.IncompleteControlDataSlice) { if (startIndex == 0) { // put separated control bytes in front int startPartLength = pendingMessage.Length; int targetLength = startPartLength + length; byte[] targetData = new byte[targetLength]; pendingMessage.Data.CopyTo(targetData, 0); Array.Copy(source, startIndex, targetData, startPartLength, length); if (targetLength > StartMessageControlMinByteCount) { try { pendingMessage = null; return(ReadRawMessage(targetData, ref startIndex, targetLength, unusedSharedMessage, ref pendingMessage)); } finally { // reset start index to fit previous buffer startIndex -= startPartLength; } } } else { // not expected -> corrupt data Logger.Error(string.Format("Invalid raw data received! Expected start index = 0; actual: {0}", startIndex)); } } else { // append message data int expectedRestBytes = pendingMessage.Data.Length - pendingMessage.Length; expectedRestBytes = Math.Min(expectedRestBytes, length); Array.Copy(source, startIndex, pendingMessage.Data, pendingMessage.Length, expectedRestBytes); pendingMessage.Length += expectedRestBytes; startIndex += expectedRestBytes; if (pendingMessage.Data.Length == pendingMessage.Length) { // message data completed var msg = pendingMessage; pendingMessage = null; // check data border byte if (source[startIndex] != DataBorderControlByte) { ThrowDataEndMarkException("Append", source, startIndex, msg.Length); } return(msg); } } } else { int oldStartIndex = startIndex; int index = startIndex; if (index < length && (source[index] == StartMessageIdentifier1 || (index = Array.IndexOf(source, StartMessageIdentifier1, index)) >= 0)) { if (index + StartMessageControlMinByteCount < length && source[index + 1] == StartMessageIdentifier[1] && source[index + 2] == StartMessageIdentifier[2]) { // message start index += 3; short messageFormatShort = BitConverter.ToInt16(source, index); RawMessageFormat msgFormat = (RawMessageFormat)messageFormatShort; index += 2; int dataLength = BitConverter.ToInt32(source, index); byte[] data = new byte[dataLength]; index += 5; int sourceDataLength = length - index; sourceDataLength = Math.Min(sourceDataLength, dataLength); Array.Copy(source, index, data, 0, sourceDataLength); index += sourceDataLength; startIndex = index; if (dataLength > sourceDataLength || length == index) // received byte length ends exactly at payload end (separator byte still expected) { // first message part read pendingMessage = unusedSharedMessage; pendingMessage.MessageFormat = msgFormat; pendingMessage.Data = data; pendingMessage.Length = sourceDataLength; } else { // complete message // check data border byte if (source[startIndex] != DataBorderControlByte) { ThrowDataEndMarkException($"param length: {length}; data.Length: {data.Length}; source.Length: {source.Length}", source, startIndex, data.Length); } startIndex++; pendingMessage = null; var message = unusedSharedMessage; // update message data message.MessageFormat = msgFormat; message.Data = data; message.Length = dataLength; return(message); } } else { var restByteCount = length - index; if (restByteCount > 0) { // incomplete encapsulation control data slice pendingMessage = unusedSharedMessage; pendingMessage.MessageFormat = RawMessageFormat.IncompleteControlDataSlice; byte[] endRawControlData = new byte[restByteCount]; Array.Copy(source, index, endRawControlData, 0, restByteCount); pendingMessage.Data = endRawControlData; pendingMessage.Length = restByteCount; } } } } } catch (Exception ex) { Logger.Error(ex.ToString()); pendingMessage = null; } return(null); }
/// <summary> /// Called when [receive data]. /// </summary> /// <param name="socketStateObj">The socket state obj.</param> protected async ValueTask OnReceiveDataAsync(SocketState state) { Socket clientSocket = state.Client.socket; Stream clientStream = state.Client.stream; byte[] readBuffer = state.readBuffer; int readBufferLength = readBuffer.Length; var cancelToken = cancelTokenSource.Token; try { IRawMessage rawMessage = new RawMessage(state.Client.SessionId); IRawMessage pendingMessage = null; IRawMessage receivedMessage; while (clientSocket.Connected) { int bytesReadCount = await clientStream.ReadAsync(readBuffer, 0, readBufferLength, cancelToken).ConfigureAwait(false); if (bytesReadCount > 0) { int readIndex = 0; while ((receivedMessage = ReadRawMessage(readBuffer, ref readIndex, bytesReadCount, rawMessage, ref pendingMessage)) != null) { // raw message received await rawMessageReceivedDelegate(receivedMessage); } if (bytesReadCount == readBuffer.Length && bytesReadCount < maxReadBufferSize) { // auto extend internal read buffer size if complete buffer is filled int newSize = readBuffer.Length * 2; state.readBuffer = new byte[newSize]; readBuffer = state.readBuffer; readBufferLength = newSize; } } else { // Connection closed Close(state.Client, $"OnReceiveDataAsync rc: {bytesReadCount}; Socket: {state?.Client?.socket?.Connected}"); return; } } if (!state.Client.socket.Connected) { Close(state.Client, "OnReceiveDataAsync state"); return; } } catch (IOException ioEx) { if (ioEx.InnerException is SocketException) { SocketException sockEx = (SocketException)ioEx.InnerException; CloseOrLogSocketException(state, sockEx); } else if (ioEx.InnerException is ObjectDisposedException) { Close(state.Client, nameof(ObjectDisposedException)); } else { Logger.Error(ioEx.ToString()); Close(state.Client, $"{nameof(IOException)} {ioEx.Message}"); } } catch (SocketException socketEx) { CloseOrLogSocketException(state, socketEx); } catch (OperationCanceledException) { /* connection closed exception */ Close(state.Client, nameof(OperationCanceledException)); } catch (ObjectDisposedException) { /* connection closed exception */ Close(state.Client, nameof(ObjectDisposedException)); } catch (Exception ex) { Logger.Error(ex.ToString()); Close(state.Client, $"{ex.GetType().Name} {ex.Message}"); } }
private void SetTimeSent(IRawMessage rawMessage) { rawMessage.Headers[Collector.MessageBusTechnologies.NServiceBus.Headers.TimeSent] = ToNServiceBusDateTime(DateTime.UtcNow); }
public int CompareTo(IRawMessage otherIRawMessage) { if (otherIRawMessage is MockRawMessage) { MockRawMessage other = (MockRawMessage)otherIRawMessage; return this.Timestamp.CompareTo(other.Timestamp); } else { throw new NotSupportedException("Don't know how to compare a MockRawMessage and a " + otherIRawMessage.GetType()); } }
public void AddTrackingHeaders(IRawMessage rawMessage, long retryId) { rawMessage.Headers.Remove(Headers.Retry); rawMessage.Headers.Add(Headers.Retry, retryId.ToString()); }
public void ParseBody(IRawMessage message, MessageDocument messageDocument) { messageDocument.Body = message.Body; }
public static IMessage Parse(IRawMessage rawMessage) { return Kernel.Get<IMessageParser>().Parse(rawMessage); }
public void Send(IRawMessage message) { NetworkStream stream = base.GetStream(); byte[] encoding = this.Encoding.GetBytes(message.Text); if (stream.CanWrite) { stream.BeginWrite(encoding, 0, encoding.Length, SentMessage, encoding); } else { this.Disconnect(); } }
public void HandleMessage(IRawMessage message) { logger.Trace("handling message on {0}", QueueSettings.LogInfo); storeMessagesFactory.MessageStorageServiceFor(message).Store(message, QueueSettings); messageMeter.Mark(); }
//private ILocation LocationWithIn(string sourceText) //{ // // snippet of code from parsing of content after "In" which was inexplicably // // differnet from approach used when after L: // // //search for a location then trim the array one character at a time until you reach the ':' character // //while (address.Length >= 1) // //{ // // //Regex re = new Regex("(#[a-zA-Z0-9_]+$$)"); // // ILocation newLocation = Parse(address); // // if (newLocation != null && newLocation.Accuracy != null) // // { // // if (best == null) best = newLocation; // // if (newLocation.Accuracy >= best.Accuracy) best = newLocation; // // } // // Regex endRegex = new Regex("([ |,][^( |,)]+$$)"); // // Match endMatch = endRegex.Match(address); // // if (endMatch.Groups.Count > 1) // // { // // address = address.TrimEnd(endMatch.Groups[0].Value.ToCharArray()); // // address = address.Trim(); // // } // // else break; // // //address = address.Substring(0, address.Length - 2); // //} // //return best; //} private IEnumerable<ITag> ParseTags(string sourceText, IRawMessage message) { Regex re = new Regex("(#[a-zA-Z0-9_]+)"); MatchCollection results = re.Matches(sourceText); foreach (Match match in results) { string tagString = match.Groups[0].Value; tagString = tagString.Replace("#", ""); tagString = SubstituteTagIfSubstituteExists(tagString); ITag tag = _tagProvider.GetTagIfExists(tagString, TagType.tag); yield return tag ?? new Tag(TagType.tag, tagString); } }