MSMQ Trigger to Call a Windows Service - windows-services

When ever there is a message in the queue, I need my windows service to process the message in the queue.
I was thinking that it would probably be best to set up a windows service and when ever there is a message in the queue, that MSMQ should trigger, firing a call to the windows service.
Does anyone know how to do this?

If you wanted to, you can host a WCF ServiceHost in the Windows Service, which will automatically pick up the messages as they are received. No hook-ups to MSMQ are required. WCF will automatically pull the messages into the service when they appear.
Lets say you are already writing to the MSMQ private queue 'test'. To write a running Windows Service, you do something like this, forgive the example for method accuracy in the service:
namespace WcfService
{
public class Order
{
public int ID { get; set; }
}
[ServiceContract]
public interface IOrderService
{
[OperationContract(TransactionScopeRequired=true)]
void ProcessOrder(Order order);
}
public class OrderService : IOrderService
{
public void ProcessOrder(Order order)
{
Debug.Print("Order ID: ", order.ID);
}
}
}
namespace Client
{
public class WindowsService : IDisposable
{
private ServiceHost host = null;
// TODO: Implement static void Main to initialize service
// OnStart
public void OnStart()
{
if(host == null)
host = new ServiceHost( typeof ( OrderService ) );
host.Open();
}
public void OnStop()
{
host.Close();
}
public void Dispose()
{
// TODO: Implement Dispose() pattern properly
if(host!=null)
host.Dispose();
}
}
}
Then configuration for the Windows Service to read from MSMQ
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<netMsmqBinding>
<binding name="readFromQueueBinding" exactlyOnce="false">
<security mode="None"/>
</binding>
</netMsmqBinding>
</bindings>
<services>
<service name="WcfService.OrderService">
<endpoint address="net.msmq://localhost/private/test"
binding="netMsmqBinding"
contract="WcfService.IOrderService"
name="IOrderService_Msmq_Service"
bindingConfiguration="readFromQueueBinding"/>
</service>
</services>
</system.serviceModel>
</configuration>

This is an overly broad question, but you can create a Windows service that listens to a queue syncronously or asynchronously, receives messages and processes them as they arrive. As to how to accomplish that, the default service project provided by Visual Studio is a good start. From there you can create a class that gets instantiated when the service starts, binds to the queue and calls Receive or BeginReceive (sync or async) to get messages and process them.
Another option is to use activation services. This is potentially more complicated from an environmental perspective, and you need a certain version of Windows and .NET for it to be available.
Finally there's MSMQ Triggers. This is a service that is (optionally) installed along with MSMQ itself. It can be configured to monitor a queue and perform an action when a message arrives. This would be the simplest option, however if you opt for this then I'd suggest just creating a normal EXE instead of a service, and using the trigger to execute it.
This article covers some of the pros and cons of each approach; I'd suggest reading it before you make a decision.

Related

Readiness for Spring Cloud Data Flow

Spring Cloud Data Flow's documentation describes how to integrate with kubernetes Readiness probes. I'm developing my dataflow locally and running it in a docker-compose configuration, while we wait for our k8s SCDF environment to be stood up.
Is there another way to implement a readiness / do not send data context for SCDF? Upon component spin-up, I need to make a RESTful call and then run some computations on the results. Things attempted unsuccessfully:
use of ApplicationAvailabilityEvents - publishing a ReadinessState.ACCEPTING_TRAFFIC after the load + compilation is complete, after publishing a ReadinessState.REFUSING_TRAFFIC. When Spring completes its own load, it publishes an ACCEPTING_TRAFFIC, and so doesn't wait for mine from my service.
setting up an ApplicationRunner which also serves as an ApplicationListener for custom events which I throw when the computations are complete. Effectively, the run() method looks like:
public class ApplicationStartupRunner implements ApplicationRunner, ApplicationListener {
private boolean sessionLoaded = false;
public void run(ApplicationArguments args) {
doTimeExpensiveThing();
while (!sessionLoaded) {
TimeUnit.MILLISECONDS.sleep(150);
}
}
public void onApplicationEvent(SessionLoadEvent event) {
this.sessionLoaded = true;
}
}
Additional technical note: the Spring Boot application is built as a processor, which is using a function exposed as a Bean to provide its capability, ala
public Function<Flux<ChangeEvent>, Flux<Alert>> processChangeEvents()
Optimally, whatever approach I use which works in docker-compose, I'll wire into an indicator which'll be picked up by k8s and its readiness probe. Given that SCDF can be deployed on k8s, docker-compose (locally), or CloudFoundry, hoping that there's a model I can hook into that I've just overlooked.
Potential answer: instead of using the ApplicationRunner, wait in the processChangeEvents method and do not return the function until startup processing is complete.
In our case, because the doTimeExpensiveThing is an asynchronous activity, I use the technique of watching/waiting for the sessionLoaded flag, but now within the processChangeEvents method itself.
#Configuration
public class ConfigurationForProcessor implements ApplicationEventListener<SessionLoadEvent> {
boolean sessionLoaded;
Function<Flux<ChangeEvent>, Flux<Alert>> processChangeEvents() {
doTimeExpensiveAsynchronousThing();
while (!sessionLoaded) {
TimeUnit.MILLISECONDS.sleep(150);
}
return (Flux<ChangeEvent>) -> ... code which returns a Flux of Alert
}
public void onApplicationEvent(SessionLoadEvent event) {
this.sessionLoaded = true;
}
}
Very open to guidance on other approaches. This appears like it's working, though not sure there aren't gotchas I haven't caught yet.

