In Akka how do you know which request timed out? - timeout

This is how a callback is assigned for failure
future.onFailure(new FailureHandler(), context().system().dispatcher());
In the method FailureHandler()
public final class FailureHandler extends OnFailure {
public void onFailure(Throwable throwable) throws Throwable {
System.out.println(throwable.toString());
}
}
I can't figure out a way to find out which request failed. This is a common requirement and I believe I am missing something trivial.

It was trivial indeed, need to declare a class level variable to hold the transactionId onFailure
public final class FailureHandler extends OnFailure {
String transactionId;
public FailureHandler(String transactionId){
this.transactionId = transactionId;
}
#Override
public void onFailure(Throwable throwable) throws Throwable {
logger.error(transactionId + " failed");
}
}

Related

Vaadin 23 override internal error message

when an error occurs inside the application, the user sees the following message:
Is it possible to override it?
I aaded the following:
public class CustomErrorHandler implements ErrorHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);
#Override
public void error(ErrorEvent errorEvent) {
logger.error("Something wrong happened", errorEvent.getThrowable());
Notification.show("An internal error has occurred. Please contact support.");
if (UI.getCurrent() != null) {
UI.getCurrent().access(() -> {
Notification.show("An internal error has occurred. Please contact support.");
});
}
}
}
#Component
public class ServiceListener implements VaadinServiceInitListener {
private static final Logger logger = LoggerFactory.getLogger(LanguageReceiver.class);
#Override
public void serviceInit(ServiceInitEvent event) {
event.getSource().addSessionInitListener(
initEvent -> {
logger.info("A new Session has been initialized!");
VaadinSession.getCurrent().setErrorHandler(new CustomErrorHandler());
});
event.getSource().addUIInitListener(
initEvent -> logger.info("A new UI has been initialized!"));
}
}
#ParentLayout(MainLayout.class)
#AnonymousAllowed
public class ExceptionHandler extends VerticalLayout implements HasErrorParameter<Exception> {
static final Logger logger = LoggerFactory.getLogger(ExceptionHandler.class);
#Override
public int setErrorParameter(BeforeEnterEvent event, ErrorParameter<Exception> parameter) {
logger.error("Error", parameter.getException());
Label label = new Label(parameter.getException().getMessage());
add(label);
return HttpServletResponse.SC_NOT_FOUND;
}
}
but still unable to override the mentioned error on the screenshot above. Please show how to do this.
Generally, you need to extend SystemMessages and override getInternalErrorMessage().
Then you can register it using:
YourSystemMessages sysMessages = new YourSystemMessages();
VaadinService.getCurrent().setSystemMessagesProvider(systemMessagesInfo -> sysMessages);
and if you want to reset it to the default one:
VaadinService.getCurrent().setSystemMessagesProvider(DefaultSystemMessagesProvider.get());
In a Spring Boot based application you can register it in any implementation of VaadinServiceInitListener such as:
#Component
public class CustomSystemMessagesInitializer implements VaadinServiceInitListener {
#Autowired
private YourSystemMessages sysMessages;
// You can provide your SystemMessages instance in any way that suits you.
#Override
public void serviceInit(ServiceInitEvent serviceInitEvent) {
serviceInitEvent.getSource()
.setSystemMessagesProvider(systemMessagesInfo -> sysMessages);
}
}
Note that serviceInitEvent.getSource() returns the VaadinService instance, so it can be used as the reference as an alternative to VaadinService.getCurrent.

How to access ReactiveSecurityContextHolder from ExceptionResolver?

I understand that in order to keep the context, the reactive chain of methods must not be broken. However, I need to get access to the context from the ExceptionResolver (after an exception has been thrown.)
My exception resolver is extending AbstractErrorWebExceptionHandler and when I try to get the context via ReactiveSecurityContextHolder.getContext() it returns empty. Obviously because the reactive chain has been broken.
How can I get access to the authentication object?
You can get access to the authentication object by overriding the handle method:
public class TestHandler extends AbstractErrorWebExceptionHandler {
public TestHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
ApplicationContext applicationContext) {
super(errorAttributes, resourceProperties, applicationContext);
}
#Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return null;
}
#Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
Mono<Principal> authObject = exchange.getPrincipal();
//Handle exception here
return exchange.getResponse().setComplete();
}
}
Another approach is to implement the ErrorWebExceptionHandler directly:
public class TestHandler implements ErrorWebExceptionHandler {
#Override
public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) {
Mono<Principal> authObject = serverWebExchange.getPrincipal();
//Handle exception here
return serverWebExchange.getResponse().setComplete();
}
}

Vaadin 7 : RPC call from Server to Client

