Forwarding Messages to Remote Endpoint in Nservicebus - nservicebus

In my message publisher configuration I have
<MsmqTransportConfig
InputQueue="EnformMessages"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig ForwardReceivedMessagesTo="testqueue#cgy1-web01">
<MessageEndpointMappings>
<!-- publishers don't need to set this for their own message types -->
</MessageEndpointMappings>
</UnicastBusConfig>
which I was hoping would copy the messages published to EnformMessages to a queue on a remote machine. No messages ever seem to be sent to the remote machine although messages are certainly being received locally. The remote listener's config file looks like
<MsmqTransportConfig
InputQueue="worker"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="EnformMessages" Endpoint="testqueue" />
</MessageEndpointMappings>
</UnicastBusConfig>
I also tried using the distributor in the fashion described at http://www.candland.net/blog/2009/06/08/NServiceBusDistributorOverview.aspx. So my publisher configuration looked like
<MsmqTransportConfig
InputQueue="client"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
<!-- publishers don't need to set this for their own message types -->
<add Messages="EnformMessages" Endpoint="distributordatabus#cgy1-web01" />
</MessageEndpointMappings>
</UnicastBusConfig>
Subscriber configuration like
<MsmqTransportConfig
InputQueue="EnformMessages"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig
DistributorControlAddress="distributorcontrolbus#cgy1-web01"
DistributorDataAddress="distributordatabus#cgy1-web01">
<MessageEndpointMappings>
<!--<add Messages="EnformMessages" Endpoint="EnformMessages" />-->
</MessageEndpointMappings>
</UnicastBusConfig>
and distributor like
<appSettings>
<add key="NumberOfWorkerThreads" value="1"/>
<add key="DataInputQueue" value="distributorDataBus"/>
<add key="ControlInputQueue" value="distributorControlBus"/>
<add key="ErrorQueue" value="error"/>
<add key="StorageQueue" value="distributorStorage"/>
<add key="NameSpace" value="http://www.UdiDahan.com"/>
<!-- relevant for a Serialization of "interfaces" or "xml" -->
<add key="Serialization" value="xml"/>
<!-- can be either "xml", or "binary" -->
</appSettings>
<MsmqTransportConfig
InputQueue="distributorControlBus"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig >
<MessageEndpointMappings >
<add Messages="EnformMessages" Endpoint="EnformMessages" />
</MessageEndpointMappings>
</UnicastBusConfig>
No messages seem to arrive. In fact nothing is printed out by the distributor at all. I added a logging section to the config file in the hopes it would produce some output but got nothing.
Nservicebus 2.0.0.768

In a pub/sub scenario, it is the subscriber that will be forwarding messages to an audit queue, not the publisher. Also, you've told your subscriber that its publisher is "testqueue" but you specified your publisher's input queue as "EnformMessages". These two queues need to match up.

Related

App.Config MessageEndpointMappings not working in NSB 3.3.8

In version 3.2.6 of NSB I had my endpoints mapped in my app config like this:
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Foo.Bar.Baz1, Foo.Interfaces" Endpoint="Foo.Bar.Monitor" />
<add Messages="Foo.Bar.Baz2, Foo.Interfaces" Endpoint="Foo.Bar.Monitor" />
<add Messages="Foo.Bar.Baz3, Foo.Interfaces" Endpoint="Foo.Bar.Monitor" />
</MessageEndpointMappings>
</UnicastBusConfig>
This worked fine. When I upgraded to NSB 3.3.8 I saw that the API for endpointmappings had changed, and that in particular, the Messages attribute was deprecated, so I tried to port my code to one of the new methods. None of them work. Here are the three different methods I tried:
<UnicastBusConfig>
<MessageEndpointMappings>
<add Assembly="Foo.Interfaces" Endpoint="Foo.Bar.Monitor" />
</MessageEndpointMappings>
</UnicastBusConfig>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Assembly="Foo.Interfaces" Namespace="Foo.Bar" Endpoint="Foo.Bar.Monitor" />
</MessageEndpointMappings>
</UnicastBusConfig>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Assembly="Foo.Interfaces" Type="Foo.Bar.Baz1" Endpoint="Foo.Bar.Monitor" />
<add Assembly="Foo.Interfaces" Type="Foo.Bar.Baz2" Endpoint="Foo.Bar.Monitor" />
<add Assembly="Foo.Interfaces" Type="Foo.Bar.Baz3" Endpoint="Foo.Bar.Monitor" />
</MessageEndpointMappings>
</UnicastBusConfig>
Using any of these methods, when I try to send a Baz1 I get an InvalidOperationException: No destination specified for message(s): Foo.Bar.Baz1.
It's worth noting that if I intentionally put in a typo in my type name (e.g. Foo.Bar.Bazzzzz1), NSB correctly faults during startup when it can't find the specified type, indicating that something must be happening to the ones that have no typos.
I can work around this issue by directly specifying my endpoint as a parameter to Send, but NSB recommends not doing that.
So my question is: Am I still doing something wrong in my configuration, or is this truly a bug in NSB 3.3.8?

