Embracing Nservicebus Best Practices

35
~

description

Mapping Sages to logical Properties with Nservicebus

Transcript of Embracing Nservicebus Best Practices

Page 1: Embracing Nservicebus Best Practices

~

Page 2: Embracing Nservicebus Best Practices

~

Roy CornelissenSoftware Architect

@roycornelissen

Mark TalingLead Developer

@marktaling

Page 3: Embracing Nservicebus Best Practices

Where we started

Discovering NServiceBus

Multi tenancy

Saga’s

The evolution of NServiceBus

Performance considerations

Maintainability

NServiceBus in a brownfield

Wrap up

Q&A

Page 4: Embracing Nservicebus Best Practices

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

Page 5: Embracing Nservicebus Best Practices

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

Page 6: Embracing Nservicebus Best Practices
Page 7: Embracing Nservicebus Best Practices

Tenant ID

Tenant ID

Tenant ID

Tenant ID

Page 8: Embracing Nservicebus Best Practices

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;}

Page 9: Embracing Nservicebus Best Practices

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;}

Page 10: Embracing Nservicebus Best Practices

- Multiple properties- Concatenation- IFindSaga

- ISagaPersister

Page 11: Embracing Nservicebus Best Practices
Page 12: Embracing Nservicebus Best Practices

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); }}

Page 13: Embracing Nservicebus Best Practices

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); }}

Page 14: Embracing Nservicebus Best Practices

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); }}

Page 15: Embracing Nservicebus Best Practices

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); }}

Page 16: Embracing Nservicebus Best Practices

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);

Page 17: Embracing Nservicebus Best Practices
Page 18: Embracing Nservicebus Best Practices
Page 19: Embracing Nservicebus Best Practices
Page 20: Embracing Nservicebus Best Practices
Page 21: Embracing Nservicebus Best Practices

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

Page 22: Embracing Nservicebus Best Practices

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

Page 23: Embracing Nservicebus Best Practices

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

Page 24: Embracing Nservicebus Best Practices

Keep yourtransactions on a diet

Design withparallelism in mind

{Tx}[Unique] saga

properties

Page 25: Embracing Nservicebus Best Practices

Keep yourtransactions on a diet

Design withparallelism in mind

{Tx}{Tx}

[Unique] saga properties

{Tx}

Page 26: Embracing Nservicebus Best Practices
Page 27: Embracing Nservicebus Best Practices
Page 28: Embracing Nservicebus Best Practices
Page 29: Embracing Nservicebus Best Practices
Page 30: Embracing Nservicebus Best Practices
Page 31: Embracing Nservicebus Best Practices
Page 32: Embracing Nservicebus Best Practices

UseTransport<Rfc1149>();

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

Page 33: Embracing Nservicebus Best Practices

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

Page 34: Embracing Nservicebus Best Practices

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

Page 35: Embracing Nservicebus Best Practices

~

Roy CornelissenSoftware Architect

@roycornelissen

Mark TalingLead Developer

@marktaling

blogs.infosupport.com