예제 #1
0
        public override async Task SendEventAsync(IEnumerable <Message> messages, CancellationToken cancellationToken)
        {
            await this.HandleTimeoutCancellation(async() =>
            {
                // List to hold messages in Amqp friendly format
                var messageList = new List <Data>();

                foreach (Message message in messages)
                {
                    using (AmqpMessage amqpMessage = message.ToAmqpMessage())
                    {
                        var data = new Data()
                        {
                            Value = MessageConverter.ReadStream(amqpMessage.ToStream())
                        };
                        messageList.Add(data);
                    }
                }

                Outcome outcome;
                using (AmqpMessage amqpMessage = AmqpMessage.Create(messageList))
                {
                    amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;
                    outcome = await this.SendAmqpMessageAsync(amqpMessage, cancellationToken);
                }

                if (outcome.DescriptorCode != Accepted.Code)
                {
                    throw AmqpErrorMapper.GetExceptionFromOutcome(outcome);
                }
            }, cancellationToken);
        }
예제 #2
0
        public override async Task SendTwinPatchAsync(TwinCollection reportedProperties, CancellationToken cancellationToken)
        {
            try
            {
                await EnableTwinPatchAsync(cancellationToken);

                var body       = JsonConvert.SerializeObject(reportedProperties);
                var bodyStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(body));

                var amqpMessage = AmqpMessage.Create(bodyStream, true);
                amqpMessage.MessageAnnotations.Map["operation"] = "PATCH";
                amqpMessage.MessageAnnotations.Map["resource"]  = "/properties/reported";
                amqpMessage.MessageAnnotations.Map["version"]   = null;

                await RoundTripTwinMessage(amqpMessage, cancellationToken);
            }
            catch (Exception exception)
            {
                if (exception.IsFatal())
                {
                    throw;
                }

                throw AmqpClientHelper.ToIotHubClientContract(exception);
            }
        }
        public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoApplicationProperties()
        {
            AmqpMessage amqpResponse = AmqpMessage.Create();
            TimeSpan?   actual       = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval);

            Assert.IsNull(actual);
        }