SignalR with orleans how to pass SignalR from startup to grain

I am very new with orleans and trying to grasp everything with grains and so forth.
What i got is that in my startup.cs file i add the SignalR like this
public IServiceProvider ConfigureServices(IServiceCollection services)
{
Program.WriteConsole("Adding singletons");
services
.AddSingleton(achievementManager)
.AddMvc();
services.AddSingleton(SignalRClient);
return services.BuildServiceProvider();
}
So far everything is fine i can start my host/application and it connects to SignalR as it should. But what i cant wrap my head around is how do i get this down to my grain? if i had a controller i would simply send it down in the constructor on startup but how do i do this with a grain? Or can i even do it like this. Any guidance is appreciated.
In the grain then i want to do something like this
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private HubConnection SignalRClient { get; }
public NotifierGrain(HubConnection signalRClient)
{
SignalRClient = signalRClient;
SignalRClient.SendAsync(Methods.RegisterService, Constants.ServiceName);
}
public Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
SignalRClient.SendAsync(Methods.RegisterUserToMultipleGroups, registerUserNotification.UserId, registerUserNotification.InfoIds);
}
return Task.CompletedTask;
}
Then i try to call the Notify method from another grain like this
var notifier = GrainFactory.GetGrain<INotifierGrain>(Constants.NotifierGrain);
await notifier.NotifyClients(notification, MessageType.RegisterUser);
But trying to do this ends up with an error like this
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Client.HubConnection' while attempting to activate 'User.Implementation.Grains.NotifierGrain'.
Orleans supports constructor injection, so you can inject the SignalRClient into your grain constructor. In your code you are already correctly registering the client using services.AddSingleton(SignalRClient), so I will focus on how to inject the type into your grain.
I do not know what the type the SignalR client object is, but in this example I assume that the type is "SignalRClient":
[StatelessWorker]
[Reentrant]
public class NotifierGrain : Grain, INotifierGrain
{
private readonly SignalRClient signalRClient;
public NotifierGrain(SignalRClient signalRClient)
{
this.signalRClient = signalRClient;
}
public async Task NotifyClients(object message, MessageType type)
{
var registerUserNotification = (RegisterUserNotificationModel)message;
await this.signalRClient.SendAsync(
MessageMethods.RegisterUserToMultipleGroups,
registerUserNotification.UserId,
registerUserNotification.infoIds);
}
}
Depends how you're thinking to use SignalR Server, if you're going to host your SignalR server with Microsoft Orleans for sure you need to have backplane to handle the Orleans cluster communications.
You can use SignalR Orleans which has everything done out of the box for you :)
Also if you need a reactive SignalR library for the frontend, you can use Sketch7 SignalR Client
PS I m one of the authors of both libraries.

Inject OSGi Services in a non-component class

