Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Embracing Nservicebus Best Practices

1,819 views

Published on

Mapping Sages to logical Properties with Nservicebus

Published in: Technology
  • Be the first to comment

Embracing Nservicebus Best Practices

  1. 1. ~
  2. 2. ~ Roy Cornelissen Software Architect @roycornelissen Mark Taling Lead Developer @marktaling
  3. 3. Where we started Discovering NServiceBus Multi tenancy Saga’s The evolution of NServiceBus Performance considerations Maintainability NServiceBusin a brownfield Wrap up Q&A
  4. 4. Integration Layer Service Layer NIS Presentation Layer Planning UI Reporting UI customer external apps Employee Self Service Common Forecast Realization Payment Schedule
  5. 5. Monitoring & Control Integration Layer Service Layer NIS Presentation Layer Planning UI Reporting UI Employee Self Service Common Forecast Payment Schedule Service Bus Integration Services IS HRM IS Payroll IS Budget IS Provisioning IS Time IS Point of Sale Realization
  6. 6. Tenant ID Tenant ID Tenant ID Tenant ID
  7. 7. publicclassBuildPrincipalFromHeaders:IMutateIncomingMessages { publicobjectMutateIncoming(objectmessage) { Thread.CurrentPrincipal=null; stringtenantId=Headers.GetMessageHeader(message,“urn:dv:tenantid”); ICollection<Claim>claims=newList<Claim>(); … claims.Add(newClaim(SecurityConstants.TenantIdClaim,tenantId)); varprincipal=newClaimsPrincipal( newClaimsIdentityCollection{ newClaimsIdentity(claims) }); Thread.CurrentPrincipal=principal; returnmessage; } …
  8. 8. publicclassSetHeadersFromPrincipal:IMutateOutgoingMessages { publicIBusBus{get;set;} publicobjectMutateOutgoing(objectmessage) { IClaimsIdentityidentity= Thread.CurrentPrincipal.IdentityasIClaimsIdentity; stringtenantId=identity.GetTenantId(); if(!string.IsNullOrWhiteSpace(tenantId)) { Bus.SetMessageHeader(message,“urn:dv:tenantid”,tenantId); } returnmessage; } …
  9. 9. -Multiple properties -Concatenation -IFindSaga -ISagaPersister
  10. 10. publicclassAdvancedRavenSagaPersister: RavenSagaPersister, ISagaPersister{ publicAdvancedRavenSagaPersister(RavenSessionFactorysessionFactory): base(sessionFactory) { } publicnewvoidSave(IContainSagaDatasaga) { base.Save(saga); } publicnewvoidComplete(IContainSagaDatasaga) { base.Complete(saga); } voidISagaPersister.Save(IContainSagaDatasaga) { Save(saga); } voidISagaPersister.Complete(IContainSagaDatasaga) { Complete(saga); } }
  11. 11. publicclassAdvancedRavenSagaPersister: RavenSagaPersister, ISagaPersister{ publicAdvancedRavenSagaPersister(RavenSessionFactorysessionFactory): base(sessionFactory) { } publicnewvoidSave(IContainSagaDatasaga) { base.Save(saga); } publicnewvoidComplete(IContainSagaDatasaga) { base.Complete(saga); } voidISagaPersister.Save(IContainSagaDatasaga) { Save(saga); } voidISagaPersister.Complete(IContainSagaDatasaga) { Complete(saga); } }
  12. 12. publicclassAdvancedRavenSagaPersister: RavenSagaPersister, ISagaPersister{ publicAdvancedRavenSagaPersister(RavenSessionFactorysessionFactory): base(sessionFactory) { } publicnewvoidSave(IContainSagaDatasaga) { base.Save(saga); StoreMappingKeys(saga); } publicnewvoidComplete(IContainSagaDatasaga) { RemoveMappingKeys(saga); base.Complete(saga); } voidISagaPersister.Save(IContainSagaDatasaga) { Save(saga); } voidISagaPersister.Complete(IContainSagaDatasaga) { Complete(saga); } }
  13. 13. publicclassAdvancedRavenSagaPersister: RavenSagaPersister, ISagaPersister{ privatereadonlyRavenSessionFactory_sessionFactory; publicAdvancedRavenSagaPersister(RavenSessionFactorysessionFactory): base(sessionFactory) { _sessionFactory= sessionFactory; } publicnewvoidSave(IContainSagaDatasaga) { base.Save(saga); StoreMappingKeys(saga); } publicnewvoidComplete(IContainSagaDatasaga) { RemoveMappingKeys(saga); base.Complete(saga); } voidISagaPersister.Save(IContainSagaDatasaga) { Save(saga); } voidISagaPersister.Complete(IContainSagaDatasaga) { Complete(saga); } }
  14. 14. publicclassAdvancedRavenSagaPersister: RavenSagaPersister, ISagaPersister{ privatereadonlyRavenSessionFactory_sessionFactory; publicAdvancedRavenSagaPersister(RavenSessionFactorysessionFactory): base(sessionFactory) { _sessionFactory= sessionFactory; } publicnewvoidSave(IContainSagaDatasaga) { base.Save(saga); StoreMappingKeys(saga); } publicnewvoidComplete(IContainSagaDatasaga) { RemoveMappingKeys(saga); base.Complete(saga); } voidISagaPersister.Save(IContainSagaDatasaga) { Save(saga); } voidISagaPersister.Complete(IContainSagaDatasaga) { Complete(saga); } } vardocument = _sessionFactory.Session.Include("SagaDocId").Load<SagaMappingIdentity>(mappingId); return_sessionFactory.Session.Load<TSagaData>(document.SagaId);
  15. 15. RequestUtcTimeout<PolicyRenewal>(TimeSpan.FromDays(300));
  16. 16. Lessonslearned -Upgrade regularly -RetryPoCsandassumptions -Beware of abstractions
  17. 17. Lessonslearned -Upgrade regularly -RetryPoCsandassumptions -Beware of abstractions
  18. 18. Keep yourtransactions on a diet Design withparallelismin mind {Tx} [Unique] saga properties
  19. 19. Keep yourtransactions on a diet Design withparallelismin mind {Tx} {Tx} [Unique] saga properties {Tx}
  20. 20. UseTransport<Rfc1149>(); http://www.make-awesome.com/2014/04/nservicebus-transport-for-rfc-1149/
  21. 21. NServiceBusis an opinionatedframework If it fits, it fits like a glove Prepare to make concessionsat first Clean up later Messaging makes totally different use cases possible Requires a new mindsetfor everyone
  22. 22. NServiceBusis a greatway tobreak open existingarchitectures Despiteitsflexibility andpluggability, alwaysfollow itsdesign principles Go withthe flow, itsolvesreal life problemsyoumightnotknowyouhave
  23. 23. ~ Roy Cornelissen Software Architect @roycornelissen Mark Taling Lead Developer @marktaling blogs.infosupport.com

×