예제 #4
0
        public void DisposeClearsTheSize()
        {
            var options = new CreateBatchOptions {
                MaxSizeInBytes = 5000
            };
            var messages = new AmqpMessage[5];

            for (var index = 0; index < messages.Length; ++index)
            {
                messages[index] = AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x66 })
                });
            }

            // Add the messages to the batch; all should be accepted.

            var batch = new AmqpMessageBatch(options);

            for (var index = 0; index < messages.Length; ++index)
            {
                Assert.That(batch.TryAdd(new ServiceBusMessage(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted.");
            }

            Assert.That(batch.SizeInBytes, Is.GreaterThan(0), "The size should have been set when the batch was updated.");

            batch.Dispose();
            Assert.That(batch.SizeInBytes, Is.EqualTo(GetReservedSize(batch)), "The size should have been reset when the batch was cleared.");
        }
예제 #5
0
        public void GetIdentityTest()
        {
            // Arrange
            var amqpValue = new AmqpValue
            {
                Value = TokenHelper.CreateSasToken("edgehubtest1.azure-devices.net/devices/device1/modules/mod1")
            };
            AmqpMessage validAmqpMessage = AmqpMessage.Create(amqpValue);

            validAmqpMessage.ApplicationProperties.Map[CbsConstants.PutToken.Type]     = "azure-devices.net:sastoken";
            validAmqpMessage.ApplicationProperties.Map[CbsConstants.PutToken.Audience] = "edgehubtest1.azure-devices.net/devices/device1";
            validAmqpMessage.ApplicationProperties.Map[CbsConstants.Operation]         = CbsConstants.PutToken.OperationValue;

            var clientCredentials = Mock.Of <IClientCredentials>();
            var identityFactory   = new Mock <IClientCredentialsFactory>();

            identityFactory.Setup(i => i.GetWithSasToken(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), true, It.IsAny <Option <string> >()))
            .Returns(clientCredentials);

            string iotHubHostName = "edgehubtest1.azure-devices.net";
            var    authenticator  = new Mock <IAuthenticator>();
            var    cbsNode        = new CbsNode(identityFactory.Object, iotHubHostName, authenticator.Object, new NullCredentialsCache());

            // Act
            IClientCredentials receivedClientCredentials = cbsNode.GetClientCredentials(validAmqpMessage);

            // Assert
            Assert.NotNull(receivedClientCredentials);
            Assert.Equal(clientCredentials, receivedClientCredentials);
        }
예제 #6
0
        public void TryAddSetsTheCount()
        {
            var options = new CreateBatchOptions {
                MaxSizeInBytes = 5000
            };
            var messages = new AmqpMessage[5];

            for (var index = 0; index < messages.Length; ++index)
            {
                messages[index] = AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x66 })
                });
            }

            // Add the messages to the batch; all should be accepted.

            var batch = new AmqpMessageBatch(options);

            for (var index = 0; index < messages.Length; ++index)
            {
                Assert.That(batch.TryAdd(new ServiceBusMessage(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted.");
            }

            Assert.That(batch.Count, Is.EqualTo(messages.Length), "The count should have been set when the batch was updated.");
        }
        public void CreateEventFromMessagePopulatesSystemProperties()
        {
            var offset         = 123;
            var sequenceNumber = (Int64.MaxValue - 10);
            var enqueuedTime   = DateTimeOffset.Parse("2015-10-27T12:00:00Z");
            var partitionKey   = "OMG! partition!";

            using var bodyStream = new MemoryStream(new byte[] { 0x11, 0x22, 0x33 }, false);
            using var message    = AmqpMessage.Create(bodyStream, true);

            message.ApplicationProperties.Map.Add("First", 1);
            message.ApplicationProperties.Map.Add("Second", "2");

            message.MessageAnnotations.Map.Add(AmqpProperty.Offset, offset.ToString());
            message.MessageAnnotations.Map.Add(AmqpProperty.SequenceNumber, sequenceNumber);
            message.MessageAnnotations.Map.Add(AmqpProperty.EnqueuedTime, new DescribedType(AmqpProperty.Descriptor.DateTimeOffset, enqueuedTime.Ticks));
            message.MessageAnnotations.Map.Add(AmqpProperty.PartitionKey, partitionKey);

            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.Count, Is.EqualTo(message.ApplicationProperties.Map.Count()), "The event should have a set of properties.");
            Assert.That(eventData.Offset, Is.EqualTo(offset), "The offset should match.");
            Assert.That(eventData.SequenceNumber, Is.EqualTo(sequenceNumber), "The sequence number should match.");
            Assert.That(eventData.EnqueuedTime, Is.EqualTo(enqueuedTime), "The enqueue time should match.");
            Assert.That(eventData.PartitionKey, Is.EqualTo(partitionKey), "The partition key should match.");
        }
예제 #8
0
        static AmqpMessage GetBatchedMessage(IEnumerable <string> contents)
        {
            var messageList = new List <Data>();
            int ctr         = 0;

            foreach (string msgContent in contents)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(msgContent);
                using (AmqpMessage msg = AmqpMessage.Create(new MemoryStream(bytes), false))
                {
                    msg.Properties.MessageId  = $"{ctr}";
                    msg.ApplicationProperties = new ApplicationProperties();
                    msg.ApplicationProperties.Map["MsgCnt"]  = $"{ctr++}";
                    msg.ApplicationProperties.Map["MsgData"] = msgContent;
                    var data = new Data
                    {
                        Value = ReadStream(msg.ToStream())
                    };
                    messageList.Add(data);
                }
            }

            AmqpMessage amqpMessage = AmqpMessage.Create(messageList);

            amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;
            return(amqpMessage);
        }