I would like to create custom image component .So I followed step by step from Integrating with Server-side. For basic or first-step , I created for the test Server to Client RPC call as following steps.
MyComponentWidget.java
public class MyComponentWidget extends HTML {
public MyComponentWidget() {
getElement().setAttribute("class", "thumbnail");
}
public final void createCustomImage(final String url) {
getElement().setInnerHTML("<div class='delete-block'></div><img src=" + url + " />");
}
}
MyComponentState.java
public class MyComponentState extends AbstractComponentState {
private String url;
private String html;
public final String getUrl() {
return url;
}
public final void setUrl(final String url) {
this.url = url;
}
public final String getHtml() {
return html;
}
public final void setHtml(final String html) {
this.html = html;
}
}
MyComponentConnector.java
public class MyComponentConnector extends AbstractComponentConnector {
public MyComponentConnector() {
registerRpc(MyComponentClientRpc.class, new MyComponentClientRpc() {
#Override
public void getMessage() {
// never reach to this place
System.err.println("Reach Here !");
getState().setHtml(getWidget().getHTML());
}
});
}
#Override
public final MyComponentWidget getWidget() {
return (MyComponentWidget) super.getWidget();
}
#Override
public final MyComponentState getState() {
return (MyComponentState) super.getState();
}
#OnStateChange("url")
final void updateText() {
getWidget().createCustomImage(getState().getUrl());
}
}
MyComponentClientRpc.java
import com.vaadin.shared.communication.ClientRpc;
public interface MyComponentClientRpc extends ClientRpc {
void getMessage();
}
MyComponent.java
public class MyComponent extends AbstractComponent {
public MyComponent(final String url) {
getState().setUrl(url);
}
public final MyComponentState getState() {
return (MyComponentState) super.getState();
}
public final String getHTML() {
getRpcProxy(MyComponentClientRpc.class).getMessage();
return getState().getHtml();
}
}
and call as
MyComponent image = new MyComponent("myImageUrl");
System.out.println(image.getHTML());
My problem is why I always get null value at my console ? I can see the image at browser but System.out.println(image.getHTML()); produces null. What am I missing ?
To make a rpc call from client to server, you must extend the ServerRpc interface, for example:
package com.example.client.MyServerRpc
public interface MyServerRpc extends com.vaadin.shared.communication.ServerRpc {
void sendHTML(String html);
}
In your connector your register the rpc:
private MyServerRpc rpc = RpcProxy.create(MyServerRpc.class, this);
And then you can send a value by using the registered rpc in your connector:
rpc.sendHTML(html);
To receive the value on your component's or extension's server-side class, you must create an instance of the rpc interface:
private MyServerRpc rpc = new MyServerRpc() {
#Override
public void sendHTML(String html) {
// this method will be called!
}
};
and register that in the constructor:
registerRpc(rpc);
After these steps RPC from client to server should work.

Message routing/handling with custom annotations and CDI injection

