"No message serializer has been configured" error when starting NServiceBus endpoint - nservicebus

My GenericHost hosted service is failing to start with the following message:
2010-05-07 09:13:47,406 [1] FATAL NServiceBus.Host.Internal.GenericHost [(null)] <(null)> - System.InvalidOperationException: No message serializer has been con
figured.
at NServiceBus.Unicast.Transport.Msmq.MsmqTransport.CheckConfiguration() in d:\BuildAgent-02\work\672d81652eaca4e1\src\impl\unicast\NServiceBus.Unicast.Msmq\
MsmqTransport.cs:line 241
at NServiceBus.Unicast.Transport.Msmq.MsmqTransport.Start() in d:\BuildAgent-02\work\672d81652eaca4e1\src\impl\unicast\NServiceBus.Unicast.Msmq\MsmqTransport
.cs:line 211
at NServiceBus.Unicast.UnicastBus.NServiceBus.IStartableBus.Start(Action startupAction) in d:\BuildAgent-02\work\672d81652eaca4e1\src\unicast\NServiceBus.Uni
cast\UnicastBus.cs:line 694
at NServiceBus.Unicast.UnicastBus.NServiceBus.IStartableBus.Start() in d:\BuildAgent-02\work\672d81652eaca4e1\src\unicast\NServiceBus.Unicast\UnicastBus.cs:l
ine 665
at NServiceBus.Host.Internal.GenericHost.Start() in d:\BuildAgent-02\work\672d81652eaca4e1\src\host\NServiceBus.Host\Internal\GenericHost.cs:line 77
My endpoint configuration looks like:
public class ServiceEndpointConfiguration
: IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
public void Init()
{
// build out persistence infrastructure
var sessionFactory = Bootstrapper.InitializePersistence();
// configure NServiceBus infrastructure
var container = Bootstrapper.BuildDependencies(sessionFactory);
// set up logging
log4net.Config.XmlConfigurator.Configure();
Configure.With()
.Log4Net()
.UnityBuilder(container)
.XmlSerializer();
}
}
And my app.config looks like:
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="Logging" type="NServiceBus.Config.Logging, NServiceBus.Core" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
</configSections>
<Logging Threshold="DEBUG" />
<MsmqTransportConfig
InputQueue="NServiceBus.ServiceInput"
ErrorQueue="NServiceBus.Errors"
NumberOfWorkerThreads="1"
MaxRetries="2" />
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="NServiceBus.Auditing">
<MessageEndpointMappings>
<!-- publishers don't need to set this for their own message types -->
</MessageEndpointMappings>
</UnicastBusConfig>
<connectionStrings>
<add name="Db" connectionString="Data Source=..." providerName="System.Data.SqlClient" />
</connectionStrings>
<log4net debug="true">
<root>
<level value="INFO"/>
</root>
<logger name="NHibernate">
<level value="ERROR" />
</logger>
</log4net>
This has worked in the past, but seems to be failing when the generic host starts. My endpoint configuration is below, along with the app.config for the service. What is strange is that in my endpoint configuration, I am specifying to use the XmlSerializer for message serialization. I don't see any other errors in the console output preceding the error message. What am I missing?
Thanks, Steve

It looks like this was my own issue, though I had a hard time figuring that out based on the error message that I received. I have a base class for all of my messages:
public abstract class RequestMessage : IMessage {}
Recently, I created a partner message:
public abstract class ResponseMessage<TRequest>
where TRequest : RequestMessage {}
Apparently, when the host was starting up the IStartableBus, it would hit this generic message type and would not handle it correctly. I only really saw the underlying error when running with the DefaultBuilder, rather than the UnityBuilder that I am using in my project. It had something to do with the generic type constraint. I had assumed that this would work, but sadly it did not.
Regards,
Steve

Related

NServiceBus : Error messages does not appear in Error queue - ForwarderFaultManager does not start