예제 #9
0
        internal AmqpMessage ToAmqpMessage(bool setBodyCalled = true)
        {
            this.ThrowIfDisposed();
            if (this.serializedAmqpMessage == null)
            {
                lock (this.messageLock)
                {
                    if (this.serializedAmqpMessage == null)
                    {
                        // Interlocked exchange two variable does allow for a small period
                        // where one is set while the other is not. Not sure if it is worth
                        // correct this gap. The intention of setting this two variable is
                        // so that GetBody should not be called and all Properties are
                        // readonly because the amqpMessage has been serialized.
                        if (setBodyCalled)
                        {
                            this.SetGetBodyCalled();
                        }

                        this.SetSizeInBytesCalled();
                        this.serializedAmqpMessage = this.bodyStream == null
                            ? AmqpMessage.Create()
                            : AmqpMessage.Create(this.bodyStream, false);

                        this.serializedAmqpMessage = this.PopulateAmqpMessageForSend(this.serializedAmqpMessage);
                    }
                }
            }

            return(this.serializedAmqpMessage);
        }
예제 #10
0
        public void TryAddSetsTheCount()
        {
            var currentIndex = -1;
            var options      = new BatchOptions {
                MaximumizeInBytes = 5000
            };
            var eventMessages = new AmqpMessage[5];
            var mockEnvelope  = new Mock <AmqpMessage>();
            var mockConverter = new InjectableMockConverter();

            mockConverter.CreateBatchFromEventsHandler  = (_e, _p) => mockEnvelope.Object;
            mockConverter.CreateMessageFromEventHandler = (_e, _p) => eventMessages[++currentIndex];

            mockEnvelope
            .Setup(message => message.SerializedMessageSize)
            .Returns(0);

            for (var index = 0; index < eventMessages.Length; ++index)
            {
                eventMessages[index] = AmqpMessage.Create(new Data {
                    Value = new ArraySegment <byte>(new byte[] { 0x66 })
                });
            }

            // Add the messages to the batch; all should be accepted.

            var batch = new AmqpEventBatch(mockConverter, options);

            for (var index = 0; index < eventMessages.Length; ++index)
            {
                Assert.That(batch.TryAdd(new EventData(new byte[0])), Is.True, $"The addition for index: { index } should fit and be accepted.");
            }

            Assert.That(batch.Count, Is.EqualTo(eventMessages.Length), "The count should have been set when the batch was updated.");
        }
예제 #11
0
        private async Task <RegistrationOperationStatus> OperationStatusLookupAsync(
            AmqpClientConnection client,
            string operationId,
            string correlationId)
        {
            var amqpMessage = AmqpMessage.Create(new AmqpValue()
            {
                Value = DeviceOperations.GetOperationStatus
            });

            amqpMessage.Properties.CorrelationId = correlationId;
            amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationType] =
                DeviceOperations.GetOperationStatus;
            amqpMessage.ApplicationProperties.Map[MessageApplicationPropertyNames.OperationId] = operationId;
            var outcome = await client.AmqpSession.SendingLink
                          .SendMessageAsync(amqpMessage, new ArraySegment <byte>(Guid.NewGuid().ToByteArray()),
                                            TimeoutConstant).ConfigureAwait(false);

            ValidateOutcome(outcome);
            var amqpResponse = await client.AmqpSession.ReceivingLink.ReceiveMessageAsync(TimeoutConstant)
                               .ConfigureAwait(false);

            client.AmqpSession.ReceivingLink.AcceptMessage(amqpResponse);
            string jsonResponse = await new StreamReader(amqpResponse.BodyStream).ReadToEndAsync()
                                  .ConfigureAwait(false);

            return(JsonConvert.DeserializeObject <RegistrationOperationStatus>(jsonResponse));
        }
