MassTransit: how to send a message to specific consumers? - message-queue

Sorry if my question is dumb, I'm new to MassTransit.
My system consists of a server and multiple client devices.
I'd like to send a message from the server to a specific client or to a group of clients.
As far as I understand, IBusControl.Publish sends the message to all subscribers, and IBusControl.Send to the only one subscriber.
How can I achieve this using MassTransit?
My transports are RabbitMQ / Azure Service Bus.
Thanks!

MassTransit implements standard messaging patterns, which aren't MassTransit-specific. Point-to-point, publish-subscribe, invalid message channel, dead letter channel and so on:
You indeed have the choice between sending a message to one consumer using Send and to broadcast messages to all subscribers for that message type by using Publish.
Everything else can be easily done by adding code to consumers:
await bus.Publish(new MyMessage { ReceiverGroup = "group1", ... });
and
public async Task Consume(IContext<MyMessage> context)
{
if (context.Message.ReceiverGroup != myGroup) return;
...
}

Related

How to send a message from an Agent to Main Container in Jade?

I am working on Agent-based web-application. Front-end send to the server parameters, those parameters I am sending to the specific agent as arguments.
ContainerController ac = (ContainerController) runtime.createMainContainer(p);
Object[] obj = {Amount};
try {
AgentController ag = ac.createNewAgent("a1","agents.a1", obj);//arguments
ag.start();
AgentController ag2 = ac.createNewAgent("a2","agents.a2", obj);//arguments
ag2.start();
} catch (StaleProxyException e) {
throw new Error(e);
}
After receiving these parameters, each agent is required to send receipt confirmation in order to send it to the web-application frond-end. How can I send parameters from agents to the main container implementer.
How can it be implemented? If there are more feasible way to do it, it is also welcomed
Except in exceptional cases, which does not seem to be the case here, agents do not "communicate" with containers (a container is not an agent, so it is not possible to send it a message).
Your agents should contact the web application directly. Since the objective here is that they use a web-service, you can select a standard REST library and make a "post".
If you do not want all your agents to know the location of the web-service, then create a new agent that will play the intermediary.

Flutter send push notifications using fcm for all devices

How are you guys , my problem that my flutter app is connected to mysql db , when the user is registered a string with the class name is saved to shared preferences and there is a wall to post some posts on it , is there any way to work with fcm bassed on the shared preferences string ? Like if the user has this string and posted let all users with the same string get notifications i hope i could make it more uderstandable but i dont know how ! Thanks
This sounds like a perfect use-case for using topics to target those messages. Step-wise:
Each device subscribes to the topic based on their class. If they can have multiple classes, they'd subscribe to all topics for those classes.
You then send the message to the correct topic for its class, and FCM will deliver it to all devices subscribed to that topic.
As usual, you will need to perform the actual send operation from a trusted environment, such as your development machine, a server you control, or Cloud Functions.
you will get the token id from the device which you can store to the user table so it will use while giving the notification to every device.
For getting the token :
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
setState(() {
_homeScreenText = "Push Messaging token: $token";
});
print(_homeScreenText);
});
this token variable which you can store to the user table and use it while giving the notification to every device.

Amazon SQS Listener - Consuming message and setting attributes before failing the message

I've a fifo queue, and i'm using org.springframework.cloud.aws.messaging and here's what i'd like to do:
Consume the message
Try to handle it (inner logic)
If handles fails - write new attribute on the message (without sending the message again to the queue)
I don't want to send the messages to a new queue (i need to keep the order of the messages).
also, i don't want to use the deadletter queue for handling errors (same reason as above).
the reason i want to use message attributes is due to the fact that i need to implement in-house retry mechanism, meaning: when consuming the message i'll check the last_try_timestamp and if it's passed my validation then i'll try to handle it, else i'll throw an error.
(I know that the message will continue to be consumed until the MaxRetention and i'm fine with it)
Is something like that possible?
#SqsListener(value = "#{'${my.queue.fifo}'}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void deadLetterQueueListener(#Headers Map<String, String> headers, String message) throws Exception {
log.info("consuming message");
if(!this.handleMessage(message)){
//Set message attributes (timestamp)
throw new Exception("Failed to handle message");
}
}
As far as I know there is no way to do it purely with SQS. If you modify the message attribute you would need to resend this message to propagate this change to SQS.
It can be implemented on the application side by storing metadata like last_try_timestamp in an external datasource like a DynamoDB where you could map message id to any metadata you need.

U2F with multi-facet App ID

We have been directly using U2F on our auth web app with the hostname as our app ID (https://auth.company.com) and that's working fine. However, we'd like to be able to authenticate with the auth server from other apps (and hostnames, e.g. https://customer.app.com) that communicate with the auth server via HTTP API.
I can generate the sign requests and what-not through API calls and return them to the client apps, but it fails server-side (auth server) because the app ID doesn't validate (clients are using their own hostnames as app ID). This is understandable, but how should I handle this? I've read about facets but I cannot get it to work at all.
The client app JS is like:
var registerRequests = // ...
var signRequests = // ...
u2f.register('http://localhost:3000/facets', registerRequests, signRequests, function(registerResponse) {
if (registerResponse.errorCode) {
return alert("Registration error: " + registerResponse.errorCode);
}
// etc.
});
This gives me an Error code 5 (timeout error) after a while. I don't see any request to /facets . Is there a way around this or am I barking up the wrong tree (or a different forest)?
————
Okay, so after a few hours of researching this; I'm pretty sure this fiendish bit of the Firefox U2F plugin is the source of some of my woes:
if (u.scheme == "http")
if (url2str(u, true) == url2str(ou, true))
return resolve(challenge);
else
return reject("Not matching appID");
https://github.com/prefiks/u2f4moz/blob/master/ext/appIdValidator.js#L106-L110
It's essentially saying, if the appID's scheme is http, only allow it if it's exactly the same as the page's host (it goes on to do the behaviour for fetching the trusted facets JSON but only for https).
Still not sure if I'm on the right track though in how I'm trying to design this.
I didn't need to worry about facets for my particular situation. In the end I just pass the client app hostname through to the Auth server via the secure API interface and it uses that as the App ID. Seems to work okay so far.
The issue I was having with facets was due to using http in dev and the Firefox U2F plugin not permitting that with JSON facets.

Better Approach for sending bulk mail using JavaMail API

Is there any better approach for sending bulk mail using JavaMail API.I use the below approach.
enter code here Transport tr = session.getTransport("smtp");
tr.connect(smtphost, username, password);
tr.sendMessage(msg, msg.getAllRecipients());
i used to send 'n'number of mails using the same connection.
I is there any other separate way for sending bulk mail.Kindly help me in this for getting better solution.
In what way do you want it to be "better"?
You can use multiple threads to send more messages in parallel,
up to the limit of what your mail server will allow.
You can use Thread pooling as it gives very good performance.I have implemented and sharing you the below code snippet.
try {
ExecutorService executor = Executors.newFixedThreadPool("no. of threads");
// no. of threads is depend on your cpu/memory usage it's better to test with diff. no. of threads.
Runnable worker = new MyRunnable(message);
// message is the javax.mail.Message
executor.execute(worker);
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}