Using Thread in Sync WireTap - threadpool

I our application we plan to make wire-tap as Async call but we set some login information in the SecurityContext so if we make wire-tap as Async we will loose this data so we plan to go with the Synch Channel for Wire-tap and in the Interceptor class when we log we call a Thread to log the message in the DB.
What may be the impact with this approach is there any Thread poll limit we need to take care or is there any alternative solution for this?
We are using weblogic 12c

Looks like you should take care about SecurityContext propagation (https://jira.spring.io/browse/INT-2166). Please, read all those comments carefully.
You can add that ChannelInterceptor the channel of your wire-tap and that separate thread will get SecurityContext.
For comprehensive answer I'm adding that interceptor code here:
class SecurityContextPropagationChannelInterceptor extends ChannelInterceptorAdapter {
#Override
Message<?> preSend(Message<?> message, MessageChannel channel) {
if (!(channel in AbstractPollableChannel) || message.headers.securityContext || !SecurityContextHolder.context.authentication) return message
return MessageBuilder.fromMessage(message).with {
setHeader 'securityContext', SecurityContextHolder.context
build()
}
}
#Override
Message<?> postReceive(Message<?> message, MessageChannel channel) {
if (channel in AbstractPollableChannel && message.headers.securityContext) {
SecurityContextHolder.context = message.headers.securityContext
}
return message
}
}

Related

Does event_bus consumer support to run Async. method?

I am new for Vert.x async programming. I have event_bus consumer, once it receives a message, then it needs to call a Async. method async_method_to_access_database to get database records from Database. async_method_to_access_database will return a Future. The code looks like following.
Here I have one questions:
Inside event_bus consumer, could it run a Async. method? I doubt whether consumer handler supports to run Async. method? In Vertx, I understand Vertilce contains event loop, it supports Async. method, I am not sure if event_bus consumer handler supports it?
EventBus eb = vertx.eventBus();
MessageConsumer<String> consumer = eb.consumer("my_address");
consumer.handler(message -> {
Future<List<DataRecord>> listFuture = async_method_to_access_database();
listFuture.onSuccess(ar->{
doSomething();
});
});
You can have async code in the handler. The important part to understand that you have two ways of sending messages on the eventbus: request/publish.
With publish you just fire-and-forget
And with request you will register a handler wich waits until the consumer answers the message by calling message.reply().
In both cases your async code in the consumer will be executed, but when you use send, you have the option to have additional logic on the sender side, (e.g: repeat on error, validate response, etc)
EventBus eb = vertx.eventBus();
// sender
eb.request("my_address","testmessage", h -> {
if(h.succeeded()){
System.out.println("successful access to db");
}else{
System.out.println(h.cause());
}
});
// consumer
MessageConsumer<String> consumer = eb.consumer("my_address");
consumer.handler(message -> {
Future<List<DataRecord>> listFuture = async_method_to_access_database();
listFuture.onComplete(ar->{
if (ar.succeeded()) {
message.reply("updated elements successfully" + listFuture.size());
}
message.fail(1,"critical error") // will trigger error in sender
});
});

Google pubsub listener not receiving all the messages

I'm using Google Cloud Storage for storing objects, with the bucket associated to a topic and subscription id. The flow is such that a Java application requests for the upload link(s), and upload object(s) using those upload link(s). I also have a pubsub listener implemented in Java, which receives the upload notification message, and does something on every successful upload. This is the snippet that handles the event listening.
public void eventListener() {
MessageReceiver messageReceiver = (message, consumer) -> {
final Map<String, Object> uploadMetaDataMap = getUploadDataMap(message);
LOGGER.info("Upload event detected => {} ", uploadMetaDataMap);
// do something
consumer.ack();
};
Subscriber subscriber = null;
Subscriber finalSubscriber = subscriber;
/* To ensure that any messages already being handled by receiveMessage run to completion */
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
finalSubscriber.stopAsync().awaitTerminated();
}
});
try {
subscriber = Subscriber.newBuilder(subscription, messageReceiver)
.setCredentialsProvider(FixedCredentialsProvider.create(creds)).build();
subscriber.addListener(new Subscriber.Listener() {
#Override
public void failed(Subscriber.State from, Throwable failure) {
// Handle failure. This is called when the Subscriber encountered a fatal error and is shutting down.
LOGGER.error(String.valueOf(failure));
}
}, MoreExecutors.directExecutor());
subscriber.startAsync().awaitRunning();
subscriber.awaitTerminated();
} finally {
if (subscriber != null) {
subscriber.stopAsync().awaitTerminated();
}
}
}
I'm storing the objects in this format => bucket/uuid/objectName.extension and on every successful upload, LOGGER.info("Upload event detected => {} ", uploadMetaDataMap); logs messages like this
2020-08-03 16:12:14,686 [Gax-1] INFO listener.AsynchronousPull - Upload event detected => {size=85, uuid=6dff9a20-3995-4f28-93e9-79e6c3cf613d, bucket=bucketName}
The issue I'm facing now is, not all the successful upload events send out notification message. I can see the folder structure created in the GCS with the respective object inside it, but notification related to that upload is nowhere to be found in the logs printed by pubsub listener. It's been bothering me for a while now, and could really use some help with this.