예제 #12
0
        public void AmqpMessageSerializedSizeTest()
        {
            var message = AmqpMessage.Create(new Data()
            {
                Value = new ArraySegment <byte>(new byte[60])
            });
            long size = message.SerializedMessageSize;

            Assert.True(size > 0);

            message.Properties.MessageId = Guid.NewGuid();
            long size2 = message.SerializedMessageSize;

            Assert.True(size2 > size);

            message.MessageAnnotations.Map["property"] = "v1";
            long size3 = message.SerializedMessageSize;

            Assert.True(size3 > size2);

            var stream   = (BufferListStream)message.ToStream();
            var message2 = AmqpMessage.CreateInputMessage(stream);

            Assert.Equal("v1", message2.MessageAnnotations.Map["property"]);

            message.Properties.MessageId = "12345";
            message.MessageAnnotations.Map["property"] = "v2";
            stream = (BufferListStream)message.ToStream();
            var message3 = AmqpMessage.CreateInputMessage(stream);

            Assert.Equal((MessageId)"12345", message3.Properties.MessageId);
            Assert.Equal("v2", message3.MessageAnnotations.Map["property"]);
        }
        /// <summary>
        ///   Builds an <see cref="AmqpMessage" /> from an <see cref="EventData" />.
        /// </summary>
        ///
        /// <param name="source">The event to use as the source of the message.</param>
        /// <param name="partitionKey">The partition key to annotate the AMQP message with; if no partition key is specified, the annotation will not be made.</param>
        ///
        /// <returns>The <see cref="AmqpMessage" /> constructed from the source event.</returns>
        ///
        private static AmqpMessage BuildAmqpMessageFromEvent(EventData source,
                                                             string partitionKey)
        {
            var body    = new ArraySegment <byte>((source.Body.IsEmpty) ? Array.Empty <byte>() : source.Body.ToArray());
            var message = AmqpMessage.Create(new Data {
                Value = body
            });

            if (source.Properties?.Count > 0)
            {
                message.ApplicationProperties = message.ApplicationProperties ?? new ApplicationProperties();

                foreach (var pair in source.Properties)
                {
                    if (TryCreateAmqpPropertyValueForEventProperty(pair.Value, out var amqpValue))
                    {
                        message.ApplicationProperties.Map[pair.Key] = amqpValue;
                    }
                }
            }

            if (!String.IsNullOrEmpty(partitionKey))
            {
                message.MessageAnnotations.Map[AmqpAnnotation.PartitionKey] = partitionKey;
            }

            return(message);
        }
예제 #14
0
 public static AmqpMessage CreateMessage(ArraySegment <byte> binaryData)
 {
     return(AmqpMessage.Create(new Data[] { new Data()
                                            {
                                                Value = binaryData
                                            } }));
 }
예제 #15
0
        internal async Task <AmqpIoTOutcome> SendTwinPatchMessageAsync(string correlationId, TwinCollection reportedProperties, TimeSpan timeout)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, $"{nameof(SendTwinPatchMessageAsync)}");
            }

            var body       = JsonConvert.SerializeObject(reportedProperties);
            var bodyStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(body));

            AmqpMessage amqpMessage = AmqpMessage.Create(bodyStream, true);

            amqpMessage.Properties.CorrelationId            = correlationId;
            amqpMessage.MessageAnnotations.Map["operation"] = "PATCH";
            amqpMessage.MessageAnnotations.Map["resource"]  = "/properties/reported";
            amqpMessage.MessageAnnotations.Map["version"]   = null;

            Outcome outcome = await SendAmqpMessageAsync(amqpMessage, timeout).ConfigureAwait(false);

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, $"{nameof(SendTwinPatchMessageAsync)}");
            }

            return(new AmqpIoTOutcome(outcome));
        }
예제 #16
0
        public void ToMessageNoAppPropsTest()
        {
            // 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 = null;

                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, 0);
            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");
        }