I am running NServiceBus 5.2.14 with NServiceBus.Host 6.0.0
I am using MSMQ as transport and RavenDBPersistence.
All queues appear in computer management except for the error queue.
Everything functions fine for messages and endpoints. Errors are retried 5 times as they should. However after retrying 5 times they do not appear in the error queue.
I have specified the error queue in as such:
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
and included in configSections:
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
Edit1: app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="TransportConfig" type="NServiceBus.Config.TransportConfig, NServiceBus.Core" />
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
</configSections>
<TransportConfig MaximumConcurrencyLevel="5" MaxRetries="5" />
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
<UnicastBusConfig ForwardReceivedMessagesTo="audit">
<MessageEndpointMappings>
...
</MessageEndpointMappings>
</UnicastBusConfig>
...
Edit2 : endpointconfig:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server
{
...
public void Customize(BusConfiguration busConfiguration)
{
...
var containerFactory = new ContainerFactory();
Container.InitializeContainer(containerFactory);
AutoMapperInitializer.Configure();
busConfiguration.AssembliesToScan(AllAssemblies.Matching("NServiceBus").And("OurProjectName."));
busConfiguration.UseTransport<MsmqTransport>();
busConfiguration.EndpointName(ConfigurationManager.AppSettings["InputQueueName"]);
busConfiguration.UseContainer<WindsorBuilder>(customizations => customizations.ExistingContainer(Container.Instance));
busConfiguration.UsePersistence<RavenDBPersistence>();
busConfiguration.EnableCriticalTimePerformanceCounter();
busConfiguration.RegisterComponents(components => { components.ConfigureComponent<UsernameForwarder>(DependencyLifecycle.InstancePerCall); });
...
}
}
I run the endpoints in self-hosting console. In the list of FEATURES I see this:
Name: ForwarderFaultManager
Version: 5.2.14
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not meet one of the dependencies:
Name: InMemoryFaultManager
Version: 5.2.14
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None
I suspect my problem is with the ForwarderFaultManager, however there is nothing listed in the missing dependencies list. What may I be missing? Where could I start looking?

Subscriber is unable to handler message from publisher

I'm testing NServiceBus on ASP.NET MVC3. At the moment, I'm able to send command message to the backend and the message handler is listening to it. But when i try to publish the same message, the message handler is not listening.
The problem i found is that message is not published to the subscriber's queue. When i debug and check NServiceBusHost console, it says
2012-01-19 22:53:35,042 [1] INFO NServiceBus.Unicast.UnicastBus [(null)] <(null
)> - Subscribing to SampleMessage.Person1WasCreated, SampleMessage, Version=1.0.
0.0, Culture=neutral, PublicKeyToken=null at publisher queue Test-web
I checked my config settings again and again for few days and it seems correct for me . Can anyone please check for me what I'm missing? The thing I'm trying to do is to publish a message from the web and the message should be handle at the backend (ServiceHost2).
ASP.NET MVC3 Web.config
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="MsmqSubscriptionStorageConfig" type="NServiceBus.Config.MsmqSubscriptionStorageConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core"/>
</configSections>
<MsmqTransportConfig InputQueue="Test-web" ErrorQueue="Test-web-error" NumberOfWorkerThreads="1" MaxRetries="5" />
<MsmqSubscriptionStorageConfig Queue="Test-subscriptionstorage" />
Global.asax.cs
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
Global.Bus = Configure.WithWeb()
.Log4Net()
.CastleWindsorBuilder()
.XmlSerializer()
.MsmqTransport().IsTransactional(false)
.UnicastBus()
.LoadMessageHandlers()
.MsmqSubscriptionStorage()
.CreateBus()
.Start()
;
}
App.Config in ServiceHost2 Project
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="MsmqSubscriptionStorageConfig" type="NServiceBus.Config.MsmqSubscriptionStorageConfig, NServiceBus.Core" />
</configSections>
<MsmqSubscriptionStorageConfig Queue="Service2-AC1-subscriptionstorage" />
<MsmqTransportConfig InputQueue="Service2-AC1" ErrorQueue="Service2-AC1-Error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="SampleMessage" Endpoint="Test-web" />
</MessageEndpointMappings>
</UnicastBusConfig>
<appSettings>
<add key="EndpointConfigurationType" value="ServiceHost2.EndpointConfig, ServiceHost2"/>
</appSettings>
</configuration>
EndpointConfig for ServiceHost2
namespace ServiceHost2
{
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
public void Init()
{
Configure.With()
.Log4Net()
.CastleWindsorBuilder()
.MsmqTransport()
.MsmqSubscriptionStorage()
.XmlSerializer()
.UnicastBus().LoadMessageHandlers()
;
}
}
}
Method in the controller which publish the message
public ActionResult CreatePerson(Person p)
{
var Person1WasCreated = new Person1WasCreated {Id = p.Id,Name = p.Name};
Global.Bus.Publish(Person1WasCreated);
return View();
}
Thanks.
I think I found out why. I was reading on this article today about Why not publish NServiceBus messages from a web application?
It states very clear that, message is not suppose to publish from the web. Somehow The subscription storage created by my web project doesn't allow anything to subscribe to it.
So my solution is, I send the command message from the web to a message handler in Service1, and publish a new event message to Service2. Even the event message is able to subscribe into Service1's subscription storage.Everything works fine now. Thanks.

