Note: This extension is still in an experimental stage.
Maven
<dependency>
<groupId>io.holixon.axon.gateway</groupId>
<artifactId>axon-gateway-springboot-starter</artifactId>
<version>${axon-gateway-extension.version}</version>
</dependency>
Imagine, you are sending a command, and you want to query for the result of its effect in the projection. A Revision-Aware Gateway is capable of retrieving for a certain (minimal) revision of the projection. In order to do so, you need to pass the revision along with your command, packaged in metadata by using the helper method:
commandGateway.send<Void>(
GenericCommandMessage.asCommandMessage<UpdateApprovalRequestCommand>(
CreateApprovalRequestCommand(
requestId = requestId,
subject = value.subject,
currency = value.currency,
amount = value.amount
)
).withMetaData(RevisionValue(revision).toMetaData())
)
Now you can query for a certain revision, if the result contains the revision information inside the payload
(the query result implements Revisionable
).
queryGateway.query(
GenericCommandMessage
.asCommandMessage<ApprovalRequestQuery>(ApprovalRequestQuery(requestId.trim()))
.withMetaData(RevisionQueryParameters(revision).toMetaData()),
ResponseTypes.instanceOf(ApprovalRequestQueryResult::class.java)
).join()
As alternative, you can query for a certain revision, if the query method returns QueryResponseMessage<T>
and carries
metadata inside the message metadata
field.
queryGateway.query(
GenericCommandMessage
.asCommandMessage<ApprovalRequestQuery>(ApprovalRequestQuery(requestId.trim()))
.withMetaData(RevisionQueryParameters(revision).toMetaData()),
QueryResponseMessageType.queryResponseMessageType<ApprovalRequest>()
).join()
The query gateway will detect the revision metadata in the query and wait until the specified response with specified revision has arrived in the projection. In order not to wait forever, you can either pass the timeout with the query or setup default timeout using the application properties.
In order to maintain revisions in your projection, make sure your event get the revision information from
the command and the projection stores it. Currently, the revision must be transported inside the query result,
by implementing the Revisionable
interface or by returning QueryResponseMessage<T>
from your handler method.
If you have any questions how to use the extension, please have a look on example project.
By default, the Axon Server Connector will register all command handlers it finds by AutoConfiguration
both on "Local" and "Remote"
segments of the command bus. In order to have more flexibility on that, for example by hiding some CommandHandlers
from registration,
you might want to have a possibility to exclude CommandHandler
registration on a remote command bus. By doing so, the locally dispatched
commands should still get delivered to command handlers by using the local segment of the command bus.
The Dispatch-aware command bus is designed exactly for the purpose above. In order to use it, you will need the Axon Server Connector
to be configured to use Axon Server (axon.axonserver.enabled
must not be set to false
). In addition, you need to enable the following
property:
axon-gateway:
command:
dispatch-aware:
enabled: true
Now you need to specify a CommandDispatchStrategy
. You can do this manually, by providing a bean factory for this, a component
implementing this interface or by using the predefined components using properties to configure predicates for command names excluded from
remote registration. For doing so, specify the following properties in your application.yml
axon-gateway:
command:
dispatch-aware:
enabled: true
strategy:
exclude-command-names:
- io.holixon.axon.gateway.example.UpdateApprovalRequestCommand
- io.holixon.axon.gateway.example.OtherCommand
exclude-command-packages:
- example.matching.all.commands.in.this.package.and.sub.packages
Please check the implementations of CommandDispatchStrategy
for more details.
If you are using this extension with Jackson
serialization, it is required that the query response type is
serializable by Jackson. For this purpose, we provide a small Jackson module which needs to be included and registered in your project.
To do so, please add the following dependency to your classpath:
Maven
<dependency>
<groupId>io.holixon.axon.gateway</groupId>
<artifactId>axon-gateway-jackson-module</artifactId>
<version>${axon-gateway-extension.version}</version>
</dependency>
and register it in your Jackson ObjectMapper:
@Bean
fun objectMapper(): ObjectMapper = jacksonObjectMapper()
.registerModule(AxonGatewayJacksonModule())
If you want to build the extension locally, you need to check it out from GiHub and run the following command:
./mvnw clean install
The project includes an example module demonstrating usage of the extension. If you want to skip the example build, please run the following command line:
./mvnw clean install -DskipExamples
To start example please run the AxonGatewayExampleApplication
. By supplying the Spring profile inmem
you can run it without the
Axon Server. If you run it with Axon Server, make use of example/docker-compose.yml
to start one using Docker.
To play with example, navigate to http://localhost:8079/swagger-ui/index.html
with your browser and send some REST requests.