예제 #17
0
            protected override IEnumerator <IteratorAsyncResult <AmqpCbsLink.SendTokenAsyncResult> .AsyncStep> GetAsyncSteps()
            {
                string str;

                AmqpCbsLink.SendTokenAsyncResult sendTokenAsyncResult = this;
                IteratorAsyncResult <AmqpCbsLink.SendTokenAsyncResult> .BeginCall beginCall = (AmqpCbsLink.SendTokenAsyncResult thisPtr, TimeSpan t, AsyncCallback c, object s) => thisPtr.tokenProvider.BeginGetMessagingToken(this.namespaceAddress, thisPtr.resource, thisPtr.requiredClaims[0], false, t, c, s);
                yield return(sendTokenAsyncResult.CallAsync(beginCall, (AmqpCbsLink.SendTokenAsyncResult thisPtr, IAsyncResult r) => thisPtr.swt = (SimpleWebSecurityToken)thisPtr.tokenProvider.EndGetMessagingToken(r), IteratorAsyncResult <TIteratorAsyncResult> .ExceptionPolicy.Transfer));

                if (this.swt is SharedAccessSignatureToken)
                {
                    str = "servicebus.windows.net:sastoken";
                }
                else if (this.swt != null)
                {
                    str = "amqp:swt";
                }
                else
                {
                    str = null;
                }
                string str1 = str;

                if (str1 != null)
                {
                    if (!this.cbsLink.FaultTolerantLink.TryGetOpenedObject(out this.requestResponseLink))
                    {
                        AmqpCbsLink.SendTokenAsyncResult sendTokenAsyncResult1 = this;
                        IteratorAsyncResult <AmqpCbsLink.SendTokenAsyncResult> .BeginCall beginCall1 = (AmqpCbsLink.SendTokenAsyncResult thisPtr, TimeSpan t, AsyncCallback c, object s) => thisPtr.cbsLink.FaultTolerantLink.BeginGetInstance(t, c, s);
                        yield return(sendTokenAsyncResult1.CallAsync(beginCall1, (AmqpCbsLink.SendTokenAsyncResult thisPtr, IAsyncResult r) => thisPtr.requestResponseLink = thisPtr.cbsLink.FaultTolerantLink.EndGetInstance(r), IteratorAsyncResult <TIteratorAsyncResult> .ExceptionPolicy.Transfer));
                    }
                    AmqpValue amqpValue = new AmqpValue()
                    {
                        Value = this.swt.Token
                    };
                    AmqpMessage applicationProperty = AmqpMessage.Create(amqpValue);
                    applicationProperty.ApplicationProperties = new ApplicationProperties();
                    applicationProperty.ApplicationProperties.Map["operation"]  = "put-token";
                    applicationProperty.ApplicationProperties.Map["type"]       = str1;
                    applicationProperty.ApplicationProperties.Map["name"]       = this.audience;
                    applicationProperty.ApplicationProperties.Map["expiration"] = this.swt.ExpiresOn;
                    AmqpMessage amqpMessage = null;
                    yield return(base.CallAsync((AmqpCbsLink.SendTokenAsyncResult thisPtr, TimeSpan t, AsyncCallback c, object s) => this.requestResponseLink.BeginRequest(applicationProperty, t, c, s), (AmqpCbsLink.SendTokenAsyncResult thisPtr, IAsyncResult r) => amqpMessage = this.requestResponseLink.EndRequest(r), IteratorAsyncResult <TIteratorAsyncResult> .ExceptionPolicy.Transfer));

                    int    item  = (int)amqpMessage.ApplicationProperties.Map["status-code"];
                    string item1 = (string)amqpMessage.ApplicationProperties.Map["status-description"];
                    if (item != 202)
                    {
                        base.Complete(AmqpCbsLink.SendTokenAsyncResult.ConvertToException(item, item1));
                    }
                    else
                    {
                        this.ValidTo = this.swt.ValidTo;
                    }
                }
                else
                {
                    base.Complete(new InvalidOperationException(SRAmqp.AmqpUnssuportedTokenType));
                }
            }
예제 #18
0
        static AmqpMessage CreateCommandMessage(IAmqpSerializable command)
        {
            AmqpValue value = new AmqpValue {
                Value = command
            };

            return(AmqpMessage.Create(value));
        }
예제 #19
0
 public static AmqpMessage ToAmqpMessage(this ServiceBusMessage message)
 {
     if (message.AmqpMessage.Body is AmqpDataMessageBody dataBody)
     {
         return(AmqpMessage.Create(dataBody.Data.AsAmqpData()));
     }
     throw new NotSupportedException($"{message.AmqpMessage.Body.GetType()} is not a supported message body type.");
 }
 public static AmqpMessage ToAmqpMessage(this ServiceBusMessage message)
 {
     if (message.AmqpMessage.Body.TryGetData(out IEnumerable <ReadOnlyMemory <byte> > dataBody))
     {
         return(AmqpMessage.Create(dataBody.AsAmqpData()));
     }
     throw new NotSupportedException($"{message.AmqpMessage.Body.GetType()} is not a supported message body type.");
 }
예제 #21
0
        public async Task SendLargeMessageThrowsTest()
        {
            // Arrange
            bool disposeMessageCalled = true;
            var  identity             = Mock.Of <IIdentity>(i => i.Id == "d1");

            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.GetDeviceListener() == Task.FromResult(deviceListener));
            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 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 productInfoStore = Mock.Of <IProductInfoStore>();
            var modelIdStore     = Mock.Of <IModelIdStore>();
            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(identity, amqpLink, requestUri, boundVariables, connectionHandler, messageConverter, productInfoStore, modelIdStore);

                // Act
                await linkHandler.OpenAsync(TimeSpan.FromSeconds(30));

                // Assert
                Assert.NotNull(onMessageCallback);

                // Act
                onMessageCallback.Invoke(amqpMessage);

                // Assert
                await WaitAndAssert(() => disposeMessageCalled, TimeSpan.FromSeconds(5));
            }
        }
예제 #22
0
        public static AmqpMessage BrokeredMessagesToAmqpMessage(IEnumerable <BrokeredMessage> brokeredMessages, bool batchable)
        {
            AmqpMessage     amqpMessage          = null;
            AmqpMessage     firstAmqpMessage     = null;
            BrokeredMessage firstBrokeredMessage = null;
            List <Data>     dataList             = null;
            int             messageCount         = 0;

            foreach (var brokeredMessage in brokeredMessages)
            {
                messageCount++;

                amqpMessage = AmqpMessageConverter.ClientGetMessage(brokeredMessage);
                if (firstAmqpMessage == null)
                {
                    firstAmqpMessage     = amqpMessage;
                    firstBrokeredMessage = brokeredMessage;
                    continue;
                }

                if (dataList == null)
                {
                    dataList = new List <Data>()
                    {
                        ToData(firstAmqpMessage)
                    };
                }

                dataList.Add(ToData(amqpMessage));
            }

            if (messageCount == 1 && firstAmqpMessage != null)
            {
                firstAmqpMessage.Batchable = batchable;
                return(firstAmqpMessage);
            }

            amqpMessage = AmqpMessage.Create(dataList);
            amqpMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;

            if (firstBrokeredMessage.MessageId != null)
            {
                amqpMessage.Properties.MessageId = firstBrokeredMessage.MessageId;
            }
            if (firstBrokeredMessage.SessionId != null)
            {
                amqpMessage.Properties.GroupId = firstBrokeredMessage.SessionId;
            }

            if (firstBrokeredMessage.PartitionKey != null)
            {
                amqpMessage.MessageAnnotations.Map[AmqpMessageConverter.PartitionKeyName] =
                    firstBrokeredMessage.PartitionKey;
            }

            amqpMessage.Batchable = batchable;
            return(amqpMessage);
        }
