JMS listener with netty TCP - tcp

I'm trying to develop Netty using TCP. I am using the IBM MQ client to connect to the MQ broker, and the idea is I need to develop a TCP server that receives a message passes it to MQ and if the server responds send it to the client that sent the request. Therefore, I need to implement a JMS listener for async message. The problem is that the JMS listener is outside of the Netty channel and I'm trying to figure out how to read the message add it to a Netty channel and send it immediately to the client connected to TCP socket. I can send messages perfectly. The problem is when the server responds. I receive the message, get the context/channel from the clientConnectionProvider and I writeAndFlush, but I don't see the message arrive at the client.
I create the listener in the main class.
public class Main {
private final Integer port;
private final Destination sendDestination;
private final JMSContext jmsSendContext;
private final JMSConsumer consumer;
private final JMSContext jmsRecieveContext;
private final Destination consumerDestination;
private final ClientConnectionProvider clientConnectionProvider;
public Main(Properties properties)
throws JMSException {
if (properties.containsKey(ConfigurationEnum.SERVER_PORT) {
this.port = properties.getProperty(ConfigurationEnum.SERVER_PORT)
} else {
log.error("server.port not defined in properties"
throw new ConfigException(
String.format("server.port not defined in properties");
}
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(JmsConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty(CommonConstants.WMQ_HOST_NAME,
properties.getProperty(ConfigurationEnum.IBM_MQ_HOST.getValue()));
cf.setIntProperty(CommonConstants.WMQ_PORT,
Integer.parseInt(properties.getProperty(ConfigurationEnum.IBM_MQ_PORT.getValue())));
cf.setStringProperty(CommonConstants.WMQ_CHANNEL,
properties.getProperty(ConfigurationEnum.IBM_MQ_CHANNEL.getValue()));
cf.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(CommonConstants.WMQ_QUEUE_MANAGER,
properties.getProperty(ConfigurationEnum.IBM_QUEUE_MANAGER.getValue()));
cf.setStringProperty(CommonConstants.WMQ_APPLICATIONNAME, "FIX Orchestra Gateway");
cf.setBooleanProperty(JmsConstants.USER_AUTHENTICATION_MQCSP, true);
cf.setStringProperty(JmsConstants.USERID, properties.getProperty(ConfigurationEnum.IBM_APP_USER.getValue()));
cf.setStringProperty(JmsConstants.PASSWORD, properties.getProperty(ConfigurationEnum.IBM_APP_PASS.getValue()));
clientConnectionProvider = new ClientConnectionProvider();
jmsRecieveContext = cf.createContext();
consumerDestination = jmsRecieveContext
.createQueue(properties.getProperty(ConfigurationEnum.IBM_QUEUE_CONSUMER.getValue()));
consumer = jmsRecieveContext.createConsumer(consumerDestination);
consumer.setMessageListener(new JMSMessageListener(clientConnectionProvider));
jmsRecieveContext.start();
jmsSendContext = cf.createContext();
sendDestination = jmsSendContext
.createQueue(properties.getProperty(ConfigurationEnum.IBM_QUEUE_TRANSACTION.getValue()));
}
public void start() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(10);
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100).option(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new DefaultChannelInitializer());
// Start the server.
ChannelFuture f = serverBootstrap.bind(port).sync();
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
jmsRecieveContext.stop();
jmsRecieveContext.close();
jmsSendContext.close();
}
}
public static void main(String[] args) throws InterruptedException {
Properties properties = new Properties();
try (InputStream inputStream = new FileInputStream(args[0])) {
properties.load(inputStream);
new Main(properties).start();
} catch (FileNotFoundException e) {
log.error("Properties file specified in path {} was not found.", args[0], e);
} catch (IOException e) {
log.error("There was an IO error.", e);
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ConfigException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The listener is a simple class.
#AllArgsConstructor
public class JMSMessageListener implements MessageListener {
private final ClientConnectionProvider clientConnectionProvider;
#Override
public void onMessage(Message message) {
try {
String messageString = message.getBody(String.class);
if (clientConnectionProvider.contains(ClientID.get(messageString))) {
ClientConnection cc = clientConnectionProvider.getConnection(ClientID.get(messageString));
if (cc.getCtx() == null) {
// TODO: Need to save message when client reconects
} else {
cc.getCtx().channel().write(messageString);
}
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}

You should call writeAndFlush(...) and attach a ChannelFutureListener to the ChannelFuture returned to it. In the listener you can check if the write did succeed or fail (and if so print the exception). In your current code you only call write(...) which only put the message in the outboundbuffer of the Channel but not actually flush it to the socket.

Related

How can I write message from server to an IP/Port using Netty 3.8 ServerBootstrap (TCP)

I want to send a message from server to an IP/Port but it's not working when I write the channel. I'm not sure what I'm doing wrong.
private Channel channel;
private void createConnection() {
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
this.bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
#Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new SimpleChannelHandler());
}
});
bootstrap.setOption("localAddress", new InetSocketAddress("localhost", 0));
bootstrap.setOption("reuseAddress", true);
bootstrap.setOption("child.sendBufferSize", 65536);
bootstrap.setOption("child.receiveBufferSize", 65536);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
this.channel = bootstrap.bind();
}
I'm writing a component using apache camel. When my component proccess, I want it sends a message to an IP/Port.
public void send(Exchange exchange) {
String ip = exchange.getIn().getHeader("ip", String.class);
int port = exchange.getIn().getHeader("port", Integer.class);
Object msg = exchange.getIn().getBody();
InetSocketAddress inetSocketAddress = new InetSocketAddress(ip, port);
this.channel.write(msg, inetSocketAddress);
}
I'm getting a "getUnsupportedOperationFuture". I'm not sure what I'm doing wrong. I'm using Netty 3.8 and I think the connection is set correctly. Any help?

Spring Integration tcp client multiple connections

I use Spring Integration tcp-outbound-adapter and tcp-inbound-adapter in order to communicate with a third party external system through TCP.
The connection factory I use is of type "client" and has single-use="false", because the nature of communication with the external system is a session of several dozens requests and replies.
The external system expects I will open a new TCP connection for each session.
Is there any way to do that with Spring Integration?
My code uses SI successfully for one such session. But I want my system to open several such connections so I can handle several concurrent sessions.
Currently, if I send a message of a new session to the inbound adapter, it uses the same TCP connection.
Please help.
UPDATE:
While using the ThreadAffinity solution given by Gary here, we get this exception when we do more than 4 concurrent requests. Any idea why is that?
11:08:02.083 [pool-1-thread-2] 193.xxx.yyy.zz:443:55729:46c71372-5933-4707-a27b-93cc4bf78c59 Message sent GenericMessage [payload=byte[326], headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#2fb866, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel#2fb866, ip_tcp_remotePort=55718, ip_connectionId=127.0.0.1:55718:4444:7f71ce96-eaac-4b21-8b2c-bf736102f818, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, id=2dc3e330-d703-8a61-c46c-012233cadf6f, ip_hostname=127.0.0.1, timestamp=1481706480700}]
11:08:12.093 [pool-1-thread-2] Remote Timeout on 193.xxx.yyy.zz:443:55729:46c71372-5933-4707-a27b-93cc4bf78c59
11:08:12.093 [pool-1-thread-2] Tcp Gateway exception
org.springframework.integration.MessageTimeoutException: Timed out waiting for response
at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:146)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:109)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:373)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:292)
at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:212)
at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:129)
at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:115)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:423)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:150)
at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:42)
at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97)
at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:441)
at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:409)
at org.springframework.integration.ip.tcp.TcpInboundGateway.doOnMessage(TcpInboundGateway.java:120)
at org.springframework.integration.ip.tcp.TcpInboundGateway.onMessage(TcpInboundGateway.java:98)
at org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorSupport.onMessage(TcpConnectionInterceptorSupport.java:159)
at org.springframework.integration.ip.tcp.connection.TcpNetConnection.run(TcpNetConnection.java:182)
at org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorSupport.run(TcpConnectionInterceptorSupport.java:111)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
It depends on what constitutes a "session" - if all the requests from a session on the client side all run on a single thread, you could write a simple wrapper for the connection factory that stores the connection in a ThreadLocal. You would need some mechanism to call the factory wrapper after the last request to close the connection and remove it from the ThreadLocal.
If the requests for a session can occur on multiple threads, it would be a bit more complicated but you could still do it with a ThreadLocal that maps to a connection instance.
EDIT
Here's an example...
#SpringBootApplication
public class So40507731Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(So40507731Application.class, args);
MessageChannel channel = context.getBean("clientFlow.input", MessageChannel.class);
MessagingTemplate template = new MessagingTemplate(channel);
ThreadAffinityClientConnectionFactory affinityCF = context.getBean(ThreadAffinityClientConnectionFactory.class);
ExecutorService exec = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(2);
exec.execute(() -> {
String result = new String(template.convertSendAndReceive("foo", byte[].class));
System.out.println(Thread.currentThread().getName() + " " + result);
result = new String(template.convertSendAndReceive("foo", byte[].class));
System.out.println(Thread.currentThread().getName() + " " + result);
affinityCF.release();
latch.countDown();
});
exec.execute(() -> {
String result = new String(template.convertSendAndReceive("foo", byte[].class));
System.out.println(Thread.currentThread().getName() + " " + result);
result = new String(template.convertSendAndReceive("foo", byte[].class));
System.out.println(Thread.currentThread().getName() + " " + result);
affinityCF.release();
latch.countDown();
});
latch.await(10, TimeUnit.SECONDS);
context.close();
exec.shutdownNow();
}
#Bean
public TcpNetClientConnectionFactory delegateCF() {
TcpNetClientConnectionFactory clientCF = new TcpNetClientConnectionFactory("localhost", 1234);
clientCF.setSingleUse(true); // so each thread gets his own connection
return clientCF;
}
#Bean
public ThreadAffinityClientConnectionFactory affinityCF() {
return new ThreadAffinityClientConnectionFactory(delegateCF());
}
#Bean
public TcpOutboundGateway outGate() {
TcpOutboundGateway outGate = new TcpOutboundGateway();
outGate.setConnectionFactory(affinityCF());
return outGate;
}
#Bean
public IntegrationFlow clientFlow() {
return f -> f.handle(outGate());
}
#Bean
public TcpNetServerConnectionFactory serverCF() {
return new TcpNetServerConnectionFactory(1234);
}
#Bean
public TcpInboundGateway inGate() {
TcpInboundGateway inGate = new TcpInboundGateway();
inGate.setConnectionFactory(serverCF());
return inGate;
}
#Bean
public IntegrationFlow serverFlow() {
return IntegrationFlows.from(inGate())
.transform(Transformers.objectToString())
.transform("headers['ip_connectionId'] + ' ' + payload")
.get();
}
public static class ThreadAffinityClientConnectionFactory extends AbstractClientConnectionFactory
implements TcpListener {
private final AbstractClientConnectionFactory delegate;
private final ThreadLocal<TcpConnectionSupport> connection = new ThreadLocal<>();
public ThreadAffinityClientConnectionFactory(AbstractClientConnectionFactory delegate) {
super("", 0);
delegate.registerListener(this);
this.delegate = delegate;
}
#Override
protected TcpConnectionSupport obtainConnection() throws Exception {
TcpConnectionSupport tcpConnection = this.connection.get();
if (tcpConnection == null || !tcpConnection.isOpen()) {
tcpConnection = this.delegate.getConnection();
this.connection.set(tcpConnection);
}
return tcpConnection;
}
public void release() {
TcpConnectionSupport connection = this.connection.get();
if (connection != null) {
connection.close();
this.connection.remove();
}
}
#Override
public void start() {
this.delegate.start();
setActive(true);
super.start();
}
#Override
public void stop() {
this.delegate.stop();
setActive(false);
super.stop();
}
#Override
public boolean onMessage(Message<?> message) {
return getListener().onMessage(message);
}
}
}
Result:
pool-2-thread-2 localhost:64559:1234:3d898822-ea91-421d-97f2-5f9620b9d369 foo
pool-2-thread-1 localhost:64560:1234:227f8a9f-1461-41bf-943c-68a56f708b0c foo
pool-2-thread-2 localhost:64559:1234:3d898822-ea91-421d-97f2-5f9620b9d369 foo
pool-2-thread-1 localhost:64560:1234:227f8a9f-1461-41bf-943c-68a56f708b0c foo