Usually I have seen in OSGi development that one service binds to another service. However I am trying to inject an OSGi service in a non-service class.
Scenario trying to achieve: I have implemented a MessageBusListener which is an OSGi service and binds to couple of more services like QueueExecutor etc.
Now one of the tasks of the MessageBusListener is to create a FlowListener (non-service class) which would invoke the flows based on the message content. This FlowListener requires OSGi services like QueueExecutor to invoke the flow.
One of the approach I tried was to pass the reference of the services while creating the instance of FlowListener from MessageBusListener. However when the parameterized services are deactivated and activated back, I think OSGi service would create a new instance of a service and bind to MessageBusListener, but FlowListener would still have a stale reference.
#Component
public class MessageBusListener
{
private final AtomicReference<QueueExecutor> queueExecutor = new AtomicReference<>();
#Activate
protected void activate(Map<String, Object> osgiMap)
{
FlowListener f1 = new FlowListener(queueExeciutor)
}
Reference (service = QueueExecutor.class, cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC)
protected void bindQueueExecutor(QueueExecutor queueExecutor)
{
this.queueExecutor = queueExecutor;
}
}
public class FlowListener
{
private final AtomicReference<QueueExecutor> queueExecutor;
FlowListener(QueueExecutor queueExecutor)
{
this.queueExecutor = queueExecutor;
}
queueExecutor.doSomething() *// This would fail in case the QueueExecutor
service was deactivated and activated again*
}
Looking forward to other approaches which could suffice my requirement.
Your approach is correct you just need to also handle the deactivation if necessary.
If the QueueExecutor disappears the MessageBuslistener will be shut down. You can handle this using a #Deactivate method. In this method you can then also call a sutdown method of FlowListener.
If a new QeueExecutor service comes up then DS will create a new MessageBuslistener so all should be fine.
Btw. you can simply inject the QueueExecutor using:
#Reference
QueueExecutor queueExecutor;

How to use a Singleton Signalr client within an MVC application

I have a need to use a .net client to connect to a Signalr enabled application.
The client class needs to be a singleton and loaded for use globally.
I want to know what is the best technique for using singletons globally within an MVC application.
I have been looking into using the application start to get the singleton, where I keep it is a mystery to me.
The HUB cant be a singleton by design SignalR creates a instance for each incoming request.
On the client I would use a IoC framework and register the client as a Singleton, this way eachb module that tries to get it will get the same instance.
I have made a little lib that takes care of all this for you, install server like
Install-Package SignalR.EventAggregatorProxy
Read here for the few steps to hook it up, it needs a back plate service bus or event aggregator to be able to pickup your events
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki
Once configured install the .NET client in your client project with
Install-Package SignalR.EventAggregatorProxy.Client.DotNet
See here how to set it up
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki/.NET-Client
Once configured any class can register itself as a listener like
public class MyViewModel : IHandle<MyEvent>
{
public MyViewModel(IEventAggregator eventAggregator)
{
eventAggregator.Subscribe(this);
}
public void Handle(MyEvent message)
{
//Act on MyEvent
}
}
On the server you can send a message from outside the hub to all connected clients using the GetClients() method like this:
public MyHub : Hub
{
// (Your hub methods)
public static IHubConnectionContext GetClients()
{
return GlobalHost.ConnectionManager.GetHubContext<MyHub>().Clients;
}
}
You can use it like this:
MyHub.GetClients().All.SomeMethod();

Any existing projects/software for sending hourly status emails

Classic requirement of checking system state and notifying users. Specifically, I'll be hitting the database every x-amount of time, getting some data, then sending out email notifications based on the results. Heck, this service might not even send out an email, but create a notification record in the database.
Seems like with IOC and configuration there could be a generic windows service that manages all this, along with metrics and management, in a simple manner.
In the past I've done email notifications by:
1) Running scripts as cron (at on Windows) jobs
2) running custom executables as cron/at jobs
3) using something like SQLServer's DatabaseMail.
4) Custom NT Services that run all the time monitoring things.
Is there any open source projects that manages this? It's the type of code I've written many, many times in various platforms, but don't want to spend the few days doing it now.
The only thing I found so far was Quartz.Net
Thanks
I just create a Windows service and use the Reactive Extensions to schedule tasks. If you don't need as much flexibility as cron offers, this works fine. Here's an abstract hourly task runner. (uses log4net)
public abstract class HourlyTask : IWantToRunAtStartup
{
protected readonly ILog Log = LogManager.GetLogger(typeof (HourlyTask).FullName);
private IDisposable _Subscription;
private void ExecuteWithLog()
{
Log.Debug("Triggering " + GetType());
try
{
Execute();
}
catch (Exception exception)
{
Log.Error("Hourly execution failed", exception);
}
}
public abstract void Execute();
public void Run()
{
_Subscription = Observable
.Interval(TimeSpan.FromMinutes(1))
.Select(x => DateTime.Now.Hour)
.DistinctUntilChanged()
.Subscribe(i => ExecuteWithLog());
}
public void Stop()
{
if (_Subscription == null)
{
return;
}
_Subscription.Dispose();
}
}
Then in your start up method you can just resolve all IWantToRunAtStartup instances and call Run() on them.

Resources