static async Task Main(string[] args) { using var actorSystem = ActorSystem.Create("poc"); using var mat = actorSystem.Materializer(); var connectionSettings = AmqpConnectionDetails.Create("localhost", 5672) .WithCredentials(AmqpCredentials.Create("mirero", "system")) .WithAutomaticRecoveryEnabled(true) .WithNetworkRecoveryInterval(TimeSpan.FromSeconds(1)); var queueName = "Amqp_Test_1"; var queueDeclation = QueueDeclaration.Create(queueName) .WithDurable(false) .WithAutoDelete(true); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclation)); var amqpSource = AmqpSource.CommittableSource(NamedQueueSourceSettings.Create(connectionSettings, queueName) .WithDeclarations(queueDeclation), 1); var input = new[] { "one", "two", "three", "four", "five" }; await Source.From(input) .Select(ByteString.FromString) .RunWith(amqpSink, mat); await actorSystem.Terminate(); }
public void Publish_from_one_source_and_consume_elements_with_multiple_sinks() { var queueName = "amqp-conn-it-spec-work-queues-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSink = AmqpSink.CreateSimple( AmqpSinkSettings.Create(_connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclaration)); var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat); var mergedSources = Source.FromGraph(GraphDsl.Create(b => { const int count = 3; var merge = b.Add(new Merge <IncomingMessage>(count)); for (var n = 0; n < count; n++) { var source = b.Add( AmqpSource.AtMostOnceSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 1)); b.From(source.Outlet).To(merge.In(n)); } return(new SourceShape <IncomingMessage>(merge.Out)); })); var result = mergedSources.Select(x => x.Bytes.ToString()).Take(input.Length).RunWith(Sink.Seq <string>(), _mat); result.Result.OrderBy(x => x).ToArray().Should().Equal(input.OrderBy(x => x).ToArray()); }
public void Not_republish_message_without_autoAck_false_if_nack_is_sent() { var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration)); var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat).Wait(); var amqpSource = AmqpSource.CommittableSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 10); var result1 = amqpSource .SelectAsync(1, async cm => { await cm.Nack(requeue: false); return(cm); }) .Take(input.Length) .RunWith(Sink.Seq <CommittableIncomingMessage>(), _mat); result1.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue(); var result2 = amqpSource .SelectAsync(1, async cm => { await cm.Ack(); return(cm); }) .Take(input.Length) .RunWith(Sink.Seq <CommittableIncomingMessage>(), _mat); result2.Wait(TimeSpan.FromSeconds(1)).Should().BeFalse(); }
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 void Publish_and_consume_elements_through_a_simple_queue_again_in_the_same_process_without_autoAck() { var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration)); //#create-source-withoutautoack var amqpSource = AmqpSource.CommittableSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 10); //#create-source-withoutautoack var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat).Wait(); //#run-source-withoutautoack var result = amqpSource .SelectAsync(1, async cm => { await cm.Ack(); return(cm); }) .Take(input.Length) .RunWith(Sink.Seq <CommittableIncomingMessage>(), _mat); //#run-source-withoutautoack result.Result.Select(x => x.Message.Bytes.ToString()).Should().Equal(input); }
public void Not_fail_on_a_fast_producer_and_a_slow_consumer() { var queueName = "amqp-conn-it-spec-simple-queue-2-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSource = AmqpSource.AtMostOnceSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 2); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration)); var publisher = this.CreatePublisherProbe <ByteString>(); var subscriber = this.CreateSubscriberProbe <IncomingMessage>(); amqpSink.AddAttributes(Attributes.CreateInputBuffer(1, 1)).RunWith(Source.FromPublisher(publisher), _mat); amqpSource.AddAttributes(Attributes.CreateInputBuffer(1, 1)).RunWith(Sink.FromSubscriber(subscriber), _mat); // note that this essentially is testing rabbitmq just as much as it tests our sink and source publisher.EnsureSubscription(); subscriber.EnsureSubscription(); publisher.ExpectRequest().Should().Be(1); publisher.SendNext(ByteString.FromString("one")); publisher.ExpectRequest(); publisher.SendNext(ByteString.FromString("two")); publisher.ExpectRequest(); publisher.SendNext(ByteString.FromString("three")); publisher.ExpectRequest(); publisher.SendNext(ByteString.FromString("four")); publisher.ExpectRequest(); publisher.SendNext(ByteString.FromString("five")); subscriber.Request(4); subscriber.ExpectNext().Bytes.ToString().Should().Be("one"); subscriber.ExpectNext().Bytes.ToString().Should().Be("two"); subscriber.ExpectNext().Bytes.ToString().Should().Be("three"); subscriber.ExpectNext().Bytes.ToString().Should().Be("four"); subscriber.Request(1); subscriber.ExpectNext().Bytes.ToString().Should().Be("five"); subscriber.Cancel(); publisher.SendComplete(); }
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); }
public static Source <CommittableIncomingMessage, Akka.NotUsed> CommittableQueue(Action <SimpleQueueOptions> opt) { var option = new SimpleQueueOptions(); opt.Invoke(option); var connectionSettings = AmqpConnectionDetails.Create(option.HostAndPorts.First().Host, option.HostAndPorts.First().Port) .WithHostsAndPorts(option.HostAndPorts.First(), option.HostAndPorts.ToArray()) .WithCredentials(AmqpCredentials.Create(option.UserName, option.Password)) .WithAutomaticRecoveryEnabled(true) .WithNetworkRecoveryInterval(TimeSpan.FromSeconds(1)) .WithVirtualHost(option.VirtualHost); var queueDeclaration = QueueDeclaration.Create(option.QueueName) .WithDurable(false) .WithAutoDelete(false); return(AmqpSource.CommittableSource(NamedQueueSourceSettings.Create(connectionSettings, option.QueueName) .WithDeclarations(queueDeclaration), 1)); }
public void Keep_connection_open_if_downstream_closes_and_there_are_pending_acks() { var queueName = "amqp-conn-it-spec-simple-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration)); var amqpSource = AmqpSource.CommittableSource( NamedQueueSourceSettings.Create(_connectionSettings, queueName).WithDeclarations(queueDeclaration), bufferSize: 10); var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat).Wait(); var result = amqpSource.Take(input.Length).RunWith(Sink.Seq <CommittableIncomingMessage>(), _mat); foreach (var cm in result.Result) { cm.Ack().Wait(); } }
public void Publish_via_RPC_which_expects_2_responses_per_message_and_then_consume_through_a_simple_queue_again_in_the_same_process() { var queueName = "amqp-conn-it-spec-rpc-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpRpcFlow = AmqpRpcFlow.CreateSimple( AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration), repliesPerMessage: 2); var amqpSource = AmqpSource.AtMostOnceSource(NamedQueueSourceSettings.Create(_connectionSettings, queueName), bufferSize: 1); var input = new[] { "one", "two", "three", "four", "five" }; var t = Source.From(input) .Select(ByteString.FromString) .ViaMaterialized(amqpRpcFlow, Keep.Right) .ToMaterialized(this.SinkProbe <ByteString>(), Keep.Both) .Run(_mat); var rpcQueueF = t.Item1; var probe = t.Item2; rpcQueueF.Result.Should().NotBeNullOrWhiteSpace("RPC flow materializes into response queue name"); var amqpSink = AmqpSink.ReplyTo(AmqpReplyToSinkSettings.Create(_connectionSettings)); amqpSource .SelectMany(b => new[] { new OutgoingMessage(b.Bytes.Concat(ByteString.FromString("a")), false, false, b.Properties), new OutgoingMessage(b.Bytes.Concat(ByteString.FromString("aa")), false, false, b.Properties) }) .RunWith(amqpSink, _mat); probe .Request(10) .ExpectNextUnorderedN(input.SelectMany(s => new[] { ByteString.FromString(s + "a"), ByteString.FromString(s + "aa") })) .ExpectComplete(); }
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); }
public void Publish_via_RPC_and_then_consume_through_a_simple_queue_again_in_the_same_process_without_autoAck() { var queueName = "amqp-conn-it-spec-rpc-queue-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var input = new[] { "one", "two", "three", "four", "five" }; var amqpRpcFlow = AmqpRpcFlow.CommittableFlow( AmqpSinkSettings.Create(_connectionSettings).WithRoutingKey(queueName).WithDeclarations(queueDeclaration), bufferSize: 10); var t = Source.From(input) .Select(ByteString.FromString) .Select(bytes => new OutgoingMessage(bytes, false, false)) .ViaMaterialized(amqpRpcFlow, Keep.Right) .SelectAsync(1, async cm => { await cm.Ack(); return(cm.Message); }) .ToMaterialized(this.SinkProbe <IncomingMessage>(), Keep.Both) .Run(_mat); var rpcQueueF = t.Item1; var probe = t.Item2; rpcQueueF.Wait(); var amqpSink = AmqpSink.ReplyTo(AmqpReplyToSinkSettings.Create(_connectionSettings)); var amqpSource = AmqpSource.AtMostOnceSource(NamedQueueSourceSettings.Create(_connectionSettings, queueName), bufferSize: 1); amqpSource .Select(b => new OutgoingMessage(b.Bytes, false, false, b.Properties)) .RunWith(amqpSink, _mat); probe.ToStrict(TimeSpan.FromSeconds(3)).Select(x => x.Bytes.ToString()).Should().Equal(input); }
public void Declare_connection_that_does_not_require_server_acks() { //var connectionSettings = AmqpConnectionDetails.Create("localhost", 5672); var queueName = "amqp-conn-it-spec-fire-and-forget-" + Environment.TickCount; var queueDeclaration = QueueDeclaration.Create(queueName); var amqpSink = AmqpSink.CreateSimple(AmqpSinkSettings.Create(_connectionSettings) .WithRoutingKey(queueName) .WithDeclarations(queueDeclaration)); var amqpSource = AmqpSource.CommittableSource(NamedQueueSourceSettings.Create(_connectionSettings, queueName) .WithAckRequired(false) .WithDeclarations(queueDeclaration), bufferSize: 10); var input = new[] { "one", "two", "three", "four", "five" }; Source.From(input).Select(ByteString.FromString).RunWith(amqpSink, _mat).Wait(); var result = amqpSource.Take(input.Length).RunWith(Sink.Seq <CommittableIncomingMessage>(), _mat).Result; result.Select(x => x.Message.Bytes.ToString(Encoding.UTF8)).Should().Equal(input); }
public async Task Publish_and_consume_elements_through_a_simple_queue_again_in_the_same_process() { Connection.DisableServerCertValidation = true; Trace.TraceLevel = TraceLevel.Frame; Trace.TraceListener = (l, f, a) => Output.WriteLine(DateTime.Now.ToString("[hh:mm:ss.fff]") + " " + string.Format(f, a)); var connection = new Connection(_address); var session = new Session(connection); var queueName = "simple-v1-queue-test" + Guid.NewGuid(); var senderLinkName = "amqp-v1-conn-test-sender"; var receiverLinkName = "amqp-v1-conn-test-receiver"; //create sink and source var amqpSink = AmqpSink.Create(new NamedQueueSinkSettings <string>(session, senderLinkName, queueName, _serializer)); var amqpSource = AmqpSource.Create(new NamedQueueSourceSettings <string>(session, receiverLinkName, queueName, 200, _serializer)); //run sink var input = new[] { "one", "two", "three", "four", "five" }; await Source.From(input).RunWith(amqpSink, _materializer); //run source var result = amqpSource .Take(input.Length) .RunWith(Sink.Seq <string>(), _materializer); await result; Assert.True(result.IsCompleted); Assert.Equal(input, result.Result); await session.CloseAsync(); await connection.CloseAsync(); }