Exemple #1
0
        public async Task <IHttpActionResult> PostOrder([FromBody] TicketOrder order)
        {
            var error   = "";
            var handler = HandlersFactory.GetProfilerHandler(TheSettingService, TheLoggerService);

            handler.Start(LOG_TAG, "PostOrder", GetServiceProperties());

            try
            {
                TicketOrder.Validate(order);

                ServiceLocationService locator          = new ServiceLocationService();
                UriBuilderService      builder          = new UriBuilderService(Constants.ContosoEventsApplicationInstance, Constants.ContosoEventsTicketOrderServiceName);
                ITicketOrderService    dispenderService = locator.Create <ITicketOrderService>(builder.ToUri());
                return(Ok(await dispenderService.EnqueueOrder(order)));
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return(BadRequest(ex.Message));
            }
            finally
            {
                handler.Stop(error);
            }
        }
        public async Task ProcessOrder(TicketOrder order)
        {
            var error   = "";
            var handler = HandlersFactory.GetProfilerHandler(SettingService, LoggerService);

            handler.Start(LOG_TAG, "ProcessOrder", GetActorProperties());

            try
            {
                if (order == null)
                {
                    handler.Info("Process order is null");
                    return;
                }

                var state = await this.StateManager.GetStateAsync <TicketOrder>(ActorStatePropertyName);

                state = order;

                // Validate the order
                bool isValid = true;
                try
                {
                    TicketOrder.Validate(state);
                }
                catch (Exception e)
                {
                    state.Note = e.Message;
                    isValid    = false;
                }

                if (isValid)
                {
                    // Validate the event
                    TicketEvent tEvent = await this.DataStoreService.GetEventById(order.EventId);

                    if (tEvent == null)
                    {
                        state.FulfillDate = null;
                        state.IsFulfilled = false;
                        state.Note        = "The Event ID is not valid!";
                        //TODO: Exercise 6 - Task 1
                        //state.Status = OrderStatuses.Invalid;
                    }
                    else
                    {
                        state.PricePerTicket = tEvent.PricePerTicket;
                        state.Currency       = tEvent.Currency;
                        state.Price          = state.Tickets * state.PricePerTicket;

                        // Locate the event actor
                        IEventActor eventActor  = this.ActorLocationService.Create <IEventActor>(new ActorId(order.EventId), Constants.ContosoEventsApplicationName);
                        bool        isAvailable = await eventActor.ReserveTickets(order);

                        if (isAvailable || !SettingService.IsTicketAvailabilityCheck())
                        {
                            // Charge credit card
                            string confirmationNumber = await this.PaymentProcessorService.Authorize(order);

                            if (!string.IsNullOrEmpty(confirmationNumber))
                            {
                                state.PaymentProcessorConfirmation = confirmationNumber;
                                state.FulfillDate = DateTime.Now;
                                state.IsFulfilled = true;
                                //TODO: Exercise 6 - Task 1
                                //state.Status = OrderStatuses.Fufilled;
                            }
                            else
                            {
                                state.FulfillDate = null;
                                state.IsFulfilled = false;
                                state.Note        = "Credit card failed to authorize!";
                                await eventActor.FailTickets(order);

                                //TODO: Exercise 6 - Task 1
                                //state.Status = OrderStatuses.CreditCardDenied;
                            }
                        }
                        else
                        {
                            state.FulfillDate = null;
                            state.IsFulfilled = false;
                            state.Note        = "Event Tickets are exhausted!";
                            //TODO: Exercise 6 - Task 1
                            //state.Status = OrderStatuses.TicketsExhausted;
                        }
                    }
                }
                else
                {
                    state.FulfillDate = null;
                    state.IsFulfilled = false;
                    //TODO: Exercise 6 - Task 1
                    //state.Status = OrderStatuses.Invalid;
                }

                // Make sure the state is saved
                await SetEntityStateAsync(state);

                // Externalize the state
                await this.ExternalizationService.Externalize(state);

                // Notify the user
                await this.NotificationService.Notify(state);
            }
            catch (Exception ex)
            {
                error = ex.Message;
            }
            finally
            {
                handler.Stop(error);
                if (!string.IsNullOrEmpty(error))
                {
                    this.HealthReporterService.SendReportForService(HealthState.Error, GetHealthErrorMessage("ProcessOrder", error));
                }
            }
        }
        // ITicketDispenserService Interface Implementation
        public async Task <string> EnqueueOrder(TicketOrder order)
        {
            var error   = "";
            var handler = HandlersFactory.GetProfilerHandler(SettingService, LoggerService);

            handler.Start(LOG_TAG, "EnqueueOrder", GetServiceProperties());
            string orderId   = Guid.NewGuid().ToString();
            bool   blProceed = true;

            try
            {
                // Do some sanity checking
                TicketOrder.Validate(order);

                // Quick check to see if tickets are available
                if (SettingService.IsTicketAvailabilityCheck())
                {
                    IEventActor eventActor = this.ActorLocationService.Create <IEventActor>(new ActorId(order.EventId), Constants.ContosoEventsApplicationName);
                    if (!await eventActor.CheckTickets(order))
                    {
                        handler.Info("Processing order - Event Id: " + order.EventId + " - Order Id: " + orderId + " - tickets: " + order.Tickets + " - Tickets are exhausted!");
                        // Do not throw an exception because we will get a health issue
                        // throw new Exception("Tickets are exhausted!");
                        // Need to alert the admin only as tickets are exhausted

                        // Prevent proceeding with the order
                        blProceed = false;
                        // Reset the order id to indicate to the Web API client that the order did not go through
                        orderId = "";
                    }
                }

                if (blProceed)
                {
                    order.Id = orderId;
                    handler.Info("Processing order - Event Id: " + order.EventId + " - Order Id: " + orderId + " - tickets: " + order.Tickets);

                    //TODO: Task 2.1 - Get (or create) a reliable queue called "OrderQueue" in this partition.
                    //var requests = await this.StateManager./*...complete this...*/<IReliableQueue<TicketOrder>>(OrderQueueName);
                    var requests = await this.StateManager.GetOrAddAsync <IReliableQueue <TicketOrder> >(OrderQueueName);

                    //TODO: Task 2.2 - Create a new transaction scope
                    //using (var tx = this.StateManager./*...complete this...*/)
                    //{
                    // TODO: Task 2.3 - Enqueue the order to the reliable queue within the transaction
                    //await requests.EnqueueAsync(/*...complete this...*/, /*...complete this...*/);

                    // TODO: Task 2.4 - Commit the transaction if enqueue was successful
                    //await tx./*...complete this...*/();
                    //}

                    using (var tx = this.StateManager.CreateTransaction())
                    {
                        await requests.EnqueueAsync(tx, order);

                        await tx.CommitAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                error = ex.Message;
                throw ex;
            }
            finally
            {
                handler.Stop(error);
                if (!string.IsNullOrEmpty(error))
                {
                    this.HealthReporterService.SendReportForService(HealthState.Error, GetHealthErrorMessage("EnqueueOrder", error));
                }
            }

            return(orderId);
        }