public void Set_routing_key_per_message_and_consume_them_in_the_same_process() { string GetRoutingKey(string s) => $"key.{s}"; var exchangeName = "amqp.topic." + Environment.TickCount; var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var exchangeDeclaration = ExchangeDeclaration.Create(exchangeName, "topic"); var queueDeclaration = QueueDeclaration.Create(queueName); var bindingDeclaration = BindingDeclaration.Create(queueName, exchangeName).WithRoutingKey(GetRoutingKey("*")); var amqpSink = AmqpSink.Create( AmqpSinkSettings.Create(_connectionSettings) .WithExchange(exchangeName) .WithDeclarations(exchangeDeclaration, queueDeclaration, bindingDeclaration)); var amqpSource = AmqpSource.AtMostOnceSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(exchangeDeclaration, queueDeclaration, bindingDeclaration), bufferSize: 10); var input = new[] { "one", "two", "three", "four", "five" }; var routingKeys = input.Select(GetRoutingKey); Source.From(input) .Select(s => new OutgoingMessage(ByteString.FromString(s), false, false, routingKey: GetRoutingKey(s))) .RunWith(amqpSink, _mat) .Wait(); var result = amqpSource .Take(input.Length) .RunWith(Sink.Seq <IncomingMessage>(), _mat) .Result; result.Select(x => x.Envelope.RoutingKey).Should().Equal(routingKeys); result.Select(x => x.Bytes.ToString()).Should().Equal(input); }
public void Publish_and_consume_elements_through_a_simple_queue_again_in_the_same_process() { ExchangeDeclaration.Create("logs", "topic"); //queue declaration var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName).WithDurable(false).WithAutoDelete(true); //create sink var amqpSink = AmqpSink.CreateSimple( AmqpSinkSettings.Create(_connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclaration)); //create source var amqpSource = AmqpSource.AtMostOnceSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 10); //run sink var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat).Wait(); //run source var result = amqpSource.Select(m => m.Bytes.ToString(Encoding.UTF8)) .Take(input.Length) .RunWith(Sink.Seq <string>(), _mat); result.Wait(TimeSpan.FromSeconds(3)); Assert.Equal(input, result.Result); }
public Task DeclareExchangeAsync(ExchangeDeclaration exchange) { if (IsDeclared(exchange)) { return(_completed); } var scheduled = new ScheduledExchangeTask(exchange); _topologyTasks.Enqueue(scheduled); EnsureWorker(); return(scheduled.TaskCompletionSource.Task); }
protected override Task DeclareExchangeAsync(ExchangeDeclaration exchange, IPipeContext context, CancellationToken token) { var policy = context.GetPolicy(PolicyKeys.ExchangeDeclare); return(policy.ExecuteAsync( action: ct => base.DeclareExchangeAsync(exchange, context, ct), cancellationToken: token, contextData: new Dictionary <string, object> { [RetryKey.TopologyProvider] = TopologyProvider, [RetryKey.ExchangeDeclaration] = exchange, [RetryKey.PipeContext] = context, [RetryKey.CancellationToken] = token, })); }
public void Pub_sub_from_one_source_with_multiple_sinks() { // with pubsub we arrange one exchange which the sink writes to and then one queue for each source which subscribes to the // exchange - all this described by the declarations //#exchange-declaration var exchangeName = "amqp-conn-it-spec-pub-sub-" + Environment.TickCount; var exchangeDeclaration = ExchangeDeclaration.Create(exchangeName, "fanout"); //#create-exchange-sink var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings).WithExchange(exchangeName).WithDeclarations(exchangeDeclaration)); //#create-exchange-source const int fanoutSize = 4; var mergedSources = Enumerable.Range(0, fanoutSize) .Aggregate(Source.Empty <(int, string)>(), (source, fanoutBranch) => source.Merge( AmqpSource.AtMostOnceSource( TemporaryQueueSourceSettings.Create(_connectionSettings, exchangeName).WithDeclarations(exchangeDeclaration), bufferSize: 1) .Select(msg => (branch: fanoutBranch, message: msg.Bytes.ToString()))) ); var completion = new TaskCompletionSource <Done>(); mergedSources.RunWith(Sink.Aggregate <(int branch, string msg), ImmutableHashSet <int> >(ImmutableHashSet.Create <int>(), (seen, t) => { if (seen.Count == fanoutSize) { completion.SetResult(Done.Instance); } return(seen.Add(t.branch)); }), _mat); Sys.Scheduler.Advanced.ScheduleOnce( TimeSpan.FromSeconds(5), () => completion.TrySetException(new Exception("Did not get at least one element from every fanout branch"))); Source.Repeat("stuff").Select(ByteString.FromString).RunWith(amqpSink, _mat); completion.Task.Result.Should().Be(Done.Instance); }
public void PublishAndConsume() { var connectionSettings = AmqpConnectionDetails.Create("localhost", 5672).WithAutomaticRecoveryEnabled(true).WithNetworkRecoveryInterval(TimeSpan.FromSeconds(1)); var exchange = ExchangeDeclaration.Create("logs", "topic"); //queue declaration var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName).WithDurable(false).WithAutoDelete(true); //create sink var amqpSink = AmqpSink.CreateSimple( AmqpSinkSettings.Create(connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclaration)); //create source int bufferSize = 10; var amqpSource = AmqpSource.Create( NamedQueueSourceSettings.Create(DefaultAmqpConnection.Instance, queueName) .WithDeclarations(queueDeclaration), bufferSize); //run sink var input = new List <string> { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _materializer).Wait(); //run source var result = amqpSource.Select(m => m.Bytes.ToString(Encoding.UTF8)) .Take(input.Count) .RunWith(Sink.Seq <string>(), _materializer); result.Wait(TimeSpan.FromSeconds(3)); Assert.Equal(input, result.Result); }
private void DeclareExchange(ExchangeDeclaration exchange) { if (IsDeclared(exchange)) { return; } _logger.Info("Declaring exchange {exchangeName}.", exchange.Name); var channel = GetOrCreateChannel(); channel.ExchangeDeclare( exchange.Name, exchange.ExchangeType, exchange.Durable, exchange.AutoDelete, exchange.Arguments); if (!exchange.AutoDelete) { _initExchanges.Add(exchange.Name); } }
public void Publish_elements_with_flow_then_consume_them_with_source() { ExchangeDeclaration.Create("logs", "topic"); var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName).WithDurable(false).WithAutoDelete(true); var amqpFlow = AmqpFlow.Create <string>( AmqpSinkSettings.Create(_connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclaration)); var input = new[] { "one", "two", "three", "four", "five" }; var passedThrough = Source.From(input) .Select(x => (new OutgoingMessage(ByteString.FromString(x), true, true), x)) .Via(amqpFlow) .RunWith(Sink.Seq <string>(), _mat) .Result .ToArray(); Assert.Equal(input, passedThrough, StringComparer.InvariantCulture); var consumed = AmqpSource.AtMostOnceSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 10) .Select(m => m.Bytes.ToString(Encoding.UTF8)) .Take(input.Length) .RunWith(Sink.Seq <string>(), _mat) .Result .ToArray(); Assert.Equal(input, consumed, StringComparer.InvariantCulture); }
protected virtual Task PublishToErrorExchangeAsync(IPipeContext context, IModel channel, Exception exception, ExchangeDeclaration exchange) { var args = context.GetDeliveryEventArgs(); args.BasicProperties.Headers?.TryAdd(PropertyHeaders.Host, Environment.MachineName); args.BasicProperties.Headers?.TryAdd(PropertyHeaders.ExceptionType, exception.GetType().Name); args.BasicProperties.Headers?.TryAdd(PropertyHeaders.ExceptionStackTrace, exception.StackTrace); channel.BasicPublish(exchange.Name, args.RoutingKey, false, args.BasicProperties, args.Body); return(Task.FromResult(0)); }
protected virtual Task DeclareErrorExchangeAsync(ExchangeDeclaration exchange) { return(_provider.DeclareExchangeAsync(exchange)); }
public static bool IsDefaultExchange(this ExchangeDeclaration declaration) { return(string.IsNullOrEmpty(declaration.Name)); }
protected virtual Task DeclareExchangeAsync(ExchangeDeclaration exchange, IPipeContext context, CancellationToken token) { return(TopologyProvider.DeclareExchangeAsync(exchange)); }
protected virtual void SaveToContext(IPipeContext context, ExchangeDeclaration declaration) { SaveToContextAction?.Invoke(context, declaration); }
public ScheduledExchangeTask(ExchangeDeclaration exchange) { Declaration = exchange; }
public bool IsDeclared(ExchangeDeclaration exchange) { return(exchange.IsDefaultExchange() || _initExchanges.Contains(exchange.Name)); }
public static Task DeclareExchangeAsync(this IBusClient client, ExchangeDeclaration declaration, CancellationToken ct = default(CancellationToken)) { return(client.InvokeAsync(DeclareExchangeAction, ctx => ctx.Properties.Add(PipeKey.ExchangeDeclaration, declaration), ct)); }