public Task OpenAsync(TimeSpan timeout)
        {
            Logging.Enter(this, timeout, nameof(OpenAsync));

            try
            {
                return(_faultTolerantSession.GetOrCreateAsync(timeout));
            }
            finally
            {
                Logging.Exit(this, timeout, nameof(OpenAsync));
            }
        }
Esempio n. 2
0
        internal static async Task <AmqpResponseMessage> ExecuteRequestResponseAsync(
            AmqpConnectionScope connectionScope,
            FaultTolerantAmqpObject <RequestResponseAmqpLink> managementLink,
            AmqpRequestMessage amqpRequestMessage,
            string transactionGroup,
            TimeSpan timeout)
        {
            AmqpMessage amqpMessage = amqpRequestMessage.AmqpMessage;

            ArraySegment <byte> transactionId = AmqpConstants.NullBinary;
            var ambientTransaction            = Transaction.Current;

            if (ambientTransaction != null)
            {
                transactionId = await AmqpTransactionManager.Instance.EnlistAsync(
                    ambientTransaction,
                    connectionScope,
                    transactionGroup,
                    timeout)
                                .ConfigureAwait(false);
            }

            if (!managementLink.TryGetOpenedObject(out var requestResponseAmqpLink))
            {
                // MessagingEventSource.Log.CreatingNewLink(this.ClientId, this.isSessionReceiver, this.SessionIdInternal, true, this.LinkException);
                requestResponseAmqpLink = await managementLink.GetOrCreateAsync(timeout).ConfigureAwait(false);
            }

            var responseAmqpMessage = await Task.Factory.FromAsync(
                (c, s) => requestResponseAmqpLink.BeginRequest(amqpMessage, transactionId, timeout, c, s),
                (a) => requestResponseAmqpLink.EndRequest(a),
                null).ConfigureAwait(false);

            return(AmqpResponseMessage.CreateResponse(responseAmqpMessage));
        }
Esempio n. 3
0
        private async Task <Controller> GetController(TimeSpan timeout)
        {
            FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
            Controller controller = await faultTolerantController.GetOrCreateAsync(timeout).ConfigureAwait(false);

            return(controller);
        }
        private async Task SinglePhaseCommitAsync(SinglePhaseEnlistment singlePhaseEnlistment)
        {
            try
            {
                FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
                Controller controller = await faultTolerantController.GetOrCreateAsync(_timeout)
                                        .ConfigureAwait(false);

                await controller.DischargeAsync(AmqpTransactionId, fail : false).ConfigureAwait(false);

                singlePhaseEnlistment.Committed();
                ServiceBusEventSource.Log.TransactionDischarged(
                    _transactionId,
                    AmqpTransactionId,
                    false);
                await CloseAsync().ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Exception exception = AmqpExceptionHelper.TranslateException(e, null);
                ServiceBusEventSource.Log.TransactionDischargeException(
                    _transactionId,
                    AmqpTransactionId,
                    exception);
                singlePhaseEnlistment.InDoubt(exception);
            }
        }
