org.reactivecommons.async.api.HandlerRegistry Maven / Gradle / Ivy
package org.reactivecommons.async.api;
import io.cloudevents.CloudEvent;
import io.cloudevents.core.provider.EventFormatProvider;
import io.cloudevents.jackson.JsonFormat;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.reactivecommons.async.api.handlers.CommandHandler;
import org.reactivecommons.async.api.handlers.EventHandler;
import org.reactivecommons.async.api.handlers.QueryHandler;
import org.reactivecommons.async.api.handlers.QueryHandlerDelegate;
import org.reactivecommons.async.api.handlers.registered.RegisteredCommandHandler;
import org.reactivecommons.async.api.handlers.registered.RegisteredEventListener;
import org.reactivecommons.async.api.handlers.registered.RegisteredQueryHandler;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@Getter
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public class HandlerRegistry {
public static final String DEFAULT_DOMAIN = "app";
private final Map>> domainEventListeners = new ConcurrentHashMap<>();
private final List> dynamicEventHandlers = new CopyOnWriteArrayList<>();
private final List> eventNotificationListener = new CopyOnWriteArrayList<>();
private final List> handlers = new CopyOnWriteArrayList<>();
private final List> commandHandlers = new CopyOnWriteArrayList<>();
public static HandlerRegistry register() {
HandlerRegistry instance = new HandlerRegistry();
instance.domainEventListeners.put(DEFAULT_DOMAIN, new CopyOnWriteArrayList<>());
return instance;
}
public HandlerRegistry listenDomainEvent(String domain, String eventName, EventHandler handler, Class eventClass) {
domainEventListeners.computeIfAbsent(domain, ignored -> new CopyOnWriteArrayList<>())
.add(new RegisteredEventListener<>(eventName, handler, eventClass));
return this;
}
public HandlerRegistry listenEvent(String eventName, EventHandler handler, Class eventClass) {
domainEventListeners.computeIfAbsent(DEFAULT_DOMAIN, ignored -> new CopyOnWriteArrayList<>())
.add(new RegisteredEventListener<>(eventName, handler, eventClass));
return this;
}
public HandlerRegistry listenEvent(String eventName, EventHandler handler) {
return listenEvent(eventName, handler, inferGenericParameterType(handler));
}
public HandlerRegistry listenNotificationEvent(String eventName, EventHandler handler, Class eventClass) {
eventNotificationListener.add(new RegisteredEventListener<>(eventName, handler, eventClass));
return this;
}
public HandlerRegistry handleDynamicEvents(String eventNamePattern, EventHandler handler, Class eventClass) {
dynamicEventHandlers.add(new RegisteredEventListener<>(eventNamePattern, handler, eventClass));
return this;
}
public HandlerRegistry handleDynamicEvents(String eventNamePattern, EventHandler handler) {
return handleDynamicEvents(eventNamePattern, handler, inferGenericParameterType(handler));
}
public HandlerRegistry handleCommand(String commandName, CommandHandler fn, Class commandClass) {
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, commandClass));
return this;
}
public HandlerRegistry handleCommand(String commandName, CommandHandler fn) {
commandHandlers.add(new RegisteredCommandHandler<>(commandName, fn, inferGenericParameterType(fn)));
return this;
}
public HandlerRegistry serveQuery(String resource, QueryHandler handler) {
return serveQuery(resource, handler, inferGenericParameterType(handler));
}
public HandlerRegistry serveQuery(String resource, QueryHandler handler, Class queryClass) {
if(queryClass == CloudEvent.class){
handlers.add(new RegisteredQueryHandler<>(resource, (ignored, message) ->
{
CloudEvent query = EventFormatProvider
.getInstance()
.resolveFormat(JsonFormat.CONTENT_TYPE)
.deserialize(message);
return handler.handle((R) query);
} , byte[].class));
}
else{
handlers.add(new RegisteredQueryHandler<>(resource, (ignored, message) -> handler.handle(message), queryClass));
}
return this;
}
public HandlerRegistry serveQuery(String resource, QueryHandlerDelegate handler, Class queryClass) {
handlers.add(new RegisteredQueryHandler<>(resource, handler, queryClass));
return this;
}
@SuppressWarnings("unchecked")
private Class inferGenericParameterType(QueryHandler handler) {
try {
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
return (Class) genericSuperclass.getActualTypeArguments()[1];
} catch (Exception e) {
throw new RuntimeException("Fail to infer generic Query class, please use serveQuery(path, handler, " +
"class) instead");
}
}
@SuppressWarnings("unchecked")
private Class inferGenericParameterType(CommandHandler handler) {
try {
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
return (Class) genericSuperclass.getActualTypeArguments()[0];
} catch (Exception e) {
throw new RuntimeException("Fail to infer generic Command class, please use handleCommand(path, handler, " +
"class) instead");
}
}
private Class inferGenericParameterType(EventHandler handler) {
try {
ParameterizedType genericSuperclass = (ParameterizedType) handler.getClass().getGenericInterfaces()[0];
return (Class) genericSuperclass.getActualTypeArguments()[0];
} catch (Exception e) {
throw new RuntimeException("Fail to infer generic Query class, please use listenEvent(eventName, handler," +
" class) instead");
}
}
}
© 2015 - 2026 Weber Informatics LLC | Privacy Policy