deliver data to cometd server using a channel - java

How can I deliver some data to server side while subscribing to server?
As an example,
When I subscribing /alert/12345, I want to send some other information such as alert_type, date_time etc to CometD server.

You can pass a data map in subscribe:
cometd.subscribe(channelId, undefined, callback, { data: data })
But as far as I could see, you can only get a reference to the data map in org.cometd.bayeux.server.Authorizer. I couldn't get it via org.cometd.bayeux.server.BayeuxServer.SubscriptionListener because there is no reference to the ServerMessage.
You can see my use of it here:
https://github.com/uklance/tapestry-cometd/blob/master/src/main/resources/org/lazan/t5/cometd/PushTarget.js#L37
https://github.com/uklance/tapestry-cometd/blob/master/src/main/java/org/lazan/t5/cometd/services/internal/AuthorizersImpl.java#L67

Related

Azure Service bus with AMQP - how to specify the session ID

I am trying to send messages to Service bus using AMQP QPID java library
I am getting this error:
"SessionId needs to be set for all brokered messages to a Partitioned
Topic that supports Ordering"
My topic has "Enforce Message ordering" turned on (this is way i get this error i guess)
When using the Azure Service bus java library (and not AMQP) i have this function :
this.entity.setSessionId(...);
When using the AMQP library i do not see an option to set the session ID on the message i want to send
Note that if i un-check the option "Enforce Message ordering" the message will be sent successfully
This is my code
private boolean sendServiceBusMsg(MessageProducer sender,Session sendSession) {
try {
// generate message
BytesMessage createBytesMessage = (BytesMessage)sendSession.createBytesMessage();
createBytesMessage.setStringProperty(CAMPAIGN_ID, campaignKey);
createBytesMessage.setJMSMessageID("ID:" + bm.getMessageId());
createBytesMessage.setContentType(Symbol.getSymbol("application/octet-stream"));
/*message is the actual data i send / not seen here*/
createBytesMessage.writeBytes(message.toByteArray());
sender.send(createBytesMessage);
} catch (JMSException e) {
}
The SessionId property is mapped to AMQP message properties.group-id. The Qpid JMS client should map it to JMSXGroupID property, so try the following,
createBytesMessage.setStringProperty("JMSXGroupID", "session-1");
As you guessed, there is a similar SO thread Azure Service Bus topics partitioning verified that to disable the feature Enforce Message Ordering via set SupportOrdering with false can solve the issue, but it can't be done via Azure Service Bus Java library because the property supportsOrdering is privated now.
And you can try to set property Group as #XinChen said using AMQP, as the content below from here.
Service Bus Sessions, also called 'Groups' in the AMQP 1.0 protocol, are unbounded sequences of related messages. ServiceBus guarantees ordering of messages in a session.
Hope it helps.

Camel Exchange on different routes in the same route builder

My REST application will post data to a queue (Q1) on rabbitMQ. There's another separate application that will read from Q1, process the data and post the result back to Q2. My application will read the data from Q2 and return the result. Many clients will use these 2 queues so I generate a UUID and set it in the header so that I can listen on Q2 (the response topic). I will then query each incoming message and match the incoming UUID in the header to the one I generated when I posted to Q1.
from("direct:test")
.choice().when(isValid)
.bean(FOOProcessor.class, "setFooQuery")
.to(FOO_REQUEST_QUEUE).log(LoggingLevel.INFO, "body=${in.body}")
.otherwise()
.setBody(constant("error"))
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400)).log(LoggingLevel.INFO, "body=${in.body}")
.to("direct:error");
from(FOO_RESPONSE_QUEUE)
.unmarshal(new JacksonDataFormat(JsonNode.class))
.bean(FooProcessor.class, "setFooResponse")
.to("direct:end");
from("direct:error").log(LoggingLevel.DEBUG, "end");
from("direct:end").log(LoggingLevel.DEBUG, "end");
The trouble is the 2 "from" statements - they create to separate Camel exchanges/contexts and I can't get the original UUID. Any suggestions?
I solved this by using a processor that had a route builder embedded in it (with its own producer and consumer).
The processor provided a reference to the main exchange from this
process(final Exchange exchange)

