I am subscribed to a Azure servicebus topic made by an external department. The way I want the code to work is as follows:
Trigger an http endpoint that starts processorClient and listens to the topic.
Fetches one message
Does required actions to that message
Closes processorClient connection.
Repeat
I am using the ServiceBusProcessorClient class as shown in the following documentation Receive messages from a subscription
Is there a way to utilize this code in order to only fetch one message from the topic at a time before calling the processorClient.close();
I have tried using setting maxConcurrentCalls and setting prefetchCount(0).
Related
The idea is to send messages to topic and consume them in stripes via pub/sub only (without queues) and using PERSISTENT delivery mode. For simplicity, lets say producer(s) publish messages to specific topics having the following hierarchy: bus/<componentId/<transactionId>.
Consumers want to receive topic "stripes", for simplicity lets say there are 10 consumers and they want to stripe traffic among themselves by transactionId:
bus/*/0*
bus/*/1*
...
bus/*/9*
When I try to subscribe to topic endpoint using wildcards, like this:
DurableTopicEndpoint topicEndpoint = JCSMPFactory.onlyInstance().createDurableTopicEndpoint("bus/*/1*");
ConsumerFlowProperties propsFlow = new ConsumerFlowProperties();
propsFlow.setEndpoint(topicEndpoint);
I get the following exception:
Exception in thread "main" java.lang.IllegalArgumentException: Topic Endpoint name "bus/*/1*" contains illegal character [*]
at com.solacesystems.common.util.DestinationUtil.isValidEndpointName(DestinationUtil.java:234)
at com.solacesystems.common.util.DestinationUtil.isValidTopicEndpointPhysicalName(DestinationUtil.java:209)
at com.solacesystems.common.util.DestinationUtil.isValidDTEPhysicalName(DestinationUtil.java:213)
at com.solacesystems.jcsmp.impl.SessionModeSupport.createFlow(SessionModeSupport.java:247)
at com.solacesystems.jcsmp.impl.SessionModeSupport.createFlow(SessionModeSupport.java:170)
at com.solacesystems.jcsmp.impl.JCSMPBasicSession.createFlow(JCSMPBasicSession.java:953)
In the light of this article's section "Adding Subscriptions to Topic Endpoints" - is it at all possible with Solace Java API?
There are two problems here.
You are trying to create an TopicEndpoint named bus/*/1*. Note that this is the name of the TopicEndpoint and not the topic that it is subscribing to. * is not a valid character for the name of a TopicEndpoint.
TopicEndpoints are only allowed to have one subscription. This means that you can only subscribe to bus/*/0*. If you want to subscribe to bus/*/0* all the way to bus/*/9* you will need to make use of a Queue instead of a TopicEndpoint.
Is there a way by which AWS SQS can call my REST API? Basically as soon as message is pushed to AWS SQS, I want to hear it and perform required action. I can schedule a listener that can pull messages every second but that won't be an optimizes solution and also the queue might be empty(sometimes).
Thanks In Advance!!
A couple of thoughts:
Use Publisher/Subscriber
Look into using a publisher-subscriber model with SNS/SQS, so that you publish a message to SNS and subscribe to it via SQS. If you absolutely need to handle a message as soon as it is published, you can publish to SNS and set another consumer in addition to your SQS subscription (such as a lambda subscriber that calls your Rest API?) to process it instead.
SQS Long Polling
Regarding SQS, it sounds like you would benefit from long polling. From the documentation:
Long polling helps reduce your cost of using Amazon SQS by reducing
the number of empty responses (when there are no messages available to
return in reply to a ReceiveMessage request sent to an Amazon SQS
queue) and eliminating false empty responses (when messages are
available in the queue but aren't included in the response):
Long polling reduces the number of empty responses by allowing Amazon
SQS to wait until a message is available in the queue before sending a
response. Unless the connection times out, the response to the
ReceiveMessage request contains at least one of the available
messages, up to the maximum number of messages specified in the
ReceiveMessage action.
Long polling eliminates false empty responses by querying all (rather than a limited number) of the servers.
Long polling returns messages as soon any message becomes available.
Also from the documentation, to enable long polling programmatically, use the following for any of these SQS actions:
ReceiveMessage: WaitTimeSeconds parameter
CreateQueue: ReceiveMessageWaitTimeSeconds attribute
SetQueueAttributes: ReceiveMessageWaitTimeSeconds attribute
Reference:
Publish–subscribe (PubSub) Pattern
SQS Documentation - Long Polling
Sounds like you would be much better of using SNS instead of SQS. What you are trying to get SQS to do, SNS was designed to do:
You can use Amazon SNS to send notification messages to one or more
HTTP or HTTPS endpoints. When you subscribe an endpoint to a topic,
you can publish a notification to the topic and Amazon SNS sends an
HTTP POST request delivering the contents of the notification to the
subscribed endpoint. When you subscribe the endpoint, you select
whether Amazon SNS uses HTTP or HTTPS to send the POST request to the
endpoint. If you use HTTPS, then you can take advantage of the support
in Amazon SNS for the following...
http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html
I have a process where, at some point, two different kind of message can occurs, and if none appears after a time, the workflow goes timeout.
Based on the documentation, I have modelised the process using a event gateway :
To progress my activiti workflow, I am using activiti REST API. However, I cannot find in the documentation how to send a message to the gateway in order to continue to either Message 1 or Message 2. I tried triggering message to all execution IDs linked to my process ID but to no avail.
What is the right REST API command to progress in this workflow ?
Thanks for your support.
Edit 1 :
It seems that the Event Gateway is subbed to only one event.
It react to :
POST http://localhost:8082/activiti-rest/service/runtime/executions/20178
{"action":"messageEventReceived","messageName":"Message 1"}
and continue the process for the Message 1. However, with Message 2 defined exactly the same (but with another message), it returns the not found subscription error :
Execution with id '20178' does not have a subscription to a message event with name 'Message 2'"
For an event gateway (https://www.activiti.org/userguide/#bpmnEventbasedGateway). The intermediate message/signal catching events are mutually exclusive. It will follow only one path from the gateway depending on which message is received. In your case, you have fired message 1 already, so the execution continues on message 1 path and other message subscriptions are deleted. Therefore you are getting the error.
I was going through the tutorial shared by RabbitMQ here
I am assuming that the client code below
while (true)
{
var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
if (ea.BasicProperties.CorrelationId == corrId)
{
return Encoding.UTF8.GetString(ea.Body);
}
}
Would receive all messages on the queue and will unnecessarily iterate through messages not designated for it. Is their anyway we can avoid it i.e we can modify the client to only receive the messages intended for it only.
The basic work that i intend to achieve through RabbitMQ is Request-Response pattern where a request would be received by web-service which will send data in a queue the data object would have a unique reference number . This would be received by an asynchronous tcp-client which will send data on a tcp/ip layer based on message it had received.
On receiving reply from the asynchronous channel of tcp/ip the channel would parse the data and respond back on the queue with the corresponding request reference number.
The RPC approach is well suited for it but the client code shared have this shortcoming would appreciate feedback on it.
Actually I didn’t understand well your aim, but when you create an RPC model, you have to create an “reply queue”, this queue is bound only to the client.
It means that you will receive back only the client messages, and not all messages.
Since the Rabbitmq RPC model is asynchronous you can execute more than one request without wait the responses and replies could not have the same publish order.
The correlation id is necessary to map your client requests with the replies, so there are not "unnecessarily" messages
hope it helps
I have a problem concerning receiving messages (I use #ManagedService). I use the same connection to send and receive messages between browser and my Java program. I can see that all the messages pass through ManagedAtmosphereHandler.message(AtmosphereResource resource, Object o) method.
If it is an incoming message, Atmosphere iterates through all methods marked #Message. Then it tries to find a decoder and eventually invokes correct method.
For outgoing messages, Atmosphere retrieves invoked method. It does so by getting localAttribute named "ManagedAtmosphereHandler" (name of current class). It is present only for outgoing messages. Then the message is encoded and send to browser.
The problem is, sometimes invokedMethod is set for incoming messages. It results in treating my incoming messages as outgoing. Does anybody know why it happens? My outgoing messages are scheduled and I suppose that's the reason why it happens, but I'm not sure. When are these localAttributes set and what are they for?
I updated Atmosphere 2.3.0-RC6 to 2.3.0 and it works like a charm now.