예제 #1
0
        public static AmqpFilter GetFilter(Filter filter)
        {
            AmqpFilter amqpTrueFilter = null;

            if (filter is TrueFilter)
            {
                amqpTrueFilter = new AmqpTrueFilter();
            }
            else if (filter is FalseFilter)
            {
                amqpTrueFilter = new AmqpFalseFilter();
            }
            else if (!(filter is SqlFilter))
            {
                if (!(filter is CorrelationFilter))
                {
                    throw new NotSupportedException();
                }
                amqpTrueFilter = new AmqpCorrelationFilter()
                {
                    CorrelationId = ((CorrelationFilter)filter).CorrelationId
                };
            }
            else
            {
                AmqpSqlFilter amqpSqlFilter = new AmqpSqlFilter();
                SqlFilter     sqlFilter     = (SqlFilter)filter;
                amqpSqlFilter.Expression         = sqlFilter.SqlExpression;
                amqpSqlFilter.CompatibilityLevel = new int?(sqlFilter.CompatibilityLevel);
                amqpTrueFilter = amqpSqlFilter;
            }
            return(amqpTrueFilter);
        }
예제 #2
0
        public static Filter GetFilter(AmqpFilter amqpFilter)
        {
            Filter sqlFilter;

            if (amqpFilter.DescriptorCode == AmqpSqlFilter.Code)
            {
                sqlFilter = new SqlFilter(((AmqpSqlFilter)amqpFilter).Expression);
            }
            else if (amqpFilter.DescriptorCode == AmqpTrueFilter.Code)
            {
                sqlFilter = new TrueFilter();
            }
            else if (amqpFilter.DescriptorCode != AmqpFalseFilter.Code)
            {
                if (amqpFilter.DescriptorCode != AmqpCorrelationFilter.Code)
                {
                    throw new NotSupportedException();
                }
                sqlFilter = new CorrelationFilter(((AmqpCorrelationFilter)amqpFilter).CorrelationId);
            }
            else
            {
                sqlFilter = new FalseFilter();
            }
            return(sqlFilter);
        }
        public void BuildFilterExpressionHonorsInclusiveFlagForSequenceNumber(bool inclusive)
        {
            var comparison = (inclusive) ? ">=" : ">";
            var position   = EventPosition.FromSequenceNumber(123, inclusive);
            var filter     = AmqpFilter.BuildFilterExpression(position);

            Assert.That(filter, Contains.Substring(comparison), "The comparison should be based on the inclusive flag.");
        }
        public void BuildFilterExpressionEnsuresAnEventPositionIsFilterable()
        {
            // Unset all properties for the event position.

            var position = EventPosition.FromOffset(1);

            position.Offset = null;

            Assert.That(() => AmqpFilter.BuildFilterExpression(position), Throws.ArgumentException);
        }
        public void CreateConsumerFilterCreatesTheFilter()
        {
            var expression = "test > 1";
            var filter     = AmqpFilter.CreateConsumerFilter(expression);

            Assert.That(filter, Is.Not.Null, "The filter should have been created");
            Assert.That(filter.DescriptorName, Is.EqualTo((AmqpSymbol)AmqpFilter.ConsumerFilterName), "The filter name should have been populated");
            Assert.That(filter.DescriptorCode, Is.EqualTo(AmqpFilter.ConsumerFilterCode), "The filter code should have been populated");
            Assert.That(filter.Value, Is.EqualTo(expression), "The filter expression should have been used as the body of the filter");
        }
        public void BuildFilterExpressionIgnoresInclusiveFlagForEnqueuedTime(bool inclusive)
        {
            var position = EventPosition.FromEnqueuedTime(DateTimeOffset.Parse("2015-10-27T12:00:00Z"));

            position.IsInclusive = inclusive;

            var filter = AmqpFilter.BuildFilterExpression(position);

            Assert.That(filter, Does.Not.Contain("="), "The comparison should not consider the inclusive flag.");
        }
예제 #7
0
        public static AmqpRuleDescription GetRuleDescription(RuleDescription description)
        {
            AmqpFilter     filter     = MessageConverter.GetFilter(description.Filter);
            AmqpRuleAction ruleAction = MessageConverter.GetRuleAction(description.Action);

            return(new AmqpRuleDescription()
            {
                Filter = filter,
                Action = ruleAction
            });
        }
        public void BuildFilterExpressionUsesEnqueuedTime()
        {
            // Set all properties for the event position.

            var enqueuedTime = DateTimeOffset.Parse("2015-10-27T12:00:00Z");
            var position     = EventPosition.FromEnqueuedTime(enqueuedTime);

            var filter = AmqpFilter.BuildFilterExpression(position);

            Assert.That(filter, Contains.Substring(AmqpFilter.EnqueuedTimeName), "The enqueued time should have been used.");
            Assert.That(filter, Contains.Substring(enqueuedTime.ToUnixTimeMilliseconds().ToString()), "The enqueued time value should be present in the filter.");
        }
        public void BuildFilterExpressionPrefersSequenceNumberToEnqueuedTime()
        {
            // Set all properties for the event position.

            var sequence = 2345;
            var position = EventPosition.FromSequenceNumber(sequence);

            position.EnqueuedTime = DateTimeOffset.Parse("2015-10-27T12:00:00Z");

            var filter = AmqpFilter.BuildFilterExpression(position);

            Assert.That(filter, Contains.Substring(AmqpFilter.SequenceNumberName), "The sequence number should have precedence over the enqueued time for filtering.");
            Assert.That(filter, Contains.Substring(sequence.ToString()), "The sequence number value should be present in the filter.");
        }
        public void BuildFilterExpressionPrefersOffset()
        {
            // Set all properties for the event position.

            var offset   = 1;
            var position = EventPosition.FromOffset(offset);

            position.SequenceNumber = 222;
            position.EnqueuedTime   = DateTimeOffset.Parse("2015-10-27T12:00:00Z");

            var filter = AmqpFilter.BuildFilterExpression(position);

            Assert.That(filter, Contains.Substring(AmqpFilter.OffsetName), "The offset should have precedence for filtering.");
            Assert.That(filter, Contains.Substring(offset.ToString()), "The offset value should be present in the filter.");
        }
 public void CreateConsumerFilterValidatesTheExpression(string expression)
 {
     Assert.That(() => AmqpFilter.CreateConsumerFilter(expression), Throws.InstanceOf <ArgumentException>());
 }
 public void BuildFilterExpressionAllowsLatest()
 {
     Assert.That(() => AmqpFilter.BuildFilterExpression(EventPosition.Latest), Throws.Nothing);
 }
