NServiceBus 2.0 loses first published message when using MsmqSubscriptionStorage - nservicebus

I am using MsmqSubscriptionStorage in a pub/sub scenario and the first message is lost when the subscriptions has not been stored. If I watch the debug messages, while running in the GenericHost, I see that all the subscriptions are setup but the first message is never sent to the subscribers. If more messages are sent, then they are successfully sent to the subscribers (as indicated in the logs)
I am using version 2.0.0.0.
Here is the bus configuration I'm using.
var bus = Configure.With(
new List<Assembly>
{
typeof(Configure).Assembly,
typeof(IBus).Assembly
})
.DefaultBuilder()
.Log4Net()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.UnicastBus()
.ImpersonateSender(false)
.LoadMessageHandlers()
.MsmqSubscriptionStorage()
.CreateBus()
.Start();

I'm answering my own post so no one sees this issue and draws the conclusion that there is something wrong with NServiceBus. This was a GCE - (Gross Conceptual Error) on my part. My hosting environment was deferring resolution of a static reference to the Bus. Changing the initialization of my process to setup the static Bus reference at start up solve the problem.

If you Publish before any subscription has been registered those messages won't have a destination and will be ignored. You may want to look into the DB subscription storage to have something less transient.

Related

NServiceBus Subscriber failing on server

