예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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());
        }
예제 #4
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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);
        }
예제 #9
0
        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));
        }
예제 #10
0
        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();
            }
        }
예제 #11
0
        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();
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }