private void PublishExceptionAsync(ProcessingCommand processingCommand, IPublishableException exception, int retryTimes)
 {
     _ioHelper.TryAsyncActionRecursively("PublishExceptionAsync",
                                         () => _exceptionPublisher.PublishAsync(exception),
                                         currentRetryTimes => PublishExceptionAsync(processingCommand, exception, currentRetryTimes),
                                         result =>
     {
         CompleteCommand(processingCommand, CommandStatus.Failed, exception.GetType().Name, (exception as Exception).Message);
     },
                                         () =>
     {
         var serializableInfo = new Dictionary <string, string>();
         exception.SerializeTo(serializableInfo);
         var exceptionInfo = string.Join(",", serializableInfo.Select(x => string.Format("{0}:{1}", x.Key, x.Value)));
         return(string.Format("[commandId:{0}, exceptionInfo:{1}]", processingCommand.Message.Id, exceptionInfo));
     },
                                         errorMessage =>
     {
         _logger.Fatal(string.Format("Publish event has unknown exception, the code should not be run to here, errorMessage: {0}", errorMessage));
     },
                                         retryTimes, true);
 }
        public async Task RunApprenticeshipUpdateJob(string jobId)
        {
            _logger.Info($"{nameof(AcademicYearEndExpiryProcessor)} run at {_currentDateTime.Now} for Academic Year CurrentAcademicYearStartDate: {_academicYearProvider.CurrentAcademicYearStartDate}, CurrentAcademicYearEndDate: {_academicYearProvider.CurrentAcademicYearEndDate}, LastAcademicYearFundingPeriod: {_academicYearProvider.LastAcademicYearFundingPeriod}, JobId: {jobId}");


            var expiredApprenticeshipUpdates =
                (await _apprenticeshipUpdateRepository
                 .GetExpiredApprenticeshipUpdates(_academicYearProvider.CurrentAcademicYearStartDate))
                .Where(m => m.Cost != null || m.TrainingCode != null || m.StartDate != null)
                .ToArray();


            _logger.Info($"Found {expiredApprenticeshipUpdates.Length} apprenticeship updates that will be set to expired, JobId: {jobId}");

            foreach (var update in expiredApprenticeshipUpdates)
            {
                _logger.Info($"Updating ApprenticeshipUpdate to expired, ApprenticeshipUpdateId: {update.Id}, JobId: {jobId}");
                await _apprenticeshipUpdateRepository.ExpireApprenticeshipUpdate(update.Id);

                var apprenticeship =
                    await _apprenticeshipRepository.GetApprenticeship(update.ApprenticeshipId);

                await _messagePublisher.PublishAsync(new ApprenticeshipUpdateCancelled(
                                                         apprenticeship.EmployerAccountId,
                                                         apprenticeship.ProviderId,
                                                         apprenticeship.Id));
            }

            var expiredApprenticeshipUpdatesAfterJob =
                (await _apprenticeshipUpdateRepository
                 .GetExpiredApprenticeshipUpdates(_academicYearProvider.CurrentAcademicYearStartDate))
                .Where(m => m.Cost != null || m.TrainingCode != null || m.StartDate != null)
                .ToArray();

            if (expiredApprenticeshipUpdatesAfterJob.Length != 0)
            {
                throw new Exception($"AcademicYearEndProcessor not completed successfull, Should not be any pending ApprenticeshipUpdates after job done, There are {expiredApprenticeshipUpdatesAfterJob.Length} , JobId: {jobId}");
            }
        }
Exemple #3
0
        public async Task <IProcessResult> Process(UpdateProductPriceCommand command)
        {
            var model = await databaseContext.Products.FindAsync(command.Id);

            if (model is null)
            {
                return(ProcessResult.NotFound());
            }

            model.UpdatePrice(Money.FromDecimal(command.Price));
            await databaseContext.ProductPrices.AddAsync(model.InitializePrice(Money.FromDecimal(command.Price)));

            await databaseContext.SaveChangesAsync();

            await messagePublisher.PublishAsync(new ProductPriceUpdatedIntegrationEvent
            {
                Id    = model.Id,
                Price = model.Price
            });

            return(ProcessResult.Ok());
        }
Exemple #4
0
        public async Task Can_Create_Messaging_Bus_Fluently_For_A_Queue()
        {
            // Arrange
            var services = new ServiceCollection()
                           .AddLogging((p) => p.AddXUnit(OutputHelper))
                           .AddJustSaying(
                (builder) =>
            {
                builder.Client((options) => options.WithBasicCredentials("accessKey", "secretKey").WithServiceUri(TestEnvironment.SimulatorUrl))
                .Messaging((options) => options.WithRegions("eu-west-1"))
                .Publications((options) => options.WithQueue <QueueMessage>())
                .Subscriptions((options) => options.ForQueue <QueueMessage>())
                .Services((options) => options.WithMessageMonitoring(() => new MyMonitor()));
            })
                           .AddJustSayingHandler <QueueMessage, QueueHandler>();

            IServiceProvider serviceProvider = services.BuildServiceProvider();

            IMessagePublisher publisher = serviceProvider.GetRequiredService <IMessagePublisher>();
            IMessagingBus     listener  = serviceProvider.GetRequiredService <IMessagingBus>();

            using (var source = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
            {
                // Act
                listener.Start(source.Token);

                var message = new QueueMessage();

                await publisher.PublishAsync(message, source.Token);

                // Assert
                while (!source.IsCancellationRequested && !QueueHandler.MessageIds.Contains(message.Id))
                {
                    await Task.Delay(TimeSpan.FromSeconds(0.2), source.Token);
                }

                QueueHandler.MessageIds.ShouldContain(message.Id);
            }
        }
 private void PublishDomainEventAsync(ProcessingCommand processingCommand, DomainEventStreamMessage eventStream, int retryTimes)
 {
     _ioHelper.TryAsyncActionRecursively("PublishEventAsync",
                                         () => _domainEventPublisher.PublishAsync(eventStream),
                                         currentRetryTimes => PublishDomainEventAsync(processingCommand, eventStream, currentRetryTimes),
                                         result =>
     {
         if (_logger.IsDebugEnabled)
         {
             _logger.DebugFormat("Publish event success, {0}", eventStream);
         }
         var commandHandleResult = processingCommand.CommandExecuteContext.GetResult();
         var commandResult       = new CommandResult(CommandStatus.Success, processingCommand.Message.Id, eventStream.AggregateRootId, commandHandleResult, typeof(string).FullName);
         CompleteCommand(processingCommand, commandResult);
     },
                                         () => string.Format("[eventStream:{0}]", eventStream),
                                         errorMessage =>
     {
         _logger.Fatal(string.Format("Publish event has unknown exception, the code should not be run to here, errorMessage: {0}", errorMessage));
     },
                                         retryTimes, true);
 }
        public async Task Can_Create_Messaging_Bus_With_Contributors()
        {
            // Arrange
            var services = new ServiceCollection()
                           .AddLogging((p) => p.AddXUnit(OutputHelper))
                           .AddJustSaying()
                           .AddSingleton <IMessageBusConfigurationContributor, AwsContributor>()
                           .AddSingleton <IMessageBusConfigurationContributor, MessagingContributor>()
                           .AddSingleton <IMessageBusConfigurationContributor, QueueContributor>()
                           .AddSingleton <IMessageBusConfigurationContributor, RegionContributor>()
                           .AddJustSayingHandler <QueueMessage, QueueHandler>()
                           .AddSingleton <MyMonitor>();

            IServiceProvider serviceProvider = services.BuildServiceProvider();

            IMessagePublisher publisher = serviceProvider.GetRequiredService <IMessagePublisher>();
            IMessagingBus     listener  = serviceProvider.GetRequiredService <IMessagingBus>();

            using (var source = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
            {
                // Act
                await listener.StartAsync(source.Token);

                await publisher.StartAsync(source.Token);

                var message = new QueueMessage();

                await publisher.PublishAsync(message, source.Token);

                // Assert
                while (!source.IsCancellationRequested && !QueueHandler.MessageIds.Contains(message.Id))
                {
                    await Task.Delay(TimeSpan.FromSeconds(0.2), source.Token);
                }

                QueueHandler.MessageIds.ShouldContain(message.Id);
            }
        }
        private async Task PublishAsync(
            IMessagePublisher publisher,
            Message message,
            PublishMetadata metadata,
            int attemptCount,
            CancellationToken cancellationToken)
        {
            attemptCount++;
            try
            {
                var watch = Stopwatch.StartNew();

                await publisher.PublishAsync(message, metadata, cancellationToken)
                .ConfigureAwait(false);

                watch.Stop();
                Monitor.PublishMessageTime(watch.Elapsed);
            }
            catch (Exception ex)
            {
                if (attemptCount >= Config.PublishFailureReAttempts)
                {
                    Monitor.IssuePublishingMessage();
                    _log.LogError(0, ex, "Failed to publish a message of type '{MessageType}'. Halting after attempt number {PublishAttemptCount}.",
                                  message.GetType(), attemptCount);
                    throw;
                }

                _log.LogWarning(0, ex, "Failed to publish a message of type '{MessageType}'. Retrying after attempt number {PublishAttemptCount} of {PublishFailureReattempts}.",
                                message.GetType(), attemptCount, Config.PublishFailureReAttempts);

                var delayForAttempt = TimeSpan.FromMilliseconds(Config.PublishFailureBackoff.TotalMilliseconds * attemptCount);
                await Task.Delay(delayForAttempt, cancellationToken).ConfigureAwait(false);

                await PublishAsync(publisher, message, metadata, attemptCount, cancellationToken).ConfigureAwait(false);
            }
        }
Exemple #8
0
        public async Task <IProcessResult> Process(CreateSpecificAttributeCommand command)
        {
            var product = await databaseContext.Products.FindAsync(command.ProductId);

            if (product is null)
            {
                return(ProcessResult.BadRequest("Product not exists."));
            }

            var attribute = product.InitializeSpecificAttribute(Name.FromString(command.Name), command.Value);
            await databaseContext.SpecificAttributes.AddAsync(attribute);

            await databaseContext.SaveChangesAsync();

            await messagePublisher.PublishAsync(new SpecificAttributeCreatedIntegrationEvent
            {
                Id        = attribute.Id,
                ProductId = product.Id,
                Name      = attribute.Name,
                Value     = attribute.Value
            });

            return(ProcessResult.Ok());
        }
Exemple #9
0
        private async Task AssertMessagePublishedAndReceivedAsync <T>(
            IServiceCollection services,
            IHandlerAsync <T> handler,
            TaskCompletionSource <object> completionSource)
            where T : Message, new()
        {
            IServiceProvider serviceProvider = services.BuildServiceProvider();

            IMessagePublisher publisher = serviceProvider.GetRequiredService <IMessagePublisher>();
            IMessagingBus     listener  = serviceProvider.GetRequiredService <IMessagingBus>();

            using var source = new CancellationTokenSource(Timeout);
            listener.Start(source.Token);

            var message = new T();

            // Act
            await publisher.PublishAsync(message, source.Token);

            // Assert
            completionSource.Task.Wait(source.Token);

            await handler.Received(1).Handle(Arg.Is <T>((p) => p.UniqueKey() == message.UniqueKey()));
        }
Exemple #10
0
        private async Task ApproveApprenticeshipUpdate(AcceptApprenticeshipChangeCommand command, Apprenticeship apprenticeship, ApprenticeshipUpdate pendingUpdate)
        {
            var commitment = await _commitmentRepository.GetCommitmentById(apprenticeship.CommitmentId);

            if (commitment.ProviderId == null)
            {
                throw new InvalidOperationException($"The provider id on commitment {apprenticeship.CommitmentId} is null when calling {nameof(ApproveApprenticeshipUpdate)}");
            }

            var historyService = new HistoryService(_historyRepository);

            historyService.TrackUpdate(commitment, CommitmentChangeType.EditedApprenticeship.ToString(), commitment.Id, null, command.Caller.CallerType, command.UserId, apprenticeship.ProviderId, apprenticeship.EmployerAccountId, command.UserName);
            historyService.TrackUpdate(apprenticeship, ApprenticeshipChangeType.Updated.ToString(), null, apprenticeship.Id, command.Caller.CallerType, command.UserId, apprenticeship.ProviderId, apprenticeship.EmployerAccountId, command.UserName);

            _mapper.ApplyUpdate(apprenticeship, pendingUpdate);

            await Task.WhenAll(
                _apprenticeshipUpdateRepository.ApproveApprenticeshipUpdate(pendingUpdate, apprenticeship, command.Caller),
                CreateEvents(commitment, apprenticeship, pendingUpdate),
                historyService.Save(),
                _messagePublisher.PublishAsync(new ApprenticeshipUpdateAccepted(commitment.EmployerAccountId, commitment.ProviderId.Value, command.ApprenticeshipId)),
                _v2EventsPublisher.PublishApprenticeshipUpdatedApproved(commitment, apprenticeship)
                );
        }
        private Task PublishExceptionAsync(ProcessingCommand processingCommand, IDomainException exception, int retryTimes, TaskCompletionSource <bool> taskSource)
        {
            exception.MergeItems(processingCommand.Message.Items);

            _ioHelper.TryAsyncActionRecursivelyWithoutResult("PublishExceptionAsync",
                                                             () => _exceptionPublisher.PublishAsync(exception),
                                                             currentRetryTimes => PublishExceptionAsync(processingCommand, exception, currentRetryTimes, taskSource),
                                                             async() =>
            {
                await CompleteCommand(processingCommand, CommandStatus.Failed, exception.GetType().Name, (exception as Exception).Message).ConfigureAwait(false);
                taskSource.SetResult(true);
            },
                                                             () =>
            {
                var serializableInfo = new Dictionary <string, string>();
                exception.SerializeTo(serializableInfo);
                var exceptionInfo = string.Join(",", serializableInfo.Select(x => string.Format("{0}:{1}", x.Key, x.Value)));
                return(string.Format("[commandId:{0}, exceptionInfo:{1}]", processingCommand.Message.Id, exceptionInfo));
            },
                                                             null,
                                                             retryTimes, true);

            return(taskSource.Task);
        }
        public async Task <bool> Handle(OrderPlacedEvent message)
        {
            // Returning true would indicate:
            //   The message was handled successfully
            //   The message can be removed from the queue.
            // Returning false would indicate:
            //   The message was not handled successfully
            //   The message handling should be retried (configured by default)
            //   The message should be moved to the error queue if all retries fail

            try
            {
                _logger.LogInformation("Order {orderId} for {description} received", message.OrderId, message.Description);

                // This is where you would actually handle the order placement
                // Intentionally left empty for the sake of this being a sample application

                _logger.LogInformation("Order {OrderId} ready", message.OrderId);

                await Task.Delay(RandomNumberGenerator.GetInt32(50, 100));

                var orderReadyEvent = new OrderReadyEvent
                {
                    OrderId = message.OrderId
                };

                await _publisher.PublishAsync(orderReadyEvent).ConfigureAwait(false);

                return(true);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to handle message for {orderId}", message.OrderId);
                return(false);
            }
        }
Exemple #13
0
        public override async Task ProcessBatchAsync(ICollection <EventContext> contexts)
        {
            var stacks = new Dictionary <string, Tuple <bool, Stack> >();

            foreach (var ctx in contexts)
            {
                if (String.IsNullOrEmpty(ctx.Event.StackId))
                {
                    // only add default signature info if no other signature info has been added
                    if (ctx.StackSignatureData.Count == 0)
                    {
                        ctx.StackSignatureData.AddItemIfNotEmpty("Type", ctx.Event.Type);
                        ctx.StackSignatureData.AddItemIfNotEmpty("Source", ctx.Event.Source);
                    }

                    string signatureHash = ctx.StackSignatureData.Values.ToSHA1();
                    ctx.SignatureHash = signatureHash;

                    Tuple <bool, Stack> value;
                    if (stacks.TryGetValue(signatureHash, out value))
                    {
                        ctx.Stack = value.Item2;
                    }
                    else
                    {
                        ctx.Stack = await _stackRepository.GetStackBySignatureHashAsync(ctx.Event.ProjectId, signatureHash).AnyContext();

                        if (ctx.Stack != null)
                        {
                            stacks.Add(signatureHash, Tuple.Create(false, ctx.Stack));
                        }
                    }

                    if (ctx.Stack == null)
                    {
                        Logger.Trace().Message("Creating new event stack.").Write();
                        ctx.IsNew = true;

                        string title = _formattingPluginManager.GetStackTitle(ctx.Event);
                        var    stack = new Stack {
                            OrganizationId   = ctx.Event.OrganizationId,
                            ProjectId        = ctx.Event.ProjectId,
                            SignatureInfo    = new SettingsDictionary(ctx.StackSignatureData),
                            SignatureHash    = signatureHash,
                            Title            = title?.Truncate(1000),
                            Tags             = ctx.Event.Tags ?? new TagSet(),
                            Type             = ctx.Event.Type,
                            TotalOccurrences = 1,
                            FirstOccurrence  = ctx.Event.Date.UtcDateTime,
                            LastOccurrence   = ctx.Event.Date.UtcDateTime
                        };

                        ctx.Stack = stack;
                        stacks.Add(signatureHash, Tuple.Create(true, ctx.Stack));
                    }
                }
                else
                {
                    ctx.Stack = await _stackRepository.GetByIdAsync(ctx.Event.StackId, true).AnyContext();

                    if (ctx.Stack == null || ctx.Stack.ProjectId != ctx.Event.ProjectId)
                    {
                        ctx.SetError("Invalid StackId.");
                        continue;
                    }

                    ctx.SignatureHash = ctx.Stack.SignatureHash;

                    if (!stacks.ContainsKey(ctx.Stack.SignatureHash))
                    {
                        stacks.Add(ctx.Stack.SignatureHash, Tuple.Create(false, ctx.Stack));
                    }
                    else
                    {
                        stacks[ctx.Stack.SignatureHash] = Tuple.Create(false, ctx.Stack);
                    }
                }

                if (!ctx.IsNew && ctx.Event.Tags != null && ctx.Event.Tags.Count > 0)
                {
                    if (ctx.Stack.Tags == null)
                    {
                        ctx.Stack.Tags = new TagSet();
                    }

                    List <string> newTags = ctx.Event.Tags.Where(t => !ctx.Stack.Tags.Contains(t)).ToList();
                    if (newTags.Count > 0)
                    {
                        ctx.Stack.Tags.AddRange(newTags);
                        // make sure the stack gets saved
                        if (!stacks.ContainsKey(ctx.Stack.SignatureHash))
                        {
                            stacks.Add(ctx.Stack.SignatureHash, Tuple.Create(true, ctx.Stack));
                        }
                        else
                        {
                            stacks[ctx.Stack.SignatureHash] = Tuple.Create(true, stacks[ctx.Stack.SignatureHash].Item2);
                        }
                    }
                }

                ctx.Event.IsFirstOccurrence = ctx.IsNew;

                // sync the fixed and hidden flags to the error occurrence
                ctx.Event.IsFixed  = ctx.Stack.DateFixed.HasValue;
                ctx.Event.IsHidden = ctx.Stack.IsHidden;
            }

            var stacksToAdd = stacks.Where(kvp => kvp.Value.Item1 && String.IsNullOrEmpty(kvp.Value.Item2.Id)).Select(kvp => kvp.Value.Item2).ToList();

            if (stacksToAdd.Count > 0)
            {
                await _stackRepository.AddAsync(stacksToAdd, true, sendNotification : stacksToAdd.Count == 1).AnyContext();

                if (stacksToAdd.Count > 1)
                {
                    await _publisher.PublishAsync(new ExtendedEntityChanged { ChangeType = ChangeType.Added, Type = typeof(Stack).Name, OrganizationId = contexts.First().Organization.Id, ProjectId = contexts.First().Project.Id }).AnyContext();
                }
            }

            var stacksToSave = stacks.Where(kvp => kvp.Value.Item1 && !String.IsNullOrEmpty(kvp.Value.Item2.Id)).Select(kvp => kvp.Value.Item2).ToList();

            if (stacksToSave.Count > 0)
            {
                await _stackRepository.SaveAsync(stacksToSave, true, sendNotification : false).AnyContext(); // notification will get sent later in the update stats step
            }
            // Set stack ids after they have been saved and created
            contexts.ForEach(ctx => {
                ctx.Event.StackId = ctx.Stack?.Id;
            });
        }
Exemple #14
0
 private void PublishMessage(TTo msg)
 {
     _publisher.PublishAsync(msg);
 }
Exemple #15
0
        public async Task <IActionResult> Notify(
            [FromServices] IMessagePublisher messagePublisher)
        {
            var log = new Dictionary <string, object>();

            string out_trade_no = null;

            try
            {
                using var ms = new System.IO.MemoryStream();

                await this.Request.Body.CopyToAsync(ms);

                var xml_data = System.Text.Encoding.UTF8.GetString(ms.ToArray()); //IOHelper.StreamToString(ms);

                log["notify_data"] = xml_data;

                var notify_data = this.wxPayApi.ParseNotifyData(xml_data);
                log["notify_data_model"] = notify_data;
                out_trade_no             = this.__parse_order_no__(notify_data.out_trade_no);
                log["out_trade_no"]      = out_trade_no;

                {
                    //收到回调不管怎么样都添加记录
                    var notify_data_log = this.__get_notify_log__(notify_data, out_trade_no, xml_data);
                    log["notify_data_log"] = notify_data_log;
                    await messagePublisher.PublishAsync(notify_data_log);
                }

                if (ValidateHelper.IsEmpty(out_trade_no))
                {
                    throw new WxPayException("回调信息中未找到订单号");
                }

                log["publish"] = true;

                if (!notify_data.IsSuccess())
                {
                    throw new WxPayException("通知状态为不成功");
                }

                var my_sign = this.wxPayApi.MD5Sign(notify_data.Parameters, out var sign_str);
                log["notify_sign_str"] = sign_str;

                if (notify_data.sign != my_sign)
                {
                    throw new WxPayException("签名校验失败");
                }

                var count = await this.orderService.SetAsPayed(out_trade_no, notify_data.transaction_id, PayMethodEnum.Wechat);

                if (count <= 0)
                {
                    throw new WxPayException("更新订单失败");
                }

                {
                    var order = await this.orderService.GetOrderByNo(out_trade_no);

                    if (order != null)
                    {
                        await this.AddOrderStatusHistoryLog(order.UID);
                    }
                    else
                    {
                        this._logger.AddErrorLog("____pls_notice____");
                    }
                }

                return(this.__response__(true));
            }
            catch (WxPayException e)
            {
                log["out_exception"]      = e.Message;
                log["out_exception_info"] = e.Info;
                //更新状态失败,检查订单状态是否时已支付,如果是就直接返回成功

                if (ValidateHelper.IsNotEmpty(out_trade_no))
                {
                    try
                    {
                        var success = await this.__return_success__(out_trade_no);

                        if (success)
                        {
                            return(this.__response__(true));
                        }
                    }
                    catch (Exception err)
                    {
                        log["retry_in_ex_block"] = new
                        {
                            err.Message,
                            err.GetType().FullName,
                        };
                    }
                }

                var info = log.ToJson();

                this._logger.AddErrorLog($"处理微信支付回调失败:{info}", e);

                return(this.__response__(false, e.Message.Take(50).JoinAsString(string.Empty)));
            }
        }
Exemple #16
0
 public static Task PublishAsync(this IMessagePublisher publisher, Message message)
 {
     return(publisher.PublishAsync(message, CancellationToken.None));
 }
Exemple #17
0
 /// <summary>
 /// Serializes the message to JSON and sends a single message to the queue.
 /// </summary>
 /// <param name="messagePublisher">The message publisher.</param>
 /// <param name="message">The message.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The task.</returns>
 public static Task PublishAsJsonAsync <T>(this IMessagePublisher <T> messagePublisher, T message, CancellationToken cancellationToken = default)
 {
     return(messagePublisher.PublishAsync(ConvertToMessage(message), cancellationToken));
 }
Exemple #18
0
        public void TestSendReceiveAs(string format)
        {
            string       exchange         = GetType().Name;
            const string routingKeyPrefix = "Messages";

            IConnectionFactory connectionFactory = new ConnectionFactory {
                HostName = "localhost"
            };
            IMessageSource <IMessage>    messageSource    = CreateMessageSource(format, connectionFactory, exchange, routingKeyPrefix);
            IMessagePublisher <IMessage> messagePublisher = CreateMessagePublisher(format, connectionFactory, exchange, routingKeyPrefix);

            List <TestMessage> receivedMessages1 = new List <TestMessage>();

            messageSource.Messages
            .OfType <TestMessage>()
            .Subscribe(msg => { Console.WriteLine(msg); receivedMessages1.Add(msg); }, Console.WriteLine, () => Console.WriteLine("Completed!"));

            List <TestMessage> receivedMessages2 = new List <TestMessage>();

            messageSource.Messages
            .OfType <TestMessage>()
            .Subscribe(msg => { Console.WriteLine(msg); receivedMessages2.Add(msg); }, Console.WriteLine, () => Console.WriteLine("Completed!"));

            List <TestMessage> messages = new List <TestMessage>
            {
                new TestMessage {
                    Data = "Hello"
                },
                new TestMessage {
                    Data = "World!"
                },
                new TestMessage {
                    Data = "..."
                },
                new TestMessage {
                    Data = "Good"
                },
                new TestMessage {
                    Data = "Bye"
                },
                new TestMessage {
                    Data = "Cruel"
                },
                new TestMessage {
                    Data = "World"
                }
            };

            foreach (TestMessage message in messages)
            {
                messagePublisher.PublishAsync(message);
            }

            Thread.Sleep(TimeSpan.FromSeconds(1));

            Assert.That(receivedMessages1.Count, Is.EqualTo(7), "Incorrect number of messages received for first subscription");
            Assert.That(receivedMessages2.Count, Is.EqualTo(7), "Incorrect number of messages received for second subscription");

            for (int index = 0; index < messages.Count; index++)
            {
                TestMessage message   = messages[index];
                TestMessage received1 = receivedMessages1[index];
                TestMessage received2 = receivedMessages2[index];
                Assert.That(received1.Data == message.Data && received1.Timestamp == message.Timestamp, string.Format("Incorrect message1: {0}", received1));
                Assert.That(received2.Data == message.Data && received2.Timestamp == message.Timestamp, string.Format("Incorrect message2: {0}", received2));
            }
        }
Exemple #19
0
        /// <summary>
        /// Sends a single message to the queue.
        /// </summary>
        /// <param name="messagePublisher">The message publisher.</param>
        /// <param name="message">The message.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task.</returns>
        public static Task PublishAsync(this IMessagePublisher messagePublisher, Message message, CancellationToken cancellationToken = default)
        {
            _ = message ?? throw new ArgumentNullException(nameof(message));

            return(messagePublisher.PublishAsync(new Message[] { message }, cancellationToken));
        }
Exemple #20
0
 private async Task SendApprenticeshipUpdateCancelledEvent(Apprenticeship apprenticeship)
 {
     await _messagePublisher.PublishAsync(new ApprenticeshipUpdateCancelled(apprenticeship.EmployerAccountId, apprenticeship.ProviderId, apprenticeship.Id));
 }
Exemple #21
0
 public async Task PublishAsync(IMessage message, CancellationToken token)
 => await _publisher.PublishAsync(message, token);
Exemple #22
0
 /// <summary>
 /// Serializes the messages to JSON and sends them to the queue.
 /// </summary>
 /// <param name="messagePublisher">The message publisher.</param>
 /// <param name="messages">The messages.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The task.</returns>
 public static Task PublishAsJsonAsync <T>(this IMessagePublisher <T> messagePublisher, IEnumerable <T> messages, CancellationToken cancellationToken = default)
 {
     return(messagePublisher.PublishAsync(messages.Select(ConvertToMessage), cancellationToken));
 }
Exemple #23
0
        public async Task <IHttpActionResult> ChangePlanAsync(string id, string planId, string stripeToken = null, string last4 = null, string couponId = null)
        {
            if (String.IsNullOrEmpty(id) || !CanAccessOrganization(id))
            {
                return(NotFound());
            }

            if (!Settings.Current.EnableBilling)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Plans cannot be changed while billing is disabled.")));
            }

            var organization = await GetModelAsync(id, false);

            if (organization == null)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Invalid OrganizationId.")));
            }

            var plan = BillingManager.GetBillingPlan(planId);

            if (plan == null)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Invalid PlanId.")));
            }

            if (String.Equals(organization.PlanId, plan.Id) && String.Equals(BillingManager.FreePlan.Id, plan.Id))
            {
                return(Ok(ChangePlanResult.SuccessWithMessage("Your plan was not changed as you were already on the free plan.")));
            }

            // Only see if they can downgrade a plan if the plans are different.
            if (!String.Equals(organization.PlanId, plan.Id))
            {
                var result = await _billingManager.CanDownGradeAsync(organization, plan, CurrentUser);

                if (!result.Success)
                {
                    return(Ok(result));
                }
            }

            var customerService     = new StripeCustomerService(Settings.Current.StripeApiKey);
            var subscriptionService = new StripeSubscriptionService(Settings.Current.StripeApiKey);

            try {
                // If they are on a paid plan and then downgrade to a free plan then cancel their stripe subscription.
                if (!String.Equals(organization.PlanId, BillingManager.FreePlan.Id) && String.Equals(plan.Id, BillingManager.FreePlan.Id))
                {
                    if (!String.IsNullOrEmpty(organization.StripeCustomerId))
                    {
                        var subs = await subscriptionService.ListAsync(new StripeSubscriptionListOptions { CustomerId = organization.StripeCustomerId });

                        foreach (var sub in subs.Where(s => !s.CanceledAt.HasValue))
                        {
                            await subscriptionService.CancelAsync(sub.Id);
                        }
                    }

                    organization.BillingStatus = BillingStatus.Trialing;
                    organization.RemoveSuspension();
                }
                else if (String.IsNullOrEmpty(organization.StripeCustomerId))
                {
                    if (String.IsNullOrEmpty(stripeToken))
                    {
                        return(Ok(ChangePlanResult.FailWithMessage("Billing information was not set.")));
                    }

                    organization.SubscribeDate = SystemClock.UtcNow;

                    var createCustomer = new StripeCustomerCreateOptions {
                        SourceToken = stripeToken,
                        PlanId      = planId,
                        Description = organization.Name,
                        Email       = CurrentUser.EmailAddress
                    };

                    if (!String.IsNullOrWhiteSpace(couponId))
                    {
                        createCustomer.CouponId = couponId;
                    }

                    var customer = await customerService.CreateAsync(createCustomer);

                    organization.BillingStatus = BillingStatus.Active;
                    organization.RemoveSuspension();
                    organization.StripeCustomerId = customer.Id;
                    if (customer.Sources.TotalCount > 0)
                    {
                        organization.CardLast4 = customer.Sources.Data.First().Card.Last4;
                    }
                }
                else
                {
                    var update = new StripeSubscriptionUpdateOptions {
                        PlanId = planId
                    };
                    var  create      = new StripeSubscriptionCreateOptions();
                    bool cardUpdated = false;

                    if (!String.IsNullOrEmpty(stripeToken))
                    {
                        update.Source = stripeToken;
                        create.Source = stripeToken;
                        cardUpdated   = true;
                    }

                    var subscriptionList = await subscriptionService.ListAsync(new StripeSubscriptionListOptions { CustomerId = organization.StripeCustomerId });

                    var subscription = subscriptionList.FirstOrDefault(s => !s.CanceledAt.HasValue);
                    if (subscription != null)
                    {
                        await subscriptionService.UpdateAsync(subscription.Id, update);
                    }
                    else
                    {
                        await subscriptionService.CreateAsync(organization.StripeCustomerId, planId, create);
                    }

                    await customerService.UpdateAsync(organization.StripeCustomerId, new StripeCustomerUpdateOptions {
                        Email = CurrentUser.EmailAddress
                    });

                    if (cardUpdated)
                    {
                        organization.CardLast4 = last4;
                    }

                    organization.BillingStatus = BillingStatus.Active;
                    organization.RemoveSuspension();
                }

                BillingManager.ApplyBillingPlan(organization, plan, CurrentUser);
                await _repository.SaveAsync(organization, o => o.Cache());

                await _messagePublisher.PublishAsync(new PlanChanged { OrganizationId = organization.Id });
            } catch (Exception e) {
                _logger.Error().Exception(e).Message("An error occurred while trying to update your billing plan: " + e.Message).Critical().Identity(CurrentUser.EmailAddress).Property("User", CurrentUser).SetActionContext(ActionContext).Write();
                return(Ok(ChangePlanResult.FailWithMessage(e.Message)));
            }

            return(Ok(new ChangePlanResult {
                Success = true
            }));
        }
 public static Task PublishAsync <T>(this IMessagePublisher publisher, T message, TimeSpan?delay = null) where T : class
 {
     return(publisher.PublishAsync(typeof(T), message, delay));
 }
