view Workflow/Client/MainWindow.xaml.cs @ 89:3c67e54e3a17

Working version
author stevenhollidge <stevenhollidge@hotmail.com>
date Mon, 30 Apr 2012 10:45:32 +0100
parents
children
line wrap: on
line source

using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using Burrow;
using Burrow.Extras;
using Client.Controls;
using Client.Messages;

namespace Client
{
    public partial class MainWindow
    {
        private const string QUEUE_CONNECTION_STRING = "host=localhost;username=guest;password=guest";
        private readonly ITunnel tunnel;
        private readonly Subscription subscriptionOrder;
        private readonly Subscription subscriptionPayment;
        private readonly Subscription subscriptionDelivery;
        private readonly Subscription subscriptionError;
        private readonly Guid orderId;
        private const string ORDER_ROUTING_KEY = "Order";
        private const string PAYMENT_ROUTING_KEY = "Payment";
        private const string DELIVERY_ROUTING_KEY = "Delivery";
        private const string ORDER_STORYBOARD_KEY = "OrderStoryboard";
        private const string PAYMENT_STORYBOARD_KEY = "PaymentStoryboard";
        private const string DELIVERY_STORYBOARD_KEY = "DeliveryStoryboard";
        private const string FADEINGIFT_STORYBOARD_KEY = "FadeInGiftStoryboard";
        private readonly Storyboard orderStoryboard;
        private readonly Storyboard paymentStoryboard;
        private readonly Storyboard deliveryStoryboard;
        private readonly Storyboard fadeInGiftStoryboard;

        public MainWindow()
        {
            InitializeComponent();

            // set up rabbitmq tunnel
            tunnel = RabbitTunnel.Factory.Create(QUEUE_CONNECTION_STRING);
            tunnel.SetSerializer(new JsonSerializer());

            // set up a subscription to each message type
            subscriptionOrder = tunnel.SubscribeAsync<OrderMessage>("Workflow",
                (message, args) => Dispatcher.BeginInvoke(new Action(() => OnOrderReceived(message, args))));

            subscriptionPayment = tunnel.SubscribeAsync<PaymentMessage>("Workflow",
                (message, args) => Dispatcher.BeginInvoke(new Action(() => OnPaymentReceived(message, args))));

            subscriptionDelivery = tunnel.SubscribeAsync<DeliveryMessage>("Workflow",
                (message, args) => Dispatcher.BeginInvoke(new Action(() => OnDeliveryReceived(message, args))));

            //subscriptionError = tunnel.SubscribeAsync<?????>("Workflow",
            //    (message, args) => Dispatcher.BeginInvoke(new Action(() => OnErrorReceived(message, args))));

            // make sure all storyboards are available
            orderStoryboard = (Storyboard)this.TryFindResource(ORDER_STORYBOARD_KEY);
            paymentStoryboard = (Storyboard)this.TryFindResource(PAYMENT_STORYBOARD_KEY);
            deliveryStoryboard = (Storyboard)this.TryFindResource(DELIVERY_STORYBOARD_KEY);
            fadeInGiftStoryboard = (Storyboard)this.TryFindResource(FADEINGIFT_STORYBOARD_KEY);
            if (orderStoryboard == null) throw new ResourceReferenceKeyNotFoundException("Cannot find OrderStoryboard resource", ORDER_STORYBOARD_KEY);
            if (paymentStoryboard == null) throw new ResourceReferenceKeyNotFoundException("Cannot find PaymentStoryboard resource", PAYMENT_STORYBOARD_KEY);
            if (deliveryStoryboard == null) throw new ResourceReferenceKeyNotFoundException("Cannot find DeliveryStoryboard resource", DELIVERY_STORYBOARD_KEY);
            if (fadeInGiftStoryboard == null) throw new ResourceReferenceKeyNotFoundException("Cannot find FadeInGiftStoryboard resource", FADEINGIFT_STORYBOARD_KEY);

            // create an orderid for the workflow
            orderId = Guid.NewGuid();
        }

        private void NotifyUI(UIMessage ctrl, MessageType messageType, string text)
        {
            Dispatcher.BeginInvoke(new Action(() =>
                {
                    ctrl.MessageType = messageType;
                    ctrl.Text = text;
                    ctrl.Show();
                }));
        }

        #region EventHandlers

        private void btnSubmit_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                orderStoryboard.Begin();
                NotifyUI(NotificationRight, MessageType.Success, "Order submitted");
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
        }

        private void OnOrderStoryboardCompleted(object sender, EventArgs e)
        {
            try
            {
                tunnel.Publish(new OrderMessage
                {
                    OrderId = orderId,
                    OrderDate = DateTime.Now,
                    ProductCode = "ABCDE",
                    Quantity = 10,
                    UnitPrice = 9.99m
                }, ORDER_ROUTING_KEY);

                NotifyUI(NotificationLeft, MessageType.Success, "Order published");
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
        }

        private void OnOrderReceived(OrderMessage order, MessageDeliverEventArgs args)
        {
            try
            {
                NotifyUI(NotificationRight, MessageType.Success, "Order received");
                paymentStoryboard.Begin();
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
            finally
            {
                if (subscriptionOrder != null) subscriptionOrder.Ack(args.DeliveryTag);
            }
        }

        private void OnPaymentStoryboardCompleted(object sender, EventArgs e)
        {
            try
            {
                tunnel.Publish(new PaymentMessage()
                {
                    OrderId = orderId,
                    IsConfirmed = true
                }, PAYMENT_ROUTING_KEY);

                NotifyUI(NotificationLeft, MessageType.Success, "Payment published");
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
        }

        private void OnPaymentReceived(PaymentMessage payment, MessageDeliverEventArgs args)
        {
            try
            {
                NotifyUI(NotificationRight, MessageType.Success, "Payment received");
                deliveryStoryboard.Begin();
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
            finally
            {
                if (subscriptionPayment != null) subscriptionPayment.Ack(args.DeliveryTag);
            }
        }

        private void OnDeliveryStoryboardCompleted(object sender, EventArgs e)
        {
            try
            {
                tunnel.Publish(new DeliveryMessage()
                {
                    OrderId = orderId,
                    Address = "123 Some Street, Somewhere"
                }, DELIVERY_ROUTING_KEY);

                NotifyUI(NotificationLeft, MessageType.Success, "Delivery published");
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
        }

        private void OnDeliveryReceived(DeliveryMessage delivery, MessageDeliverEventArgs args)
        {
            try
            {
                NotifyUI(NotificationRight, MessageType.Success, "Delivery received");
                fadeInGiftStoryboard.Begin();
            }
            catch (Exception ex)
            {
                NotifyUI(NotificationRight, MessageType.Error, ex.Message);
            }
            finally
            {
                if (subscriptionDelivery != null) subscriptionDelivery.Ack(args.DeliveryTag);
            }
        }

        #endregion

        private void Window_Closed(object sender, EventArgs e)
        {
            Application.Current.Shutdown();
        }
    }
}