How to use EmbeddedResourceVirtualPathPovider with IIS6

While developing a ASP.NET MVC4 web application with VS2010, using the Mvc.JQuery.Datatables Nuget,
I found that the EmbeddedResourceVirtualPathProvider NuGet that is referenced, worked beautifully
on my dev box, but failed miserably on my production box.
The production box is Windows 2003, with IIS6 and .NET 4.0 installed.
I searched many things on SO, and Googling, but after implementing the suggested workarounds,
it still fails:
Here's what I've done.
Implement AppInitialize as suggested by https://stackoverflow.com/a/5178993
Implemented Wildcard mapping for ASP.NET as suggested by http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx
Implemented IgnoreRoute for static files as suggested by https://stackoverflow.com/a/3144841
but it still doesn't serve all of the files. I'm getting the embedded partial views, but not
the embedded css, js, and jpg files.
My web.config has an entry for the StaticFileHandler as follows:
<system.webServer>
<handlers>
<add path="*.css" verb="GET" name="Static css" type="System.Web.StaticFileHandler" />
<add path="*.js" verb="GET" name="Static js" type="System.Web.StaticFileHandler" />
<add path="*.jpg" verb="GET" name="Static jpg" type="System.Web.StaticFileHandler" />
<add path="*.gif" verb="GET" name="Static gif" type="System.Web.StaticFileHandler" />
</handlers>
</system.WebServer>
I appear to be missing something critical. Any Suggestions?
When using IIS6, all of the items listed in #1-3 are required, but additionally, you need to
recognize that IIS6 defines its handlers as httpHandlers in the system.web section,
whereas IIS7 calls them handlers and they are in the system.webServer section of the config file.
Therefore, you need to add the following to make it work in IIS6
<system.web>
....
<httpHandlers>
<add path="*.css" verb="GET" type="System.Web.StaticFileHandler" />
<add path="*.js" verb="GET" type="System.Web.StaticFileHandler" />
<add path="*.jpg" verb="GET" type="System.Web.StaticFileHandler" />
<add path="*.gif" verb="GET" type="System.Web.StaticFileHandler" />
</httpHandlers>
</system.web>

Elmah.MVC 2.0.1 - securing the elmah logs

Setup:
For an ASP.NET MVC 4 app I am using Elmah.MVC 2.0.1 to log errors.
I installed Elmah.MVC using NuGet. It works fine.
Problem:
The Elmah.MVC package installs no controller or area, so I can see no obvious way to apply security via Authorize attributes, as is recommended for ASP.NET MVC.
Question:
I only want users in the Admin role to be able to view the Elmah page.
How do I do this?
Ouch!
Just found the answer;
Elmah MVC 2.0.1 NuGet package adds the following into <appSettings> (in web.config):
<add key="elmah.mvc.requiresAuthentication" value="false" />
<add key="elmah.mvc.allowedRoles" value="*" />
To achieve what I want simply:
<add key="elmah.mvc.requiresAuthentication" value="true" />
<add key="elmah.mvc.allowedRoles" value="Admin" />
I believe you can also use URL access control like this:
<location path="elmah.axd">
<system.web>
<httpHandlers>
<add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>
<authorization>
<allow roles="YourRole" />
<deny users="*" />
</authorization>
</system.web>
<system.webServer>
<handlers>
<add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>
</location>

HTTPHandler and svc

