Пример #1
0
        private static ZyRabbitOptions GetTestOptions(ZyRabbitOptions options)
        {
            options = options ?? new ZyRabbitOptions();
            options.ClientConfiguration = options.ClientConfiguration ?? ZyRabbitConfiguration.Local;
            options.ClientConfiguration.Queue.AutoDelete    = true;
            options.ClientConfiguration.Exchange.AutoDelete = true;

            return(options);
        }
Пример #2
0
        public async Task Should_Use_Custom_Policy()
        {
            var defaultCalled = false;
            var customCalled  = false;
            var defaultPolicy = Policy
                                .Handle <Exception>()
                                .FallbackAsync(ct =>
            {
                defaultCalled = true;
                return(Task.FromResult(0));
            });
            var declareQueuePolicy = Policy
                                     .Handle <OperationInterruptedException>()
                                     .RetryAsync(async(e, retryCount, ctx) =>
            {
                customCalled        = true;
                var defaultQueueCfg = ctx.GetPipeContext().GetClientConfiguration().Queue;
                var topology        = ctx.GetTopologyProvider();
                var queue           = new QueueDeclaration(defaultQueueCfg)
                {
                    Name = ctx.GetQueueName(), Durable = false
                };
                await topology.DeclareQueueAsync(queue);
            });

            var options = new ZyRabbitOptions
            {
                Plugins = p => p.UsePolly(c => c
                                          .UsePolicy(defaultPolicy)
                                          .UsePolicy(declareQueuePolicy, PolicyKeys.QueueBind)
                                          )
            };

            using (var client = ZyRabbitFactory.CreateTestClient(options))
            {
                await client.SubscribeAsync <BasicMessage>(
                    message => Task.FromResult(0),
                    ctx => ctx.UseSubscribeConfiguration(cfg => cfg
                                                         .Consume(c => c
                                                                  .FromQueue("does_not_exist"))
                                                         ));
            }

            Assert.True(customCalled);
            Assert.False(defaultCalled, "The custom retry policy should be called");
        }
        public async Task Should_Support_Chained_Message_Sequences()
        {
            var sequenceOptions = new ZyRabbitOptions
            {
                Plugins = p => p
                          .UseStateMachine()
                          .UseMessageContext(context => new MessageContext {
                    GlobalRequestId = Guid.NewGuid()
                })
                          .UseContextForwarding()
                          .UseGlobalExecutionId()
            };

            using (var serviceA = ZyRabbitFactory.CreateTestClient(sequenceOptions))
                using (var serviceB = ZyRabbitFactory.CreateTestClient(sequenceOptions))
                    using (var serviceC = ZyRabbitFactory.CreateTestClient(sequenceOptions))
                    {
                        /* Setup */
                        await serviceB.SubscribeAsync <FirstMessage>(async message =>
                        {
                            var nestedSequence = serviceB.ExecuteSequence(s => s
                                                                          .PublishAsync(new SecondMessage())
                                                                          .Complete <ThirdMessage>());
                            await nestedSequence.Task;
                            await serviceB.PublishAsync(new ForthMessage());
                        }
                                                                     );

                        await serviceC.SubscribeAsync <SecondMessage>(message =>
                        {
                            return(serviceC.PublishAsync(new ThirdMessage()));
                        });

                        /* Test */
                        var mainSequence = serviceA.ExecuteSequence(s => s
                                                                    .PublishAsync(new FirstMessage())
                                                                    .Complete <ForthMessage>()
                                                                    );
                        await mainSequence.Task;

                        /* Assert */
                        Assert.True(true, "Shoud complete sequence");
                    }
        }