Esempio n. 5
0
        public async Task <EventHubRuntimeInformation> GetRuntimeInformationAsync()
        {
            RequestResponseAmqpLink requestLink = await link.GetOrCreateAsync(
                TimeSpan.FromSeconds(AmqpClientConstants.AmqpSessionTimeoutInSeconds)).ConfigureAwait(false);

            // Create request and attach token.
            AmqpMessage request = CreateGetRuntimeInformationRequest();

            request.ApplicationProperties.Map[AmqpClientConstants.ManagementSecurityTokenKey] = await GetTokenString().ConfigureAwait(false);

            AmqpMessage response = await requestLink.RequestAsync(request, eventHubClient.ConnectionStringBuilder.OperationTimeout).ConfigureAwait(false);

            int    statusCode        = (int)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusCode];
            string statusDescription = (string)response.ApplicationProperties.Map[AmqpClientConstants.ResponseStatusDescription];

            if (statusCode != (int)AmqpResponseStatusCode.Accepted && statusCode != (int)AmqpResponseStatusCode.OK)
            {
                AmqpSymbol errorCondition = AmqpExceptionHelper.GetResponseErrorCondition(response, (AmqpResponseStatusCode)statusCode);
                Error      error          = new Error {
                    Condition = errorCondition, Description = statusDescription
                };
                throw AmqpExceptionHelper.ToMessagingContract(error);
            }

            AmqpMap infoMap = null;

            if (response.ValueBody != null)
            {
                infoMap = response.ValueBody.Value as AmqpMap;
            }

            if (infoMap == null)
            {
                throw new InvalidOperationException($"Return type mismatch in GetRuntimeInformationAsync. Response returned NULL or response isn't AmqpMap.");
            }

            return(new EventHubRuntimeInformation()
            {
                Type = (string)infoMap[new MapKey("type")],
                Path = (string)infoMap[new MapKey("name")],
                CreatedAt = (DateTime)infoMap[new MapKey("created_at")],
                PartitionCount = (int)infoMap[new MapKey("partition_count")],
                PartitionIds = (string[])infoMap[new MapKey("partition_ids")],
            });
        }
        private async Task <SendingAmqpLink> GetSendingLinkAsync()
        {
            if (!_faultTolerantSendingLink.TryGetOpenedObject(out SendingAmqpLink sendingLink))
            {
                sendingLink = await _faultTolerantSendingLink.GetOrCreateAsync(OpenTimeout).ConfigureAwait(false);
            }

            return(sendingLink);
        }
        internal static async Task <ReceivingAmqpLink> GetReceivingLinkAsync(this FaultTolerantAmqpObject <ReceivingAmqpLink> faultTolerantReceivingLink)
        {
            if (!faultTolerantReceivingLink.TryGetOpenedObject(out ReceivingAmqpLink receivingLink))
            {
                receivingLink = await faultTolerantReceivingLink.GetOrCreateAsync(IotHubConnection.DefaultOpenTimeout).ConfigureAwait(false);
            }

            return(receivingLink);
        }
Esempio n. 8
0
        public void FaultTolerantAmqpObjectShouldInvokeCloseMethodOnClose()
        {
            bool isCloseHandlerInvoked = false;
            var  faultTolerantObject   = new FaultTolerantAmqpObject <TestAmqpObject>(
                span => Task.FromResult(new TestAmqpObject("string")),
                amqpObject => { isCloseHandlerInvoked = true; });
            var testAmqpObject = faultTolerantObject.GetOrCreateAsync(TimeSpan.FromSeconds(3)).Result;

            testAmqpObject.Close();
            Assert.True(isCloseHandlerInvoked);
        }
Esempio n. 9
0
        internal async ValueTask <TransportMessageBatch> CreateBatchInternalAsync(
            CreateBatchOptions options,
            TimeSpan timeout)
        {
            Argument.AssertNotNull(options, nameof(options));

            // Ensure that maximum message size has been determined; this depends on the underlying
            // AMQP link, so if not set, requesting the link will ensure that it is populated.

            if (!MaximumMessageSize.HasValue)
            {
                await _sendLink.GetOrCreateAsync(timeout).ConfigureAwait(false);
            }

            // Ensure that there was a maximum size populated; if none was provided,
            // default to the maximum size allowed by the link.

            options.MaximumSizeInBytes ??= MaximumMessageSize;

            Argument.AssertInRange(options.MaximumSizeInBytes.Value, ServiceBusSender.MinimumBatchSizeLimit, MaximumMessageSize.Value, nameof(options.MaximumSizeInBytes));
            return(new AmqpMessageBatch(options));
        }
        public async Task <SendingAmqpLink> CreateSendingLinkAsync(string path, TimeSpan timeout)
        {
            var timeoutHelper = new TimeoutHelper(timeout);

            AmqpSession session;

            if (!this.faultTolerantSession.TryGetOpenedObject(out session))
            {
                session = await faultTolerantSession.GetOrCreateAsync(timeoutHelper.RemainingTime()).ConfigureAwait(false);
            }

            var linkAddress = this.connectionString.BuildLinkAddress(path);

            var linkSettings = new AmqpLinkSettings()
            {
                Role = false,
                InitialDeliveryCount = 0,
                Target = new Target()
                {
                    Address = linkAddress.AbsoluteUri
                },
                SndSettleMode = null,                        // SenderSettleMode.Unsettled (null as it is the default and to avoid bytes on the wire)
                RcvSettleMode = null,                        // (byte)ReceiverSettleMode.First (null as it is the default and to avoid bytes on the wire)
                LinkName      = Guid.NewGuid().ToString("N") // Use a human readable link name to help with debugging
            };

            SetLinkSettingsCommonProperties(linkSettings, timeoutHelper.RemainingTime());

            var link = new SendingAmqpLink(linkSettings);

            link.AttachTo(session);

            await OpenLinkAsync(link, timeoutHelper.RemainingTime()).ConfigureAwait(false);

            return(link);
        }
        protected override async Task <AmqpTransactionEnlistment> OnCreateAsync(TimeSpan timeout)
        {
            try
            {
                FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
                Controller controller = await faultTolerantController.GetOrCreateAsync(timeout).ConfigureAwait(false);

                AmqpTransactionId = await controller.DeclareAsync().ConfigureAwait(false);

                ServiceBusEventSource.Log.TransactionDeclared(_transactionId, AmqpTransactionId);
                return(this);
            }
            catch (Exception exception)
            {
                ServiceBusEventSource.Log.TransactionInitializeException(_transactionId, exception.ToString());
                _transactionManager.RemoveEnlistment(_transactionId);
                throw;
            }
        }
        private async Task <SendingAmqpLink> GetSendingLinkAsync()
        {
            Logging.Enter(this, $"_faultTolerantSendingLink = {_faultTolerantSendingLink?.GetHashCode()}", nameof(GetSendingLinkAsync));

            try
            {
                if (!_faultTolerantSendingLink.TryGetOpenedObject(out SendingAmqpLink sendingLink))
                {
                    sendingLink = await _faultTolerantSendingLink.GetOrCreateAsync(OpenTimeout).ConfigureAwait(false);
                }

                Logging.Info(this, $"Retrieved SendingAmqpLink [{sendingLink?.Name}]", nameof(GetSendingLinkAsync));

                return(sendingLink);
            }
            finally
            {
                Logging.Exit(this, $"_faultTolerantSendingLink = {_faultTolerantSendingLink?.GetHashCode()}", nameof(GetSendingLinkAsync));
            }
        }
        private async Task RollbackAsync(SinglePhaseEnlistment singlePhaseEnlistment)
        {
            try
            {
                FaultTolerantAmqpObject <Controller> faultTolerantController = _connectionScope.TransactionController;
                Controller controller = await faultTolerantController.GetOrCreateAsync(_timeout)
                                        .ConfigureAwait(false);

                await controller.DischargeAsync(AmqpTransactionId, fail : true).ConfigureAwait(false);

                singlePhaseEnlistment.Aborted();
                MessagingEventSource.Log.AmqpTransactionDischarged(_transactionId, AmqpTransactionId, true);
            }
            catch (Exception e)
            {
                Exception exception = AmqpExceptionHelper.TranslateException(e, null);
                MessagingEventSource.Log.AmqpTransactionDischargeException(
                    _transactionId,
                    AmqpTransactionId,
                    exception);
                singlePhaseEnlistment.Aborted(exception);
            }
        }
Esempio n. 14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="timeout"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task <long> ScheduleMessageInternalAsync(
            ServiceBusMessage message,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            var stopWatch = Stopwatch.StartNew();

            using (AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message))
            {
                var request = AmqpRequestMessage.CreateRequest(
                    ManagementConstants.Operations.ScheduleMessageOperation,
                    timeout,
                    null);

                if (_sendLink.TryGetOpenedObject(out SendingAmqpLink sendLink))
                {
                    request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name;
                }

                ArraySegment <byte>[] payload = amqpMessage.GetPayload();
                var 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;
                    }

                    if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey))
                    {
                        entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey;
                    }
                }

                request.Map[ManagementConstants.Properties.Messages] = new List <AmqpMap> {
                    entry
                };

                RequestResponseAmqpLink mgmtLink = await _managementLink.GetOrCreateAsync(
                    UseMinimum(_connectionScope.SessionTimeout,
                               timeout.CalculateRemaining(stopWatch.Elapsed)))
                                                   .ConfigureAwait(false);

                using AmqpMessage response = await mgmtLink.RequestAsync(
                          request.AmqpMessage,
                          timeout.CalculateRemaining(stopWatch.Elapsed))
                                             .ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();
                stopWatch.Stop();

                AmqpResponseMessage amqpResponseMessage = AmqpResponseMessage.CreateResponse(response);

                if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK)
                {
                    var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers);
                    if (sequenceNumbers == null || sequenceNumbers.Length < 1)
                    {
                        throw new ServiceBusException(true, "Could not schedule message successfully.");
                    }

                    return(sequenceNumbers[0]);
                }
                else
                {
                    throw amqpResponseMessage.ToMessagingContractException();
                }
            }
        }
 public Task OpenAsync(TimeSpan timeout)
 {
     return(_faultTolerantSession.GetOrCreateAsync(timeout));
 }