Skip to content

Commit

Permalink
Adjust SimpleEventHandlerInvoker#eventHandlers
Browse files Browse the repository at this point in the history
We should adjust the SimpleEventHandlerInvoker#eventHandlers to return
EventMessageHandlers directly. Doing so enables the
DeadLetteringEventHandlerInvoker to retrieve these directly and use in
the evaluation runnable. Added, we should validate the builder
adjustments work as expected.

#2021
  • Loading branch information
smcvb committed Jan 31, 2022
1 parent f5ce575 commit 6241e5a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2021. Axon Framework
* Copyright (c) 2010-2022. Axon Framework
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,11 +16,13 @@

package org.axonframework.config;

import org.axonframework.common.ReflectionUtils;
import org.axonframework.common.Registration;
import org.axonframework.common.transaction.NoTransactionManager;
import org.axonframework.common.transaction.Transaction;
import org.axonframework.common.transaction.TransactionManager;
import org.axonframework.eventhandling.AbstractEventProcessor;
import org.axonframework.eventhandling.AnnotationEventHandlerAdapter;
import org.axonframework.eventhandling.ErrorContext;
import org.axonframework.eventhandling.ErrorHandler;
import org.axonframework.eventhandling.EventHandler;
Expand Down Expand Up @@ -70,6 +72,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.axonframework.common.ReflectionUtils.getFieldValue;
import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -1123,10 +1126,20 @@ public EventHandlerInvoker getEventHandlerInvoker() {
}

