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: trueNow 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.packagesPlease 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 installThe 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 -DskipExamplesTo 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.