/
2-architecture-overview.xml
248 lines (247 loc) · 16.1 KB
/
2-architecture-overview.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2010-2014. Axon Framework
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<chapter xml:id="architecture-overview" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>Technical Overview</title>
<sect1>
<title>Architectural Overview</title>
<para>CQRS on itself is a very simple pattern. It only describes that the component of an
application that processes commands should be separated from the component that
processes queries. Although this separation is very simple on itself, it provides a
number of very powerful features when combined with other patterns. Axon provides the
building block that make it easier to implement the different patterns that can be used
in combination with CQRS. </para>
<para>The diagram below shows an example of an extended layout of a CQRS-based event driven
architecture. The UI component, displayed on the left, interacts with the rest of the
application in two ways: it sends commands to the application (shown in the top
section), and it queries the application for information (shown in the bottom section). </para>
<figure>
<title>Architecture overview of a CQRS application</title>
<mediaobject>
<imageobject role="fo">
<imagedata align="center" format="svg"
fileref="detailed-architecture-overview.svg" width="15cm"/>
</imageobject>
<imageobject role="html">
<imagedata format="png" fileref="detailed-architecture-overview.png"/>
</imageobject>
</mediaobject>
</figure>
<simplesect>
<title>Command Handling</title>
<para>Commands are typically represented by simple and straightforward objects that
contain all data necessary for a command handler to execute it. A command expresses
its intent by its name. In Java terms, that means the class name is used to figure
out what needs to be done, and the fields of the command provide the information
required to do it. </para>
<para>The Command Bus receives commands and routes them to the Command Handlers. Each
command handler responds to a specific type of command and executes logic based on
the contents of the command. In some cases, however, you would also want to execute
logic regardless of the actual type of command, such as validation, logging or
authorization. </para>
<para>Axon provides building blocks to help you implement a command handling
infrastructure with these features. These building blocks are thoroughly described
in <xref linkend="command-handling"/>. </para>
</simplesect>
<simplesect>
<title>Domain Modeling</title>
<para>The command handler retrieves domain objects (Aggregates) from a repository and
executes methods on them to change their state. These aggregates typically contain
the actual business logic and are therefore responsible for guarding their own
invariants. The state changes of aggregates result in the generation of Domain
Events. Both the Domain Events and the Aggregates form the domain model. Axon
provides supporting classes to help you build a domain model. They are described in
<xref linkend="domain-modeling"/>. </para>
</simplesect>
<simplesect>
<title>Repositories and Event Stores</title>
<para>Repositories are responsible for providing access to aggregates. Typically, these
repositories are optimized for lookup of an aggregate by its unique identifier only.
Some repositories will store the state of the aggregate itself (using Object
Relational Mapping, for example), while other store the state changes that the
aggregate has gone through in an Event Store. The repository is also responsible for
persisting the changes made to aggregates in its backing storage. </para>
<para>Axon provides support for both the direct way of persisting aggregates (using
object-relational-mapping, for example) and for event sourcing. More about
repositories and event stores can be found in <xref
linkend="repositories-and-event-stores"/>. </para>
</simplesect>
<simplesect>
<title>Event Processing </title>
<para>The event bus dispatches events to all interested event listeners. This can either
be done synchronously or asynchronously. Asynchronous event dispatching allows the
command execution to return and hand over control to the user, while the events are
being dispatched and processed in the background. Not having to wait for event
processing to complete makes an application more responsive. Synchronous event
processing, on the other hand, is simpler and is a sensible default. Synchronous
processing also allows several event listeners to process events within the same
transaction. </para>
<para>Event listeners receive events and handle them. Some handlers will update data
sources used for querying while others send messages to external systems. As you
might notice, the command handlers are completely unaware of the components that are
interested in the changes they make. This means that it is very non-intrusive to
extend the application with new functionality. All you need to do is add another
event listener. The events loosely couple all components in your application
together. </para>
<para>In some cases, event processing requires new commands to be sent to the
application. An example of this is when an order is received. This could mean the
customer's account should be debited with the amount of the purchase, and shipping
must be told to prepare a shipment of the purchased goods. In many applications,
logic will become more complicated than this: what if the customer didn't pay in
time? Will you send the shipment right away, or await payment first? The saga is the
CQRS concept responsible for managing these complex business transactions. </para>
<para>The building blocks related to event handling and dispatching are explained in
<xref linkend="event-processing"/>. Sagas are thoroughly explained in <xref
xmlns:xlink="http://www.w3.org/1999/xlink" linkend="sagas"/>.</para>
</simplesect>
<simplesect>
<title>Querying for data</title>
<para>The thin data layer in between the user interface and the data sources provides a
clearly defined interface to the actual query implementation used. This data layer
typically returns read-only DTO objects containing query results. The contents of
these DTOs are typically driven by the needs of the User Interface. In most cases,
they map directly to a specific view in the UI (also referred to as table-per-view). </para>
<para>Axon does not provide any building blocks for this part of the application. The
main reason is that this is very straightforward and doesn't differ from the layered
architecture.</para>
</simplesect>
</sect1>
<sect1>
<title>Axon Module Structure</title>
<para>Axon Framework consists of a number of modules that target specific problem areas of
CQRS. Depending on the exact needs of your project, you will need to include one or more
of these modules.</para>
<para>As of Axon 2.1, all modules are OSGi compatible bundles. This means they contain the
required headers in the manifest file and declare the packages they import and export.
At the moment, only the Slf4J bundle (1.7.0 <= version < 2.0.0) is required. All
other imports are marked as optional, although you're very likely to need others, like
<code>org.joda.time</code>.</para>
<sect2>
<title>Main modules</title>
<para>Axon's main modules are the modules that have been thoroughly tested and are
robust enough to use in demanding production environments. The maven groupId of all
these modules is <code>org.axonframework</code>.</para>
<simplesect>
<title>Axon Core</title>
<para>The Core module contains, as the name suggests, the Core components of Axon.
If you use a single-node setup, this module is likely to provide all the
components you need. All other Axon modules depend on this module, so it must
always be available on the classpath.</para>
</simplesect>
<simplesect>
<title>Axon Test</title>
<para>The Test modules contains test fixtures that you can use to test Axon based
components, such as your Command Handlers, Aggregates and Sagas. You typically
do not need this module at runtime and will only need to be added to the
classpath during tests.</para>
</simplesect>
<simplesect>
<title>Axon Distributed CommandBus</title>
<para>The Distributed CommandBus modules contains a CommandBus implementation that
can be used to distribute commands over multiple nodes. It comes with a
JGroupsConnector that is used to connect DistributedCommandBus implementation on
these nodes.</para>
</simplesect>
<simplesect>
<title>Axon AMQP</title>
<para>The AMQP module provides components that allow you to build up an EventBus
using an AMQP-based message broker as distribution mechanism. This allows for
guaranteed-delivery, even when the Event Handler node is temporarily
unavailable.</para>
</simplesect>
<simplesect>
<title>Axon Integration</title>
<para>The Integration module allows Axon components to be connected to Spring
Integration channels. It provides an implementation for the EventBus that uses
Spring Integration channels to distribute events as well as a connector to
connect another EventBus to a Spring Integration channel.</para>
</simplesect>
<simplesect>
<title>Axon Mongo</title>
<para>MongoDB is a document based NoSQL database. The Mongo module provides an
EventStore implementation that stores event streams in a MongoDB
database.</para>
</simplesect>
<simplesect>
<title>Axon Monitoring JMX</title>
<para>Several AxonFramework components provide monitoring information. This module
publishes that information over JMX. There is no configuration involved. If this
module is on the classpath, statistics and monitoring information is
automatically published over JMX.</para>
</simplesect>
</sect2>
<sect2>
<title>Incubator modules</title>
<para>Incubator modules have not undergone the same amount of testing as the main
modules, are not as well documented, and may therefore not be suitable for demanding
production environments. They are typically work-in-progress and may have some
"rough edges". Use these modules at your own peril.</para>
<para>The maven groupId for incubator modules is
<code>org.axonframework.incubator</code>.</para>
<simplesect>
<title>Axon Cassandra</title>
<para>This module aims to provide an implementation of the EventStore that uses
Cassandra as backing storage.</para>
</simplesect>
<simplesect>
<title>Axon Google App Engine</title>
<para>The Google App Engine modules provides building blocks that use specific APIs
provided by GAE, such as an Event Store that uses the DatastoreService and a
special XStream based serializer that works around some of the limitations of
the GAE platform.</para>
</simplesect>
<simplesect>
<title>Axon Redis</title>
<para>Redis is a key-value based NoSQL store with very high performance
characteristics. This module aims to provide an implementation of the EventStore
that uses Redis as backing storage.</para>
</simplesect>
</sect2>
</sect1>
<sect1>
<title>Working with Axon APIs</title>
<annotation>
<para>CQRS is an architectural pattern, making it impossible to provide a single
solution that fits all projects. Axon Framework does not try to provide that one
solution, obviously. Instead, Axon provides implementations that follow best
practices and the means to tweak each of those implementations to your specific
requirements.</para>
<para>Almost all infrastructure building blocks will provide hook points (such as
Interceptors, Resolvers, etc.) that allow you to add application-specific behavior
to those building blocks. In many cases, Axon will provide implementations for those
hook points that fit most use cases. If required, you can simply implement your
own.</para>
<para>Non-infrastructural objects, such as Messages, are generally immutable. This
ensures that these objects are safe to use in a multi-threaded environment, without
side-effects.</para>
</annotation>
<para>To ensure maximum customization, all Axon components are defined using interfaces.
Abstract and concrete implementations are provided to help you on your way, but will
nowhere be required by the framework. It is always possible to build a completely custom
implementation of any building block using that interface.</para>
</sect1>
<sect1>
<title>Spring Support</title>
<para>Axon Framework provides extensive support for Spring, but does not require you to
use Spring in order to use Axon. All components can be configured programmatically
and do not require Spring on the classpath. However, if you do use Spring, much of
the configuration is made easier with the use of Spring's namespace support.
Building blocks, such as the Command Bus, Event Bus and Saga Managers can be
configured using a single XML element in your Spring Application Context.</para>
<para>Check out the documentation of each building block for more information on how to
configure it using Spring.</para>
</sect1>
</chapter>