Skip to content
This repository was archived by the owner on Dec 7, 2018. It is now read-only.

Commit 67ed500

Browse files
authored
Merge pull request #59 from AxonFramework/interceptor-examples
Added code samples for command interceptors.
2 parents 7b15834 + 2573af5 commit 67ed500

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

part-iii-infrastructure-components/command-dispatching.md

+57
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,33 @@ There are different types of interceptors: Dispatch Interceptors and Handler Int
158158

159159
Message Dispatch Interceptors are invoked when a command is dispatched on a Command Bus. They have the ability to alter the Command Message, by adding Meta Data, for example, or block the command by throwing an Exception. These interceptors are always invoked on the thread that dispatches the Command.
160160

161+
Let's create a Message Dispatch Interceptor which logs each command message being dispatched on a `CommandBus`.
162+
```java
163+
public class MyCommandDispatchInterceptor implements MessageDispatchInterceptor<CommandMessage<?>> {
164+
165+
private static final Logger LOGGER = LoggerFactory.getLogger(MyCommandDispatchInterceptor.class);
166+
167+
@Override
168+
public BiFunction<Integer, CommandMessage<?>, CommandMessage<?>> handle(List<? extends CommandMessage<?>> messages) {
169+
return (index, command) -> {
170+
LOGGER.info("Dispatching a command {}.", command);
171+
return command;
172+
};
173+
}
174+
}
175+
```
176+
We can register this dispatch interceptor with a `CommandBus` by doing the following:
177+
```java
178+
public class CommandBusConfiguration {
179+
180+
public CommandBus configureCommandBus() {
181+
CommandBus commandBus = new SimpleCommandBus();
182+
commandBus.registerDispatchInterceptor(new MyCommandDispatchInterceptor());
183+
return commandBus;
184+
}
185+
}
186+
```
187+
161188
#### Structural validation
162189

163190
There is no point in processing a command if it does not contain all required information in the correct format. In fact, a command that lacks information should be blocked as early as possible, preferably even before any transaction is started. Therefore, an interceptor should check all incoming commands for the availability of such information. This is called structural validation.
@@ -180,6 +207,36 @@ Unlike Dispatch Interceptors, Handler Interceptors are invoked in the context of
180207

181208
Handler Interceptors are also typically used to manage transactions around the handling of a command. To do so, register a `TransactionManagingInterceptor`, which in turn is configured with a `TransactionManager` to start and commit \(or roll back\) the actual transaction.
182209

210+
Let's create a Message Handler Interceptor which will only allow the handling of commands that contain `axonUser` as a value for the `userId` field in the `MetaData`. If the `userId` is not present in the meta-data, an exception will be thrown which will prevent the command from being handled. And if the `userId`'s value does not match `axonUser`, we will also not proceed up the chain.
211+
212+
```java
213+
public class MyCommandHandlerInterceptor implements MessageHandlerInterceptor<CommandMessage<?>> {
214+
215+
@Override
216+
public Object handle(UnitOfWork<? extends CommandMessage<?>> unitOfWork, InterceptorChain interceptorChain) throws Exception {
217+
CommandMessage<?> command = unitOfWork.getMessage();
218+
String userId = Optional.ofNullable(command.getMetaData().get("userId"))
219+
.map(uId -> (String) uId)
220+
.orElseThrow(IllegalCommandException::new);
221+
if ("axonUser".equals(userId)) {
222+
return interceptorChain.proceed();
223+
}
224+
return null;
225+
}
226+
}
227+
```
228+
We can register the handler interceptor with a `CommandBus` like so:
229+
```java
230+
public class CommandBusConfiguration {
231+
232+
public CommandBus configureCommandBus() {
233+
CommandBus commandBus = new SimpleCommandBus();
234+
commandBus.registerHandlerInterceptor(new MyCommandHandlerInterceptor());
235+
return commandBus;
236+
}
237+
}
238+
```
239+
183240
## Distributing the Command Bus
184241

185242
The CommandBus implementations described in earlier only allow Command Messages to be dispatched within a single JVM. Sometimes, you want multiple instances of Command Buses in different JVMs to act as one. Commands dispatched on one JVM's Command Bus should be seamlessly transported to a Command Handler in another JVM while sending back any results.

0 commit comments

Comments
 (0)