Пример #4
0
        public async Task Should_Be_Able_To_Create_Unique_Queues_With_Naming_Suffix()
        {
            var options = new ZyRabbitOptions
            {
                Plugins = ioc => ioc
                          .UseApplicationQueueSuffix()
                          .UseQueueSuffix()
            };

            using (var firstSubscriber = ZyRabbitFactory.CreateTestClient(options))
                using (var secondSubscriber = ZyRabbitFactory.CreateTestClient(options))
                    using (var publisher = ZyRabbitFactory.CreateTestClient())
                    {
                        /* Setup */
                        var firstTcs  = new TaskCompletionSource <BasicMessage>();
                        var secondTcs = new TaskCompletionSource <BasicMessage>();
                        var message   = new BasicMessage {
                            Prop = "I'm delivered twice."
                        };
                        await firstSubscriber.SubscribeAsync <BasicMessage>(msg =>
                        {
                            firstTcs.TrySetResult(msg);
                            return(Task.FromResult(0));
                        }, ctx => ctx.UseCustomQueueSuffix("first")
                                                                            );

                        await secondSubscriber.SubscribeAsync <BasicMessage>(msg =>
                        {
                            secondTcs.TrySetResult(msg);
                            return(Task.FromResult(0));
                        }, ctx => ctx.UseCustomQueueSuffix("second")
                                                                             );

                        /* Test */
                        await publisher.PublishAsync(message);

                        await firstTcs.Task;
                        await secondTcs.Task;

                        /* Assert */
                        Assert.Equal(message.Prop, firstTcs.Task.Result.Prop);
                        Assert.Equal(message.Prop, secondTcs.Task.Result.Prop);
                    }
        }
Пример #5
0
        public async Task Should_Be_Able_To_Override_Custom_Suffix()
        {
            var customSuffix = new ZyRabbitOptions
            {
                Plugins = p => p.UseCustomQueueSuffix("custom")
            };

            using (var publisher = ZyRabbitFactory.CreateTestClient())
                using (var firstClient = ZyRabbitFactory.CreateTestClient(customSuffix))
                    using (var secondClient = ZyRabbitFactory.CreateTestClient(customSuffix))
                    {
                        /* Setup */
                        var firstTsc  = new TaskCompletionSource <BasicMessage>();
                        var secondTsc = new TaskCompletionSource <BasicMessage>();
                        await firstClient.SubscribeAsync <BasicMessage>(message =>
                        {
                            firstTsc.TrySetResult(message);
                            return(Task.FromResult(0));
                        });

                        await secondClient.SubscribeAsync <BasicMessage>(message =>
                        {
                            secondTsc.TrySetResult(message);
                            return(Task.FromResult(0));
                        }, ctx => ctx.UseCustomQueueSuffix("special"));

                        /* Test */
                        await publisher.PublishAsync(new BasicMessage());

                        await firstTsc.Task;
                        await secondTsc.Task;

                        /* Assert */
                        Assert.True(true, "Should be delivered to both subscribers");
                    }
        }
        public async Task Should_Forward_For_Rpc()
        {
            var withGloblalExecutionId = new ZyRabbitOptions
            {
                Plugins = p => p.UseGlobalExecutionId()
            };

            using (var requester = ZyRabbitFactory.CreateTestClient(withGloblalExecutionId))
                using (var firstResponder = ZyRabbitFactory.CreateTestClient(withGloblalExecutionId))
                    using (var secondResponder = ZyRabbitFactory.CreateTestClient(withGloblalExecutionId))
                        using (var thridResponder = ZyRabbitFactory.CreateTestClient(withGloblalExecutionId))
                            using (var consumer = ZyRabbitFactory.CreateTestClient())
                            {
                                /* Setup */
                                var taskCompletionSources = new List <TaskCompletionSource <BasicDeliverEventArgs> >
                                {
                                    new TaskCompletionSource <BasicDeliverEventArgs>(),
                                    new TaskCompletionSource <BasicDeliverEventArgs>(),
                                    new TaskCompletionSource <BasicDeliverEventArgs>()
                                };
                                await firstResponder.RespondAsync <FirstRequest, FirstResponse>(async message =>
                                {
                                    await firstResponder.PublishAsync(new SecondMessage());
                                    return(new FirstResponse());
                                });

                                await secondResponder.SubscribeAsync <SecondMessage>(message => secondResponder.PublishAsync(new ThirdMessage()));

                                await thridResponder.SubscribeAsync <ThirdMessage>(message => Task.FromResult(0));

                                await consumer.DeclareQueueAsync(new QueueDeclaration
                                {
                                    AutoDelete = true,
                                    Name       = "take_all",
                                });

                                await consumer.BasicConsumeAsync(args =>
                                {
                                    var tsc = taskCompletionSources.First(t => !t.Task.IsCompleted);
                                    tsc.TrySetResult(args);
                                    return(Task.FromResult <Acknowledgement>(new Ack()));
                                }, ctx => ctx
                                                                 .UseConsumeConfiguration(cfg => cfg
                                                                                          .FromQueue("take_all")
                                                                                          .OnExchange("zyrabbit.integrationtests.testmessages")
                                                                                          .WithRoutingKey("#")
                                                                                          )
                                                                 );

                                /* Test */
                                await requester.RequestAsync <FirstRequest, FirstResponse>();

                                Task.WaitAll(taskCompletionSources.Select(t => t.Task).ToArray <Task>());

                                var results = new List <string>();
                                foreach (var tcs in taskCompletionSources)
                                {
                                    var id = Encoding.UTF8.GetString(tcs.Task.Result.BasicProperties.Headers[ZyRabbit.Enrichers.GlobalExecutionId.PropertyHeaders.GlobalExecutionId] as byte[]);
                                    results.Add(id);
                                }

                                /* Assert */
                                Assert.NotNull(results[0]);
                                Assert.Equal(results[0], results[1]);
                                Assert.Equal(results[1], results[2]);
                            }
        }