Unsatisfied dependency expressed through object property

So I am building publisher and following is my config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
<section name="DBSubscriptionStorageConfig" type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.Core" />
</configSections>
<!-- 1. In order to configure remote endpoints use the format: "queue#machine"
2. Input queue must be on the same machine as the process feeding off of it.
3. Error queue can (and often should) be on a different machine.
4. The community edition doesn't support more than one worker thread.
-->
<MsmqTransportConfig
InputQueue="HomeOfficePublisherQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<DBSubscriptionStorageConfig>
<NHibernateProperties>
<add Key="connection.provider"
Value="NHibernate.Connection.DriverConnectionProvider"/>
<add Key="connection.driver_class"
Value="NHibernate.Driver.SqlClientDriver"/>
<add Key="connection.connection_string"
Value="Server=<dbserver>;initial catalog=NServiceBus;Integrated Security=SSPI"/>
<add Key="dialect"
Value="NHibernate.Dialect.MsSql2005Dialect"/>
</NHibernateProperties>
</DBSubscriptionStorageConfig>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>
and here is my endpoint
class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
public void Init()
{
NServiceBus.Configure.With()
.Log4Net()
.DefaultBuilder()
.XmlSerializer()
.UnicastBus()
.ImpersonateSender(false)
.MsmqTransport()
.IsTransactional(true)
.DBSubcriptionStorage();
}
}
}
I get following exception
Exception when starting endpoint, error has been logged. Reason: Error creating object with name 'NServiceBus.Unicast.UnicastBus' : Unsatisfied dependency expressed through object property 'SubscriptionStorage': There are 2 objects of Type [NServiceBus.Unicast.Subscriptions.ISubscriptionStorage] for autowire by type, when there should have been just 1 to be able to autowire property 'SubscriptionStorage' of object 'NServiceBus.Unicast.UnicastBus'.
Any help is appreciated
I just had the same problem, and solved it by calling .CreateBus() at the end of the configuration:
class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
public void Init()
{
NServiceBus.Configure.With()
.Log4Net()
.DefaultBuilder()
.XmlSerializer()
.UnicastBus()
.ImpersonateSender(false)
.MsmqTransport()
.IsTransactional(true)
.DBSubcriptionStorage()
.CreateBus();
}
}
Only use the roles if their settings are what you want. Try to remove As_aPublisher and see if that does it for you. In your case both the role and your own code will register a sub.storeage and that is what gives you the exception.

Connecting to multiple databases in Active Record

I'm trying to connect to multiple databases in castle active record (which uses nhibernate.) My config file looks like this:
<configSections>
<section name="activerecord" type="Castle.ActiveRecord.Framework.Config.ActiveRecordSectionHandler, Castle.ActiveRecord" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<activerecord>
<config type="Navtrak.Business.Schemas.CommonSchemas.Models.NavtrakOperations.NavtrakOperationsDatabase`1, CommonSchemas">
<add key="hibernate.connection.connection_string" value="myconnstring" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
</config>
<config type="Navtrak.Business.Schemas.CommonSchemas.Models.Errors.ErrorsDatabase`1, CommonSchemas">
<add key="hibernate.connection.connection_string" value="Data Source=myconnstring" />
<add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" />
<add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2005Dialect" />
<add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
</config>
</activerecord>
And then I have a base abstract class for each database like this:
public abstract class NavtrakOperationsDatabase<T> : ActiveRecordBase<T>
{
}
And then each class inherits from this. I'm then initializing active record like this:
ActiveRecordStarter.Initialize(typeof(SimpleModel).Assembly, ActiveRecordSectionHandler.Instance);
Which gives me the error:
Could not find the dialect in the configuration
If I change the activation code to this:
ActiveRecordStarter.Initialize(
ActiveRecordSectionHandler.Instance,
typeof(NavtrakOperationsDatabase<>),
typeof(ErrorsDatabase<>)
);
Then I get the following error:
You have accessed an ActiveRecord class that wasn't properly initialized. There are two possible explanations: that the call to ActiveRecordStarter.Initialize() didn't include Navtrak.Business.Schemas.CommonSchemas.Models.NavtrakOperations.Application class, or that Navtrak.Business.Schemas.CommonSchemas.Models.NavtrakOperations.Application class is not decorated with the [ActiveRecord] attribute.
I obviously don't want to include every single class in the Initialize function.
Any ideas?
In my case - which was the same situation - I have added this to the InitializeAR method:
LoggerProvider.SetLoggersFactory(new NoLoggingLoggerFactory());
It ended up like this:
lock (typeof(SessionManager))
{
if (!initialized)
{
LoggerProvider.SetLoggersFactory(new NoLoggingLoggerFactory());
System.Reflection.Assembly bin = typeof(SimpleModel).Assembly;
IConfigurationSource s = (IConfigurationSource)ConfigurationManager.GetSection("activerecord");
ActiveRecordStarter.Initialize(bin, s);
}
initialized = true;
}
Drop the "hibernate." prefix from all config keys. That prefix was used in NHibernate 1.x