Sharing SignalR hub with ASP.NET Website and a Web API Mobile Backend

I've set up SignalR Realtime communication for my ASP.NET based website. However, I need to know if it's possible to share the same SignalR Hub with a separate Mobile Backend Project which deals with the same server and database. Basically like accessing the facebook's inbox through web and mobile at the same time?
That would be a ASP.NET Web project and a Mobile Client connected to one hub.
If you want to find SignalR for Android, I suggest the following working link for your to start
SignalR/java-client at GitHub
You can refer to the following sample code (this is from my question on SO about SignalR for Android: SignalR for Android: how can I pass dynamic class to SubscriptionHandler1
public <T> void startSignalR(String transport, String serverUrl, final String userName, final Class<T> tClass) {
Platform.loadPlatformComponent(new AndroidPlatformComponent());
Credentials credentials = new Credentials() {
#Override
public void prepareRequest(Request request) {
request.addHeader(HEADER_KEY_USERNAME, userName);
}
};
mConnection = new HubConnection(serverUrl);
mConnection.setCredentials(credentials);
mHub = mConnection.createHubProxy(SERVER_HUB_CHAT);
if (transport.equals("ServerSentEvents")) {
mTransport = new ServerSentEventsTransport(mConnection.getLogger());
} else if (transport.equals("LongPolling")) {
mTransport = new LongPollingTransport(mConnection.getLogger());
}
mAwaitConnection = mConnection.start(mTransport);
try {
mAwaitConnection.get();
} catch (InterruptedException e) {
e.printStackTrace();
return;
} catch (ExecutionException e) {
e.printStackTrace();
return;
}
mHub.on("broadcastMessage",
new SubscriptionHandler1<Object>() {
#Override
public void run(final Object msg) {
final String finalMsg;
Gson gson = new Gson();
Object object = gson.fromJson(msg.toString(), tClass);
Field[] fields = object.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
try {
System.out.println("Value = " + fields[i].get(object));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
, Object.class);
...
}
Hope this helps!

Jersey2 Client reuse not working AsyncInvoker

I am trying to reuse a Jersey2(Jersey 2.16) Client for async invocation. However after 2 requests, I see that the threads going into a waiting state, waiting on a lock. Since client creation is an expensive operation, I am trying to reuse the client in the async calls. The issue occurs only with ApacheConnectorProvider as the connector class. I want to use ApacheConnectorProvider, as I need to use a proxy and set SSL properties and I want to use PoolingHttpClientConnectionManager.
The sample code is given below:
public class Example {
Integer eventId = 0;
private ClientConfig getClientConfig()
{
ClientConfig clientConfig = new ClientConfig();
ApacheConnectorProvider provider = new ApacheConnectorProvider();
clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING,RequestEntityProcessing.BUFFERED);
clientConfig.connectorProvider(provider);
return clientConfig;
}
private Client createClient()
{
Client client = ClientBuilder.newClient(getClientConfig());
return client;
}
public void testAsyncCall()
{
Client client = createClient();
System.out.println("Testing a new Async call on thread " + Thread.currentThread().getId());
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", eventId++);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
invoker(client, "http://requestb.in/nn0sffnn" , jsonObject);
client.close();
}
private void invoker(Client client, String URI, JSONObject jsonObject)
{
final Future<Response> responseFuture = client.target(URI)
.request()
.async()
.post(Entity.entity(jsonObject.toJSONString(), MediaType.TEXT_PLAIN));
try {
Response r = responseFuture.get();
System.out.println("Response is on URI " + URI + " : " + r.getStatus());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[])
{
Example client1 = new Example();
client1.testAsyncCall();
return;
}
}
The response I see is:
Testing a new Async call on thread 1
Response is on URI http://requestb.in/nn0sffnn : 200
Response is on URI http://requestb.in/nn0sffnn : 200
On looking at the thread stack, I see the following trace:
"jersey-client-async-executor-0" prio=6 tid=0x043a4c00 nid=0x56f0 waiting on condition [0x03e5f000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x238ee148> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:133)
at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:282)
at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:177)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:170)
Can someone give me a suggestion as to how to reuse Client objects for async requests and may be how to get over this issue as well.

How to handle timeout of AsynchronousResponse object in RestEasy

i am implementing a jax-rs service with RestEasy on JBoss AS 7.1.2 an i would like to use asynchronous HTTP processsing as described here: http://docs.jboss.org/resteasy/docs/1.0.0.GA/userguide/html/Asynchronous_HTTP_Request_Processing.html
For thr AsynchronousResponse I define a timeout of 10 seconds. When this period expires, the request is responded with a 200 OK and an empty body. I would like to modify this behaviour so i need to be notified about the timeout event.
In my solution, I would like to handle the timeout event in a NotificationManager object, which keeps the AsycnhronousResponse for the time being. Please see the code below for details.
So far, i could not figure out how to do that. Does anyone have more experience with the RestEasy Asynchronous HTTP processing?
#POST
#Path("/blabla")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void subscribeLongPolling (
final #Suspend(10000) AsynchronousResponse response,
JAXBElement<LongPollingRequestParameters> rqParam,
#Context HttpServletRequest req) throws Exception {
//do some stuff with req
Thread t = new Thread("ThreadSubscribeTo:" + channelID)
{
#Override
public void run() {
//hand over to Notification Manager to return notifications in case some exist
try {
NotificationManager nm = new NotificationManager();
nm.setAsyncResponseObject(response);
logger.info("Response object registered in NotificationManager");
}catch (Exception e){
e.printStackTrace();
}
}
};
t.start();
logger.info("Releasing Thread");
}
public class NotificationManager {
private AsynchronousResponse response;
private NotificationList nList;
public synchronized void setAsyncResponseObject(AsynchronousResponse response) {
this.response = response;
if (nList.getAny().size() > 0) {
logger.info("Stored notification send to web client: " + nList.getAny().get(0).toString());
sendNotification(nList.getAny().remove(0));
}
}
public synchronized void sendNotification(Object message){
if (response != null){
logger.info("Response object found. Send notification immediately: " + message.toString());
Response responseObject = Response.ok(message, MediaType.APPLICATION_XML).build();
response.setResponse(responseObject);
response = null;
}else{
logger.info("Response object not found notification will be stored");
addNotification(message);
}
}
}
Thanks in advance,
Alex

Resources