I've got an existing web application, that is installed on several machines. script clients and .net clients consume ".asmx" services through one machine, that routes all calls to other machines.
Client ----> |Website \ Virtual directory(HttpHandler)| ----> |Other server \ real .asmx|
I added a new .svc service that does the same functionality, and added a handler for it (directory's config):
<system.webServer>
<handlers>
<add name="MY_ASMX" verb="*" path="*.asmx" type="MY.AO.HttpProxy, Astea.AO.HttpProxy" resourceType="Unspecified" preCondition="integratedMode" />
<add name="MY_ASPX" verb="*" path="*.aspx" type="MY.AO.HttpProxy, Astea.AO.HttpProxy" resourceType="Unspecified" preCondition="integratedMode" />
<add name="MY_WSDL" verb="*" path="*.wsdl" type="MY.AO.HttpProxy, Astea.AO.HttpProxy" resourceType="Unspecified" preCondition="integratedMode" />
<add name="MY_SVC" verb="*" path="*.svc" type="MY.AO.HttpProxy, Astea.AO.HttpProxy" resourceType="Unspecified" preCondition="integratedMode" />
while asmx request are routed fine, my new .svc on the end server does not get called, and even the Httphandler is skipped. if i call the .svc directly on the other machine it works.
the error i get is:
WebHost failed to process a request.
Sender Information: System.ServiceModel.Activation.HostedHttpRequestAsyncResult/26458746
Exception: System.Web.HttpException (0x80004005): The service '/Mysite/MyDirectory/settings.svc' does not exist. ---> System.ServiceModel.EndpointNotFoundException: The service '/Mysite/MyDirectory/settings.svc' does not exist.
I already tried the folowing
add "buildProviders" to compilation section that removes .svc
Click on MimeTypes and enter “.svc” and “application/octet-stream” and save
add a handler :
nothing helps, http handler is not being called
p.s. Im working with AppPool .net 4.0 Integrated
.svc extensions are considered by default to be WCF services, and handlers/modules are already present for them. You can remove the existing handlers/modules by putting a element before your <add> element:
<remove name="svc-ISAPI-4.0_32bit" />
(or, if on win64:)
<remove name="svc-ISAPI-4.0_64bit" />
And, in the <modules> element:
<remove name="ServiceModel-4.0" />
I've found it. Adding:
<compilation debug="true" >
<buildProviders>
<remove extension=".svc"/>
</buildProviders>
</compilation>
caused an error, that got me to back off, at the first time:
"~/ServiceManagement.svc" demanded that the buildProvider for ".svc" will be on
"~/ServiceManagement.svc" is automatiacally created in the machine root config when you install MS AppFabric. Since I'm using that folder only for redirection, I don't need Appfabric there, so I removed it:
<system.serviceModel>
<serviceHostingEnvironment>
<serviceActivations>
<remove relativeAddress="~/ServiceManagement.svc"/>
</serviceActivations>
</serviceHostingEnvironment>

NServiceBus: Trouble getting PubSub working with Distributor

I'm using NServiceBus 2.5 and trying to get a simplified version of the NServiceBus PubSub sample working with the distributor. The simplification:
1 Publisher
Distributor
1 Subscriber
All of this is on a single machine.
I would like to get this working before I move on to more complex things like multiple subscribers behind a single distributor, multiple machines, etc.
First I got the simplified pub sub example working without the distributor (i.e 1 pub and 1 sub - and I got that working fine).
As I understand it, the way it should work is:
The distributor defines its own control and data queues.
The publisher has it's control queue, but no other config refers to this queue. The publisher refers to the distributes data queue.
The subscriber refers to the distributors data and control queues.
I've not been able to get the simplified pub-sub distributor working with this config. I've done some debugging of the publisher and what I've found is that the publisher's Bus.Publish doesn't find any subscribers to publish to.
Any ideas what I'm doing wrong and what I need to do to get this working?
Here's configs for each of those:
Publisher:
<?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" />
</configSections>
<MsmqTransportConfig InputQueue="MyPublisherInputQueue" ErrorQueue="error" NumberOfWorkerThreads="1" MaxRetries="5" />
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="MyMessages" Endpoint="distributorDataBus" />
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>
Distributor
<add key="DataInputQueue" value="distributorDataBus"/>
<add key="ControlInputQueue" value="distributorControlBus"/>
<add key="ErrorQueue" value="error"/>
<add key="StorageQueue" value="distributorStorage"/>
<add key="NameSpace" value="http://www.UdiDahan.com"/>
<!-- relevant for a Serialization of "interfaces" or "xml" -->
<add key="Serialization" value="xml"/>
<!-- can be either "xml", or "binary" -->
</appSettings>
</configuration>
Subscriber
<?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" />
</configSections>
<MsmqTransportConfig
InputQueue="Subscriber1InputQueue_1"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig DistributorControlAddress="distributorControlBus" DistributorDataAddress="distributorDataBus">
<MessageEndpointMappings />
</UnicastBusConfig>
</configuration>
Ok, I finally got this working. The key clue came from here: http://tech.groups.yahoo.com/group/nservicebus/message/8525
Basically, the subscriber needs to be pointed to the publisher by adding this section:
<UnicastBusConfig DistributorControlAddress="distributorControlBus" DistributorDataAddress="distributorDataBus">
<MessageEndpointMappings>
<add Messages="MyMessages" Endpoint="MyPublisherInputQueue" />
</MessageEndpointMappings>
</UnicastBusConfig>
I initially thought that this is making the subscriber register directly with the publisher, but no. I tested that out with two different subscribers pointed to the same distributor and noted that only one of the subscribers gets any single event published.