예제 #23
0
        public static AmqpMessage EventDatasToAmqpMessage(IEnumerable <EventData> eventDatas, string partitionKey, bool batchable)
        {
            if (eventDatas == null)
            {
                throw new ArgumentNullException(nameof(eventDatas));
            }

            AmqpMessage returnMessage = null;
            var         dataCount     = eventDatas.Count();

            if (dataCount > 1)
            {
                IList <Data> bodyList   = new List <Data>();
                EventData    firstEvent = null;
                foreach (EventData data in eventDatas)
                {
                    if (firstEvent == null)
                    {
                        //this.ProcessFaultInjectionInfo(data);
                        firstEvent = data;
                    }

                    AmqpMessage amqpMessage = EventDataToAmqpMessage(data, partitionKey);
                    amqpMessage.Batchable = batchable;

                    if ((amqpMessage.Sections & ClientAmqpPropsSetOnSendToEventHub) == 0 &&
                        (data.Body.Array == null || data.Body.Count == 0))
                    {
                        throw new InvalidOperationException(Resources.CannotSendAnEmptyEvent.FormatForUser(data.GetType().Name));
                    }

                    ArraySegment <byte> buffer = StreamToBytes(amqpMessage.ToStream());
                    bodyList.Add(new Data {
                        Value = buffer
                    });
                }

                returnMessage               = AmqpMessage.Create(bodyList);
                returnMessage.Batchable     = true;
                returnMessage.MessageFormat = AmqpConstants.AmqpBatchedMessageFormat;
                UpdateAmqpMessageHeadersAndProperties(returnMessage, null, partitionKey, firstEvent, copyUserProperties: false);
            }
            else if (dataCount == 1) // ??? can't be null
            {
                var data = eventDatas.First();
                //this.ProcessFaultInjectionInfo(data);
                returnMessage           = EventDataToAmqpMessage(data, partitionKey);
                returnMessage.Batchable = batchable;
                if ((returnMessage.Sections & ClientAmqpPropsSetOnSendToEventHub) == 0 &&
                    (data.Body.Array == null || data.Body.Count == 0))
                {
                    throw new InvalidOperationException(Resources.CannotSendAnEmptyEvent.FormatForUser(data.GetType().Name));
                }
            }

            return(returnMessage);
        }
예제 #24
0
        public void UpdateMessageHeaderAndPropertiesTest()
        {
            byte[] bytes           = { 1, 2, 3, 4 };
            string messageId       = Guid.NewGuid().ToString();
            string correlationId   = Guid.NewGuid().ToString();
            string contentType     = "application/json";
            string contentEncoding = "UTF-8";
            string to                 = "d1";
            var    enqueuedTime       = new DateTime(2018, 4, 5, 04, 05, 06, DateTimeKind.Utc);
            byte   deliveryCount      = 10;
            string messageSchema      = "testSchema";
            string connectionDeviceId = "connD1";
            string connectionModuleId = "connM1";

            using (AmqpMessage amqpMessage =
                       AmqpMessage.Create(new Amqp.Framing.Data {
                Value = new ArraySegment <byte>(bytes)
            }))
            {
                amqpMessage.Properties.MessageId       = messageId;
                amqpMessage.Properties.CorrelationId   = correlationId;
                amqpMessage.Properties.ContentType     = contentType;
                amqpMessage.Properties.ContentEncoding = contentEncoding;
                amqpMessage.Properties.To = to;

                amqpMessage.MessageAnnotations.Map[MessageSystemPropertyNames.EnqueuedTime]       = enqueuedTime;
                amqpMessage.MessageAnnotations.Map[MessageSystemPropertyNames.DeliveryCount]      = deliveryCount;
                amqpMessage.MessageAnnotations.Map[MessageSystemPropertyNames.ConnectionDeviceId] = connectionDeviceId;
                amqpMessage.MessageAnnotations.Map[MessageSystemPropertyNames.ConnectionModuleId] = connectionModuleId;

                amqpMessage.ApplicationProperties.Map[MessageSystemPropertyNames.MessageSchema] = messageSchema;

                amqpMessage.ApplicationProperties.Map["Prop1"] = "Value1";
                amqpMessage.ApplicationProperties.Map["Prop2"] = "Value2";

                var message = new Message(bytes);

                MessageConverter.UpdateMessageHeaderAndProperties(amqpMessage, message);

                Assert.AreEqual(messageId, message.MessageId);
                Assert.AreEqual(correlationId, message.CorrelationId);
                Assert.AreEqual(contentType, message.ContentType);
                Assert.AreEqual(contentEncoding, message.ContentEncoding);
                Assert.AreEqual(to, message.To);

                Assert.AreEqual(enqueuedTime, message.EnqueuedTimeUtc);
                Assert.AreEqual(deliveryCount, message.DeliveryCount);
                Assert.AreEqual(connectionDeviceId, message.ConnectionDeviceId);
                Assert.AreEqual(connectionModuleId, message.ConnectionModuleId);

                Assert.AreEqual(messageSchema, message.MessageSchema);

                Assert.AreEqual("Value1", message.Properties["Prop1"]);
                Assert.AreEqual("Value2", message.Properties["Prop2"]);
            }
        }
