How to connect to ActiveMQ on startup with WCF and IIS - wcf

What is the best way to combine a single instance WCF service that uses ActiveMQ and runs within IIS/AppFabric?
Our Services need to support both HTTP transports and ActiveMQ (listening and sending messages). We've elected not to use MSMQ, and will use Spring.Net.NMS. The fundamental issue I have now is that ActiveMQ needs to connect to the queue(s) at startup and remain connected, but WAS is getting in the way with it's message-activation feature. If the service is not activated until a message arrives (HTTP/MSMQ, etc) then there is no trigger to have the connection to AMQ occur.
I know I can disable the recycling behavior, and I know I can do self-hosting with a Windows Service. But I want to take advantage of the monitoring and other features in AppFabric. I've already been down the route with IServiceBehavior and will use that for other nice things. But that interface is not called until a (non-AMQ) message arrives. So it won't work for this. What I was hoping for was something along the line of how ServletContextListeners work in Java, where you get both the start up and shutdown events. But it seems no such thing exists in WAS... it is driven only by messages arriving.
I've scoured every inch of web info for 3 days and the only thing I came across was to use a static class construction (C#) trick as the trigger. That's a hack, but i can live with it. It still leaves the issue of cleanly shutting down, which I can figure out later.
Anyone have a solid solution to this?

The direct WCF support for ActiveMQ that Ladislav mentions is still being supported. There just hasn't been an official release for the module in a while. However, you can still get the latest version of it from the 1.5.x branch or trunk and compile it yourself.
1.5.x branch for use with Apache.NMS 1.5.0:
https://svn.apache.org/repos/asf/activemq/activemq-dotnet/Apache.NMS.WCF/branches/1.5.x/
Check out instructions:
http://activemq.apache.org/nms/source.html

There was direct WCF support for ActiveMQ but I guess it is not developed anymore. Your problem actually is the IIS / WAS (provides hosting for non-http protocols) hosting architecture. Services in WAS are always activated when message arrives - there is no global startup. The reason for this is that WAS hosting expects that there is separate process (windows service) running the listener all the time and this process has adapter which calls WAS and uses message level activation. I guess you don't have such process for ActiveMQ and because of that you will have trouble to use ActiveMQ endpoint hosted in WAS. Developing such listener can be challenging task (example for UDP).
Creating custom listener can be probably avoided by using IIS 7.5 / AppFabric auto start feature. There is also not very well documented way to run the code when the application starts.

Related

Masstransit: Can it use central msmq server? (Or should I start w/RabbitMQ from the start?)

I set up the Masstransit sample apps, and all was great. Local operation, msmq, looks good.
Now I am starting to put masstransit in my real app. In my real app, I have jobs coming from four servers, and processing happening on two worker systems.
It seems that masstransit always wants to push to:
msmq://localhost/...
But I thought I would set up a single, central, msmq server: msmq:///...
It appears (I may be missing something! Please correct me if I am off!) that when using msmq, that I need to set up msmq on multiple machines, and configure msmq to route from machine to machine.
Am I missing something?
Should I skip msmq and jump to rabbitmq right off, (which appears to solve for this)?
Is there some fundamental msmq knowledge (that is perhaps not in the masstransit docs) ?
thank you!
First off I always suggest people use RabbitMQ over MSMQ unless you MUST use DTC for some reason. And even then, I'd suggest you rethink using DTC.
But given you have some constraint you can't fight. You're welcomed to use a central MSMQ server but it doesn't provide a ton of value. Each server sending messages must have MSMQ installed locally because of how it works. Messages actually end up in an outgoing queue before they are sent over the other machine in question. If you have multi-machine MSMQ setups, in the past for me it's been like:
Core Machine runs MassTransit.RuntimeServices at /mt_subscriptions, and maybe one service at /service_1
Other processing machine runs a specific heavy load service at /service_2 and it's configuration references msmq://coremachine/mt_subscriptions for the subscription service.
Yet another processing machine with similar setup
So with those 3 machines, the only thing you don't have msmq://localhost/ is the reference to the subscription service in configuration.

Can't read from remote transactional private queue using WCF in workgroup mode (can do using System.Messaging !)