I have a rather simple Pub/sub setup which works fine on our developer machines but when I deploy to our test serveres it throws this error for all messages:
System.NullReferenceException: Object reference not set to an instance of an object.
at NServiceBus.Unicast.UnicastBus.HandleTransportMessage(IBuilder childBuilder, TransportMessage msg) in c:\BuildAgent\work\nsb.master_6\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 1328
at NServiceBus.Unicast.UnicastBus.TransportMessageReceived(Object sender, TransportMessageReceivedEventArgs e) in c:\BuildAgent\work\nsb.master_6\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 1247
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at NServiceBus.Unicast.Transport.Transactional.TransactionalTransport.OnTransportMessageReceived(TransportMessage msg) in c:\BuildAgent\work\nsb.master_6\src\impl\unicast\transport\NServiceBus.Unicast.Transport.Transactional\TransactionalTransport.cs:line 480
We allready have other SendOnly, Distributors and workers running on the same servers, so msmq etc. should be installed corretly. This is the first time however we are using Pub/Sub on these servers.
If i use the exact same binaries and config on a developer machine it runs smoothly, but not on the servers which are 2008R2, Powershell V3.
We are using a fluent configuration for the subscriber:
return NServiceBus.Configure.With()
.DefineEndpointName(queuePrefix)
.Log4Net(_serviceBusLog.Build())
.StructureMapBuilder()
.JsonSerializer()
.License(ConfigTable.GetConfigString(ConfigTableKeys.NServiceBus, "License"))
.MsmqTransport()
.IsTransactional(true)
.RunTimeoutManagerWithInMemoryPersistence()
.EnablePerformanceCounters()
.UnicastBus()
.CreateBus()
.Start(() => NServiceBus.Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
We also have our own UnicastBus config which scans for message handlers (they're message types) and then automatically creates the endpoint mappings. This was my first concern so I disabled it and used the app.config way of setting up endpoints, but the error still occurs.
Note the error occours for every single message.
Note we are running version 3.3.5 of NSB.
Im still travering the server settings as I believe there must be some difference that makes it tick but i have not found it yet.
Anyone has any recommendations as for what to look for?
Kind regards
It appears that I have found the error.
After testing a raw simple console Pub/Sub on the server I added a try catch in the handler and caught... My own exception....
Im embrassed.
But it appears that the exception is not forwarded correctly to the log in NSB and i was therefore completely thrown of from the real problem.
I do not know if this is something that is fixed in later versions of NSB, but i hope so.
Until then Im using my own try catch logic to add a custom log entry.
Kind regards.

How do I get my MVC application to send commands and subscribe to events in NServiceBus

Perhaps I'm missing something here and this question is maybe the same as this one so sorry for any duplication.
I have an MVC4 site that quite happily Sends() commands to my NServiceBus server. I now want the same MVC site to be able to subscribe to IEvents Publish()ed from the same NServiceBus server. But I just can't get it to work.
Messages are being published from the server and are showing in MSMQ but I can't get the MVC site to pick them up.
Is this possible with NServiceBus 3.3.5? And if so, how do I have to set up my MVC site to make it work?
Thanks in advance!
Edit: Here's the config I have in the MVC app:
Configure.With()
.Log4Net()
.StructureMapBuilder()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(false)
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.JsonSerializer()
.CreateBus()
.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
I don't have an EndpointConfig class that implements the IConfigureThisEndpoint or and AsA_ interfaces. I've tried adding one but it never gets called and I can't work out what the host would be or how to start the NServiceBus host application from the web app. Or even what context the host would run under if the code sits inside IIS (if that makes sense!).
My guess is you're missing the .LoadMessageHandlers() line in your fluent config after .UnicastBus() - that's the most common error that leads to self-hosted applications not processing messages sent to them.
If that's not the case, add your fluent config block to your question and we'll take a look.
Edit: After fluent config posted
My next guess is that you're declaring your serializer too late. The .UnicastBus() step is one of the last stops before "Let's start this thing!" I'm thinking perhaps by the time you've hit this point, the config has made the assumption you're going with the default XmlSerializer. Could you try moving the serializer line to right after .StructureMapBuilder() and see if that works better?
If that doesn't work I might consider using the .DefaultBuilder() momentarily just to rule out an problem with your IoC container.
In regards to your other comments, a self-hosted bus will never have an EndpointConfig. That's a pointer for endpoints hosted by the NServiceBus.Host.exe only.
I also suppose it's not completely obvious where you're calling this fluent config from. This code needs to be called once when the webapp is started up - usually from the application start method in the Global.asax. Because the webapp is in control, there's no automatic assembly scanning to find and wire up your NServiceBus pipeline like in the NServiceBus Host.

NServiceBus V3 how to config endpoints within WPF app

I'm getting the following error when trying to configure an instance of the bus.
No endpoint name could be generated, please specify your own
convention using Configure.DefineEndpointName(...)
Hmm so I need to tell the bus about endpoint message mappings. I normally use the app.config to specify this, and it works fine accept for my WPF app, (I'm no expert with WPF).
It appears the app.config is not being read within my WPF app or something is wrong...
My startup code looks like this (which works fine in winforms or console app)
Bus = Configure.With()
.AutofacBuilder(container)
.XmlSerializer()
.MsmqTransport().IsTransactional(true).PurgeOnStartup(false)
.UnicastBus().ImpersonateSender(false).LoadMessageHandlers()
.CreateBus()
.Start();
Any suggestions...
Ultimately I would like the message to endpoint mappings stored centrally so that all desktop apps could read this on startup ie. central DB that all clients have access to.
An example of how to config the bus this way would be appreciated.
Just to add to the accepted answer above: the order in which you call the methods is important. In my case I couldn't get DefineEndpointName() to work unless it was directly after Configure.With()
Bus = Configure.With()
.DefineEndpointName("WPFSubscriber")
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("MyMessages"))
.Log4Net()
.DefaultBuilder()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.UnicastBus().
ImpersonateSender(false)
.LoadMessageHandlers()
.CreateBus()
.Start();
Per the error, just add that to your initialization:
Bus = Configure.With()
.AutofacBuilder(container)
.DefineEndpointName("ENDPOINTNAME")
.XmlSerializer()
.MsmqTransport().IsTransactional(true).PurgeOnStartup(false)
.UnicastBus().ImpersonateSender(false).LoadMessageHandlers()
.CreateBus()
.Start();
This will also become your input queue name.

NServiceBus message handler not going to 'error' queue on exception

I have a sample NServiceBus application to test the waters.. All is going well, sending and handling is working correctly.
I have deliberately thrown an exception within a certain message handler to see what happens - but nothing does. The exception is logged correctly to the console, yet the message is pulled off the queue and NOT placed in the error queue as I'd expect. Also, the 5 times retry didn't occur either. Is this correct behaviour?
Also, the queue was created correctly at startup when first specified.
the config and bootstrap code for the server (where the handler resides are below)
config:
<MsmqTransportConfig
InputQueue="SiteServer1"
NumberOfWorkerThreads="1"
MaxRetries="5"
ErrorQueue="SiteServer1Errors"
/>
program.cs:
var bus = NServiceBus.Configure.With()
.Log4Net()
.CastleWindsorBuilder(container)
.XmlSerializer()
.MsmqTransport()
.UnicastBus()
.LoadMessageHandlers()
.CreateBus()
.Start();
Am I missing anything here?
I modified the bootstrapper code to include
.IsTransactional(true)
on the bus config and now it is working! It seems that non-transactional messages are disposable. Makes sense!
Are you running Windows Server 2008? If so you will find an event log in the event viewer, under the Application event logs -> windows -> MSMQ - End2End. This will record every action taken by the MSMQ subsystem on your machine.
I am guessing that NSB has tried to send the message to the error queue. However, what is really hapenning is that the MSMQ subsystem on your machine has consumed the message, but not been able to deliver it to the error queue for some reason.
I would look in the MSMQ log for an idea of what is going on.

NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer

A suite of integration services that use NServiceBus have been dropped in my lap (unfortunately I was not involved in the original implementation and the person who did write the code has left).
The services work fine in our development & testing environments; but I cannot get them to run in our production environment. I get the error
NServiceBus.Unicast.Transport.CompletionMessage was not registered in the serializer.
Check that it appears in the list of configured assemblies/types to scan.
I've checked the config files on the servers and they're almost identical; in particular the MsmqTransportConfig and UnicastBusConfig blocks are identical. The major difference between the two environments is that in production, the web/app/database tiers are on separate servers whereas in the testing environment they all reside on the same server. However, the integration service calls are only made from the app tier, and even in production the app tier and integration services reside on the same server (at least for now), so I'm not sure this should make a difference.
I did download the documentation (the .chm file) but every topic I click on says "broken link".
I've also read several the questions and answers including this one, but since the code is working in our testing environment I'm somewhat reluctant to make changes to it.
We're configuring NServiceBus as follows:
NServiceBus.Configure.WithWeb()
.Log4Net()
.StructureMapBuilder(ObjectFactory.Container)
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.MsmqSubscriptionStorage()
.UnicastBus()
.LoadMessageHandlers()
.ImpersonateSender(false)
.CreateBus()
.Start();
and the transport is configured like so:
<MsmqTransportConfig
InputQueue="OutboundSubscriptionRequestQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
I would really appreciate any assistance. I'm not necessarily looking to have an answer handed to me, just a nudge in the right direction ... right now I feel as though I'm shooting in the dark.
Sounds like nsb fails to scan nservicebus.core.dll for types. Can you verify that its present, not blocked and that log4net.dll is deployed in the same dir.