Exemple #25
0
        /// <inheritdoc />
        public Task LaunchAsync()
        {
            IView mainView = _serviceProvider.GetRequiredService <MainView>();

            return(_messagePublisher.PublishAsync(new AddViewMessage("Shell.ViewsHost", mainView, new Scope(_serviceProvider))));
        }
Exemple #26
0
        public static Task PublishAsync(this IMessagePublisher publisher, Func <MqttMessageBuilder, MqttMessageBuilder> builder)
        {
            var message = builder(new MqttMessageBuilder()).Build();

            return(publisher.PublishAsync(message));
        }
Exemple #27
0
        private async Task OnCreateTodo(CreateTodo todo, CancellationToken ct)
        {
            var newTodo = await _todoRepo.AddAsync(todo.Title);

            await _publisher.PublishAsync(new TodoCreated(newTodo), ct);
        }
Exemple #28
0
 public virtual async Task PublishAsync(SampleMessage message)
 {
     await _publisher.PublishAsync(message);
 }
Exemple #29
0
 public static Task PublishEventAsync <TEvent>(this IMessagePublisher publisher,
                                               TEvent @event)
     where TEvent : class, IEvent
 => publisher.PublishAsync(@event);
        public async Task PublishAsync(object message)
        {
            await _eventConsumer.Consume(message);

            await _messagePublisher.PublishAsync(message);
        }