How to know who received a message in a MUC room

For my thesis, I am using Smack to log a XMPP network that uses the MUC module.
Another software is currently sending IoT sensor data into different MUC rooms.
I'd like to know for every message sent into a MUC room, which users were in that room at the time of the message. Is this possible? I could use a messageListener to every muc room, however the listener only receives a message as an argument. Therefore I could not know who is logged into the room inside the listener method.
you can get all muc message in StanzaListener in xmpp. Please follow few steps to done this
Step 1. Declare as a global variables
ChatManagerListener chatListener;
Chat chat;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
Step 3. Methods for one to one chat purposer
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
Message msg = new Message();
msg.setTo(JidCreate.bareFrom(jid));
msg.setFrom(XMPP.getInstance().getConnection(acitiviy)
.getUser());
ChatStateExtension ext = new ChatStateExtension(
ChatState.paused);
msg.addExtension(ext);
lastComposing = System.currentTimeMillis();
chat.sendMessage(msg);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
Hope this will help you and if you want more information take a look from here. Thankyou
Nothing prervents you from calling Multi UserCaht.getParticipants() from within the listener. But be warned: If your goal is to determine the other receivers of receivers, then this approach is fragile. I also suggest to think about using PubSub instead of MUC for your IoT use case.

Netty: when does writeAndFlush channel future listener callback get executed?

I am new to netty and trying to understand how the channel future for writeAndFlush works. Consider the following code running on a netty client:
final ChannelFuture writeFuture = abacaChannel.writeAndFlush("Test");
writeFuture.addListener(new ChannelFutureListener() {
#Override
public void operationComplete(ChannelFuture future) throws Exception {
if (writeFuture.isSuccess()) {
LOGGER.debug("Write successful");
} else {
LOGGER.error("Error writing message to Abaca host");
}
}
});
When does this writeFuture operationComplete callback executed?
After netty hands over the data to the OS send buffers (or)
After the OS writes the data to the network socket. (or)
After this data is actually received by the server.
TIA
1. After netty hands over the data to the OS send buffers (or)
Listener will be notified after data is removed from ChannelOutboundBuffer (netty's send buffer)

GWT RequestFactory : Send a request in ClosingHandler

I'm developping an audit service for a GWT-based application with the RequestFactory framework. I have some trouble to audit the user logout using a ClosingHandler. Here's my code:
A sum up of my audit service:
private static final int MAX_CACHE_SIZE = 15;
private int cacheSize = 0;
private AuditServiceRequestContext context;
#Override
public void audit(String event, String details) {
if (context == null)
context = createContext();
AuditServiceRequestContext cxt = createContext();
context.append(cxt);
AuditProxy proxy = cxt.create(AuditProxy.class);
/* intialize the proxy with event and details */
cxt.persist(proxy);
if (++cacheSize >= MAX_CACHE_SIZE)
flush();
}
public void flush() {
context.fire();
cacheSize = 0;
context = null;
}
How I currently handle the log out event:
Window.addWindowClosingHandler(new ClosingHandler() {
#Override
public void onWindowClosing(ClosingEvent event) {
audit.audit("logout", "the user has closed the app");
audit.flush();
}
});
The data are persisted but the request fails because of the HTTP request on /gwtRequest doesn't return any response (status canceled on the chrome's developer tools).
Any idea to solve this issue ?
EDIT:
Strangely, there is no error using a CloseHandler with Window#addCloseHandler(CloseHandler). Don't understand why, but it works (and if someone can explain it to me, I really enjoy) :D
When you're navigating away from the page, the browser cancels ongoing requests. Because you make yours at window closing, you cannot even be sure the request was sent over the wire and reached your server. There's no workaround.
One possibility, but which is likely to fail too, is to open a new window so you can safely make requests there, and then close that window when you're done. It's likely to fail however as such windows are likely to be blocked by browsers' popup blockers (built-in or addons).