Embracing Nservicebus Best Practices

Post on 24-Jun-2015

468 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

Mapping Sages to logical Properties with Nservicebus

Transcript

~

~

Roy CornelissenSoftware Architect

@roycornelissen

Mark TalingLead Developer

@marktaling

Where we started

Discovering NServiceBus

Multi tenancy

Saga’s

The evolution of NServiceBus

Performance considerations

Maintainability

NServiceBus in a brownfield

Wrap up

Q&A

Inte

grat

ion

La

yer

Serv

ice

Laye

r

NIS

Pre

sen

tati

on

La

yer

Planning UI Reporting UI

customer external apps

Employee Self Service

Common Forecast Realization PaymentSchedule

Monitoring & Control

Inte

grat

ion

La

yer

Serv

ice

Laye

r

NIS

Pre

sen

tati

on

La

yer

Planning UI Reporting UIEmployee Self

Service

Common Forecast PaymentSchedule

Service Bus

Integration Services

IS HRM

IS Payroll

IS Budget

IS Provisioning

IS Time

IS Point of Sale

Realization

Tenant ID

Tenant ID

Tenant ID

Tenant ID

public class BuildPrincipalFromHeaders : IMutateIncomingMessages{

public object MutateIncoming(object message){

Thread.CurrentPrincipal = null;

string tenantId = Headers.GetMessageHeader(message, “urn:dv:tenantid”);

ICollection<Claim> claims = new List<Claim>();…claims.Add(new Claim(SecurityConstants.TenantIdClaim, tenantId));

var principal = new ClaimsPrincipal(new ClaimsIdentityCollection { new ClaimsIdentity(claims) });

Thread.CurrentPrincipal = principal;

return message;}

public class SetHeadersFromPrincipal : IMutateOutgoingMessages{

public IBus Bus { get; set; }

public object MutateOutgoing(object message){

IClaimsIdentity identity =Thread.CurrentPrincipal.Identity as IClaimsIdentity;

string tenantId = identity.GetTenantId();

if (!string.IsNullOrWhiteSpace(tenantId)){

Bus.SetMessageHeader(message, “urn:dv:tenantid”, tenantId);}

return message;}

- Multiple properties- Concatenation- IFindSaga

- ISagaPersister

public class AdvancedRavenSagaPersister : RavenSagaPersister, ISagaPersister{

public AdvancedRavenSagaPersister(RavenSessionFactory sessionFactory):base(sessionFactory)

{

}

public new void Save(IContainSagaData saga){base.Save(saga);

}

public new void Complete(IContainSagaData saga){

base.Complete(saga);}

void ISagaPersister.Save(IContainSagaData saga) { Save(saga); }

void ISagaPersister.Complete(IContainSagaData saga) { Complete(saga); }}

public class AdvancedRavenSagaPersister : RavenSagaPersister, ISagaPersister{

public AdvancedRavenSagaPersister(RavenSessionFactory sessionFactory):base(sessionFactory)

{

}

public new void Save(IContainSagaData saga){base.Save(saga);

}

public new void Complete(IContainSagaData saga){

base.Complete(saga);}

void ISagaPersister.Save(IContainSagaData saga) { Save(saga); }

void ISagaPersister.Complete(IContainSagaData saga) { Complete(saga); }}

public class AdvancedRavenSagaPersister : RavenSagaPersister, ISagaPersister{

public AdvancedRavenSagaPersister(RavenSessionFactory sessionFactory):base(sessionFactory)

{

}

public new void Save(IContainSagaData saga){base.Save(saga);StoreMappingKeys(saga);

}

public new void Complete(IContainSagaData saga){RemoveMappingKeys(saga);base.Complete(saga);

}

void ISagaPersister.Save(IContainSagaData saga) { Save(saga); }

void ISagaPersister.Complete(IContainSagaData saga) { Complete(saga); }}

public class AdvancedRavenSagaPersister : RavenSagaPersister, ISagaPersister{private readonly RavenSessionFactory _sessionFactory;

public AdvancedRavenSagaPersister(RavenSessionFactory sessionFactory):base(sessionFactory)

{_sessionFactory = sessionFactory;

}

public new void Save(IContainSagaData saga){base.Save(saga);StoreMappingKeys(saga);

}

public new void Complete(IContainSagaData saga){RemoveMappingKeys(saga);base.Complete(saga);

}

void ISagaPersister.Save(IContainSagaData saga) { Save(saga); }

void ISagaPersister.Complete(IContainSagaData saga) { Complete(saga); }}

public class AdvancedRavenSagaPersister : RavenSagaPersister, ISagaPersister{private readonly RavenSessionFactory _sessionFactory;

public AdvancedRavenSagaPersister(RavenSessionFactory sessionFactory):base(sessionFactory)

{_sessionFactory = sessionFactory;

}

public new void Save(IContainSagaData saga){base.Save(saga);StoreMappingKeys(saga);

}

public new void Complete(IContainSagaData saga){RemoveMappingKeys(saga);base.Complete(saga);

}

void ISagaPersister.Save(IContainSagaData saga) { Save(saga); }

void ISagaPersister.Complete(IContainSagaData saga) { Complete(saga); }}

var document = _sessionFactory.Session.Include("SagaDocId").Load<SagaMappingIdentity>(mappingId);return _sessionFactory.Session.Load<TSagaData>(document.SagaId);

RequestUtcTimeout<PolicyRenewal>(TimeSpan.FromDays(300));

Lessons learned- Upgrade regularly- Retry PoCs and assumptions- Beware of abstractions

Lessons learned- Upgrade regularly- Retry PoCs and assumptions- Beware of abstractions

Keep yourtransactions on a diet

Design withparallelism in mind

{Tx}[Unique] saga

properties

Keep yourtransactions on a diet

Design withparallelism in mind

{Tx}{Tx}

[Unique] saga properties

{Tx}

UseTransport<Rfc1149>();

http://www.make-awesome.com/2014/04/nservicebus-transport-for-rfc-1149/

NServiceBus is an opinionated framework

If it fits, it fits like a glove

Prepare to make concessions at first

Clean up later

Messaging makes totally different use cases possible

Requires a new mindset for everyone

NServiceBus is a great

way to break open

existing architectures

Despite its flexibility and

pluggability, always follow

its design principles

Go with the flow, it solves

real life problems you

might not know you have

~

Roy CornelissenSoftware Architect

@roycornelissen

Mark TalingLead Developer

@marktaling

blogs.infosupport.com

top related