Using Java the spring-rabbitmq has a isRunning method in the RabbitTemplate class. Is this method equivalent to rabbitmq’s server-check through http-api: /api/aliveness-test/vhost? Can both be used for the purpose of just checking if the rabbitmq server is running ?
No. They are different things.
RabbitTemplate's class is checking if any of RabbitMQ listeners in your application are still running.
synchronized (this.directReplyToContainers) {
return this.directReplyToContainers.values()
.stream()
.anyMatch(AbstractMessageListenerContainer::isRunning);
}
API check through HTTP checks vhost's (server's) aliveness.
Related
Actually, I have on premises spring boot application which consumes rabbitMQ messages using #RabbitListener and I have migrated the same application to azure which consumes AzureServiceBus messages using #JMSListener.
We are maintaining same code for both on premises and Azure . So, because of these two listeners, I'm planning to replicate the same consumer code in two different classes with same content with two different Listeners
consumer with JMSListener:
#JmsListener(destination = "${queue}", concurrency = "${threads}", containerFactory = "defaultContainer")
public Message processMessage(#Payload final String message) {
//do stuff with same content
}
consumer with RabbitListener:
#RabbitListener(queues = "${app.rabbitmq.queue}")
public Message processMessage(#Payload final String message) {
//do stuff with same content
}
Is there any possibility of avoiding the duplicate code in two classes ? How can we handle listeners on a fly with only one consumer? Can any one please suggest me out ?
You can add both annotations to the same method with the autoStartup property set according to which Spring profile is active.
For #RabbitListener there is an autoStartup property on the annotation itself but, in both cases, there are Spring Boot properties auto-startup to control whether the container starts or not.
I am in the process of migrating NServiceBus up to v6 and am at a roadblock in the process of removing reference to IBus.
We build upon a common library for many of our applications (Website, Micro Services etc) and this library has the concept of IEventPublisher which is essentially a Send and Publish interface. This library has no knowledge of NSB.
We can then supply the implementation of this IEventPublisher using DI from the application, this allows the library's message passing to be replaced with another technology very easily.
So what we end up with is an implementation similar to
public class NsbEventPublisher : IEventPublisher
{
IEndpointInstance _instance;
public NsbEventPublisher(IEndpointInstance endpoint)
{
instance = endpoint;
}
public void Send(object message)
{
instance.Send(message, sendOptions);
}
public void Publish(object message)
{
instance.Publish(message, sendOptions);
}
}
This is a simplification of what actually happens but illustrates my problem.
Now when the DI container is asked for an IEventPublisher it knows to return a NsbEventPublisher and it knows to resolve the IEndpointInstance as we bind this in the bootstrapper for the website to the container as a singleton.
All is fine and my site runs perfect.
I am now migrating the micro-services (running in NSB.Host) and the DI container is refusing to resolve IEndpointInstance when resolving the dependencies within a message handler. Reading the docs this is intentional and I should be using IMessageHandlerContext when in a message handler.
https://docs.particular.net/nservicebus/upgrades/5to6/moving-away-from-ibus
The docs even elude to the issue I have in the bottom example around the class MyContextAccessingDependency. The suggestion is to pass the message context through the method which puts a hard dependency on the code running in the context of a message handler.
What I would like to do is have access to a sender/publisher and the DI container can give me the correct implementation. The code does not need any concept of the caller and if it was called from a message handler or from a self hosted application that just wants to publish.
I see that there is two interfaces for communicating with the "Bus" IPipelineContext and IMessageSession which IMessageHandlerContext and IEndpointInstance interfaces extend respectively.
What I am wondering is there some unification of the two interfaces that gets bound by NSB into the container so I can accept an interface that sends/publishes messages. In a handler it is an IMessageHandlerContext and on my self hosted application the IEndPointInstance.
For now I am looking to change my implementation of IEventPublisher depending on application hosting. I was just hoping there might be some discussion about how this approach is modeled without a reliable interface to send/publish irrespective of what initiated the execution of the code path.
A few things to note before I get to the code:
The abstraction over abstraction promise, never works. I have never seen the argument of "I'm going to abstract ESB/Messaging/Database/ORM so that I can swap it in future" work. ever.
When you abstract message sending functionality like that, you'll lose some of the features the library provides. In this case, you can't perform 'Conversations' or use 'Sagas' which would hinder your overall experience, e.g. when using monitoring tools and watching diagrams in ServiceInsight, you won't see the whole picture but only nugets of messages passing through the system.
Now in order to make that work, you need to register IEndpointInstance in your container when your endpoint starts up. Then that interface can be used in your dependency injection e.g. in NsbEventPublisher to send the messages.
Something like this (depending which IoC container you're using, here I assume Autofac):
static async Task AsyncMain()
{
IEndpointInstance endpoint = null;
var builder = new ContainerBuilder();
builder.Register(x => endpoint)
.As<IEndpointInstance>()
.SingleInstance();
//Endpoint configuration goes here...
endpoint = await Endpoint.Start(busConfiguration)
.ConfigureAwait(false);
}
The issues with using IEndpointInstance / IMessageSession are mentioned here.
I'm new to webservices and I have some questions but I hope to get a more clear picture by asking.
I've created a simple webservice with Apache CXF and it works.
I what at startup to build some objects, like database connection or... for example a new thread.
I want the following scenario:
-all the requests should access only the published methods of the webservice.
-all the methods must access varialbes of the running background startup threads.
So the threads will run in background and the published methods will access their result stored in ...maybe a static varialbes.
At the moment I'm using TomcatServer7
The class that it's methods are published is looking like this:
public class OperatorClass {
public int add(int a, int b){
return a+b;
}
public int OneArgument(int a){
return a+45;
}
}
How is possible to implement this and where to write the startup thread clases? maybe a sample code or a link to see how it's done would be very useful.
Tks
If you are using Spring with CXF you can create a bean and implement InitializingBean interface, then in afterPropertiesSet() method you can start you threads depending on your needs. The other alternative with Spring is to use: #PostConstruct annotation on the method which you want to be called after dependency injection.
If you are not using Spring then you can set up ServletContextListener to do the job. See my answer here for more information how to set up context listener.
And now there are many ways of getting the data from the threads you've started on start up. You just need to come up with a more specific question (if you can't get it working) and we will be glad to help.
I'm making a WCF service with netTcpBinding which has a main lobby with multiple chatrooms which the clients can enter. The Lobby class implements ILobby as the service contract.
When a client wishes to enter a room I want to callback the client exposing a new Channel containing the InstanceContext for the room he just entered but after much searching I am doubting that this is possible.
For example on the Service side I might have
class Lobby : ILobby
{
Dictionary<string, Chatroom> rooms;
public void JoinRoom(string roomname)
{
if (rooms[roomname].TryEnter()) {}
}
}
class ChatRoom : IChatRoom
{
public bool TryEnter(string username)
{
ILobbyCallback callback =
OperationContext.Current.GetCallbackChannel<ILobbyCallback>();
// How do I do this next bit?
callback.JoinedRoom(pass some instance context here);
return true;
}
}
On the client side callback method I want
public void JoinedRoom(InstanceContext for the room on the service side)
{
// Create a new WCF proxy using above InstanceContext
// Create a WPF UI for the new room passing the proxy so it can communicate
// with the room class directly without going via the root service
}
Is this possible? What's the best practice for spawning new classes with their own contracts on the service side? Or do I just have to bundle everything into one massive MyService class and handle everything myself?
You cannot pass instance context as parameter to any operation contract. It doesn't make sense because that context has local scope. It is called "instance context" = it is context of current service instance. In duplex scenario both client and server has its own service:
Clients calls server's service through its proxy
Server calls client' service through received callback channel
Server's service instance context has meaning only on the server. It is not clear what you are trying to achieve (except very complex architecture).
If you want to share context on client you can try to pass around the instance context used for the very first proxy you created - I'm not sure if it will work but you can try it
If you want to share service instance context between multiple proxies you must develop your own IInstanceContextProvider and perhaps also your own IInstanceProvider (depending on what you want to achieve), wrap them in behavior and add them to the service. That will put whole complexity of session handling and correct instance releasing under your control (it obviously has its pros and cons).
But is it really needed? When I look at your code I see that one service and one proxy is enough. Also your JoinRoom operation doesn't need to use callback at all, it can be just request response method.
I'm trying to learn WCF to use it as an IPC mechanism for a host/plugin system. The host needs to be able to call the plugin to Start/Stop it, and the plugin needs to call the server back to perform logging.
I made a simple test case where the host creates an endpoint on net.pipe://localhost/SampleServer with the following ServiceContract:
[ServiceContract]
public interface IWcfServer
{
[OperationContract]
void Log(string message);
}
And the plugin creates an endpoint on net.pipe://localhost/SampleClient with the following ServiceContract:
[ServiceContract]
public interface IWcfClient
{
[OperationContract]
string Init();
}
Here's a sample of how I'm setting up each endpoint:
this.server = new ServiceHost(this);
this.server.AddServiceEndpoint(typeof(IWcfServer),
new NetNamedPipeBinding(),
"net.pipe://localhost/SampleServer");
this.server.Open();
And here's a sample of how I'm making the calls:
ChannelFactory<IWcfClient> factory = new ChannelFactory<IWcfClient>(
new NetNamedPipeBinding(),
new EndpointAddress("net.pipe://localhost/SampleClient"));
IWcfClient client = factory.CreateChannel();
using ((IClientChannel)client)
{
client.Init());
}
I already confirmed that the host can call plugin.Init(), and the plugin can call host.Log(message) without issues. However, if this following scenario happens:
Host calls plugin.Init()
During the execution of plugin.Init(), the plugin attempts to call host.Log(message)
The applications freezes, and I get a TimeoutException after 1min. Anyone has any ideas on what I'm doing wrong?
what is the InstanceContextMode of the service host ? If it is a singleton, it will block until Init() returns - resulting in a circular dependency.
1 min is the standard wcf timeout.
Do you have a circular reference?
Also, why do you have 2 contracts, when you make a call to client.init who is listening?
Turn on E2E tracing for WCF to check what exactly is timing out. - http://msdn.microsoft.com/en-us/library/ms733025.aspx. Besides your methods might be causing a deadlock since init might require log and log might require init to happen first or something like that.
"net.pipe://localhost/SampleServer"
"net.pipe://localhost/SampleClient"
You have two different URL for the Server and for the Client. It is a problem!