Multihread communication between two services in java Apache CXF (SOAP)

I have two services hosted under the same context file in Spring + Apache CXF (Services A and B). There is a third-party service C, that I have to call from service A, and that will send the response to service B. (by means of addressing). I have managed to perform the communication between services A -> C -> B. Everything OK there. The problem is I would like to perform some logic in service A according to the response sent to service B. That means I would like to do something like this in service A
ServiceC_Client clientC = ....
....
clientC.callOperation();
// somehow wait for a signal from service B or until a timeout have been reached.
// The response will be correlated to this particular thread by means of
// WS-Addressing MessageId field
// Read relevant data response sent to B (B stores the relevant data in database)
....
// continue operation of method of A
In service B, I would have something like this
public void callBackResponse(ResponseData response){
// Perform operations with response and store relevant data in database
// Service A will know data is sent to a particular run of A thanks to
// Addressing MessageID and RelatesTo fields
// Notify Service A a response was received
}
Is this possible? Can I achieve this in Java? Maybe Java Message Queues? I don't really know if it is possible.

How to check delayed/scheduled messages in RabbitMQ's Mnesia

I was checking for some alternatives for Quartz-scheduler.
Though this is not a complete replacement, I was trying out RabbitMQ Delayed Messages Plugin (suits for my use-case).
I was able to get the scheduling work but I was not to view the messages which are delayed(which are stored in Mnesia).
Is there a way to check the messages and/or number of messages in Mnesia?
Edit : I inferred that the messages are stored in Mnesia from the comment from here.
There is no way to check the messages that RabbitMQ is persisting in it's mnesia database.
RabbitMQ is not a generalized datastore. It is a purpose-built message broker and queueing system. The datastore it has in it is there to facilitate the persistence of messages, not to be queried and used as if it were a database on it's own.
To view the data inside MNESIA you could :
Write a simple Erlang program as this, as result you have:
(rabbit#gabrieles-MBP)5>
load:traverse_table_and_show('rabbit_delayed_messagerabbit#gabrieles-MBP').
{delay_entry,
{delay_key,1442258857832,
{exchange,
{resource,<<"/">>,exchange,<<"my-exchange">>},
'x-delayed-message',true,false,false,
[{<<"x-delayed-type">>,longstr,<<"direct">>}],
undefined,undefined, {[],[]}}},
{delivery,false,false,<0.2008.0>,
{basic_message,
{resource,<<"/">>,exchange,<<"my-exchange">>},
[<<>>],
{content,60,
{'P_basic',undefined,undefined,
[{<<"x-delay">>,signedint,100000}],
undefined,undefined,undefined,undefined,undefined,
undefined,undefined,undefined,undefined,undefined,
undefined},
..
OR in this way:
execute an Erlang shell session using:
erl -set-cookie ABCDEFGHI -sname monitorNode#gabrielesMBP
you have to use the same cookie that rabbitmq are using.
Typically $(HOME).erlang.cookie
execute this command:observer:start().
and you should have this:
Once you are connected to rabbitmq node open Table Viewer and from the menu Mnesia table as:
Here you can see your data:

exchange files between clients via socket

How I can send file from one client (A) to another one (B) via socket? and vice versa, send file from B to A. I mean that make the client sender and receiver at the same time.
In other word, when muticlient connect to server, how I distinguish between clients ?
You need to implement you own communication message format in short a simple protocol .
You keep a list of all active sockets in a shared list/map , and based on the request from the message you pick up the apt client and push the desired message to that.
You can implement the actual message format as you want, but this can be the blueprint.
In this case lets say your client A sends message : 1. Client Id 2. File Start 3 X . File Content 4. File End
as soon as you get a connection you get the target client id , the file start message lets you understand the next message just needs to be diverted to target and file End message defines the transfer complete.
Also, you may would like to send Acknowledgement message from server to client, in order to eradicate transfer issues.
It is good way to manage client using their id(i.e. a unique long or string or any other for each user). At the time of connection to socket client send their id , store that is in collection. And when a user(Client) want to send file send with own id and Id of that user(Client) want to send.

Categories

Resources