NServiceBus 5/6 Vanilla Server Crashes when changes transport to RabbitMQ - crash

We are in the process of upgrading out 5 year old servicebus project to the latest version 5 NSB / version 6 NSB Host. If comment out the MSMQ transport and then uncomment the rabbitmq, the project will contact rabbitmq and create the queues. 5 seconds later it crashes with no stack trace.
Either the ball was dropped in QA or I am missing something rather subtle.
The nuget for
NserviceBus.Transports.RabbitMQ is 2.0
RabbitMQ.Client is 3.3.5.0
NServiceBus.Host is 6.0
NServiceBus.Core is 5.0
NServiceBus.NLog is 1.0
A section of the app.config
<connectionStrings>
<!-- MSMQ Transport config -->
<!-- <add name="NServiceBus/Transport" connectionString="deadLetter=true;journal=true;useTransactionalQueues=true;cacheSendConnection=true" /> -->
<!-- RabbitMQ Transport config -->
<add name="NServiceBus/Transport" connectionString="host=localhost;username=nsb;password=test;" />
</connectionStrings>
Here is the endpoint config. it is very simple.
namespace CarWash.Server
{
[EndpointName("V4_CarWash.local")]
public class MessageEndpoint : ServiceBusHibernateBase, IConfigureThisEndpoint
{
public void Customize(BusConfiguration configuration)
{
configuration.UsePersistence<InMemoryPersistence>();
configuration.UseTransport<RabbitMQTransport>();
//configuration.UseTransport<MsmqTransport>();
configuration.EnableSLAPerformanceCounter(TimeSpan.FromSeconds(10));
}
/* <add Messages="DiagnosticMessage" Endpoint="diagnostics.data#mdl-nsb-d"/> */
public IBus Bus { get; set; }
}
}

Related

Can not Host & Start WCF Service with netNamedPipeBinding in Windows Service on Windows 7

