private void OnReceived(MessageEnvelope<byte[]> envelope, IMessageAck ack) { try { var typeName = envelope.Properties.Type; typeName.AssertNotNullOrEmpty("typename was expected to be added to message properties"); // PERF: needs caching var msgType = Type.GetType(typeName, throwOnError: true); Func<IMessageHandler> builder; if (!_message2HandlerBuilder.TryGetValue(msgType, out builder)) { var msg = "No IMessageHandler registered for message type " + msgType.FullName; this.Logger.Error(msg); throw new Exception(msg); } IMessageHandler handler = builder(); var message = (IMessage) _bus.Serializer.Deserialize(envelope.Body, msgType); _invoker.Invoke(msgType, message, handler); ack.Ack(); } catch (Exception e) { this.Logger.Error("Error processing message", e); ack.Reject(requeue: false); } }
public SubscriptionImpl(Uri address, RoutingSlipEvents events, RoutingSlipEventContents include, string activityName = null, MessageEnvelope message = null) { Include = include; ActivityName = activityName; Address = address; Events = events; Message = message; }
public void RegisterToSend(Uri destination, MessageEnvelope payload) { byte[] data = payload.Serialize(); Actions.ExecuteCommand("[SBQ].[RegisterToSend]", cmd => { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@localServiceName", QueueUri.ToServiceName()); cmd.Parameters.AddWithValue("@address", destination.ToServiceName()); cmd.Parameters.AddWithValue("@route", string.Format("{0}://{1}", destination.Scheme, destination.Authority)); cmd.Parameters.AddWithValue("@sizeOfData", payload.Data.Length); cmd.Parameters.AddWithValue("@deferProcessingUntilTime", (object)payload.DeferProcessingUntilUtcTime ?? DBNull.Value); cmd.Parameters.AddWithValue("@sentAt", DateTime.UtcNow); cmd.Parameters.AddWithValue("@data", data); cmd.ExecuteNonQuery(); }); }
public byte[] Serialize( MessageEnvelope messageEnvelope ) { using ( var stream = new MemoryStream() ) using ( var writer = new BinaryWriter( stream ) ) { writer.Write( messageEnvelope.DeferProcessingUntilUtcTime.HasValue ); if ( messageEnvelope.DeferProcessingUntilUtcTime.HasValue ) writer.Write( messageEnvelope.DeferProcessingUntilUtcTime.Value.ToBinary() ); writer.Write( messageEnvelope.Data.Length ); writer.Write( messageEnvelope.Data ); writer.Write( messageEnvelope.Headers.Count ); foreach ( string key in messageEnvelope.Headers ) { writer.Write( key ); writer.Write( messageEnvelope.Headers[key] ); } writer.Flush(); return stream.ToArray(); } }
public static MessageEnvelope ToMessageEnvelope(this byte[] buffer) { using (var ms = new MemoryStream(buffer)) using (var br = new BinaryReader(ms)) { var messageEnvelope = new MessageEnvelope(); if(br.ReadBoolean()) { messageEnvelope.DeferProcessingUntilUtcTime = DateTime.FromBinary(br.ReadInt64()); } var length = br.ReadInt32(); messageEnvelope.Data = br.ReadBytes(length); var headerCount = br.ReadInt32(); messageEnvelope.Headers = new NameValueCollection(headerCount); for (var j = 0; j < headerCount; j++) { messageEnvelope.Headers.Add(br.ReadString(), br.ReadString()); } return messageEnvelope; } }
public async Task TestReceiveSendMessageAsync() { var envelope1 = new MessageEnvelope(IdGenerator.NextLong(), "Test", "Test message"); ThreadPool.QueueUserWorkItem(async delegate { Thread.Sleep(500); await _queue.SendAsync(null, envelope1); }); var envelope2 = await _queue.ReceiveAsync(null, 10000); Assert.NotNull(envelope2); Assert.Equal(envelope1.MessageType, envelope2.MessageType); Assert.Equal(envelope1.Message, envelope2.Message); Assert.Equal(envelope1.CorrelationId, envelope2.CorrelationId); if (_isFifo) { await _queue.CompleteAsync(envelope2); } }
public static ResultMessage CreateResult(this MessageEnvelope envelope, Exception exc) { if (envelope == null) { throw new ArgumentNullException(nameof(envelope)); } if (exc == null) { throw new ArgumentNullException(nameof(exc)); } var result = envelope.CreateResult(exc.GetStatusCode()); if (!(result.Status == ResultStatusCodes.InternalError || string.IsNullOrWhiteSpace(exc.Message))) { result.ErrorMessage = exc.Message; } else { result.ErrorMessage = result.Status.ToString(); } return(result); }
public async Task RouteAsync <T>(T message) { var route = _messageRoutes.GetRoute(message.GetType()); var envelope = new MessageEnvelope(message, route.MessageType); OnBeforeRouting?.Invoke(envelope); try { foreach (var action in route.Actions) { var handler = _messageHandlerCreator(action.HandlerType, envelope); var resultingTask = (Task)action.Invoke(handler, envelope.Message); await resultingTask.ConfigureAwait(false); } } finally { OnAfterRouted?.Invoke(envelope); } }
public virtual bool onReceive(MessageEnvelope message, ITransport replyTransport) { if (message.Body.isLookupRequestSelected()) { MessageEnvelope result = new MessageEnvelope(); result.Id = message.Id; MessageBody body = new MessageBody(); result.Body = body; LookupResult lResult = new LookupResult(); body.selectLookupResult(lResult); try { lock (suppliers) { ISupplier supplier = suppliers[message.Body.LookupRequest.SupplierName]; LookupResultCode resCode = new LookupResultCode(); if (supplier != null) { resCode.Value = LookupResultCode.EnumType.success; } else { resCode.Value = LookupResultCode.EnumType.notFound; } lResult.Code = resCode; } replyTransport.sendAsync(result); } catch (Exception e) { Console.WriteLine(e); } return(true); } else { return(false); } }
public static byte[] Serialize(this MessageEnvelope messageEnvelope) { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { writer.Write(messageEnvelope.DeferProcessingUntilUtcTime.HasValue); if (messageEnvelope.DeferProcessingUntilUtcTime.HasValue) { writer.Write(messageEnvelope.DeferProcessingUntilUtcTime.Value.ToBinary()); } writer.Write(messageEnvelope.Data.Length); writer.Write(messageEnvelope.Data); writer.Write(messageEnvelope.Headers.Count); foreach (string key in messageEnvelope.Headers) { writer.Write(key); writer.Write(messageEnvelope.Headers[key]); } writer.Flush(); return(stream.ToArray()); } }
public void SendObject(MessageType messageType, object data) { if (!SocketConnection.IsAvailable) { SocketConnection.OnClose.Invoke(); return; } logger.Debug($"{SocketConnection.ConnectionInfo.Id}: Sending {messageType} message"); string payload; try { logger.Debug($"{SocketConnection.ConnectionInfo.Id}: Preparing message {messageType} payload"); MessageEnvelope envelope = new MessageEnvelope(); envelope.MessageType = messageType; envelope.PayloadObject = data; payload = JsonConvert.SerializeObject(envelope); } catch (Exception ex) { logger.Error(ex, $"{SocketConnection.ConnectionInfo.Id}: Error while generating message {messageType} payload"); return; } try { logger.Debug($"{SocketConnection.ConnectionInfo.Id}: Sending {messageType} data to the client ({payload.Length} bytes)"); SocketConnection.Send(payload); } catch (Exception ex) { logger.Error(ex, $"{SocketConnection.ConnectionInfo.Id}: Error while sending {messageType} data to the client"); } }
public virtual T call(T args, string consumerId, int timeout) { Message <T> envelope = new Message <T>(); envelope.Id = (queuePath + "/call-" + callCurId++); envelope.Body = (args); MessageEnvelope argsEnv = envelope.createEnvelope(); argsEnv.Body.MessageUserBody.QueuePath = this.QueuePath; argsEnv.Body.MessageUserBody.ConsumerId = consumerId; IConsumer <T> consumer = null; lock (consumers) { if (!consumers.ContainsKey(consumerId)) { throw new Exception("Consumer with id:" + consumerId + " not found!"); } else { consumer = consumers[consumerId]; } } if (consumer is IRemoteConsumer <T> ) { MessageEnvelope result = null; ITransport consTransport = ((IRemoteConsumer <T>)consumer).NetworkTransport; result = consTransport.call(argsEnv, timeout); envelope.fillFromEnvelope(result); return(envelope.Body); } else { throw new System.Exception("Call enabled only for remote consumer !"); } }
public void Add(IncomingMessage message) { MessageEnvelope consensus = null; MajorityResults majorityResult = MajorityResults.Unknown; lock (syncRoot) { if (!storage.TryGetValue(message.MessageHash, out var envelopeVote))//first result with such hash { envelopeVote = new MessageEnvelopeVote(message.Envelope, message.MessageHash); storage.Add(message.MessageHash, envelopeVote); } else { envelopeVote.AddSignature(message.Envelope.Signatures[0]); } if (storage.Count > 1) { } if (IsProcessed) { if (storage.Select(e => e.Value.Signatures.Count).Sum() == ((AlphaStateManager)majorityManager.Context.AppState).ConnectedAuditorsCount) //remove if all auditors sent results { majorityManager?.Remove(Id); } return; } majorityResult = CheckMajority(out consensus); if (majorityResult != MajorityResults.Unknown) { majorityManager.OnResult(majorityResult, consensus); IsProcessed = true; } } }
public void OrderSerializationTest() { var pubkey = new byte[32]; var signature = new byte[64]; Array.Fill(pubkey, (byte)10); Array.Fill(signature, (byte)64); var original = new OrderRequest() { Account = 1, Amount = 2131231, RequestId = 1, TimeInForce = TimeInForce.ImmediateOrCancel, Asset = 5, Price = 23423.4325 }; var message = new MessageEnvelope() { Message = original, Signatures = new List <Ed25519Signature> { new Ed25519Signature() { Signer = pubkey, Signature = signature } } }; var deserializedMessage = XdrConverter.Deserialize <MessageEnvelope>(XdrConverter.Serialize(message)); var deserialized = deserializedMessage.Message as OrderRequest; Assert.AreEqual(pubkey, deserializedMessage.Signatures[0].Signer.Data); Assert.AreEqual(signature, deserializedMessage.Signatures[0].Signature); Assert.AreEqual(original.Account, deserialized.Account); Assert.AreEqual(original.Amount, deserialized.Amount); Assert.AreEqual(original.TimeInForce, deserialized.TimeInForce); Assert.AreEqual(original.Asset, deserialized.Asset); Assert.AreEqual(original.Nonce, deserialized.Nonce); Assert.AreEqual(original.Price, deserialized.Price); }
private MqttApplicationMessage FromMessage(MessageEnvelope message) { var data = message.Message; if (_serializeEnvelope) { message.SentTime = DateTime.UtcNow; var json = JsonConverter.ToJson(message); data = Encoding.UTF8.GetBytes(json); } var qos = (MqttQualityOfServiceLevel)_qos; var topic = GetTopic(); var msg = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithPayload(data) .WithRetainFlag(_retain) .WithQualityOfServiceLevel(qos) .Build(); return(msg); }
public async Task ItShouldReturnTheExpectedResultWhenAnExceptionIsThrown( [Frozen] IStorageProvider <long> storageProvider, NotificationTransaction expectedTransaction, Exception exception, AbstractMessageProcessor <long> sut) { // Arrange A.CallTo(() => storageProvider.Store( A <IStorageMessageSerializer> ._, A <INotification <long>[]> ._)) .Throws(exception); var likeness = new MessageEnvelope(exception.Message, expectedTransaction) .AsSource() .OfLikeness <MessageEnvelope>(); // Act var actual = await sut.GetMessages(CancellationToken.None); // Assert likeness.ShouldEqual(actual); }
public virtual IRemoteSupplier lookup(string supplierName) { MessageEnvelope message = new MessageEnvelope(); MessageBody body = new MessageBody(); LookupRequest request = new LookupRequest(); request.SupplierName = supplierName; body.selectLookupRequest(request); message.Body = body; message.Id = this.ToString(); MessageEnvelope result = transport.call(message, callTimeout); if (result.Body.LookupResult.Code.Value == LookupResultCode.EnumType.success) { return(new RemoteSupplier(supplierName, transport)); } else { throw new System.Exception("Error when accessing to supplier '" + supplierName + "': " + result.Body.LookupResult.Code.Value.ToString()); } }
public async Task RouteAsync <T>(T message) { var messageType = message.GetType(); var route = _messageRoutes.GetRoute(messageType); var envelope = new MessageEnvelope(message, messageType); if (!_middlewares.Any()) { foreach (var action in route.Actions) { await action.Invoke(_messageHandlerCreator(action.HandlerType, envelope), envelope.Message).ConfigureAwait(false); } } else { foreach (var action in route.Actions) { await ProcessAsync( envelope, async e => await action.Invoke(_messageHandlerCreator(action.HandlerType, envelope), envelope.Message).ConfigureAwait(false)).ConfigureAwait(false); } } }
public static QuantumModel FromQuantum(MessageEnvelope quantum) { if (quantum == null) { throw new ArgumentNullException(nameof(quantum)); } var quantumMessage = (Quantum)quantum.Message; var account = 0; if (quantumMessage is RequestQuantum requestQuantum) { account = requestQuantum.RequestMessage.Account; } return(new QuantumModel { Apex = quantumMessage.Apex, Account = account, RawQuantum = XdrConverter.Serialize(quantum), Type = (int)quantumMessage.MessageType, TimeStamp = quantumMessage.Timestamp }); }
private async Task ProcessAsync(MessageEnvelope envelope, Func <MessageEnvelope, Task> root) { Func <MessageEnvelope, Task> prev; using (var e = _middlewares.GetEnumerator()) { if (!e.MoveNext()) { return; } prev = e.Current.Invoke(root); while (e.MoveNext()) { prev = e.Current.Invoke(prev); } } if (prev != null) { await prev.Invoke(envelope).ConfigureAwait(false); } }
public static void TryAssignAccountWrapper(this MessageEnvelope envelope, AccountStorage accountStorage) { var requestMessage = default(RequestMessage); if (envelope.Message is RequestQuantum) { requestMessage = ((RequestQuantum)envelope.Message).RequestMessage; } else if (envelope.Message is RequestMessage) { requestMessage = (RequestMessage)envelope.Message; } else { return; } if (accountStorage == null) { throw new ArgumentNullException(nameof(accountStorage)); } requestMessage.AccountWrapper = accountStorage.GetAccount(requestMessage.Account); }
private MessageEnvelope ToMessage(Message envelope, bool withLock = true) { if (envelope == null) { return(null); } var message = new MessageEnvelope { MessageType = envelope.ContentType, CorrelationId = envelope.CorrelationId, MessageId = envelope.MessageId, SentTime = envelope.ScheduledEnqueueTimeUtc, Message = envelope.Body, }; if (withLock) { message.Reference = envelope.SystemProperties?.LockToken; } return(message); }
public async Task TestOnMessageAsync() { var envelope1 = new MessageEnvelope("123", "Test", "Test message"); MessageEnvelope envelope2 = null; _queue.BeginListen(null, async(envelope, queue) => { envelope2 = envelope; await Task.Delay(0); _queue.EndListen(null); }); await _queue.SendAsync(null, envelope1); await Task.Delay(1000); Assert.NotNull(envelope2); Assert.Equal(envelope1.MessageType, envelope2.MessageType); Assert.Equal(envelope1.Message, envelope2.Message); Assert.Equal(envelope1.CorrelationId, envelope2.CorrelationId); await _queue.CloseAsync(null); }
public bool TakeMessage(string queueName, CancellationToken token, out MessageEnvelope envelope) { envelope = null; while (!token.IsCancellationRequested) { var queue = this.GetQueue(queueName); var result = this.TryGetMessage(queue, out envelope); switch (result) { case GetMessageResult.Success: this._retryCount = 0; return(true); case GetMessageResult.Empty: case GetMessageResult.Retry: this._retryCount += 1; break; case GetMessageResult.Exception: return(false); default: throw new ArgumentOutOfRangeException(); } if (this._retryCount > RetryCount) { break; } var waiting = this._waiter(this._retryCount); token.WaitHandle.WaitOne(waiting); } return(false); }
public async Task RunAsync( [EventHubTrigger("%REQUEST_QUEUE_NAME%", Connection = "REQUEST_QUEUE_CONNECTION_STRING")] MessageEnvelope eventData, ILogger logger) { if (eventData is null) { throw new ArgumentNullException(nameof(eventData)); } if (logger is null) { throw new ArgumentNullException(nameof(logger)); } logger.LogInformation($"{FunctionName} started processing a request."); var requestType = _resolver.GetTypeByCategory(eventData.MessageType); if (requestType == null) { logger.LogWarning("{messageType} not found", eventData.MessageType); return; // TODO: go to error queue or storage? } using (var body = new MemoryStream(Encoding.UTF8.GetBytes(eventData.Message))) { var hubRequest = await _rehydrator.RehydrateAsync(body, requestType).ConfigureAwait(false); if (hubRequest == null) { logger.LogWarning("CommandRouter: could not rehydrate {messageType}", eventData.MessageType); return; // TODO: go to error queue or storage? } await _commandDispatcher.DispatchAsync(hubRequest).ConfigureAwait(false); } }
protected override async Task <ResultMessage> HandleQuantum(MessageEnvelope envelope, long timestamp) { var quantum = (Quantum)envelope.Message; if (quantum.Apex != Context.QuantumStorage.CurrentApex + 1) { throw new Exception($"Current quantum apex is {quantum.Apex} but {Context.QuantumStorage.CurrentApex + 1} was expected."); } if (!(envelope.IsSignedBy(Context.Settings.AlphaKeyPair) && envelope.AreSignaturesValid())) { throw new UnauthorizedAccessException($"Quantum {quantum.Apex} has invalid Alpha signature."); } ValidateRequestQuantum(envelope); var result = await ProcessQuantumEnvelope(envelope); if (!ByteArrayComparer.Default.Equals(result.Effects.Hash, quantum.EffectsHash) && !EnvironmentHelper.IsTest) { throw new Exception($"Effects hash for quantum {quantum.Apex} is not equal to provided by Alpha."); } var messageHash = envelope.ComputeMessageHash(buffer.Buffer); Context.QuantumStorage.AddQuantum(envelope, messageHash); ProcessTransaction(result.ResultMessage, result.TxHash); result.EffectProcessorsContainer.Complete(buffer.Buffer); Context.OutgoingResultsStorage.EnqueueResult(result.ResultMessage, buffer.Buffer); logger.Trace($"Message of type {quantum.MessageType} with apex {quantum.Apex} is handled."); return(result.ResultMessage); }
protected async Task <ResultMessage> AssertQuantumHandling(MessageEnvelope quantum, Type excpectedException = null) { try { var result = await context.QuantumHandler.HandleAsync(quantum); await SnapshotHelper.ApplyUpdates(context); //check that processed quanta is saved to the storage var lastApex = await context.PermanentStorage.GetLastApex(); Assert.AreEqual(context.QuantumStorage.CurrentApex, lastApex); return(result); } catch (Exception exc) { if (excpectedException == null || excpectedException.FullName != exc.GetType().FullName) { throw; } return(null); } }
private SendMessageRequest CreateSendMessageRequest(MessageEnvelope message, bool contentBasedDupication, string queueUrl) { var content = JsonConverter.ToJson(message); var request = new SendMessageRequest() { QueueUrl = queueUrl, MessageBody = content }; if (_fifoQueue) { // A message group id is required for a fifo queue message request.MessageGroupId = message.MessageType; // A message deduplication id is required if content based duplication is turned off for the fifo queue. if (!contentBasedDupication) { request.MessageDeduplicationId = message.MessageId; } } return(request); }
public virtual void addConsumer(IConsumer <T> consumer, bool persistence, string filter) { SubscribeRequest request = new SubscribeRequest(); request.ConsumerId = consumer.Id; request.Filter = filter; if (persistence) { request.Persistence = true; } request.QueuePath = QueuePath; MessageEnvelope message = new MessageEnvelope(); MessageBody body = new MessageBody(); body.selectSubscribeRequest(request); message.Body = (body); message.Id = this.ToString(); // !!!!! //MessageEnvelope result = supplier.Connection.call(message, 1000); MessageEnvelope result = supplier.Connection.call(message, subscribeTimeout); if (result.Body.SubscribeResult.Code.Value != SubscribeResultCode.EnumType.success) { throw new System.Exception("Error when accessing to queue '" + queuePath + "' for supplier '" + supplier.Id + "': " + result.Body.SubscribeResult.Code.Value.ToString() ); } else { lock (consumers) { consumers[consumer.Id] = consumer; } } }
private void HandleQuantumResult(MessageEnvelope envelope) { if (!(envelope.Message is IEffectsContainer effectsMessage)) { return; } if (effectsMessage.Effects.Count > 0) { try { //apply effects to the client-side state foreach (var effect in effectsMessage.Effects) { AccountState.ApplyAccountStateChanges(effect); } //notify subscribers about the account state update OnAccountUpdate?.Invoke(AccountState); } catch (Exception e) { OnException?.Invoke(e); } } }
/// <summary> /// Deserializes the envelope. /// </summary> /// <param name="serializedInstance">The serialized instance.</param> /// <returns></returns> public IMessageEnvelope DeserializeEnvelope(string serializedInstance) { MessageEnvelope envelope = null; try { var stream = new MemoryStream(System.Text.ASCIIEncoding.UTF8.GetBytes(serializedInstance)); var xmlSerializer = new XmlSerializer(typeof(MessageEnvelope)); envelope = (MessageEnvelope)xmlSerializer.Deserialize(stream); } catch (System.Exception ex) { throw new MessageSerializationException("Could not Deserialize Message Envelope Containing " + serializedInstance, ex, null); } try { envelope.Message = DeserializeMessage(envelope.MessageString, envelope.MessageType); } catch (System.Exception ex) { throw new MessageSerializationException("Could not Deserialize Message Envelope with Message " + envelope.MessageType + " for " + envelope.Originator + " in " + envelope.MessageUID, ex, envelope); } return(envelope); }
// If the message contains trusted internal recipients, drop a copy in the pickup folder, so the message can sent back // through the incoming pipeline protected void RelayInternal(ISmtpMessage message, MessageEnvelope envelope) { InternalMessageSettings settings = m_settings.InternalMessage; if (!(settings.EnableRelay && settings.HasPickupFolder)) { return; } if (!envelope.HasDomainRecipients) { // No internal recipients return; } // // We have some trusted domain recipients. Drop a copy of the message into the message pickup folder // It will get passed back through the message processing loop and treated as Incoming // this.CopyMessage(message, settings.PickupFolder); // // Since we've routed the message ourselves, ensure there is no double delivery by removing them from // the recipient list // envelope.Recipients.Remove(envelope.DomainRecipients); }
private void HandleMessage(BrokeredMessage message) { // TODO: Rely on azure's serialization for MessageEnvelope? MessageEnvelope envelope = message.GetBody <MessageEnvelope>(); Type bodyType = Type.GetType(envelope.BodyType); object body = config.MessageSerializer.Deserialize(bodyType, envelope.Body); // Get handlers var handler = config.HandlerResolver.ResolveHandlerForMessage(bodyType); // Invoke try { handler(body); // Handle complete, remove from queue message.Complete(); } catch (Exception ex) { // TODO: NLog Console.WriteLine($"Error {ex.Message} handling message {message.MessageId}"); } }
public async Task HandleMessage(MessageEnvelope envelope) { await _serverBroker.SendMessage(envelope); }
public EffectProcessorsContainer(ExecutionContext context, MessageEnvelope quantum, DiffObject pendingDiffObject) : base(context) { Envelope = quantum ?? throw new ArgumentNullException(nameof(quantum)); PendingDiffObject = pendingDiffObject ?? throw new ArgumentNullException(nameof(pendingDiffObject)); }
private MessageEnvelope BuildMessageEnvelope(IEnumerable<object> messages, Guid correlationId) { byte[] messageBody; using (var stream = new MemoryStream()) { messageSerializer.Serialize(messages.ToArray(), stream); stream.Flush(); messageBody = stream.ToArray(); } var message = new MessageEnvelope(Guid.NewGuid(), correlationId, TimeSpan.MaxValue, true, new Dictionary<string, string>(), messageBody); return message; }
public P SendMessage <R, P>(string remoteActorType, MessageEnvelope <R> request) { return(SendMessage <R, P>(remoteActorType, request, TimeSpan.FromSeconds(60))); }
/// <summary> /// Adds a custom subscription message to the routing slip which is sent at the specified events /// </summary> /// <param name="address">The destination address where the events are sent</param> /// <param name="events">The events to include in the subscription</param> /// <param name="contents">The contents of the routing slip event</param> /// <param name="activityName"></param> /// <param name="message">The custom message to be sent</param> void IRoutingSlipSendEndpointTarget.AddSubscription(Uri address, RoutingSlipEvents events, RoutingSlipEventContents contents, string activityName, MessageEnvelope message) { _subscriptions.Add(new SubscriptionImpl(address, events, contents, activityName, message)); }