I have spent days reading MSDN, forums and article about this, and cannot find a solution to my problem.
As a PoC, I need to consume a queue from more than one machine since I need fault tolerance on the consumers side. Performance is not an issue since less than 100 messages a day should by exchanged.
I have coded two trivial console application , one as client, the other one as server. Using Framework 4.0 (tested also on 3.5). Messages are using transactions.
Everything runs fines on a single machine (Windows 7), even when running multiple consumers application instance.
Now I have a 2012 and a 2008 R2 virtual test servers running in the same domain (but don't want to use AD integration anyway). I am using IP address or "." in endpoint address attribute to prevent from DNS / AD resolution side effects.
Everything works fine IF the the queue is hosted by the consumer and the producer is submitting messages on the remote private queue. This is also true if I exchange the consumer / producer role of the 2012 and 2008 server.
But I have NEVER been able to make this run, using WCF, when the consumer is reading from remote queue and the producer is submitting messages localy. Submition never fails, my problem is on the consumer side.
My wish is to make this run using netMsmqBinding, but I also tried using msmqIntegrationBinding. For each test, I adapted code and configuration, then confirmed this was running ok when the consumer was consuming from the local queue.
The last test I have done is using WCF (msmqIntegrationBinding) only on the producer (local queue) and System.Messaging.MessageQueue on the consumer (remote queue) : It works fine ! => My goal is to make the same using WCF and netMsmqBinding on both sides.
In my point of view, I have proved this problem is a WCF issue, not an MSMQ one. This has nothing to do with security, authentication, firewall, transport, protocol, MSMQ version etc.
Errors info using MS Service Trace Viewer :
Using msmqIntegrationBinding when receiving the message (openning queue was ok) : An error occurred while receiving a message from the queue: The transaction specified cannot be imported. (-1072824242, 0xc00e004e). Ensure that MSMQ is installed and running. Make sure the queue is available to receive from.
Using netMsmqBinding, on opening the queue : An error occurred when converting the '172.22.1.9\private$\Test' queue path name to the format name: The queue path name specified is invalid. (-1072824300, 0xc00e0014). All operations on the queued channel failed. Ensure that the queue address is valid. MSMQ must be installed with Active Directory integration enabled and access to it is available.
If someone can help to find why my configuration cannot be handled by WCF, a much elegant and configurable way than Messaging, I would greatly appreciate !
Thank you.
You may need to post you consumer code and config to give more of an idea but it could be the construction of the queue name - e.g.
FormatName:DIRECT=TCP:192.168.0.2\SomeQueue
There are several different ways to connect to a queue and it changes when you are remote or local as well.
I have found this article in the past to help:
http://blogs.msdn.com/b/johnbreakwell/archive/2009/02/26/difference-between-path-name-and-format-name-when-accessing-msmq-queues.aspx
Also, MessageQueue Constructor on MSDN...
http://msdn.microsoft.com/en-us/library/ch1d814t.aspx

AMQP AmqpBinding IIS/WAS problems?

The setup at the current employer has one set of back office functions on a Java platform and another group of functions on two separate .NET-based platforms. There is no overall architect.
The Java guys decided to go for Apache QPID and AMQP for messaging, presumably amongst themselves, with the .NET systems and other external systems.
.NET architecture involves WCF services hosted in IIS/WAS and Windows Server AppFabric.
Does anyone have any experience of AmqpBinding and IIS/WAS, if there are any possible pitfalls?
I think your first problem will be IIS/WAS/AppFabric because non HTTP services hosted in WAS have additional requirements for infrastructure which consists of additional process (listener) running usually as as a windows service and communicating with worker process. This process is responsible for receiving and sending messages and allows service activation in WAS. I don't think that the QPID project has the listener process already created. You will most probably have to implement the listener yourselves - check this sample for custom UDP activator.

Ensuring (restart of) MSMQ WCF service hosted on IIS7.5 WAS

We have been tumbling, for more than a month now, with an issue where a wcf msmq service hosted in IIS7.5 (WAS) will stop processing messages from the queue.
We have been unable to narrow it down more than "at some point" it will stop processing messages from the queue. Calling the svc through a http browser call will start the processing again.
After reading really many articles, blogs and forum posts about this issue we have ensured the following: Security settings, protocol bindings and msmq/service naming, but alas: the service will still stop processing messages (at some point).
Encouraged by this article http://www.daczkowski.net/2010/11/19/leveraging-msmq-in-asp-net-application-through-wcf-service/ we seem to have now finally (almost) eliminated the problem for windows server 2008 r2 sp1 64 bit, but it still seems to appear on Windows 7 32 bit.
Now to get to my question: Can anyone tell me if there actually exists a guarentee (documentation on this would be appreciated) that a msmq WAS hosted wcf service will actually restart (under all conditions) on a IIS7.5 NOT running the AppFabric extension?
I am aware that this question is very compounded, but I'm hard pressed for documentation on why we should extend our OTS package with AppFabric to resolve this restart problem.
Best regards,
Are you're net.msmq endpoints actually using addresses that IIS can bind to a queue name? It's possible to use non-IIS compatible names in the config and WAS won't really ever be able to wake your application up because WAS will only ever register to queues following a path name it can resolve. In that case you need something like AppFabric or a "startup" script to actually activate your services so that they will bind to the queues in their own.

Hosting an NServiceBus subscriber in the same application as the producer

Is it possible to use NServiceBus to publish and consume messages in the same application, specifically a web application?
In the future we will almost certainly need to maintain a separate long running service to process messages generated by this application, and this is why we are hoping to use NServiceBus from the start, but right now it would be nice to just start up the consumer and the publisher when the web application starts. This will make testing and deployment far easier for us.
I presume I will need to reference the NServiceBus.Host.exe and start up the process in the global.asax, but need help on what exactly I need to call to do this.
This is not a mode of deployment that is supported out of the box. While you could make this work by manually creating an additional appdomain for the second NServiceBus endpoint, you'd also likely need to give it a custom configuration source, and of course its own queue.
All in all, I'd recommend keeping it as a separate process, even if it is on the same box. That being said, you can create a second web app to host it rather than using the generic host if you don't want to manage windows services in addition to web apps.
Hope that helps.