예제 #25
0
        public void AmqpMessageStreamTest()
        {
            AmqpMessage message = AmqpMessage.Create(new MemoryStream(new byte[12]), true);

            Assert.Equal(12, message.BodyStream.Length);

            AmqpMessage message2 = AmqpMessage.Create(new MemoryStream(new byte[12]), false);

            Assert.Equal(12, message2.BodyStream.Length);
        }
        public void ContentTypeFromAmqpMessage()
        {
            var message = AmqpMessage.Create(new MemoryStream(new byte[12]), true);

            AddSection(message, SectionFlag.Properties);
            message.Properties.ContentType = "this content type";
            var eventData = AmqpMessageConverter.AmqpMessageToEventData(message);

            Assert.Equal(message.Properties.ContentType.Value, eventData.ContentType);
        }
예제 #27
0
        static AmqpMessage GetAmqpResponse(AmqpMessage requestMessage, AmqpResponseStatusCode statusCode, string statusDescription)
        {
            AmqpMessage response = AmqpMessage.Create();

            response.Properties.CorrelationId = requestMessage.Properties.MessageId;
            response.ApplicationProperties    = new ApplicationProperties();
            response.ApplicationProperties.Map[CbsConstants.PutToken.StatusCode]        = (int)statusCode;
            response.ApplicationProperties.Map[CbsConstants.PutToken.StatusDescription] = statusDescription;
            return(response);
        }
        public static AmqpMessage EventDataToAmqpMessage(EventData eventData)
        {
            AmqpMessage amqpMessage = AmqpMessage.Create(new Data {
                Value = eventData.Body
            });

            UpdateAmqpMessageHeadersAndProperties(amqpMessage, null, eventData, true);

            return(amqpMessage);
        }
예제 #29
0
        static AmqpMessage EventDataToAmqpMessage(EventData eventData, string partitionKey)
        {
            AmqpMessage amqpMessage = AmqpMessage.Create(new Data {
                Value = eventData.Body
            });

            UpdateAmqpMessageHeadersAndProperties(amqpMessage, null, partitionKey, eventData, true);

            return(amqpMessage);
        }
예제 #30
0
 public AmqpRequestMessage(string operation, TimeSpan timeout, string trackingId)
 {
     Map         = new AmqpMap();
     AmqpMessage = AmqpMessage.Create(new AmqpValue {
         Value = Map
     });
     AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.Operation]        = operation;
     AmqpMessage.ApplicationProperties.Map[ManagementConstants.Properties.ServerTimeout] = (uint)timeout.TotalMilliseconds;
     AmqpMessage.ApplicationProperties.Map[ManagementConstants.Properties.TrackingId]    = trackingId ?? Guid.NewGuid().ToString();
 }