WCF - One OperationContract sees Web.config, another doesn't

I have a WCF service with two methods, Ping and PutAddress. Ping works fine, but PutAddress was failing to initialize NHibernate correctly. Narrowing down the issue, I realized that the relevant settings from Web.config were not being read by PutAddress.
Strangely, Ping does have access to the settings from Web.config. I removed all of the NHibernate code and boiled it down to just trying to read the settings. Ping is able to read the settings (returns non-null, values in result are correct) while PutAddress' result is null.
Again, NHibernate is now completely out of the picture. Both methods simply try to read the relevant settings from Web.config. Ping succeeds while PutAddress fails.
Any thoughts?
Interface:
[ServiceContract]
public interface IMyService
{
[OperationContract]
string Ping();
[OperationContract]
Address PutAddress(Address address);
}
Implementation:
public class MyService : IMyService
{
public string Ping()
{
NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration result =
(NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration)
System.Configuration.ConfigurationManager.GetSection("hibernate-configuration");
if (result == null)
{
System.Diagnostics.Debugger.Break(); // Does NOT break, "Pong" returned
}
return "Pong";
}
public Address PutAddress(Address address)
{
NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration result =
(NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration)
System.Configuration.ConfigurationManager.GetSection("hibernate-configuration");
if (result == null)
{
System.Diagnostics.Debugger.Break(); // Breaks, result is null
}
return address; // Return version potentially modified with DB-assigned ID
}
}
EDIT:
Here is the (sanitized) Web.config
<?xml version="1.0"?>
<configuration>
<configSections>
<!-- NHibernate Section -->
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate"/>
<!-- Log4Net Section -->
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<!-- NHibernate Configuration -->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">
NHibernate.Dialect.MySQLDialect
</property>
<property name="connection.provider">
NHibernate.Connection.DriverConnectionProvider
</property>
<property name="connection.driver_class">
NHibernate.Driver.MySqlDataDriver
</property>
<property name="connection.connection_string">
Server=localhost;Database=DB;User ID=USER;Password=PASS
</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<property name="show_sql">true</property>
<mapping assembly="MyService"/>
</session-factory>
</hibernate-configuration>
<!-- Log4Net Configuration -->
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender, log4net">
<layout type="log4net.Layout.PatternLayout, log4net">
<param name="ConversionPattern" value="%d %p %m%n"/>
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender,log4net">
<param name="File" value="log.txt"/>
<param name="AppendToFile" value="true"/>
<param name="DatePattern" value="yyyy.MM.dd"/>
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%d %p %m%n"/>
</layout>
</appender>
<root>
<priority value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
</root>
<logger name="NHibernate" additivity="false">
<level value="WARN"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="ConsoleAppender"/>
</logger>
<logger name="NHibernate.SQL" additivity="false">
<level value="ALL"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="ConsoleAppender"/>
</logger>
</log4net>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Found the problem - one call was from a Unit Test that I hand-coded, which uses MyServiceClient that was generated by Visual Studio when I added a Service Reference. The other call was from a unit test that was created by the Visual Studio (2010) Unit Test wizard, which just instantiated MyService as an object. The VS-generated unit test was running in-process as a result.
I had an odd problem myself. I could not return "DataTable" objects from a WCF operation. I wonder if there could be a problem with returning an "Address" object from a WCF operation as well.
I don't know the complete answer to your question, but I would suggest the following
In your code for PutAddress, try replacing Address PutAddress(Address address); with string PutAddress(Address address); and replace return address; with return "Pong"
By doing so, you will ascertain the flow of execution through your code. Make sure that you are actually breaking and returning null as opposed to returning a null value of address.
If the new code returns null, then you are in fact having trouble reading from the file. I suspect that it will actually return "Pong", indicating that your code is returning Address, which somehow contains null because of WCF weirdness.