I have a Java EE 6 web application and use the WebSocket protocol to communicate with browsers. The browser can send various types of messages and in the servers onMessage method I would like to route (or dispatch) the message to a specific message handler class depending on the message type. I would like to configure or register these message handlers via annotations, similar to the mechanism of servlets (#WebServlet("/there")). And like in servlets, I would like to be able to use CDI injection in the message handlers.
For now I have a MessageType annotation, a MessageHandler interface and 3 implementations.
#Documented
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface MessageType
{
String value();
}
public interface MessageHandler
{
public void processMessage(String inputMesssage);
}
#MessageType("first")
public class FirstMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
System.out.println("FirstMessageHandler#processMessage: " + inputMesssage);
System.out.println("InjectionTest: " + resourceBundleProvider.getValue("label.language"));
}
}
#MessageType("second")
public class SecondMessageHandler implements MessageHandler
{
#Override
public void processMessage(String inputMesssage)
{
System.out.println("SecondMessageHandler#processMessage: " + inputMesssage);
}
}
public class DefaultMessageHandler implements MessageHandler
{
#Override
public void processMessage(String inputMesssage)
{
System.out.println("DefaultMessageHandler#processMessage: " + inputMesssage);
}
}
I also have a class MessageDispatcher which uses reflections to scan the classpath for the annotated message handlers, instantiates them and puts them into a map:
#ApplicationScoped
public class MessageDispatcher
{
private Map<String, MessageHandler> messageHandlerMap = new HashMap<String, MessageHandler>();
#Inject
DefaultMessageHandler defaultMessageHandler;
public MessageDispatcher()
{
registerAnnotatedHandlers();
}
private void registerAnnotatedHandlers()
{
Reflections reflections = new Reflections("namespace");
try
{
for (Class<?> annotatedClass : reflections.getTypesAnnotatedWith(MessageType.class))
{
String annotationValue = annotatedClass.getAnnotation(MessageType.class).value();
for (Class<?> interfaceClass : annotatedClass.getInterfaces())
if (!annotationValue.isEmpty() && interfaceClass.equals(MessageHandler.class))
messageHandlerMap.put(annotationValue, (MessageHandler) annotatedClass.newInstance());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public MessageHandler getMessageHandler(String key)
{
MessageHandler messageHandler = messageHandlerMap.get(key);
return messageHandler != null ? messageHandler : defaultMessageHandler;
}
}
And finally in my websocket servlet's onMessage method I extract the key from the inbound message and use it for the message routing:
public synchronized void onMessage(String data)
{
String[] message = data.split(":");
// Choose the message handler from the message
MessageHandler messageHandler = messageDispatcher.getMessageHandler(message[0]);
// Process the message by the message handler
messageHandler.processMessage(message[1]);
}
My 3 incoming sample messages are:
"first:Message to handle with FirstMessageHandler"
"second:Message to handle with SecondMessageHandler"
"third:Message to handle with DefaultMessageHandler"
This works fine, The first and second messages are processed by FirstMessageHandler and SecondMessageHandler respectively. The third message is processed by the default message handler since there is no other handler registered for handling the key "third".
My Problem: I cannot use injection in the message handlers because they are created using Java reflection. Does anybody know how to get annotation processing and CDI injection 'married'? Or does anybody think this approach is bullshit and has another solution for that?
Best Regards
Sebastian
This is my final approach:
I spend a PostConstruct method to my MessageDispachter where I look for all message handler beans. For each of these beans I get their annotation value and a reference to the bean (which also includes creation of the bean). Then I store both, the annotation value and the bean reference into my messageHandlerMap. There is a lot of CDI delegating and interception involved, but it works:
public class MessageDispatcher
{
private Map<String, MessageHandler> messageHandlerMap = new HashMap<String, MessageHandler>();
#Inject
DefaultMessageHandler defaultMessageHandler;
#Inject
BeanManager beanManager;
#PostConstruct
public void registerHandlers()
{
Set<Bean<?>> messageHandlerBeans = beanManager.getBeans(MessageHandler.class, new MessageTypeLiteral());
for (Bean<?> bean : messageHandlerBeans)
{
String key = bean.getBeanClass().getAnnotation(MessageType.class).value();
if (!key.isEmpty())
{
CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
MessageHandler messageHandler = (MessageHandler) beanManager.getReference(bean, MessageHandler.class, creationalContext);
messageHandlerMap.put(key, messageHandler);
}
}
}
public MessageHandler getMessageHandler(String key)
{
MessageHandler messageHandler = (MessageHandler) messageHandlerMap.get(key);
return messageHandler != null ? messageHandler : defaultMessageHandler;
}
}
#Documented
#Qualifier
#Retention(RUNTIME)
#Target({TYPE, METHOD, FIELD, PARAMETER})
public #interface MessageType
{
#Nonbinding
String value();
}
#SuppressWarnings("all")
public class MessageTypeLiteral extends AnnotationLiteral<MessageType> implements MessageType
{
private static final long serialVersionUID = 1L;
#Override
public String value()
{
return "";
}
}
public class DefaultMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
...
#MessageType("first")
public class FirstMessageHandler implements MessageHandler
{
#Inject
ResourceBundleProvider resourceBundleProvider;
#Override
public void processMessage(String inputMesssage)
{
...
The #NonBinding annotation in the #MessageType annotation seems to be important to find all beans annotated with #MessageType("xxx") independent of the actual annotation value (here: xxx).
I hope this explains the important things. For further details please ask me
Sebastian
I think your simplest solution to this would be to keep what you have, strip out the scanning because you don't need it, change your annotation to be a qualifier and fire a CDI event with the qualifier (you'll need to create an AnnotationLiteral for each of three different qualifiers because the value is binding) and the message as the payload.
I can explain more if you need it.
See and adjust Dynamically fire CDI event with qualifier with members
It is a CDI way for dynamic runtime selecting services by runtime decision. The TypeEnum can also be a String.

SMACK: how do I listen for user availability status changes?

How do I subscribe to listen to user availability status changes in SMACK?
To get the availability status for a user I use the following:
XMPPConnection.getRoster().getPresence(name).isAvailable();
But how can I subscribe so I receive some notifications whenever the status changes? (So I don't have to poll).
You set up a listener for Roster and Presence changes.
this code may help you :
roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {
System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
}
#Override
public void entriesAdded(Collection<String> arg0) {
// TODO Auto-generated method stub
}
});
roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {
Log.e(TAG, presence.getStatus());
Log.e(TAG,presence.getFrom());
Log.e(TAG, presence.getLanguage());
Log.e(TAG,presence.getDefaultLanguage());
Log.e(TAG, presence.getType().toString());
}
#Override
public void entriesAdded(Collection<String> arg0) {
// TODO Auto-generated method stub
}
});

Resources