public async Task SendMessageWithNoFeedbackTest() { // Arrange var productInfoStore = Mock.Of <IProductInfoStore>(); var modelIdStore = Mock.Of <IModelIdStore>(); var identity = Mock.Of <IIdentity>(i => i.Id == "d1"); var deviceListener = new Mock <IDeviceListener>(); deviceListener.Setup(d => d.ProcessMessageFeedbackAsync(It.IsAny <string>(), It.IsAny <FeedbackStatus>())) .Returns(Task.CompletedTask); AmqpMessage receivedAmqpMessage = null; var connectionHandler = Mock.Of <IConnectionHandler>(c => c.GetDeviceListener() == Task.FromResult(deviceListener.Object)); var amqpAuthenticator = new Mock <IAmqpAuthenticator>(); amqpAuthenticator.Setup(c => c.AuthenticateAsync("d1")).ReturnsAsync(true); Mock <ICbsNode> cbsNodeMock = amqpAuthenticator.As <ICbsNode>(); ICbsNode cbsNode = cbsNodeMock.Object; var amqpConnection = Mock.Of <IAmqpConnection>( c => c.FindExtension <IConnectionHandler>() == connectionHandler && c.FindExtension <ICbsNode>() == cbsNode); var amqpSession = Mock.Of <IAmqpSession>(s => s.Connection == amqpConnection); var amqpLinkSettings = new AmqpLinkSettings(); var sendingLink = Mock.Of <ISendingAmqpLink>(l => l.Session == amqpSession && !l.IsReceiver && l.Settings == amqpLinkSettings && l.State == AmqpObjectState.Opened); Mock.Get(sendingLink).Setup(s => s.SendMessageAsync(It.IsAny <AmqpMessage>(), It.IsAny <ArraySegment <byte> >(), It.IsAny <ArraySegment <byte> >(), It.IsAny <TimeSpan>())) .Callback <AmqpMessage, ArraySegment <byte>, ArraySegment <byte>, TimeSpan>((m, d, t, ts) => { receivedAmqpMessage = m; }) .Returns(Task.CompletedTask); var requestUri = new Uri("amqps://foo.bar/devices/d1"); var boundVariables = new Dictionary <string, string> { { "deviceid", "d1" } }; var messageConverter = new AmqpMessageConverter(); var sendingLinkHandler = new TestSendingLinkHandler(identity, sendingLink, requestUri, boundVariables, connectionHandler, messageConverter, QualityOfService.AtMostOnce, productInfoStore, modelIdStore); var body = new byte[] { 0, 1, 2, 3 }; IMessage message = new EdgeMessage.Builder(body).Build(); // Act await sendingLinkHandler.OpenAsync(TimeSpan.FromSeconds(5)); await sendingLinkHandler.SendMessage(message); // Assert Assert.NotNull(receivedAmqpMessage); Assert.Equal(body, receivedAmqpMessage.GetPayloadBytes()); Assert.Equal((byte)SenderSettleMode.Settled, amqpLinkSettings.SndSettleMode); Assert.Equal((byte)ReceiverSettleMode.First, amqpLinkSettings.RcvSettleMode); }
/// <summary> /// Creates a new <see cref="EventDataBatch"/>. /// </summary> /// <param name="maxSizeInBytes">The maximum size allowed for the batch</param> /// <param name="partitionKey">Partition key associate with the batch</param> public EventDataBatch(long maxSizeInBytes, string partitionKey = null) { PartitionKey = partitionKey; maxSize = Math.Min(maxSizeInBytes, MaxSizeLimit); eventDataList = new List <EventData>(); // Reserve for wrapper message. using (var batchMessage = AmqpMessage.Create()) { batchMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat; AmqpMessageConverter.UpdateAmqpMessagePartitionKey(batchMessage, partitionKey); currentSize = batchMessage.SerializedMessageSize; } }
private long GetEventSizeForBatch(EventData eventData) { // Create AMQP message here. We will use the same message while sending to save compute time. AmqpMessage amqpMessage = AmqpMessageConverter.EventDataToAmqpMessage(eventData); AmqpMessageConverter.UpdateAmqpMessagePartitionKey(amqpMessage, PartitionKey); eventData.AmqpMessage = amqpMessage; // Calculate overhead depending on the message size. // Overhead is smaller for messages smaller than 256 bytes. long overhead = eventData.AmqpMessage.SerializedMessageSize < 256 ? 5 : 8; return(eventData.AmqpMessage.SerializedMessageSize + overhead); }
void Convert_SB_message_to_Amqp_message_and_back() { var messageBody = Encoding.UTF8.GetBytes("hello"); var messageId = Guid.NewGuid().ToString(); var partitionKey = Guid.NewGuid().ToString(); var viaPartitionKey = Guid.NewGuid().ToString(); var sessionId = Guid.NewGuid().ToString(); var correlationId = Guid.NewGuid().ToString(); var label = Guid.NewGuid().ToString(); var to = Guid.NewGuid().ToString(); var contentType = Guid.NewGuid().ToString(); var replyTo = Guid.NewGuid().ToString(); var replyToSessionId = Guid.NewGuid().ToString(); var publisher = Guid.NewGuid().ToString(); var timeToLive = TimeSpan.FromDays(5); var sbMessage = new Message(messageBody) { MessageId = messageId, PartitionKey = partitionKey, ViaPartitionKey = viaPartitionKey, SessionId = sessionId, CorrelationId = correlationId, Label = label, To = to, ContentType = contentType, ReplyTo = replyTo, ReplyToSessionId = replyToSessionId, TimeToLive = timeToLive }; sbMessage.UserProperties.Add("UserProperty", "SomeUserProperty"); var amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(sbMessage); var convertedSbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); Assert.Equal("SomeUserProperty", convertedSbMessage.UserProperties["UserProperty"]); Assert.Equal(messageBody, convertedSbMessage.Body); Assert.Equal(messageId, convertedSbMessage.MessageId); Assert.Equal(partitionKey, convertedSbMessage.PartitionKey); Assert.Equal(viaPartitionKey, convertedSbMessage.ViaPartitionKey); Assert.Equal(sessionId, convertedSbMessage.SessionId); Assert.Equal(correlationId, convertedSbMessage.CorrelationId); Assert.Equal(label, convertedSbMessage.Label); Assert.Equal(to, convertedSbMessage.To); Assert.Equal(contentType, convertedSbMessage.ContentType); Assert.Equal(replyTo, convertedSbMessage.ReplyTo); Assert.Equal(replyToSessionId, convertedSbMessage.ReplyToSessionId); Assert.Equal(timeToLive, convertedSbMessage.TimeToLive); }
public void CreateEventFromMessagePopulatesTheBody() { var body = new byte[] { 0x11, 0x22, 0x33 }; using var bodyStream = new MemoryStream(body, false); using var message = AmqpMessage.Create(bodyStream, true); var converter = new AmqpMessageConverter(); var eventData = converter.CreateEventFromMessage(message); Assert.That(eventData, Is.Not.Null, "The event should have been created."); Assert.That(eventData.Body, Is.Not.Null, "The event should have a body."); Assert.That(eventData.Body.ToArray(), Is.EqualTo(body), "The body contents should match."); }
public void ConvertAmqpMessageToSBMessage() { var messageBody = Encoding.UTF8.GetBytes("message1"); var data = new Data(); data.Value = messageBody; var amqpMessage = AmqpMessage.Create(data); var sbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); ReadOnlyMemory <byte> sbBody = sbMessage.Body; Assert.AreEqual(messageBody, sbBody.ToArray()); }
public async Task SendLargeMessageThrowsTest() { // Arrange bool disposeMessageCalled = true; var identity = Mock.Of <IIdentity>(i => i.Id == "d1"); var amqpAuth = new AmqpAuthentication(true, Option.Some(Mock.Of <IClientCredentials>(c => c.Identity == identity))); var deviceListener = Mock.Of <IDeviceListener>(); Mock.Get(deviceListener).Setup(d => d.ProcessDeviceMessageBatchAsync(It.IsAny <IEnumerable <IMessage> >())) .Returns(Task.CompletedTask); var connectionHandler = Mock.Of <IConnectionHandler>(c => c.GetAmqpAuthentication() == Task.FromResult(amqpAuth) && c.GetDeviceListener() == Task.FromResult(deviceListener)); var amqpConnection = Mock.Of <IAmqpConnection>(c => c.FindExtension <IConnectionHandler>() == connectionHandler); var amqpSession = Mock.Of <IAmqpSession>(s => s.Connection == amqpConnection); var amqpLink = Mock.Of <IReceivingAmqpLink>(l => l.Session == amqpSession && l.IsReceiver && l.Settings == new AmqpLinkSettings() && l.State == AmqpObjectState.Opened); Action <AmqpMessage> onMessageCallback = null; Mock.Get(amqpLink).Setup(l => l.RegisterMessageListener(It.IsAny <Action <AmqpMessage> >())).Callback <Action <AmqpMessage> >(a => onMessageCallback = a); Mock.Get(amqpLink).SetupGet(l => l.Settings).Returns(new AmqpLinkSettings()); Mock.Get(amqpLink).Setup(l => l.SafeAddClosed(It.IsAny <EventHandler>())); Mock.Get(amqpLink).Setup(l => l.DisposeMessage(It.IsAny <AmqpMessage>(), It.IsAny <Outcome>(), It.IsAny <bool>(), It.IsAny <bool>())) .Callback(() => disposeMessageCalled = true); var requestUri = new Uri("amqps://foo.bar/devices/d1/messages/events"); var boundVariables = new Dictionary <string, string> { { "deviceid", "d1" } }; var messageConverter = new AmqpMessageConverter(); using (AmqpMessage amqpMessage = AmqpMessage.Create(new MemoryStream(new byte[800000]), false)) { amqpMessage.ApplicationProperties.Map["LargeProp"] = new int[600000]; ILinkHandler linkHandler = new EventsLinkHandler(amqpLink, requestUri, boundVariables, messageConverter); // Act await linkHandler.OpenAsync(TimeSpan.FromSeconds(30)); // Assert Assert.NotNull(onMessageCallback); // Act onMessageCallback.Invoke(amqpMessage); // Assert await WaitAndAssert(() => disposeMessageCalled, TimeSpan.FromSeconds(5)); } }
async Task <long> OnScheduleMessageAsync(Message message) { // TODO: Ensure System.Transactions.Transaction.Current is null. Transactions are not supported by 1.0.0 version of dotnet core. using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message)) { var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.ScheduleMessageOperation, this.OperationTimeout, null); ArraySegment <byte>[] payload = amqpMessage.GetPayload(); BufferListStream buffer = new BufferListStream(payload); ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length); var entry = new AmqpMap(); { entry[ManagementConstants.Properties.Message] = value; entry[ManagementConstants.Properties.MessageId] = message.MessageId; if (!string.IsNullOrWhiteSpace(message.SessionId)) { entry[ManagementConstants.Properties.SessionId] = message.SessionId; } if (!string.IsNullOrWhiteSpace(message.PartitionKey)) { entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey; } } request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> { entry }; IEnumerable <long> sequenceNumbers = null; var response = await this.ExecuteRequestResponseAsync(request).ConfigureAwait(false); if (response.StatusCode == AmqpResponseStatusCode.OK) { sequenceNumbers = response.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers); } else { response.ToMessagingContractException(); } return(sequenceNumbers?.FirstOrDefault() ?? 0); } }
void Convert_SB_message_to_Amqp_message_and_back() { var messageBody = Encoding.UTF8.GetBytes("hello"); var messageId = Guid.NewGuid().ToString(); var partitionKey = Guid.NewGuid().ToString(); var sessionId = Guid.NewGuid().ToString(); var correlationId = Guid.NewGuid().ToString(); var label = Guid.NewGuid().ToString(); var to = Guid.NewGuid().ToString(); var contentType = Guid.NewGuid().ToString(); var replyTo = Guid.NewGuid().ToString(); var replyToSessionId = Guid.NewGuid().ToString(); var publisher = Guid.NewGuid().ToString(); var deadLetterSource = Guid.NewGuid().ToString(); var sbMessage = new Message(messageBody) { MessageId = messageId, PartitionKey = partitionKey, SessionId = sessionId, CorrelationId = correlationId, Label = label, To = to, ContentType = contentType, ReplyTo = replyTo, ReplyToSessionId = replyToSessionId, Publisher = publisher, DeadLetterSource = deadLetterSource, }; sbMessage.UserProperties.Add("UserProperty", "SomeUserProperty"); var amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(sbMessage); var convertedBrokeredMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); Assert.Equal("SomeUserProperty", convertedBrokeredMessage.UserProperties["UserProperty"]); Assert.Equal(messageBody, convertedBrokeredMessage.Body); Assert.Equal(messageId, convertedBrokeredMessage.MessageId); Assert.Equal(partitionKey, convertedBrokeredMessage.PartitionKey); Assert.Equal(sessionId, convertedBrokeredMessage.SessionId); Assert.Equal(correlationId, convertedBrokeredMessage.CorrelationId); Assert.Equal(label, convertedBrokeredMessage.Label); Assert.Equal(to, convertedBrokeredMessage.To); Assert.Equal(contentType, convertedBrokeredMessage.ContentType); Assert.Equal(replyTo, convertedBrokeredMessage.ReplyTo); Assert.Equal(replyToSessionId, convertedBrokeredMessage.ReplyToSessionId); Assert.Equal(publisher, convertedBrokeredMessage.Publisher); Assert.Equal(deadLetterSource, convertedBrokeredMessage.DeadLetterSource); }
public void FromMessageTest() { // Arrange byte[] bytes = { 1, 2, 3, 4 }; string messageId = Guid.NewGuid().ToString(); string correlationId = Guid.NewGuid().ToString(); string contentType = "UTF-8"; string contentEncoding = "application/json"; var systemProperties = new Dictionary <string, string> { [SystemProperties.MessageId] = messageId, [SystemProperties.MsgCorrelationId] = correlationId, [SystemProperties.ContentType] = contentType, [SystemProperties.ContentEncoding] = contentEncoding, }; var properties = new Dictionary <string, string> { ["Prop1"] = "Value1", ["Prop2"] = "Value2" }; byte[] GetMessageBody(AmqpMessage sourceMessage) { using (var ms = new MemoryStream()) { sourceMessage.BodyStream.CopyTo(ms); return(ms.ToArray()); } } var message = new EdgeMessage(bytes, properties, systemProperties); var messageConverter = new AmqpMessageConverter(); // Act using (AmqpMessage amqpMessage = messageConverter.FromMessage(message)) { // Assert Assert.NotNull(amqpMessage); Assert.Equal(bytes, GetMessageBody(amqpMessage)); Assert.Equal(messageId, amqpMessage.Properties.MessageId.ToString()); Assert.Equal(correlationId, amqpMessage.Properties.CorrelationId.ToString()); Assert.Equal(contentEncoding, amqpMessage.Properties.ContentEncoding.ToString()); Assert.Equal(contentType, amqpMessage.Properties.ContentType.ToString()); Assert.Equal("Value1", amqpMessage.ApplicationProperties.Map["Prop1"].ToString()); Assert.Equal("Value2", amqpMessage.ApplicationProperties.Map["Prop2"].ToString()); } }
public void ConvertSBMessageToAmqpMessageAndBack() { var messageBody = Encoding.UTF8.GetBytes("hello"); var messageId = Guid.NewGuid().ToString(); var partitionKey = Guid.NewGuid().ToString(); var viaPartitionKey = Guid.NewGuid().ToString(); var sessionId = partitionKey; var correlationId = Guid.NewGuid().ToString(); var label = Guid.NewGuid().ToString(); var to = Guid.NewGuid().ToString(); var contentType = Guid.NewGuid().ToString(); var replyTo = Guid.NewGuid().ToString(); var replyToSessionId = Guid.NewGuid().ToString(); var timeToLive = TimeSpan.FromDays(5); var sbMessage = new ServiceBusMessage(messageBody) { MessageId = messageId, PartitionKey = partitionKey, TransactionPartitionKey = viaPartitionKey, SessionId = sessionId, CorrelationId = correlationId, Subject = label, To = to, ContentType = contentType, ReplyTo = replyTo, ReplyToSessionId = replyToSessionId, TimeToLive = timeToLive, }; sbMessage.ApplicationProperties.Add("UserProperty", "SomeUserProperty"); var amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(sbMessage); var convertedSbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); Assert.AreEqual("SomeUserProperty", convertedSbMessage.ApplicationProperties["UserProperty"]); Assert.AreEqual(messageBody, convertedSbMessage.Body.ToArray()); Assert.AreEqual(messageId, convertedSbMessage.MessageId); Assert.AreEqual(partitionKey, convertedSbMessage.PartitionKey); Assert.AreEqual(viaPartitionKey, convertedSbMessage.TransactionPartitionKey); Assert.AreEqual(sessionId, convertedSbMessage.SessionId); Assert.AreEqual(correlationId, convertedSbMessage.CorrelationId); Assert.AreEqual(label, convertedSbMessage.Subject); Assert.AreEqual(to, convertedSbMessage.To); Assert.AreEqual(contentType, convertedSbMessage.ContentType); Assert.AreEqual(replyTo, convertedSbMessage.ReplyTo); Assert.AreEqual(replyToSessionId, convertedSbMessage.ReplyToSessionId); Assert.AreEqual(timeToLive, convertedSbMessage.TimeToLive); }
protected virtual async Task <IList <Message> > OnReceiveAsync(int maxMessageCount, TimeSpan serverWaitTime) { ReceivingAmqpLink receiveLink = null; try { TimeoutHelper timeoutHelper = new TimeoutHelper(serverWaitTime, true); receiveLink = await this.ReceiveLinkManager.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false); IEnumerable <AmqpMessage> amqpMessages = null; bool hasMessages = await Task.Factory.FromAsync( (c, s) => receiveLink.BeginReceiveRemoteMessages(maxMessageCount, DefaultBatchFlushInterval, timeoutHelper.RemainingTime(), c, s), a => receiveLink.EndReceiveMessages(a, out amqpMessages), this).ConfigureAwait(false); if (receiveLink.TerminalException != null) { throw receiveLink.TerminalException; } if (hasMessages && amqpMessages != null) { IList <Message> brokeredMessages = null; foreach (var amqpMessage in amqpMessages) { if (brokeredMessages == null) { brokeredMessages = new List <Message>(); } if (this.ReceiveMode == ReceiveMode.ReceiveAndDelete) { receiveLink.DisposeDelivery(amqpMessage, true, AmqpConstants.AcceptedOutcome); } Message message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); brokeredMessages.Add(message); } return(brokeredMessages); } return(null); } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception, receiveLink?.GetTrackingId()); } }
public void CreateMessageFromEventProperlySetsThePartitionKeyAnnotation(string partitionKey) { var body = new byte[] { 0x11, 0x22, 0x33 }; var eventData = new EventData(body); var converter = new AmqpMessageConverter(); using var message = converter.CreateMessageFromEvent(eventData, partitionKey); Assert.That(message, Is.Not.Null, "The AMQP message should have been created."); Assert.That(message.MessageAnnotations.Map.TryGetValue(AmqpAnnotation.PartitionKey, out object annotationPartionKey), Is.EqualTo(!String.IsNullOrEmpty(partitionKey)), "The partition key annotation was not correctly set."); if (!String.IsNullOrEmpty(partitionKey)) { Assert.That(annotationPartionKey, Is.EqualTo(partitionKey), "The partition key annotation should match."); } }
public void CreateMessageFromEventPopulatesTheBody() { var body = new byte[] { 0x11, 0x22, 0x33 }; var eventData = new EventData(body); var converter = new AmqpMessageConverter(); using var message = converter.CreateMessageFromEvent(eventData); Assert.That(message, Is.Not.Null, "The AMQP message should have been created."); Assert.That(message.DataBody, Is.Not.Null, "The AMQP message should a body."); var messageData = message.DataBody.ToList(); Assert.That(messageData.Count, Is.EqualTo(1), "The AMQP message should a single data body."); Assert.That(messageData[0].Value, Is.EqualTo(eventData.Body.ToArray()), "The AMQP message data should match the event body."); }
public async Task SendMessageTest() { // Arrange var feedbackStatus = FeedbackStatus.Abandon; var deviceListener = new Mock <IDeviceListener>(); deviceListener.Setup(d => d.ProcessMessageFeedbackAsync(It.IsAny <string>(), It.IsAny <FeedbackStatus>())) .Callback <string, FeedbackStatus>((m, s) => feedbackStatus = s) .Returns(Task.CompletedTask); AmqpMessage receivedAmqpMessage = null; var connectionHandler = Mock.Of <IConnectionHandler>(c => c.GetDeviceListener() == Task.FromResult(deviceListener.Object) && c.GetAmqpAuthentication() == Task.FromResult(new AmqpAuthentication(true, Option.Some(Mock.Of <IClientCredentials>())))); var amqpConnection = Mock.Of <IAmqpConnection>(c => c.FindExtension <IConnectionHandler>() == connectionHandler); var amqpSession = Mock.Of <IAmqpSession>(s => s.Connection == amqpConnection); var sendingLink = Mock.Of <ISendingAmqpLink>(l => l.Session == amqpSession && !l.IsReceiver && l.Settings == new AmqpLinkSettings() && l.State == AmqpObjectState.Opened); Mock.Get(sendingLink).Setup(s => s.SendMessageNoWait(It.IsAny <AmqpMessage>(), It.IsAny <ArraySegment <byte> >(), It.IsAny <ArraySegment <byte> >())) .Callback <AmqpMessage, ArraySegment <byte>, ArraySegment <byte> >((m, d, t) => { receivedAmqpMessage = m; }); var requestUri = new Uri("amqps://foo.bar/devices/d1"); var boundVariables = new Dictionary <string, string> { { "deviceid", "d1" } }; var messageConverter = new AmqpMessageConverter(); var sendingLinkHandler = new DeviceBoundLinkHandler(sendingLink, requestUri, boundVariables, messageConverter); var body = new byte[] { 0, 1, 2, 3 }; IMessage message = new EdgeMessage.Builder(body).Build(); var deliveryState = new Mock <DeliveryState>(new AmqpSymbol(""), AmqpConstants.AcceptedOutcome.DescriptorCode); var delivery = Mock.Of <Delivery>(d => d.State == deliveryState.Object && d.DeliveryTag == new ArraySegment <byte>(Guid.NewGuid().ToByteArray())); // Act await sendingLinkHandler.OpenAsync(TimeSpan.FromSeconds(5)); await sendingLinkHandler.SendMessage(message); // Assert Assert.NotNull(receivedAmqpMessage); Assert.Equal(body, receivedAmqpMessage.GetPayloadBytes()); // Act sendingLinkHandler.DispositionListener(delivery); await Task.Delay(TimeSpan.FromSeconds(5)); // Assert Assert.Equal(feedbackStatus, FeedbackStatus.Complete); }
public async Task SendBatchCreatesTheAmqpMessageFromTheBatch(string partitonKey) { var messageFactory = default(Func <AmqpMessage>); var expectedMaximumSize = 512; var options = new CreateBatchOptions { PartitionKey = partitonKey }; var retryPolicy = new BasicRetryPolicy(new RetryOptions { TryTimeout = TimeSpan.FromSeconds(17) }); var producer = new Mock <AmqpProducer>("aHub", null, Mock.Of <AmqpConnectionScope>(), new AmqpMessageConverter(), retryPolicy) { CallBase = true }; producer .Protected() .Setup <Task <SendingAmqpLink> >("CreateLinkAndEnsureProducerStateAsync", ItExpr.IsAny <string>(), ItExpr.IsAny <TimeSpan>(), ItExpr.IsAny <CancellationToken>()) .Callback(() => SetMaximumMessageSize(producer.Object, expectedMaximumSize)) .Returns(Task.FromResult(new SendingAmqpLink(new AmqpLinkSettings()))); producer .Protected() .Setup <Task>("SendAsync", ItExpr.IsAny <Func <AmqpMessage> >(), ItExpr.IsAny <string>(), ItExpr.IsAny <CancellationToken>()) .Callback <Func <AmqpMessage>, string, CancellationToken>((factory, key, token) => messageFactory = factory) .Returns(Task.CompletedTask); using TransportEventBatch transportBatch = await producer.Object.CreateBatchAsync(options, default); using var batch = new EventDataBatch(transportBatch, options); batch.TryAdd(new EventData(new byte[] { 0x15 })); await producer.Object.SendAsync(batch, CancellationToken.None); Assert.That(messageFactory, Is.Not.Null, "The batch message factory should have been set."); using var batchMessage = new AmqpMessageConverter().CreateBatchFromMessages(batch.AsEnumerable <AmqpMessage>(), partitonKey); using var factoryMessage = messageFactory(); Assert.That(factoryMessage.SerializedMessageSize, Is.EqualTo(batchMessage.SerializedMessageSize), "The serialized size of the messages should match."); }
public void CreateEventFromMessageAllowsAnEmptyMessageWithProperties() { var propertyValue = 1; var message = AmqpMessage.Create(); message.ApplicationProperties.Map.Add("Test", propertyValue); message.MessageAnnotations.Map.Add(AmqpProperty.Offset, propertyValue.ToString()); var eventData = new AmqpMessageConverter().CreateEventFromMessage(message); Assert.That(eventData, Is.Not.Null, "The event should have been created."); Assert.That(eventData.Properties.Count, Is.EqualTo(message.ApplicationProperties.Map.Count()), "There should have been properties present."); Assert.That(eventData.Properties.First().Value, Is.EqualTo(propertyValue), "The application property should have been populated."); Assert.That(eventData.Offset, Is.EqualTo(propertyValue), "The offset should have been populated."); }
public void PeekedMessageShouldNotIncrementDeliveryCount() { var messageBody = Encoding.UTF8.GetBytes("message1"); var amqpValue = new AmqpValue(); amqpValue.Value = new ArraySegment <byte>(messageBody); var amqpMessage = AmqpMessage.Create(amqpValue); amqpMessage.Header.DeliveryCount = 2; var sbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, isPeeked: true); sbMessage.SequenceNumber = 1L; Assert.AreEqual(2, sbMessage.DeliveryCount); }
void When_message_is_received_should_have_delivery_count_increased() { var messageBody = Encoding.UTF8.GetBytes("message1"); var amqpValue = new AmqpValue(); amqpValue.Value = new ArraySegment <byte>(messageBody); var amqpMessage = AmqpMessage.Create(amqpValue); amqpMessage.Header.DeliveryCount = 2; var sbMessage = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage, isPeeked: false); sbMessage.SystemProperties.SequenceNumber = 1L; Assert.Equal(3, sbMessage.SystemProperties.DeliveryCount); }
public void CreateMessageFromEventPopulatesSimpleApplicationProperties() { var propertyValues = new object[] { (byte)0x22, (sbyte)0x11, (Int16)5, (Int32)27, (Int64)1122334, (UInt16)12, (UInt32)24, (UInt64)9955, (Single)4.3, (Double)3.4, (Decimal)7.893, Guid.NewGuid(), DateTime.Parse("2015-10-27T12:00:00Z"), true, 'x', "hello" }; var eventData = new EventData(new byte[] { 0x11, 0x22, 0x33 }) { Properties = propertyValues.ToDictionary(value => $"{ value.GetType().Name }Property", value => value) }; using var message = new AmqpMessageConverter().CreateMessageFromEvent(eventData); Assert.That(message, Is.Not.Null, "The AMQP message should have been created."); Assert.That(message.DataBody, Is.Not.Null, "The AMQP message should a body."); Assert.That(message.ApplicationProperties, Is.Not.Null, "The AMQP message should have a set of application properties."); // The collection comparisons built into the test assertions do not recognize // the property sets as equivalent, but a manual inspection proves the properties exist // in both. foreach (var property in eventData.Properties.Keys) { var containsValue = message.ApplicationProperties.Map.TryGetValue(property, out object value); Assert.That(containsValue, Is.True, $"The message properties did not contain: [{ property }]"); Assert.That(value, Is.EqualTo(eventData.Properties[property]), $"The property value did not match for: [{ property }]"); } }
public void CreateBatchFromEventsWithOneMessagePopulatesEnvelopeProperties(string partitionKey) { var eventData = new EventData(new byte[] { 0x11, 0x22, 0x33 }); var converter = new AmqpMessageConverter(); using var message = converter.CreateBatchFromEvents(new[] { eventData }, partitionKey); Assert.That(message, Is.Not.Null, "The batch envelope should have been created."); Assert.That(message.Batchable, Is.True, "The batch envelope should be set to batchable."); Assert.That(message.MessageFormat, Is.EqualTo(AmqpConstants.AmqpBatchedMessageFormat), "The batch envelope should have a batchable format."); Assert.That(message.DataBody, Is.Not.Null, "The batch envelope should a body."); Assert.That(message.DataBody.ToList().Count, Is.EqualTo(1), "The batch envelope should contain a single event in the body."); Assert.That(message.MessageAnnotations.Map.TryGetValue(AmqpAnnotation.PartitionKey, out string partitionKeyAnnotation), Is.EqualTo(!String.IsNullOrEmpty(partitionKey)), "There should be an annotation if a partition key was present."); if (!String.IsNullOrEmpty(partitionKey)) { Assert.That(partitionKeyAnnotation, Is.EqualTo(partitionKey), "The partition key annotation should match."); } }
public void AnEventCanBeTranslatedToItself() { var sourceEvent = new EventData(new byte[] { 0x11, 0x22, 0x33 }) { Properties = new Dictionary <string, object> { { "Test", 1234 } } }; var converter = new AmqpMessageConverter(); using var message = converter.CreateMessageFromEvent(sourceEvent); var eventData = converter.CreateEventFromMessage(message); Assert.That(message, Is.Not.Null, "The AMQP message should have been created."); Assert.That(eventData, Is.Not.Null, "The translated event should have been created."); Assert.That(eventData.IsEquivalentTo(sourceEvent), "The translated event should match the source event."); }
long GetEventSizeForBatch(EventData eventData) { // Create AMQP message here. We will use the same message while sending to save compute time. var amqpMessage = AmqpMessageConverter.EventDataToAmqpMessage(eventData); AmqpMessageConverter.UpdateAmqpMessagePartitionKey(amqpMessage, this.PartitionKey); eventData.AmqpMessage = amqpMessage; // Calculate overhead depending on the message size. if (eventData.AmqpMessage.SerializedMessageSize < 256) { // Overhead is smaller for messages smaller than 256 bytes. return(eventData.AmqpMessage.SerializedMessageSize + 5); } else { return(eventData.AmqpMessage.SerializedMessageSize + 8); } }
void UpdateEventDataHeaderAndPropertiesReceiveCorrelationIdAndCopyItsValueToEventData() { // Arrange // the following simulates a message's round trip from client to broker to client var message = AmqpMessage.Create(new MemoryStream(new byte[12]), true); AddSection(message, SectionFlag.Properties); // serialize - send the message on client side ArraySegment <byte>[] buffers = ReadMessagePayLoad(message, 71); // Act var eventData = AmqpMessageConverter.AmqpMessageToEventData(message); // Assert Assert.NotNull(eventData); Assert.NotNull(eventData.SystemProperties); Assert.NotNull(eventData.SystemProperties[Properties.CorrelationIdName]); Assert.Equal("42", eventData.SystemProperties[Properties.CorrelationIdName].ToString()); }
public async Task ReceiveMessageTest() { // Arrange var deviceListener = new Mock <IDeviceListener>(); var connectionHandler = Mock.Of <IConnectionHandler>(c => c.GetDeviceListener() == Task.FromResult(deviceListener.Object)); var amqpAuthenticator = new Mock <IAmqpAuthenticator>(); amqpAuthenticator.Setup(c => c.AuthenticateAsync("d1")).ReturnsAsync(true); Mock <ICbsNode> cbsNodeMock = amqpAuthenticator.As <ICbsNode>(); ICbsNode cbsNode = cbsNodeMock.Object; var amqpConnection = Mock.Of <IAmqpConnection>( c => c.FindExtension <IConnectionHandler>() == connectionHandler && c.FindExtension <ICbsNode>() == cbsNode); var amqpSession = Mock.Of <IAmqpSession>(s => s.Connection == amqpConnection); var receivingLink = Mock.Of <IReceivingAmqpLink>(l => l.Session == amqpSession && l.IsReceiver && l.Settings == new AmqpLinkSettings() && l.State == AmqpObjectState.Opened); var requestUri = new Uri("amqps://foo.bar/devices/d1"); var boundVariables = new Dictionary <string, string> { { "deviceid", "d1" } }; var messageConverter = new AmqpMessageConverter(); var body = new byte[] { 0, 1, 2, 3 }; AmqpMessage message = AmqpMessage.Create(new Data { Value = new ArraySegment <byte>(body) }); var identity = Mock.Of <IIdentity>(i => i.Id == "d1"); var productInfoStore = Mock.Of <IProductInfoStore>(); var modelIdStore = Mock.Of <IModelIdStore>(); // Act var receivingLinkHandler = new TestReceivingLinkHandler(identity, receivingLink, requestUri, boundVariables, connectionHandler, messageConverter, productInfoStore, modelIdStore); await receivingLinkHandler.OpenAsync(Constants.DefaultTimeout); await receivingLinkHandler.ProcessMessageAsync(message); // Assert await Task.Delay(TimeSpan.FromSeconds(3)); Assert.Equal(1, receivingLinkHandler.ReceivedMessages.Count); Assert.Equal(body, receivingLinkHandler.ReceivedMessages[0].GetPayloadBytes()); }
protected virtual async Task <IList <Message> > OnReceiveBySequenceNumberAsync(IEnumerable <long> sequenceNumbers) { List <Message> messages = new List <Message>(); try { AmqpRequestMessage requestMessage = AmqpRequestMessage.CreateRequest(ManagementConstants.Operations.ReceiveBySequenceNumberOperation, this.OperationTimeout, null); requestMessage.Map[ManagementConstants.Properties.SequenceNumbers] = sequenceNumbers.ToArray(); requestMessage.Map[ManagementConstants.Properties.ReceiverSettleMode] = (uint)(this.ReceiveMode == ReceiveMode.ReceiveAndDelete ? 0 : 1); AmqpResponseMessage response = await this.ExecuteRequestResponseAsync(requestMessage).ConfigureAwait(false); if (response.StatusCode == AmqpResponseStatusCode.OK) { IEnumerable <AmqpMap> amqpMapList = response.GetListValue <AmqpMap>(ManagementConstants.Properties.Messages); foreach (AmqpMap entry in amqpMapList) { ArraySegment <byte> payload = (ArraySegment <byte>)entry[ManagementConstants.Properties.Message]; AmqpMessage amqpMessage = AmqpMessage.CreateAmqpStreamMessage(new BufferListStream(new[] { payload }), true); Message message = AmqpMessageConverter.AmqpMessageToSBMessage(amqpMessage); Guid lockToken; if (entry.TryGetValue(ManagementConstants.Properties.LockToken, out lockToken)) { message.SystemProperties.LockTokenGuid = lockToken; this.requestResponseLockedMessages.AddOrUpdate(lockToken, message.SystemProperties.LockedUntilUtc); } messages.Add(message); } } else { throw response.ToMessagingContractException(); } } catch (Exception exception) { throw AmqpExceptionHelper.GetClientException(exception); } return(messages); }
public void CreateEventFromMessageDoesNotIncludeUnknownApplicationPropertyType() { using var bodyStream = new MemoryStream(new byte[] { 0x11, 0x22, 0x33 }, false); using var message = AmqpMessage.Create(bodyStream, true); var typeDescriptor = (AmqpSymbol)"INVALID"; var describedProperty = new DescribedType(typeDescriptor, 1234); message.ApplicationProperties.Map.Add(typeDescriptor.ToString(), describedProperty); var converter = new AmqpMessageConverter(); var eventData = converter.CreateEventFromMessage(message); Assert.That(eventData, Is.Not.Null, "The event should have been created."); Assert.That(eventData.Body, Is.Not.Null, "The event should have a body."); Assert.That(eventData.Properties.Any(), Is.False, "The event should not have a set of application properties."); var containsValue = eventData.Properties.TryGetValue(typeDescriptor.ToString(), out var _); Assert.That(containsValue, Is.False, $"The event properties should not contain the described property."); }
public void CreateBatchFromMessagesWithMultipleEventsMessagePopulatesEnvelopeProperties(string partitionKey) { var converter = new AmqpMessageConverter(); using var first = converter.CreateMessageFromEvent(new EventData(new byte[] { 0x11, 0x22, 0x33 })); using var second = converter.CreateMessageFromEvent(new EventData(new byte[] { 0x44, 0x55, 0x66 })); var source = new[] { first, second }; using var batchEnvelope = converter.CreateBatchFromMessages(source, partitionKey); Assert.That(batchEnvelope, Is.Not.Null, "The batch envelope should have been created."); Assert.That(batchEnvelope.Batchable, Is.True, "The batch envelope should be marked as batchable."); Assert.That(batchEnvelope.MessageFormat, Is.EqualTo(AmqpConstants.AmqpBatchedMessageFormat), "The batch envelope should be marked with a batchable format."); Assert.That(batchEnvelope.DataBody, Is.Not.Null, "The batch envelope should a body."); Assert.That(batchEnvelope.DataBody.ToList().Count, Is.EqualTo(source.Length), "The batch envelope should contain each batch event in the body."); Assert.That(batchEnvelope.MessageAnnotations.Map.TryGetValue(AmqpAnnotation.PartitionKey, out string partitionKeyAnnotation), Is.EqualTo(!String.IsNullOrEmpty(partitionKey)), "There should be an annotation if a partition key was present."); if (!String.IsNullOrEmpty(partitionKey)) { Assert.That(partitionKeyAnnotation, Is.EqualTo(partitionKey), "The partition key annotation should match."); } }
public void ToMessageTest() { // Arrange IMessage receivedMessage; byte[] bytes = { 1, 2, 3, 4 }; string messageId = Guid.NewGuid().ToString(); string correlationId = Guid.NewGuid().ToString(); using (AmqpMessage amqpMessage = AmqpMessage.Create(new Data { Value = new ArraySegment <byte>(bytes) })) { amqpMessage.Properties.MessageId = messageId; amqpMessage.Properties.CorrelationId = correlationId; amqpMessage.Properties.ContentType = "application/json"; amqpMessage.Properties.ContentEncoding = "UTF-8"; amqpMessage.ApplicationProperties.Map["Prop1"] = "Value1"; amqpMessage.ApplicationProperties.Map["Prop2"] = "Value2"; var messageConverter = new AmqpMessageConverter(); // Act receivedMessage = messageConverter.ToMessage(amqpMessage); } // Assert Assert.NotNull(receivedMessage); Assert.Equal(receivedMessage.Body, bytes); Assert.Equal(receivedMessage.SystemProperties.Count, 4); Assert.Equal(receivedMessage.Properties.Count, 2); Assert.Equal(receivedMessage.SystemProperties[SystemProperties.MessageId], messageId); Assert.Equal(receivedMessage.SystemProperties[SystemProperties.MsgCorrelationId], correlationId); Assert.Equal(receivedMessage.SystemProperties[SystemProperties.ContentType], "application/json"); Assert.Equal(receivedMessage.SystemProperties[SystemProperties.ContentEncoding], "UTF-8"); Assert.Equal(receivedMessage.Properties["Prop1"], "Value1"); Assert.Equal(receivedMessage.Properties["Prop2"], "Value2"); }
public void CreateEventFromMessagePopulatesAnArraySegmentApplicationPropertyType() { using var bodyStream = new MemoryStream(new byte[] { 0x11, 0x22, 0x33 }, false); using var message = AmqpMessage.Create(bodyStream, true); var propertyKey = "Test"; var propertyValue = new byte[] { 0x11, 0x15, 0xF8, 0x20 }; message.ApplicationProperties.Map.Add(propertyKey, new ArraySegment <byte>(propertyValue, 1, 2)); var converter = new AmqpMessageConverter(); var eventData = converter.CreateEventFromMessage(message); Assert.That(eventData, Is.Not.Null, "The event should have been created."); Assert.That(eventData.Body, Is.Not.Null, "The event should have a body."); Assert.That(eventData.Properties.Any(), Is.True, "The event should have a set of application properties."); var containsValue = eventData.Properties.TryGetValue(propertyKey, out var eventValue); Assert.That(containsValue, Is.True, $"The event properties should contain the property."); Assert.That(eventValue, Is.EquivalentTo(propertyValue.Skip(1).Take(2))); }