I'm using two applications built using C# on 4.5 .Net Framework
WPF Desktop Application
Windows Service
and want them talk to each other using IPC(Inter Process Communication) approach as they need to frequently share some data/object state based on condition.
WCF with netNamedPipeBinding seems a very flexible solution. I've created a WCF Server and Client & tested successfully hosting in Console Application.
Since this solution worked, I wanted WCF Server to be hosted in Windows Service(which is my eventual requirement).
I could host the application successfully(guess because I don't see any visible error) but I cannot connect any client to it. I've used WcfTestClient.exe tool(Visual Studio default tool) as well as tried connecting from a console application, none of them seem working, as I keep on getting the error - Cannot obtain Metadata from net.pipe://localhost/TestWCFService/mex . Details added below.
I've registered the windows service with Admin privilege and running the console app test client & WcfTestClient.exe with the same user.
Naturally, I'm missing something, appreciate your help on fixing it.
Here is the code, I'm using in Windows Service to Host WCF netNamedPipeBinding Service:
protected override void OnStart(string[] args)
{
try
{
if (wcfServiceHostObj != null)
wcfServiceHostObj.Close();
wcfServiceHostObj = new ServiceHost(typeof(TestWCFService));
wcfServiceHostObj.Open();
EventLog.WriteEntry(ServiceName, "WCF Host - Started Successfully ", EventLogEntryType.Information);
}
catch (Exception ex)
{
EventLog.WriteEntry(ServiceName, "exception raised " + ex.InnerException, EventLogEntryType.Error);
throw;
}
}
Error: Cannot obtain Metadata from net.pipe://localhost/TestWCFService/mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: net.pipe://localhost/TestWCFService/mex Metadata contains a reference that cannot be resolved: 'net.pipe://localhost/TestWCFService/mex'. There was no endpoint listening at net.pipe://localhost/TestWCFService/mex that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. The pipe endpoint 'net.pipe://localhost/TestWCFService/mex' could not be found on your local machine.
Here my WCF Server Config Setting:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="TestWCFServiceNetPipeBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="TestWCFServiceNetPipeBehavior"
name="WCFHostTest.WCFService.TestWCFService">
<endpoint address="net.pipe://localhost/TestWCFService" binding="netNamedPipeBinding" bindingConfiguration=""
name="TestWCFServiceNetPipeEndPoint" contract="WCFHostTest.WCFService.ITestWCFService" >
</endpoint>
<endpoint address="net.pipe://localhost/TestWCFService/mex" binding="mexNamedPipeBinding" bindingConfiguration=""
name="TestWCFServiceMexPipeEndpoint" contract="IMetadataExchange" />
<host>
<!--<baseAddresses>
<add baseAddress="net.pipe://localhost/TestWCFService" />
</baseAddresses>-->
</host>
</service>
</services>
</system.serviceModel>
For Client(which is in Console Application), I'm using inline.
Here the code
private static void testClient()
{
try
{
string address = "net.pipe://localhost/TestWCFService";
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
EndpointAddress ep = new EndpointAddress(address);
ITestWCFService channel = ChannelFactory<ITestWCFService>.CreateChannel(binding, ep);
using (channel as IDisposable)
{
channel.SendMessage("First Message");
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.Write(ex.InnerException);
Console.ReadLine();
}
The most likely reason you can't connect is because there is no service address passed into the ServiceHost constructor.
Try this in your OnStart method in your Windows service:
wcfServiceHostObj = new ServiceHost(typeof(TestWCFService),
new Uri[] { "net.pipe://localhost/TestWCFService" });
Seeing the "WCF Host - Started Successfully" only means ServiceHost didn't throw an error; it doesn't guarantee that the WCF service is listening and ready to receive messages.
Also, using the using statement with WCF clients like this:
using (channel as IDisposable)
{
channel.SendMessage("First Message");
}
is considered bad practice.

WCF Exception : ServiceHost only supports class service types -- when run from windows service

i am new in wcf. i am facing this error ServiceHost only supports class service types.
here i will say i am doing & running my win service & wcf together.
i added windows service project and also add few reference like System.ServiceModel for wcf in win service project. when i am trying to run wcf service from win service then i am getting error called ServiceHost only supports class service types
i search & got many answer like
ServiceHost host = new ServiceHost(
typeof(subservice.ISubService), new Uri("someuri"));
If this is your usage, change it to use the implemented service class type of ISubService
ServiceHost host = new ServiceHost(
typeof(subservice.SubService), new Uri("someuri"));
If configuring the service in .svc then:
<%#ServiceHost Service="subservice.SubService"%>
Also in you config file, change service name to the service instead of the service contract as:
<services>
<service name="subservice.SubService">
...
other search result also said very similar things to get rid of this problem.
i have no svc file for my wcf service. i have just one file where i have contract and service classes. i also have config file.
here i am giving the brief of my service code
namespace SageDataImportWCF
{
[ServiceContract]
public interface ISagePart
{
[OperationContract]
string SageInsertionProcess(string SQLConnectionString, string CountryCode);
// TODO: Add your service operations here
}
public class SagePartInsertion : ISagePart
{
public string SageInsertionProcess(string SQLConnectionString, string CountryCode)
{
}
}
}
here i am giving the code by which i am trying to run from win service
namespace SageDataImportWCF
{
public partial class SageDateInsertionService : ServiceBase
{
#region Local Variables
ServiceHost serviceHost;
#endregion
#region Constructor
public SageDateInsertionService()
{
InitializeComponent();
serviceHost = null;
ServiceName = "Sage DataInsertion Service";
}
#endregion
protected override void OnStart(string[] args)
{
string strAdrHTTP = "http://192.168.6.2:11000/SagePartInsertion";
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(SageDataImportWCF.SagePartInsertion));
serviceHost.AddServiceEndpoint(typeof(SageDataImportWCF.ISagePart), new BasicHttpBinding(), strAdrHTTP);
ServiceMetadataBehavior behaviour = new ServiceMetadataBehavior();
behaviour.HttpGetEnabled = true;
serviceHost.Description.Behaviors.Add(behaviour);
serviceHost.Open();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
}
here is my config entry for wcf service
<configuration>
<system.serviceModel>
<services>
<service name="SageDataImportWCF.SagePartInsertion" behaviorConfiguration="SageBehavior">
<endpoint address="http://localhost:9001/SagePartInsertion" contract="SageDataImportWCF.ISagePart" binding="basicHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SageBehavior">
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
here i have pasted all the relevant code and i like to request some one please have a look at my code and tell me why i am getting the error message like ServiceHost only supports class service types when try to run it from windows service. did i miss anything in code ?
should i have a separate project for wcf class library and another separate project for windows service because i have one project there i have files for wcf & windows service both.
so looking for suggestion like what i need to rectify in code as a result win service can start the wcf service. please help.
Check the definition of the service in the Markup:
Right click on the SagePartInsertion.svc file and select "View Markup".
Make sure the service is the implementation of the interface, like this:
<%# ServiceHost Language="C#" Debug="true" Service="SageDataImportWCF.SagePartInsertion" CodeBehind="SagePartInsertion.svc.cs" %>
In the past it failed because I was referencing the interface.

NserviceBus Hosted in IIS issue

I've been working on a project where I need Nservicebus to be hosted in IIS.
I need the MVC3 webapplication to send a message, a nservicebus host should handle this message
and then send back some sort of message to the webapplication.
the Async Pages example http://docs.particular.net/samples/web/asp-mvc-application/
shows one way of doing it. I can get this to work, however this does not fully furfill my requirements. I need an object to be returned from the handler, not just an int.
To get this to work i've tried setting up a host under IIS, in my Global.asax I've got this code:
Bus = Configure.WithWeb()
.DefineEndpointName("CQRS")
.Log4Net()
.DefaultBuilder()
.DisableTimeoutManager()
.XmlSerializer()
.MsmqTransport()
.IsTransactional(true)
.PurgeOnStartup(false)
.InMemorySubscriptionStorage()
.UnicastBus()
.AllowSubscribeToSelf()
.ImpersonateSender(false)
.LoadMessageHandlers()
.CreateBus().Start();
my web.config:
<MessageForwardingInCaseOfFaultConfig ErrorQueue="CQRS.error" />
<MsmqTransportConfig NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig DistributorControlAddress="" DistributorDataAddress="" TimeoutManagerAddress="CQRS.timeouts">
<MessageEndpointMappings>
<add Messages="Nokavision.InvoiceProcessing.CQRS.Messages" Endpoint="CQRS" />
<add Messages="NServiceBus.Scheduling.Messages.ScheduledTask" Endpoint="CQRS" />
</MessageEndpointMappings>
</UnicastBusConfig>
Sending messages with the Bus object works perfectly, a message appears in the "cqrs" queue.
The handler within the webapplication however does not trigger. This is the code:
public class UpdateInkoopFactuurAlgemeenHandler : IHandleMessages<UpdateInkoopFactuurAlgemeenCommand>
{
public IBus Bus { get; set; }
public void Handle(UpdateInkoopFactuurAlgemeenCommand message)
{
P2PEntities entities = new P2PEntities();
var factuur = (from f in entities.Documenten.OfType<InkoopFactuur>()
where f.DocumentId == message.DTO.DocumentId
select f).FirstOrDefault();
if (factuur != null)
{
factuur.FactuurNummer = message.DTO.FactuurNummer;
entities.SaveChanges();
}
//Bus.Return(new UpdateInkoopFactuurAlgemeenResponse(message.DTO.ClientConnectionId));
}
}
I'm sure I'm missing something small here but what am I doing wrong, why doesn't the handler get triggered while I can clearly see a message in the queue.
Also on the Bus object I can see the handler being loaded.
If you configure installer correctly in your fluent configuration then NSB sets the rights on the queue properly.
http://andreasohlund.net/2012/01/26/installers-in-nservicebus-3-0/
Ok, I think I figured it out, it seems that the queue's created by NSB dont have full access permissions for the IIS USER. I've set "full control" for everyone on each of the queue's and restarted IIS. Somehow it seems to work now

WCF slow ServiceHost.Open() call

This is a similar question as this one:
Win32Exception # ServiceHost.Open() for WCF service.
I have a machine that is very slow on the ServiceHost.Open call below. It consistently takes 7 seconds or so to open the service, every time. This machine is my home box, and it is not part of a domain.
I can run the same code on another box (my work box) which is part of a domain and the service host opens in about 3-4 seconds on the first call, but if I run the program again the service host opens in about 1 second or less.
I have worked with MS support on this, and we generated trace logs and the part it's hanging in is where is goes out and tries to connect to a domain, even on the machine that isn't part of a domain. And it gets the "The specified domain either does not exist or could not be contacted." exception in the trace log, and that's where all the time is getting eaten up.
But what's really weird is that even on my work machine, if I'm not connected to a domain (like if I'm not on my work network and just running from home) I still don't get the delay.
I rebuilt my machine using Windows 7 64-bit, and the same behavior occurs (was running XP SP3, which I restored when Windows 7 didn't seem to fix the problem).
I just wondered if anyone had any ideas of what could cause this. By the way, if I disable "Client for microsoft networks", the time is like 4 seconds to open the ServiceHost, but that's still not as fast as this machine used to be able to open the service. Somehow, it thinks it's supposed to be part of a domain or something.
static void RunServiceWithinEXE()
{
Uri baseAddress = new Uri("http://localhost:11111/Demo");
ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Add a service endpoint
serviceHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
serviceHost.Description.Behaviors.Add(smb);
serviceHost.Opening += new EventHandler(serviceHost_Opening);
serviceHost.Opened += new EventHandler(serviceHost_Opened);
serviceHost.Open();
Console.WriteLine("The service is ready.");
// Close the ServiceHostBase to shutdown the service.
serviceHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occured: {0}", ce.Message);
serviceHost.Abort();
}
}
static void serviceHost_Opened(object sender, EventArgs e)
{
TimeSpan timeToOpen = DateTime.Now - shOpening;
Console.WriteLine("Time To Open: :" + timeToOpen.Seconds);
}
static void serviceHost_Opening(object sender, EventArgs e)
{
shOpening = DateTime.Now;
}
Here is my app.config, but I don't have any special security configuration settings for the service in there, only some diagnostic settings to enable the WCF trace.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<diagnostics>
<messageLogging maxMessagesToLog="30000"
logEntireMessage="true"
logMessagesAtServiceLevel="false"
logMalformedMessages="true"
logMessagesAtTransportLevel="true">
<filters>
<clear/>
</filters>
</messageLogging>
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning, ActivityTracing" propagateActivity="true" >
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\Server.svclog" />
</sharedListeners>
<trace autoflush="true" indentsize="4">
<listeners>
<remove name="Default" />
<add name="ScottsConsoleListener" type="System.Diagnostics.ConsoleTraceListener" />
<add name="ScottsTextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Temp\DebugLog.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Note also that my service definition has SessionMode required (see below). If I take the SessionMode requirement out, I don't get the delays.
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required)]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
[OperationContract]
string PrintName(string firstName, string lastName);
[OperationContract]
Point MakePoint(double x, double y);
}
}
Okay, my suspicion is the fact you're using a binding (WsHttpBinding) which defaults to authenticating its callers using Windows credentials unless you specifically tell it not to.
In your service hosting code, you're just instantiating a default WsHttpBinding instance - no settings in config or code to change the default security behavior, in that case.
Just for testing purposes: try to change your service hosting code to:
// Add a service endpoint
serviceHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(SecurityMode.None), // pass in SecurityMode.None
"CalculatorService");
This will effectively cancel out all security settings, e.g. the ServiceHost should no longer even attempt to find the Windows domain to authenticate callers against.
Does that change any of your observations?
It turns out that if I disable netbios on my network connections, I don't get the delays on the ServiceHost.Open calls. I am not sure why, but this seemed to fix the problem.
What's weird is that when I did a clean install of XP, I didn't have the delays even with the Netbios enabled, so I have no idea why it happens with my existing installation (I did the clean install on this same machine, and then restored my backup from an image to run these tests).
Also try stopping the Remote Access Auto Connection Manager service. For me, the issue came down to Dns.GetHostEntry(String.Empty) and this post http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/493d1b65-9ace-41de-b269-f178d27a8a1b
It seems I had the same Problem. Long Duration of Open call caused by an exception. I googled for configuration of security Settings for Wcf Service. Found the following solution which worked for me:
Under <wsHttpBinding> element in the Web.config file place the following entry:
<security mode="None" />
The Service Reference in the Client must be updated!