public List<?> getEventHandlers() {
return ((SimpleEventHandlerInvoker) ((MultiEventHandlerInvoker) getEventHandlerInvoker())
.delegates()
.get(0))
.eventHandlers();
List<EventHandlerInvoker> invokers = ((MultiEventHandlerInvoker) getEventHandlerInvoker()).delegates();
return ((SimpleEventHandlerInvoker) invokers.get(0))
.eventHandlers()
.stream()
.map(eventHandlingComponent -> {
try {
Field handlerField =
AnnotationEventHandlerAdapter.class.getDeclaredField("annotatedEventListener");
return ReflectionUtils.getFieldValue(handlerField, eventHandlingComponent);
} catch (NoSuchFieldException e) {
return null;
}
})
.collect(Collectors.toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@
*/
public class SimpleEventHandlerInvoker implements EventHandlerInvoker {

private final List<?> eventHandlers;
private final List<EventMessageHandler> wrappedEventHandlers;
private final List<EventMessageHandler> eventHandlingComponents;
private final ListenerInvocationErrorHandler listenerInvocationErrorHandler;
private final SequencingPolicy<? super EventMessage<?>> sequencingPolicy;

Expand All @@ -58,14 +57,13 @@ public class SimpleEventHandlerInvoker implements EventHandlerInvoker {
*/
protected SimpleEventHandlerInvoker(Builder<?> builder) {
builder.validate();
this.eventHandlers = builder.eventHandlers;
this.wrappedEventHandlers =
eventHandlers.stream()
.map(handler -> handler instanceof EventMessageHandler
? (EventMessageHandler) handler
: builder.wrapEventMessageHandler(handler)
)
.collect(Collectors.toCollection(ArrayList::new));
this.eventHandlingComponents =
builder.eventHandlers.stream()
.map(handler -> handler instanceof EventMessageHandler
? (EventMessageHandler) handler
: builder.wrapEventMessageHandler(handler)
)
.collect(Collectors.toCollection(ArrayList::new));
this.sequencingPolicy = builder.sequencingPolicy;
this.listenerInvocationErrorHandler = builder.listenerInvocationErrorHandler;
}
Expand Down Expand Up @@ -97,12 +95,13 @@ public static Builder<?> builder() {
}

/**
* Gets the list of Event Handler delegates. This delegates are the end point of event handling.
* Gets the list of {@link EventMessageHandler} delegates in this invoker. These delegates are the end point of
* event handling.
*
* @return the list of Event Handler delegates
* @return The list of {@link EventMessageHandler} delegates.
*/
public List<?> eventHandlers() {
return Collections.unmodifiableList(eventHandlers);
public List<EventMessageHandler> eventHandlers() {
return Collections.unmodifiableList(eventHandlingComponents);
}

@Override
Expand All @@ -122,7 +121,7 @@ protected Object sequenceIdentifier(EventMessage<?> event) {
}

protected void invokeHandlers(EventMessage<?> message) throws Exception {
for (EventMessageHandler handler : wrappedEventHandlers) {
for (EventMessageHandler handler : eventHandlingComponents) {
try {
handler.handle(message);
} catch (Exception e) {
Expand All @@ -138,11 +137,11 @@ public boolean canHandle(EventMessage<?> eventMessage, Segment segment) {

@Override
public boolean canHandleType(Class<?> payloadType) {
return wrappedEventHandlers.stream().anyMatch(eh -> eh.canHandleType(payloadType));
return eventHandlingComponents.stream().anyMatch(eh -> eh.canHandleType(payloadType));
}

private boolean hasHandler(EventMessage<?> eventMessage) {
for (EventMessageHandler eventHandler : wrappedEventHandlers) {
for (EventMessageHandler eventHandler : eventHandlingComponents) {
if (eventHandler.canHandle(eventMessage)) {
return true;
}
Expand All @@ -152,7 +151,7 @@ private boolean hasHandler(EventMessage<?> eventMessage) {

@Override
public boolean supportsReset() {
for (EventMessageHandler eventHandler : wrappedEventHandlers) {
for (EventMessageHandler eventHandler : eventHandlingComponents) {
if (!eventHandler.supportsReset()) {
return false;
}
Expand All @@ -167,7 +166,7 @@ public void performReset() {

@Override
public <R> void performReset(R resetContext) {
for (EventMessageHandler eventHandler : wrappedEventHandlers) {
for (EventMessageHandler eventHandler : eventHandlingComponents) {
eventHandler.prepareReset(resetContext);
}
}
Expand Down Expand Up @@ -207,7 +206,7 @@ public static class Builder<B extends Builder<?>> {

/**
* Sets the {@code eventHandlers} this {@link EventHandlerInvoker} will forward all its events to. If an event
* handler is assignable to {@link EventMessageHandler} it will registered as is. If not, it will be wrapped by
* handler is assignable to {@link EventMessageHandler} it will register as is. If not, it will be wrapped by
* a new {@link AnnotationEventHandlerAdapter}.
*
* @param eventHandlers an array of {@link Object}s which can handle events
Expand All @@ -219,14 +218,16 @@ public B eventHandlers(Object... eventHandlers) {

/**
* Sets the {@code eventHandlers} this {@link EventHandlerInvoker} will forward all its events to. If an event
* handler is assignable to {@link EventMessageHandler} it will registered as is. If not, it will be wrapped by
* handler is assignable to {@link EventMessageHandler} it will register as is. If not, it will be wrapped by
* a new {@link AnnotationEventHandlerAdapter}.
*
* @param eventHandlers a {@link List} of {@link Object}s which can handle events
* @return the current Builder instance, for fluent interfacing
*/
public B eventHandlers(List<?> eventHandlers) {
assertThat(eventHandlers, list -> !list.isEmpty(), "At least one EventMessageHandler should be provided");
assertThat(eventHandlers,
list -> list != null && !list.isEmpty(),
"At least one EventMessageHandler should be provided");
this.eventHandlers = eventHandlers;
//noinspection unchecked
return (B) this;
Expand Down Expand Up @@ -292,7 +293,7 @@ public B listenerInvocationErrorHandler(ListenerInvocationErrorHandler listenerI
* @return the current Builder instance, for fluent interfacing
*/
public B sequencingPolicy(SequencingPolicy<? super EventMessage<?>> sequencingPolicy) {
assertNonNull(sequencingPolicy, "{} may not be null");
assertNonNull(sequencingPolicy, "The SequencingPolicy may not be null");
this.sequencingPolicy = sequencingPolicy;
//noinspection unchecked
return (B) this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

package org.axonframework.eventhandling;

import org.axonframework.common.AxonConfigurationException;
import org.junit.jupiter.api.*;
import org.mockito.*;

import java.util.Collections;
import java.util.List;

import static org.axonframework.utils.EventTestUtils.createEvent;
import static org.axonframework.utils.EventTestUtils.createEvents;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

/**
Expand Down Expand Up @@ -93,4 +96,53 @@ void testPerformResetWithResetContext() {
verify(mockHandler1).prepareReset(eq(resetContext));
verify(mockHandler2).prepareReset(eq(resetContext));
}

@Test
void testBuildWithNullEventHandlersListThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.eventHandlers((List<?>) null));
}

@Test
void testBuildWithEmptyEventHandlersListThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.eventHandlers(Collections.emptyList()));
}

@Test
void testBuildWithoutEventHandlersListThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, builderTestSubject::build);
}

@Test
void testBuildWithNullParameterResolverFactoryThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.parameterResolverFactory(null));
}

@Test
void testBuildWithNullHandlerDefinitionThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.handlerDefinition(null));
}

@Test
void testBuildWithNullListenerInvocationErrorHandlerThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.listenerInvocationErrorHandler(null));
}

@Test
void testBuildWithNullSequencingPolicyThrowsAxonConfigurationException() {
SimpleEventHandlerInvoker.Builder<?> builderTestSubject = SimpleEventHandlerInvoker.builder();

assertThrows(AxonConfigurationException.class, () -> builderTestSubject.sequencingPolicy(null));
}
}

0 comments on commit 6241e5a

Please sign in to comment.