예제 #13
0
        /// <summary>
        ///   Creates an AMQP link for use with receiving operations.
        /// </summary>
        ///
        /// <param name="connection">The active and opened AMQP connection to use for this link.</param>
        /// <param name="endpoint">The fully qualified endpoint to open the link for.</param>
        /// <param name="eventPosition">The position of the event in the partition where the link should be filtered to.</param>
        /// <param name="consumerOptions">The set of active options for the consumer that will make use of the link.</param>
        /// <param name="timeout">The timeout to apply when creating the link.</param>
        /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param>
        ///
        /// <returns>A link for use for operations related to receiving events.</returns>
        ///
        protected virtual async Task <ReceivingAmqpLink> CreateReceivingLinkAsync(AmqpConnection connection,
                                                                                  Uri endpoint,
                                                                                  EventPosition eventPosition,
                                                                                  EventHubConsumerOptions consumerOptions,
                                                                                  TimeSpan timeout,
                                                                                  CancellationToken cancellationToken)
        {
            Argument.AssertNotDisposed(IsDisposed, nameof(AmqpConnectionScope));
            cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

            var session   = default(AmqpSession);
            var stopWatch = Stopwatch.StartNew();

            try
            {
                // Perform the initial authorization for the link.

                var authClaims        = new[] { EventHubsClaim.Listen };
                var authExpirationUtc = await RequestAuthorizationUsingCbsAsync(connection, TokenProvider, endpoint, endpoint.AbsoluteUri, endpoint.AbsoluteUri, authClaims, timeout.CalculateRemaining(stopWatch.Elapsed)).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                // Create and open the AMQP session associated with the link.

                var sessionSettings = new AmqpSessionSettings {
                    Properties = new Fields()
                };
                session = connection.CreateSession(sessionSettings);

                await OpenAmqpObjectAsync(session, timeout).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>();

                // Create and open the link.

                var filters = new FilterSet();
                filters.Add(AmqpFilter.ConsumerFilterName, AmqpFilter.CreateConsumerFilter(AmqpFilter.BuildFilterExpression(eventPosition)));

                var linkSettings = new AmqpLinkSettings
                {
                    Role            = true,
                    TotalLinkCredit = (uint)consumerOptions.PrefetchCount,
                    AutoSendFlow    = consumerOptions.PrefetchCount > 0,
                    SettleType      = SettleMode.SettleOnSend,
                    Source          = new Source {
                        Address = endpoint.AbsolutePath, FilterSet = filters
                    },
                    Target = new Target {
                        Address = Guid.NewGuid().ToString()
                    }
                };

                linkSettings.AddProperty(AmqpProperty.EntityType, (int)AmqpProperty.Entity.ConsumerGroup);

                if (!string.IsNullOrEmpty(consumerOptions.Identifier))
                {
                    linkSettings.AddProperty(AmqpProperty.ConsumerIdentifier, consumerOptions.Identifier);
                }

                if (consumerOptions.OwnerLevel.HasValue)
                {
                    linkSettings.AddProperty(AmqpProperty.OwnerLevel, consumerOptions.OwnerLevel.Value);
                }

                if (consumerOptions.TrackLastEnqueuedEventInformation)
                {
                    linkSettings.DesiredCapabilities = new Multiple <AmqpSymbol>(new List <AmqpSymbol>
                    {
                        AmqpProperty.TrackLastEnqueuedEventInformation
                    });
                }

                var link = new ReceivingAmqpLink(linkSettings);
                linkSettings.LinkName = $"{ Id };{ connection.Identifier };{ session.Identifier };{ link.Identifier }";
                link.AttachTo(session);

                stopWatch.Stop();

                // Configure refresh for authorization of the link.

                var refreshTimer = default(Timer);

                var refreshHandler = CreateAuthorizationRefreshHandler
                                     (
                    connection,
                    link,
                    TokenProvider,
                    endpoint,
                    endpoint.AbsoluteUri,
                    endpoint.AbsoluteUri,
                    authClaims,
                    AuthorizationRefreshTimeout,
                    () => refreshTimer
                                     );

                refreshTimer = new Timer(refreshHandler, null, CalculateLinkAuthorizationRefreshInterval(authExpirationUtc), Timeout.InfiniteTimeSpan);

                // Track the link before returning it, so that it can be managed with the scope.

                BeginTrackingLinkAsActive(link, refreshTimer);
                return(link);
            }
            catch
            {
                // Aborting the session will perform any necessary cleanup of
                // the associated link as well.

                session?.Abort();
                throw;
            }
        }
예제 #14
0
 public void BuildFilterExpressionValidatesTheEventPosition()
 {
     Assert.That(() => AmqpFilter.BuildFilterExpression(null), Throws.ArgumentNullException);
 }