Пример #7
0
 public static InstanceFactory CreateTestInstanceFactory(ZyRabbitOptions options = null)
 {
     return(Instantiation.ZyRabbitFactory.CreateInstanceFactory(GetTestOptions(options)));
 }
Пример #8
0
 public static Instantiation.Disposable.BusClient CreateTestClient(ZyRabbitOptions options = null)
 {
     return(Instantiation.ZyRabbitFactory.CreateSingleton(GetTestOptions(options)));
 }
Пример #9
0
        public static IServiceCollection AddZyRabbit(this IServiceCollection collection, ZyRabbitOptions options = null)
        {
            var adapter = new ServiceCollectionAdapter(collection ?? throw new ArgumentNullException(nameof(collection)));

            adapter.AddZyRabbit(options);
            return(collection);
        }
        public static ContainerBuilder RegisterZyRabbit(this ContainerBuilder builder, ZyRabbitOptions options = null)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            var adapter = new ContainerBuilderAdapter(builder);

            adapter.AddZyRabbit(options);
            builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(type => type.Namespace.StartsWith(ZyRabbit)));

            return(builder);
        }
        public static IDependencyRegister AddZyRabbit(this IDependencyRegister register, ZyRabbitOptions options = null)
        {
            register
            .AddSingleton(options?.ClientConfiguration ?? ZyRabbitConfiguration.Local)
            .AddSingleton <IConnectionFactory, ConnectionFactory>(provider =>
            {
                var cfg = provider.GetService <ZyRabbitConfiguration>();
                return(new ConnectionFactory
                {
                    VirtualHost = cfg.VirtualHost,
                    UserName = cfg.Username,
                    Password = cfg.Password,
                    Port = cfg.Port,
                    HostName = cfg.Hostnames.FirstOrDefault() ?? string.Empty,
                    AutomaticRecoveryEnabled = cfg.AutomaticRecovery,
                    TopologyRecoveryEnabled = cfg.TopologyRecovery,
                    NetworkRecoveryInterval = cfg.RecoveryInterval,
                    ClientProperties = provider.GetService <IClientPropertyProvider>().GetClientProperties(cfg),
                    Ssl = cfg.Ssl
                });
            })
            .AddSingleton <IChannelPoolFactory, AutoScalingChannelPoolFactory>()
            .AddSingleton(resolver => AutoScalingOptions.Default)
            .AddSingleton <IClientPropertyProvider, ClientPropertyProvider>()
            .AddSingleton <ISerializer>(resolver => new Serialization.JsonSerializer(new Newtonsoft.Json.JsonSerializer
            {
                TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple,
                Formatting             = Formatting.None,
                CheckAdditionalContent = true,
                ContractResolver       = new DefaultContractResolver {
                    NamingStrategy = new CamelCaseNamingStrategy()
                },
                ObjectCreationHandling     = ObjectCreationHandling.Auto,
                DefaultValueHandling       = DefaultValueHandling.Ignore,
                TypeNameHandling           = TypeNameHandling.Auto,
                ReferenceLoopHandling      = ReferenceLoopHandling.Serialize,
                MissingMemberHandling      = MissingMemberHandling.Ignore,
                PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                NullValueHandling          = NullValueHandling.Ignore
            }))
            .AddSingleton <IConsumerFactory, ConsumerFactory>()
            .AddSingleton <IChannelFactory>(resolver =>
            {
                var channelFactory = new ChannelFactory(
                    resolver.GetService <IConnectionFactory>(),
                    resolver.GetService <ZyRabbitConfiguration>(),
                    resolver.GetService <ILogger <ChannelFactory> >());
                channelFactory
                .ConnectAsync()
                .ConfigureAwait(false)
                .GetAwaiter()
                .GetResult();
                return(channelFactory);
            })
            .AddSingleton <ISubscriptionRepository, SubscriptionRepository>()
            .AddSingleton <ITopologyProvider, TopologyProvider>()
            .AddTransient <IPublisherConfigurationFactory, PublisherConfigurationFactory>()
            .AddTransient <IBasicPublishConfigurationFactory, BasicPublishConfigurationFactory>()
            .AddTransient <IConsumerConfigurationFactory, ConsumerConfigurationFactory>()
            .AddTransient <IConsumeConfigurationFactory, ConsumeConfigurationFactory>()
            .AddTransient <IExchangeDeclarationFactory, ExchangeDeclarationFactory>()
            .AddTransient <IQueueConfigurationFactory, QueueDeclarationFactory>()
            .AddSingleton <INamingConventions, NamingConventions>()
            .AddSingleton <IExclusiveLock, ExclusiveLock>()
            .AddSingleton <IBusClient, BusClient>()
            .AddSingleton <IResourceDisposer, ResourceDisposer>()
            .AddTransient <IInstanceFactory>(resolver => new InstanceFactory(resolver))
            .AddSingleton <IPipeContextFactory, PipeContextFactory>()
            .AddTransient <IExtendedPipeBuilder, PipeBuilder>(resolver => new PipeBuilder(resolver))
            .AddSingleton <IPipeBuilderFactory>(provider => new PipeBuilderFactory(provider));

            var clientBuilder = new ClientBuilder();

            options?.Plugins?.Invoke(clientBuilder);
            clientBuilder.DependencyInjection?.Invoke(register);
            register.AddSingleton(clientBuilder.PipeBuilderAction);
            options?.DependencyInjection?.Invoke(register);

            if (!register.IsRegistered(typeof(ILogger <>)))
            {
                register.AddSingleton(typeof(ILogger <>), typeof(Logger <>));
            }

            if (!register.IsRegistered(typeof(ILogger)))
            {
                register.AddSingleton <ILogger, NullLogger>(resolver => NullLogger.Instance);
            }

            if (!register.IsRegistered(typeof(ILoggerFactory)))
            {
                register.AddSingleton <ILoggerFactory, NullLoggerFactory>();
            }

            return(register);
        }