BadImageFormatException IIS hosted WCF service Win7 x86, VS2010b2

My system is Windows 7 Ultimate 32 bit. Running Visual Studio 2010 beta 2 targeting .Net 4.
I have a project containing service contracts.
A project containing the services.
And an ASP.NET Web Application that is hosting the services in IIS.
I've written my own Clients using the ChannelFactory().CreateChannel()...
Whenever I run my application that uses the ServiceClient and calls a method on the service, I get this error:
An attempt was made to load a program with an incorrect format.
(Exception from HRESULT: 0x8007000B)
I've tried to add a service reference in VS, so that the service client is auto-generated and that doesn't change anything.
Then I tried to create a new WCF Service Application from the Web category in VS2010, adding a service reference and calling the standard GetData method That works fine, so it is for sure my service or the hosting of the service that goes wrong...
UPDATE
I noticed that this error was only present when using wsHttpBindings. basicHttpBindings works fine.
This is how I instantiate the service:
private IAdminService _AdminService;
public AdminServiceClient()
{
_AdminService = new ChannelFactory<IAdminService>(String.Empty)
.CreateChannel();
}
Client config settings:
<system.serviceModel>
<client>
<endpoint address="http://AdminServices/svcs/AdminService.svc"
binding="wsHttpBinding"
contract="MyApp.Admin.Model.ServiceContracts.IAdminService" />
</client>
</system.serviceModel>
My service looks like this:
public class AdminService : IAdminService
{
public User GetUserByEmail(string email)
{
throw new NotImplementedException();
}
public void CreateUser(string fullname, string email,
string encryptedPassword,
string encryptedPasswordQuestion,
string encryptedPasswordAnswer)
{
throw new NotImplementedException();
}
public IEnumerable<Application> GetApplications()
{
IEnumerable<Application> apps = new List<Application>();
// Call data access layer method to retrieve Applications
return apps;
}
public IEnumerable<ApplicationInstance> GetApplicationInstances(
long? applicationId)
{
throw new NotImplementedException();
}
public Dictionary<string, string> GetApplicationsAndInstances()
{
Dictionary<string, string> appsAndInstances =
new Dictionary<string, string>();
appsAndInstances.Add("Dummy 1", "1");
appsAndInstances.Add("Dummy 2", "2");
return appsAndInstances;
}
}
My AdminService.svc file looks like this:
<%# ServiceHost Service="MyApp.Admin.Services.AdminService" %>
My Service Host config looks like this:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true"
targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="MyApp.Admin.Services.AdminService">
<endpoint address=""
binding="wsHttpBinding"
contract="MyApp.Admin.Model.ServiceContracts.IAdminService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I've also tried to create a new Console App, and add a service reference to http://AdminServices/svcs/AdminService.svc - that doesn't work either.
I've added AdminServices to my hosts file, and I can browse http://AdminServices/svcs/AdminService.svc and see the service information...
The most obvious cause would be that you are loading a 64 bits DLL into a 32 bits process or visa versa. However given that you are running everything on a a 32 bits development box I assume this isn't the case.
The other option is a .NET bug using a generic constraint like this:
public class SpecificClass: BaseClass: where T : class { }
If you remove the where T : class it should work just fine.