greenfield development with cqrs and windows azure

36
Greenfield Development with CQRS and Windows Azure David Hoerster October 18, 2012

Upload: resources-global-professionals

Post on 14-May-2015

1.105 views

Category:

Technology


3 download

DESCRIPTION

You have the dream situation - the ability to create a brand new product from the ground up. You want it to be scalable, performant and easily updatable (since you're building in an incremental fashion). But since you're a start-up, you don't want to deal with the headache and costs of hosting. Well, one possibility is taking advantage of cloud platforms (Windows Azure, for instance) and architecting your system using a CQRS-style pattern. See how you can create a system patterned on CQRS in the cloud. We can take a look at a product I created (BrainCredits) and also see how others would take advantage of Azure services to create CQRS-patterned systems.

TRANSCRIPT

Page 1: Greenfield Development with CQRS and Windows Azure

Greenfield Development with CQRS and Windows Azure

David HoersterOctober 18, 2012

Page 2: Greenfield Development with CQRS and Windows Azure

C# MVP (since April 2011)Co-Founder of BrainCredits (braincredits.com)Principal at AgileWaysPresident of the Pittsburgh .NET User Group (meetup.com/pghdotnet) and organizer of PGH TechFestTwitter - @DavidHoersterBlog – http://geekswithblogs.net/DavidHoersterEmail – [email protected]

About Me

Page 3: Greenfield Development with CQRS and Windows Azure

What is CQRS?Why would you use it?BenefitsSome examplesUsing CQRS in Azure

Goals

Page 4: Greenfield Development with CQRS and Windows Azure

Command

Query

Responsibility

Segregation

Is it a pattern or an architecture?

What is CQRS?

Page 5: Greenfield Development with CQRS and Windows Azure

Command Query Responsibility Segregation

Based upon Bertrand Meyer’s Command Query Separation (CQS) principle:

“every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer” (Meyer)

In essence, commands return acknowledgement; queries return data.

What is CQRS?

Page 6: Greenfield Development with CQRS and Windows Azure

Backstory

Goals for BrainCredits.com ProductFast readsScalableHandle, potentially, large volumes of requestsBe able to change quicklyAbility to track user in system and events that occurEasy to deploy, manageInexpensive (FREE????)

Page 7: Greenfield Development with CQRS and Windows Azure

Backstory

Decided to jump into cloud with AzureScalabilityDeployment via VS2010 (Familiarity)Pretty inexpensive – no HW to manage

BizSpark company (at the time)– Currently 1500 compute hours of small instance– 5 GB of SQL Azure– Small cache instance– 2 million transactions/mo– and more…

But how to store data and design system?

Page 8: Greenfield Development with CQRS and Windows Azure

Backstory

I would recommend to start looking along the CQRS style of architectures- Rinat Abdullin

Articles by Greg Young, Udi Dahan, J. Oliver, R. Abdullin

Page 9: Greenfield Development with CQRS and Windows Azure

Common Architecture IssuesBusiness logic bleeds through

layersValidation logic ends up

everywhereCopy and Paste developmentApps that cater to modification

opsLeads to general complexity within

tiersCQRS simplifies this with classes performing specific duties (SRP)

What is CQRS?

Page 10: Greenfield Development with CQRS and Windows Azure

Simple App (tightly coupled)

Evolution of a System to CQRS

ApplicationDatabase

Page 11: Greenfield Development with CQRS and Windows Azure

Breaking out business logic

WriteData(string, string, int, bool, …) { }

Evolution of a System to CQRS

Application

DatabaseBusiness Logic

Page 12: Greenfield Development with CQRS and Windows Azure

Introduce messaging

Evolution of a System to CQRS

ApplicationDatabase

Business ServiceMSG

Page 13: Greenfield Development with CQRS and Windows Azure

Evolution of a System to CQRS

Client

Read Model StoreEvent Store

Repository Command Service

Domain (ARs)

Denormalizer

Event Handler

Command Issued – ack/nackData Requested/Returned

Command SideQuery Side

Optional

Page 14: Greenfield Development with CQRS and Windows Azure

Encapsulates business logic in the domainAllows you to model tasks instead of CRUDAllows for scalability very easilyCan provide for fast reads at the ‘expense’ of more expensive writesOnce the data is read by the client, it’s already old

A system that is eventually consistent is usually acceptableEVENTUAL CONSISTENCY!

– The read model for the system eventually is consistent with the system events

What is CQRS?

Page 15: Greenfield Development with CQRS and Windows Azure

Taking this further, CQRS describes a pattern where

Commands are messages (possibly asynchronous)Queries go against a read model

Since commands are returning void, it allows for the message to be transformed into the read modelThis flips the conventional wisdom of fast writes and slow reads

What is CQRS?

Page 16: Greenfield Development with CQRS and Windows Azure

Demo

Simple Console-based System

Page 17: Greenfield Development with CQRS and Windows Azure

CommandA message sent to tell the system to do something

public class CreateReservation : CommandBase { public Guid ReservationId { get; set; } public String Name { get; set; } public Int32 NumberOfSeats { get; set; } public String DiscountCode { get; set; } }

High-Level Code Walk-through of CQRS

Page 18: Greenfield Development with CQRS and Windows Azure

DomainYour system’s business logic and raises eventspublic class Reservation : AggregateRootBase { public void CreateNewReservation(CreateReservation cmd) { //do some logic to figure out TotalCost ApplyEvent(new ReservationCreated() { ReservationId = cmd.ReservationId, ReservationMade = DateTime.UtcNow, NumberOfSeats = cmd.NumberOfSeats, SeatsReservedFor = cmd.Name, TotalCost = totalCost }); }

High-Level Code Walk-through of CQRS

Page 19: Greenfield Development with CQRS and Windows Azure

EventsMessages raised by the domain stating that something has been done

public class ReservationCreated : EventBase { public Guid ReservationId { get; set; } public DateTime ReservationMade { get; set; } public Int32 NumberOfSeats { get; set; } public String SeatsReservedFor { get; set; } public Decimal TotalCost { get; set; }}

High-Level Code Walk-through of CQRS

Page 20: Greenfield Development with CQRS and Windows Azure

Event Handlers (Denormalizers)Persist event information to the read modelpublic void Handle(ReservationCreated theEvent) { var reservation = new Reservation() {

IsDeleted = false,NumberOfSeats = theEvent.NumberOfSeats,ReservationId = theEvent.ReservationId,ReservationMade = theEvent.ReservationMade,SeatsReservedFor = theEvent.SeatsReservedFor,TotalCost = theEvent.TotalCost };

var repo = new ReservationRepository(); repo.CreateReservation(reservation);}

High-Level Code Walk-through of CQRS

Page 21: Greenfield Development with CQRS and Windows Azure

Get all of the orders for user “David” in last 30 days

Benefits

Customer (SalesLT)CustomerID

NameStyle

Title

FirstName

MiddleName

LastName

Suffix

CompanyName

SalesPerson

EmailAddress

Product (SalesLT)ProductID

Name

ProductNumber

Color

StandardCost

ListPrice

Size

Weight

ProductCategoryID

ProductModelID

SellStartDate

SellEndDate

ProductCategory (SalesLT)ProductCategoryID

ParentProductCategoryID

Name

rowguid

ModifiedDate

ProductModel (SalesLT)ProductModelID

Name

CatalogDescription

rowguid

ModifiedDate

SalesOrderDetail (SalesLT)SalesOrderID

SalesOrderDetailID

OrderQty

ProductID

UnitPrice

UnitPriceDiscount

LineTotal

rowguid

ModifiedDate

SalesOrderHeader (SalesLT)SalesOrderID

RevisionNumber

OrderDate

DueDate

ShipDate

Status

OnlineOrderFlag

SalesOrderNumber

PurchaseOrderNumber

AccountNumber

CustomerID

ShipToAddressID

BillToAddressID

ShipMethod

CreditCardApprovalCode

SubTotal

TaxAmt

Freight

Page 22: Greenfield Development with CQRS and Windows Azure

Get all the orders for user ‘David’ in last 30 days

Benefits

SELECT c.FirstName, c.MiddleName, c.LastName, soh.SalesOrderID, soh.OrderDate, sod.UnitPrice, sod.OrderQty, sod.LineTotal, p.Name as 'ProductName', p.Color, p.ProductNumber, pm.Name as 'ProductModel', pc.Name as 'ProductCategory', pcParent.Name as 'ProductParentCategory'FROM SalesLT.Customer c INNER JOIN SalesLT.SalesOrderHeader soh

ON c.CustomerID = soh.CustomerIDINNER JOIN SalesLT.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderIDINNER JOIN SalesLT.Product p ON sod.ProductID = p.ProductIDINNER JOIN SalesLT.ProductModel pm ON p.ProductModelID = pm.ProductModelIDINNER JOIN SalesLT.ProductCategory pc ON p.ProductCategoryID = pc.ProductCategoryIDINNER JOIN SalesLT.ProductCategory pcParent ON pc.ParentProductCategoryID =

pcParent.ProductCategoryIDWHERE c.FirstName = 'David'

AND soh.OrderDate > (GETDATE()-30)

Page 23: Greenfield Development with CQRS and Windows Azure

Wouldn’t it be great if it was something like?

Benefits

SELECT FirstName, MiddleName, LastName, SalesOrderID, OrderDate, UnitPrice, OrderQty, LineTotal, ProductName, Color, ProductNumber, ProductModel, ProductCategory, ProductParentCategoryFROM CustomerSalesWHERE FirstName = 'David'

AND OrderDate > (GETDATE()-30)

Page 24: Greenfield Development with CQRS and Windows Azure

Command Side Flow

Command Domain

Event 1

Event 2

Event N

Handler 1

Handler 2

Handler N

ReadModel

Page 25: Greenfield Development with CQRS and Windows Azure

Read Side Flow

ReadModel

Query Provider(Repo/

WCFDS/etc)

Client

Request for Data

DTO

Query

Results

Page 26: Greenfield Development with CQRS and Windows Azure

Demo

Moving CQRS to Azure

Page 27: Greenfield Development with CQRS and Windows Azure

Hosting CQRS in AzureTypically, you’d want 2 roles

Web Role for the UI, which also performs queryingWorker Role for the Command handling

Both roles can scale out as much as needed

Multiple web roles with a single worker role, or vice versa or both!

CQRS in the Cloud

Page 28: Greenfield Development with CQRS and Windows Azure

CQRS in Azure

Client

Read Model StoreEvent Store

Repository

Command Service

Domain (ARs)

Denormalizer

Event Handler

Worker Role

Web Role Command Side

SQL Azureor other

Repository

Table Storage?

Query Side

Page 29: Greenfield Development with CQRS and Windows Azure

How do I issue commands from my web role?Some typical solutions

WCF service on the worker role side3rd party service bus toolUse Azure storage features (blobs, queues, tables)

All have advantages and disadvantages

CQRS in the Cloud

Page 30: Greenfield Development with CQRS and Windows Azure

General flow is thisWeb role issues a command by dropping it in a blob container (name is GUID).Command blob name is then dropped in a queueWorker role monitors queue for workWhen it finds a message in the queue, it grabs blob from storage based on id in queue messageDeserializes command and then sends it through normal CQRS pipeline

CQRS in the Cloud

Page 31: Greenfield Development with CQRS and Windows Azure

CQRS in the Cloud

ControllerQueue

Blob Storage

Command Handler

Azure Table Storage

Domain

Event(s)

Denormalizer

Read Model

Repository

Web Role Worker Role

Azure Sub-system

Page 32: Greenfield Development with CQRS and Windows Azure

Web and Worker Role SeparationShare knowledge of queues and interface

If worker were to go down, web would still run

Commands would queue upProvides some level of fault tolerance

CQRS in the Cloud

Page 33: Greenfield Development with CQRS and Windows Azure

Worker role can spawn multiple threads to monitor queues

BrainCredits has several threadsCommandQueue and LogQueueDifferent polling intervalsDepending on importance of information

CQRS in the Cloud

Page 34: Greenfield Development with CQRS and Windows Azure

Using Azure Table Storage for logging user actions…

Different than events. Want to know user behavior.Storage is huge – just watch transaction costs

Consider batching log reads

But you can create replays of user interaction

Similar to event sourcing’s replay of eventsEvent sourcing doesn’t capture “Cancels” or “Reads”, which may be useful from a marketing perspective

CQRS in the Cloud

Page 35: Greenfield Development with CQRS and Windows Azure

Claim Credit for this Session

BrainCreditshttp://www.braincredits.com/Lesson/17210

Page 36: Greenfield Development with CQRS and Windows Azure

Resources

Cerebrata Cloud Storage Studio – http://cerebrata.comParaleap AzureWatch – http://paraleap.com

Conference Reservation Example on GitHubhttps://github.com/DavidHoerster/Conference

CQRS Journey – https://github.com/mspnp/cqrs-journey-docCQRS Info Site – http://cqrs.wordpress.com/DDD/CQRS Google Group - http://groups.google.com/group/dddcqrsUdi Dahan’s CQRS article “Clarified CQRS” – http://www.udidahan.com/2009/12/09/clarified-cqrs /Rinat Abdullin’s CQRS information – http://abdullin.com/cqrsDistributed Podcast - http://distributedpodcast.com/