diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..0ad0c38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/1_feature_request.md b/.github/ISSUE_TEMPLATE/1_feature_request.md new file mode 100644 index 0000000..5cc1309 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_feature_request.md @@ -0,0 +1,27 @@ +--- +name: 'Feature request' +about: 'Suggest a feature for the Reactor Extension' +title: +labels: 'Type: Feature' +--- + + + +### Feature Description + + + +### Current Behaviour + + + +### Wanted Behaviour + + + +### Possible Workarounds + + diff --git a/.github/ISSUE_TEMPLATE/2_enhancement_request.md b/.github/ISSUE_TEMPLATE/2_enhancement_request.md new file mode 100644 index 0000000..da39cec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2_enhancement_request.md @@ -0,0 +1,24 @@ +--- +name: 'Enhancement request' +about: 'Suggest an enhancement/change to an existing feature for the Reactor Extension' +title: +labels: 'Type: Enhancement' +--- + + + +### Enhancement Description + + + +### Current Behaviour + + + +### Wanted Behaviour + + + +### Possible Workarounds + + diff --git a/.github/ISSUE_TEMPLATE/3_bug_report.md b/.github/ISSUE_TEMPLATE/3_bug_report.md new file mode 100644 index 0000000..565bd30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3_bug_report.md @@ -0,0 +1,33 @@ +--- +name: 'Bug report' +about: 'Report a bug for the Reactor Extension' +title: +labels: 'Type: Bug' +--- + + + +### Basic information + +* Axon Framework version: +* JDK version: +* Reactor Extension version: +* Complete executable reproducer if available (e.g. GitHub Repo): + +### Steps to reproduce + + + +### Expected behaviour + + + +### Actual behaviour + + diff --git a/.github/close-label.yml b/.github/close-label.yml new file mode 100644 index 0000000..8ed15ea --- /dev/null +++ b/.github/close-label.yml @@ -0,0 +1,4 @@ +"Type: Bug": "Status: Resolved" +"Type: Enhancement": "Status: Resolved" +"Type: Feature": "Status: Resolved" +"Type: Dependency Upgrade": "Status: Resolved" \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d0042b7 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 5 + # Specify labels for pull requests + labels: + - "Type: Dependency Upgrade" + - "Priority 1: Must" + - "Status: In Progress" + # Add reviewers + reviewers: + - "m1l4n54v1c" + - "saratry" + - "stefanvozd" + milestone: 2 \ No newline at end of file diff --git a/.github/release-notes.yml b/.github/release-notes.yml new file mode 100644 index 0000000..bfd1dbc --- /dev/null +++ b/.github/release-notes.yml @@ -0,0 +1,20 @@ +releasenotes: + sections: + - title: "Features" + emoji: ":star:" + labels: [ "Type: Feature" ] + - title: "Enhancements" + emoji: ":chart_with_upwards_trend:" + labels: [ "Type: Enhancement" ] + - title: "Bug Fixes" + emoji: ":beetle:" + labels: [ "Type: Bug" ] + - title: "Dependency Upgrade" + emoji: ":hammer_and_wrench:" + labels: [ "Type: Dependency Upgrade" ] + issues: + exclude: + labels: [ "Type: Incorrect Repository", "Type: Question" ] + contributors: + exclude: + names: [ "dependabot" ] diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..387f51a --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,93 @@ +name: Reactor Extension + +on: + push: + branches: + - master + - axon-reactor-*.*.x + pull_request: + +jobs: + build: + name: Test and Build on JDK ${{ matrix.java-version }} + + runs-on: ubuntu-latest + + strategy: + matrix: + include: + - java-version: 8 + sonar-enabled: false + deploy: true + - java-version: 11 + sonar-enabled: true + deploy: false + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up JDK ${{ matrix.java-version }} + uses: actions/setup-java@v1.4.3 + with: + java-version: ${{ matrix.java-version }} + server-id: sonatype + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + + - name: Cache .m2 + uses: actions/cache@v2.1.3 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven + + - name: Maven operation with Sonar + if: matrix.sonar-enabled + run: | + mvn -B -U -Pcoverage \ + clean verify \ + sonar:sonar \ + -Dsonar.projectKey=AxonFramework_extension-reactor \ + -Dsonar.organization=axonframework \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Maven operation without Sonar + if: matrix.sonar-enabled != true + run: | + mvn -B -U clean verify + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy to Sonatype + if: github.github.head_ref == null && success() && matrix.deploy + run: | + ./mvnw -B -U deploy -DskipTests=true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MAVEN_USERNAME: ${{ secrets.SONATYPE_TOKEN_ID }} + MAVEN_PASSWORD: ${{ secrets.SONATYPE_TOKEN_PASS }} + + - name: Notify success to Slack + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.2 + with: + channel_id: CAGSEC92A + status: SUCCESS + color: good + + - name: Notify failure to Slack + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.2 + with: + channel_id: CAGSEC92A + status: FAILED + color: danger diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml new file mode 100644 index 0000000..b4b5039 --- /dev/null +++ b/.github/workflows/release-notes.yml @@ -0,0 +1,33 @@ +# Trigger the workflow on milestone events +on: + milestone: + types: [closed] +name: Milestone Closure +jobs: + create-release-notes: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@master + - name: Create Release Notes Markdown + uses: docker://decathlon/release-notes-generator-action:2.1.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + OUTPUT_FOLDER: temp_release_notes + USE_MILESTONE_TITLE: "true" + - name: Get the name of the created Release Notes file and extract Version + run: | + RELEASE_NOTES_FILE=$(ls temp_release_notes/*.md | head -n 1) + echo "RELEASE_NOTES_FILE=$RELEASE_NOTES_FILE" >> $GITHUB_ENV + VERSION=$(echo ${{ github.event.milestone.title }} | cut -d' ' -f2) + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Create a Draft Release Notes on GitHub + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: axon-reactor-${{ env.VERSION }} + release_name: Axon Reactor Extension v${{ env.VERSION }} + body_path: ${{ env.RELEASE_NOTES_FILE }} + draft: true diff --git a/.gitignore b/.gitignore index 9cfaab9..51fa1f0 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,10 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +# Maven build artifacts can be ignored target/ +# ...but keep the wrapper jar +!.mvn/wrapper/maven-wrapper.jar # Eclipse project files .classpath diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c6feb8b Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..c2195a6 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bf21e0c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -# We want to run this on Ubuntu 18.04 LTS -dist: bionic - -language: java - -sudo: required - -services: - - docker - -jobs: - include: - - name: "JDK 8" - jdk: openjdk8 - env: MVN_BUILD_SCRIPT="clean verify" - - name: "JDK 11 with Sonar analysis" - jdk: openjdk11 - env: MVN_BUILD_SCRIPT="-Pcoverage clean verify sonar:sonar -Dsonar.projectKey=AxonFramework_extension-reactor" - -install: true - -cache: - directories: - - $HOME/.m2 - -# We switch JDK by setting the JAVA_HOME environment variable. All JDKs are under the same base directory. -script: - - mvn -version - - mvn -B -U $MVN_BUILD_SCRIPT - -notifications: - slack: - secure: d1HN9GBeH0e6EsHjNkPVXgBaFCYqbvjkZv9GUkpWnyjNYP5V1snSk6sO4X6ONttydgzfbElZTOfrgDzRTgWJ76iDMxAPccFPY7dmGcpw8/2TOjwP6H6yEitiiZcWR9fssTM2Li2WQtuGkwaVBhw15JNABzEsexxqXC+Cu48yUfA= - -addons: - sonarcloud: - organization: "axonframework" - token: - secure: "htYEusSkwB7bvgURS8FU8CBFmIlJcfSVhA6dZQ5uF3m3KYltT8D6zC4/O9aRw/2dId0lPMC5T6XiRLkmJsa3hLJhsbnrOW+8UXyzWq6SZfuVngRAXKeo5sqrv+7XXyIir5kbq0WSgs4UBJfxUIIDynfDupE9Y4MfZAQRA0FrupkEwwV4sp+QQKIymYFO84iPgwvlHpcn+KDMI0LNtLa6+kKJuuL5u4HsKHA4tTWBDP5aSBZL2dRNt1YM8+poO3pXH+fqTW21X7qq2GfoDfyLdfWtodT9TfREBQWgJcX6dXc3yLruPMnY7wzvNZUVF7bDDjIg9rcfARLLyBDutDGtiovqilKjes5JbsjEweRw9CpLq86UqIN1Sn1dHf40ieuvuU6hDyOCRAYwbP2/DZtN5eFyVJgUKY4NpcAewOODI3KMVTrhEeVjET8uvFsKT1Phsph3Ii/qhamED5+Yqvu+0974hQq0C3jXtDaM9xKC9ViaK1Bw1Q8P6EwGUvTEDFzsEPsSpg03G0EXQoOlikk5AbgjIEhDzeD9/UQvXv8qL5DM9N9nD/fH8ELa0ma5GHzMwK9WrkjjsYmeppjyT/wJHvb0MHAZxkJvq4izHvAZmvkusBEAOGpZHGRhDdGSR59zDMT1B7d8SLLk8OH9bFVEYh7rtFeNzwl6mzaGPFO7aWc=" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66e0278..13bb26c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,40 +1,38 @@ -# Contribution guidelines +# Contribution Guidelines -Thank you for your interest in contributing to the Axon Framework. To make sure using Axon is a smooth experience for -everybody, we've set up a number of guidelines to follow. +Thank you for your interest in contributing to the Axon Framework Reactor Extension. To make sure using Axon is a smooth +experience for everybody, we've set up a number of guidelines to follow. There are different ways in which you can contribute to the framework: - 1. You can report any bugs, feature requests or ideas about improvements on our issue page: https://github.com/AxonFramework/extension-reactor/issues. - All ideas are welcome. Please be as exact as possible when reporting bugs. This will help us reproduce and thus solve - the problem faster. - 1. If you have created a component for your own application that you think might be useful to include in the - framework, send us a pull request (or patch or a zip containing the source code). We will evaluate it and try to - fit it in the framework. Please make sure code is properly documented using javadoc. This helps us to understand - what is going on. - 1. If you know of any other way you think you can help us, do not hesitate to send a message to the - [Axon Framework mailinglist](axonframework@googlegroups.com). +1. You can report any bugs, feature requests or ideas about improvements on + our [issue page](https://github.com/AxonFramework/extension-reactor/issues/new/choose). All ideas are welcome. Please + be as exact as possible when reporting bugs. This will help us reproduce and thus solve the problem faster. +2. If you have created a component for your own application that you think might be useful to include in the framework, + send us a pull request (or a patch / zip containing the source code). We will evaluate it and try to fit it in the + framework. Please make sure code is properly documented using JavaDoc. This helps us to understand what is going on. +3. If you know of any other way you think you can help us, do not hesitate to send a message to + the [AxonIQ's discussion platform](https://discuss.axoniq.io/). -## Code contributions +## Code Contributions If you're contributing code, please take care of the following: ### Contributor Licence Agreement To keep everyone out of trouble (both you and us), we require that all contributors (digitally) sign a Contributor -License Agreement. Basically, the agreement says that we may freely use the code you contribute to the Axon Framework, -and that we won't hold you liable for any unfortunate side effects that the code may cause. +License Agreement. Basically, the agreement says that we may freely use the code you contribute to the Axon Framework +Reactor Extension, and that we won't hold you liable for any unfortunate side effects that the code may cause. -To sign the CLA, visit: https://www.clahub.com/agreements/AxonFramework/extension-reactor. +To sign the CLA, visit: https://cla-assistant.io/AxonFramework/extension-reactor -### Code style - -We're trying very hard to maintain a consistent style of coding throughout the code base. Think of things like -indenting using 4 spaces, putting opening brackets (the '{') on the same line and putting proper Javadoc on all -non-private members. - -If you're using IntelliJ IDEA, you can download the code style definition from -http://www.axonframework.org/axon_code_style.xml. Simply copy the file to ~/.IntelliJIdea13/config/codestyles. After -(re)starting IntelliJ, you can pick this code style from the project settings. +### Code Style +We're trying very hard to maintain a consistent style of coding throughout the code base. Think of things like indenting +using 4 spaces, putting opening brackets (the '{') on the same line and putting proper JavaDoc on all non-private +members. +If you're using IntelliJ IDEA, you can download the code style +definition [here](https://github.com/AxonFramework/AxonFramework/blob/master/axon_code_style.xml). Simply import the XML +file in under "Settings -> Code Style -> Scheme -> Import Scheme". Doing so should make the code style selectable +immediately. diff --git a/README.md b/README.md index 2465931..6bf0120 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# Axon Framework - Reactor Extension [![Build Status](https://travis-ci.org/AxonFramework/extension-reactor.svg?branch=master)](https://travis-ci.org/AxonFramework/extension-reactor) +# Axon Framework - Reactor Extension +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.axonframework.extensions.reactor/axon-reactor/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.axonframework.extensions.reactor/axon-reactor/) +![Build Status](https://github.com/AxonFramework/extension-reactor/workflows/Reactor%20Extension/badge.svg?branch=master) +[![SonarCloud Status](https://sonarcloud.io/api/project_badges/measure?project=AxonFramework_extension-reactor&metric=alert_status)](https://sonarcloud.io/dashboard?id=AxonFramework_extension-reactor) Axon Framework is a framework for building evolutionary, event-driven microservice systems, based on the principles of Domain Driven Design, Command-Query Responsibility Segregation (CQRS) and Event Sourcing. @@ -31,9 +34,10 @@ There are a couple of things to consider when you're traversing anything Axon: as the majority of possible scenarios you might encounter when using Axon should be covered there. * If the Reference Guide does not cover a specific topic you would've expected, we'd appreciate if you could file an [issue](https://github.com/AxonIQ/reference-guide/issues) about it for us. -* There is a a [public mailing list](https://groups.google.com/forum/#!forum/axonframework) to support you in the case - the reference guide did not sufficiently answer your question. -* Next to the mailing list we also monitor Stack Overflow for any questions which are tagged with `axon`. +* There is a [forum](https://discuss.axoniq.io/) to support you in the case the reference guide did not sufficiently answer your question. +Axon Framework and Server developers will help out on a best effort basis. +Know that any support from contributors on posted question is very much appreciated on the forum. +* Next to the forum we also monitor Stack Overflow for any questions which are tagged with `axon`. ## Feature requests and issue reporting @@ -51,4 +55,3 @@ When filing features: * (Pseudo-)Code snippets showing what it might look like help us understand your suggestion better * If you have any thoughts on where to plug this into the framework, that would be very helpful too * Lastly, we value contributions to the framework highly. So please provide a Pull Request as well! - \ No newline at end of file diff --git a/axon-reactor-spring-boot-autoconfigure/pom.xml b/axon-reactor-spring-boot-autoconfigure/pom.xml index f4cefc7..a6476a8 100644 --- a/axon-reactor-spring-boot-autoconfigure/pom.xml +++ b/axon-reactor-spring-boot-autoconfigure/pom.xml @@ -19,7 +19,7 @@ axon-reactor-parent org.axonframework.extensions.reactor - 4.4.3-SNAPSHOT + 4.5-SNAPSHOT 4.0.0 @@ -58,7 +58,7 @@ org.junit.jupiter - junit-jupiter-api + junit-jupiter test diff --git a/axon-reactor-spring-boot-starter/pom.xml b/axon-reactor-spring-boot-starter/pom.xml index aa23b61..009473d 100644 --- a/axon-reactor-spring-boot-starter/pom.xml +++ b/axon-reactor-spring-boot-starter/pom.xml @@ -19,14 +19,14 @@ org.springframework.boot spring-boot-starters - 2.2.6.RELEASE + 2.2.13.RELEASE 4.0.0 org.axonframework.extensions.reactor axon-reactor-spring-boot-starter - 4.4.3-SNAPSHOT + 4.5-SNAPSHOT Axon Framework Reactor Extension - Spring Boot Starter @@ -105,7 +105,7 @@ maven-resources-plugin - 3.0.1 + 3.2.0 UTF-8 @@ -116,7 +116,7 @@ maven-compiler-plugin - 3.5.1 + 3.8.1 1.8 1.8 @@ -125,7 +125,7 @@ maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadoc diff --git a/axon-reactor/pom.xml b/axon-reactor/pom.xml index 82250d9..46b1dc9 100644 --- a/axon-reactor/pom.xml +++ b/axon-reactor/pom.xml @@ -19,7 +19,7 @@ axon-reactor-parent org.axonframework.extensions.reactor - 4.4.3-SNAPSHOT + 4.5-SNAPSHOT 4.0.0 diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGateway.java index f137feb..723cb54 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGateway.java @@ -8,6 +8,8 @@ import org.axonframework.extensions.reactor.commandhandling.callbacks.ReactorCallback; import org.axonframework.extensions.reactor.messaging.ReactorMessageDispatchInterceptor; import org.axonframework.extensions.reactor.messaging.ReactorResultHandlerInterceptor; +import org.axonframework.extensions.reactor.commandhandling.callbacks.ReactorCallback; +import org.axonframework.messaging.MetaData; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -68,13 +70,27 @@ public static Builder builder() { @Override public Mono send(Object command) { //noinspection unchecked - return Mono.>just(GenericCommandMessage.asCommandMessage(command)) + return createCommandMessage(command) .transform(this::processCommandInterceptors) .flatMap(this::dispatchCommand) .flatMap(this::processResultsInterceptors) .transform(this::getPayload); } + private Mono> createCommandMessage(Object command) { + return Mono.just(command) + .zipWith(metaDataFromContext()) + .map(commandAndMeta -> GenericCommandMessage.asCommandMessage(commandAndMeta.getT1()) + .andMetaData(commandAndMeta.getT2())); + } + + private Mono metaDataFromContext() { + return Mono.subscriberContext() + .handle((ctx,sink) -> sink.next(Objects.requireNonNull( + ctx.getOrDefault(MetaData.class, MetaData.emptyInstance()) + ))); + } + @Override public Registration registerDispatchInterceptor(ReactorMessageDispatchInterceptor> interceptor) { dispatchInterceptors.add(interceptor); @@ -96,13 +112,15 @@ private Mono> processCommandInterceptors(Mono Mono, Flux>>> dispatchCommand( CommandMessage commandMessage) { - ReactorCallback reactorCallback = new ReactorCallback<>(); - CommandCallback callback = reactorCallback; - if (retryScheduler != null) { - callback = new RetryingCallback<>(callback, retryScheduler, commandBus); - } - commandBus.dispatch(commandMessage, callback); - return Mono.just(commandMessage).zipWith(Mono.just(Flux.from(reactorCallback))); + return Mono.defer(()-> { + ReactorCallback reactorCallback = new ReactorCallback<>(); + CommandCallback callback = reactorCallback; + if (retryScheduler != null) { + callback = new RetryingCallback<>(callback, retryScheduler, commandBus); + } + commandBus.dispatch(commandMessage, callback); + return Mono.just(commandMessage).zipWith(Mono.just(Flux.from(reactorCallback))); + }); } private Mono> processResultsInterceptors( diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/ReactorCommandGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/ReactorCommandGateway.java index 8432299..d8736e8 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/ReactorCommandGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/commandhandling/gateway/ReactorCommandGateway.java @@ -26,10 +26,10 @@ public interface ReactorCommandGateway extends ReactorMessageDispatchInterceptor /** * Sends the given {@code command} once the caller subscribes to the command result. Returns immediately. - *

+ *

* The given {@code command} is wrapped as the payload of a {@link CommandMessage} that is eventually posted on the - * {@link CommandBus}, unless the {@code command} already implements {@link Message}. In that case, a - * {@code CommandMessage} is constructed from that message's payload and {@link MetaData}. + * {@link CommandBus}, unless the {@code command} already implements {@link Message}. In that case, a {@code + * CommandMessage} is constructed from that message's payload and {@link MetaData}. * * @param command the command to dispatch * @param the type of the command result @@ -44,7 +44,6 @@ public interface ReactorCommandGateway extends ReactorMessageDispatchInterceptor * @param commands a Publisher stream of commands to be dispatched * @return a Flux of command results. An ordering of command results corresponds to an ordering of commands being * dispatched - * * @see #send(Object) * @see Flux#concatMap(Function) */ @@ -52,4 +51,5 @@ default Flux sendAll(Publisher commands) { return Flux.from(commands) .concatMap(this::send); } + } diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGateway.java index d6a749f..05d7d21 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGateway.java @@ -6,10 +6,13 @@ import org.axonframework.eventhandling.EventMessage; import org.axonframework.eventhandling.GenericEventMessage; import org.axonframework.extensions.reactor.messaging.ReactorMessageDispatchInterceptor; +import org.axonframework.messaging.MetaData; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.context.ContextView; import java.util.List; +import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; import static java.util.Arrays.asList; @@ -57,11 +60,24 @@ public static Builder builder() { @Override public Flux> publish(List events) { return Flux.fromIterable(events) - .map(event -> Mono.>just(GenericEventMessage.asEventMessage(event))) + .map(this::createEventMessage) .flatMap(this::processEventInterceptors) .flatMap(this::publishEvent); } + private Mono> createEventMessage(Object event) { + return Mono.just(event) + .transformDeferredContextual((eventMono,contextView) -> + eventMono.map(ev -> GenericEventMessage.asEventMessage(ev) + .andMetaData(metaDataFromContext(contextView)) + )); + + } + + private MetaData metaDataFromContext(ContextView contextView) { + return contextView.getOrDefault(MetaData.class, MetaData.emptyInstance()); + } + @Override public Registration registerDispatchInterceptor(ReactorMessageDispatchInterceptor> interceptor) { dispatchInterceptors.add(interceptor); diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/ReactorEventGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/ReactorEventGateway.java index 1704dbc..79c2328 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/ReactorEventGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/eventhandling/gateway/ReactorEventGateway.java @@ -14,8 +14,7 @@ /** * Variation of the {@link EventGateway}, wrapping a {@link EventBus} for a friendlier API. Provides support for - * reactive return types such as {@link Flux} from Project - * Reactor. + * reactive return types such as {@link Flux} from Project Reactor. * * @author Milan Savic * @since 4.4.2 @@ -24,7 +23,7 @@ public interface ReactorEventGateway extends ReactorMessageDispatchInterceptorSu /** * Publishes given {@code events} once the caller subscribes to the resulting Flux. Returns immediately. - *

+ *

* Given {@code events} are wrapped as payloads of a {@link EventMessage} that are eventually published on the * {@link EventBus}, unless {@code event} already implements {@link Message}. In that case, a {@code EventMessage} * is constructed from that message's payload and {@link org.axonframework.messaging.MetaData}. @@ -39,8 +38,9 @@ default Flux> publish(Object... events) { // NOSONAR } /** - * Publishes the given {@code events} once the caller subscribes to the resulting {@link Flux}. Returns immediately. - *

+ * Publishes the given {@code events} once the caller subscribes to the resulting {@link Flux}. Returns + * immediately. + *

* Given {@code events} are wrapped as payloads of a {@link EventMessage} that are eventually published on the * {@link EventBus}, unless {@code event} already implements {@link Message}. In that case, a {@code EventMessage} * is constructed from that message's payload and {@link org.axonframework.messaging.MetaData}. @@ -53,8 +53,9 @@ default Flux> publish(Object... events) { // NOSONAR Flux> publish(List events); /** - * Publishes the given {@code events} once the caller subscribes to the resulting {@link Flux}. Returns immediately. - *

+ * Publishes the given {@code events} once the caller subscribes to the resulting {@link Flux}. Returns + * immediately. + *

* Given {@code events} are wrapped as payloads of a {@link EventMessage} that are eventually published on the * {@link EventBus}, unless {@code event} already implements {@link Message}. In that case, a {@code EventMessage} * is constructed from that message's payload and {@link org.axonframework.messaging.MetaData}. diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGateway.java index ccba1d0..c366cd0 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGateway.java @@ -4,18 +4,10 @@ import org.axonframework.common.Registration; import org.axonframework.extensions.reactor.messaging.ReactorMessageDispatchInterceptor; import org.axonframework.extensions.reactor.messaging.ReactorResultHandlerInterceptor; +import org.axonframework.messaging.MetaData; import org.axonframework.messaging.ResultMessage; import org.axonframework.messaging.responsetypes.ResponseType; -import org.axonframework.queryhandling.DefaultSubscriptionQueryResult; -import org.axonframework.queryhandling.GenericQueryMessage; -import org.axonframework.queryhandling.GenericSubscriptionQueryMessage; -import org.axonframework.queryhandling.QueryBus; -import org.axonframework.queryhandling.QueryMessage; -import org.axonframework.queryhandling.QueryResponseMessage; -import org.axonframework.queryhandling.SubscriptionQueryBackpressure; -import org.axonframework.queryhandling.SubscriptionQueryMessage; -import org.axonframework.queryhandling.SubscriptionQueryResult; -import org.axonframework.queryhandling.SubscriptionQueryUpdateMessage; +import org.axonframework.queryhandling.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -91,9 +83,7 @@ public Registration registerResultHandlerInterceptor( @Override public Mono query(String queryName, Q query, ResponseType responseType) { - return Mono.>fromCallable(() -> new GenericQueryMessage<>(asMessage(query), - queryName, - responseType)) + return createQueryMessage(queryName, query, responseType) .transform(this::processDispatchInterceptors) .flatMap(this::dispatchQuery) .flatMapMany(this::processResultsInterceptors) @@ -101,6 +91,21 @@ public Mono query(String queryName, Q query, ResponseType responseT .next(); } + + public Mono> createQueryMessage(String queryName, Q query, ResponseType responseType) { + return Mono.fromCallable(() -> new GenericQueryMessage<>(asMessage(query), queryName, responseType)) + .zipWith(metaDataFromContext()) + .map(queryAndMeta -> queryAndMeta.getT1().andMetaData(queryAndMeta.getT2())); + } + + + private Mono metaDataFromContext() { + return Mono.subscriberContext() + .handle((ctx,sink) -> sink.next(Objects.requireNonNull( + ctx.getOrDefault(MetaData.class, MetaData.emptyInstance()) + ))); + } + @Override public Flux scatterGather(String queryName, Q query, ResponseType responseType, Duration timeout) { return Mono.>fromCallable(() -> new GenericQueryMessage<>(asMessage(query), diff --git a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/ReactorQueryGateway.java b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/ReactorQueryGateway.java index 547e620..2a0132f 100644 --- a/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/ReactorQueryGateway.java +++ b/axon-reactor/src/main/java/org/axonframework/extensions/reactor/queryhandling/gateway/ReactorQueryGateway.java @@ -181,7 +181,7 @@ default Flux scatterGather(Publisher> queries, Durati * @param query The {@code query} to be sent * @param resultType The response type used for this query * @param The type of the query - * @param The type of the result (initial & updates) + * @param The type of the result (initial and updates) * @return Flux which can be used to cancel receiving updates * * @see QueryBus#subscriptionQuery(SubscriptionQueryMessage) @@ -207,7 +207,7 @@ default Flux subscriptionQuery(Q query, ResponseType resultType) { * @param query The {@code query} to be sent * @param resultType The response type used for this query * @param The type of the query - * @param The type of the result (initial & updates) + * @param The type of the result (initial and updates) * @return Flux which can be used to cancel receiving updates * * @see QueryBus#subscriptionQuery(SubscriptionQueryMessage) @@ -231,7 +231,7 @@ default Flux subscriptionQuery(Q query, Class resultType) { * @param query The {@code query} to be sent * @param resultType The response type used for this query * @param The type of the query - * @param The type of the result (initial & updates) + * @param The type of the result (initial and updates) * @return Flux which can be used to cancel receiving updates * * @see QueryBus#subscriptionQuery(SubscriptionQueryMessage) diff --git a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGatewayComponentTest.java b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGatewayComponentTest.java index 3b4e066..adb4f0f 100644 --- a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGatewayComponentTest.java +++ b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/commandhandling/gateway/DefaultReactorCommandGatewayComponentTest.java @@ -7,7 +7,10 @@ import org.axonframework.commandhandling.gateway.RetryScheduler; import org.axonframework.common.Registration; import org.axonframework.messaging.MessageHandler; +import org.axonframework.messaging.MetaData; +import org.axonframework.queryhandling.QueryMessage; import org.junit.jupiter.api.*; +import org.mockito.ArgumentCaptor; import reactor.core.publisher.Flux; import reactor.core.publisher.Hooks; import reactor.core.publisher.Mono; @@ -23,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; +import static reactor.util.context.Context.of; /** * Tests for {@link DefaultReactorCommandGateway} all together with Command Bus. @@ -100,7 +104,7 @@ void testSendContext() throws Exception { Mono result = reactiveCommandGateway.send("command"); verifyNoMoreInteractions(commandMessageHandler); - Context context = Context.of("k1", "v1"); + Context context = of("k1", "v1"); StepVerifier.create(result.subscriberContext(context)) .expectNext("handled") @@ -112,6 +116,33 @@ void testSendContext() throws Exception { verifyNoMoreInteractions(mockRetryScheduler); } + @Test + void testQuerySetMetaDataViaContext() throws Exception { + Mono result = reactiveCommandGateway.send("command"); + verifyNoMoreInteractions(commandMessageHandler); + + Context context = of(MetaData.class, MetaData.with("k","v")); + + StepVerifier.create(result.subscriberContext(context)) + .expectNext("handled") + .expectAccessibleContext() + .containsOnly(context) + .then() + .verifyComplete(); + + ArgumentCaptor commandMessageCaptor = ArgumentCaptor.forClass(CommandMessage.class); + + + verify(commandBus).dispatch(commandMessageCaptor.capture(),any()); + CommandMessage commandMessage = commandMessageCaptor.getValue(); + + assertTrue(commandMessage.getMetaData().containsKey("k")); + assertTrue(commandMessage.getMetaData().containsValue("v")); + + verify(commandMessageHandler).handle(any()); + verifyNoMoreInteractions(mockRetryScheduler); + } + @Test void testSendVoidHandler() throws Exception { Mono result = reactiveCommandGateway.send(1L); @@ -186,7 +217,7 @@ void testSendWithDispatchInterceptor() { @Test void testSendWithDispatchInterceptorWithContext() { - Context context = Context.of("security", true); + Context context = of("security", true); reactiveCommandGateway .registerDispatchInterceptor(cmdMono -> cmdMono @@ -207,7 +238,7 @@ void testSendWithDispatchInterceptorWithContext() { @Test void testSendWithDispatchInterceptorWithContextFiltered() { - Context context = Context.of("security", false); + Context context = of("security", false); reactiveCommandGateway .registerDispatchInterceptor(cmdMono -> cmdMono diff --git a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGatewayTest.java b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGatewayTest.java index e27d81e..5424a46 100644 --- a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGatewayTest.java +++ b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/eventhandling/gateway/DefaultReactorEventGatewayTest.java @@ -5,11 +5,15 @@ import org.axonframework.eventhandling.GenericEventMessage; import org.axonframework.messaging.Message; import org.axonframework.messaging.MetaData; +import org.axonframework.queryhandling.QueryMessage; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.*; +import org.mockito.ArgumentCaptor; import org.mockito.junit.jupiter.*; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import reactor.util.context.Context; import java.util.ArrayList; import java.util.Arrays; @@ -19,6 +23,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.*; +import static reactor.util.context.Context.of; /** * Tests for {@link DefaultReactorEventGateway}. @@ -52,6 +57,34 @@ void testPublish() { verify(eventBus).publish(any(EventMessage.class)); } + @Test + void testEventSetMetaDataViaContext() { + Context context = of(MetaData.class, MetaData.with("k","v")); + + Flux result = gateway.publish("event") + .map(Message::getPayload) + .cast(String.class) + .subscriberContext(context); + + StepVerifier.create(result) + .expectNext("event") + .expectAccessibleContext() + .containsOnly(context) + .then() + .verifyComplete(); + + + ArgumentCaptor eventMessageCaptor = ArgumentCaptor.forClass(GenericEventMessage.class); + + + verify(eventBus).publish(eventMessageCaptor.capture()); + GenericEventMessage eventMessage = eventMessageCaptor.getValue(); + + assertTrue(eventMessage.getMetaData().containsKey("k")); + assertTrue(eventMessage.getMetaData().containsValue("v")); + + } + @Test void testPublishWithError() { RuntimeException exception = new RuntimeException("oops"); diff --git a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGatewayTest.java b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGatewayTest.java index 2090c06..9b8ae7b 100644 --- a/axon-reactor/src/test/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGatewayTest.java +++ b/axon-reactor/src/test/java/org/axonframework/extensions/reactor/queryhandling/gateway/DefaultReactorQueryGatewayTest.java @@ -2,19 +2,15 @@ import org.axonframework.common.Registration; import org.axonframework.messaging.MessageHandler; +import org.axonframework.messaging.MetaData; import org.axonframework.messaging.ResultMessage; import org.axonframework.messaging.responsetypes.ResponseTypes; -import org.axonframework.queryhandling.GenericQueryMessage; -import org.axonframework.queryhandling.GenericQueryResponseMessage; -import org.axonframework.queryhandling.GenericSubscriptionQueryMessage; -import org.axonframework.queryhandling.QueryMessage; -import org.axonframework.queryhandling.QueryUpdateEmitter; -import org.axonframework.queryhandling.SimpleQueryBus; -import org.axonframework.queryhandling.SubscriptionQueryMessage; -import org.axonframework.queryhandling.SubscriptionQueryResult; -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.*; -import org.mockito.junit.jupiter.*; +import org.axonframework.queryhandling.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.junit.jupiter.MockitoExtension; import reactor.core.publisher.Flux; import reactor.core.publisher.Hooks; import reactor.core.publisher.Mono; @@ -37,6 +33,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import static reactor.util.context.Context.of; /** * Tests for {@link DefaultReactorQueryGateway}. @@ -128,9 +125,10 @@ void testQuery() throws Exception { @Test void testQueryWithContext() throws Exception { - Context context = Context.of("k1", "v1"); + Context context = of(MetaData.class, MetaData.with("k","v")); - Mono result = reactiveQueryGateway.query("criteria", String.class).subscriberContext(context); + Mono result = reactiveQueryGateway.query("criteria", String.class) + .subscriberContext(context); verifyNoMoreInteractions(queryMessageHandler1); verifyNoMoreInteractions(queryMessageHandler2); @@ -141,6 +139,33 @@ void testQueryWithContext() throws Exception { .then() .verifyComplete(); verify(queryMessageHandler1).handle(any()); + + ArgumentCaptor queryMessageCaptor = ArgumentCaptor.forClass(QueryMessage.class); + + + verify(queryBus).query(queryMessageCaptor.capture()); + QueryMessage queryMessage = queryMessageCaptor.getValue(); + + assertTrue(queryMessage.getMetaData().containsKey("k")); + assertTrue(queryMessage.getMetaData().containsValue("v")); + + } + + @Test + void testCommandSetMetaDataViaContext() throws Exception { + Context context = Context.of("k1", "v1"); + + Mono result = reactiveQueryGateway.query("criteria", String.class).subscriberContext(context); + + verifyNoMoreInteractions(queryMessageHandler1); + verifyNoMoreInteractions(queryMessageHandler2); + StepVerifier.create(result) + .expectNext("handled") + .expectAccessibleContext() + .containsOnly(context) + .then() + .verifyComplete(); + verify(queryMessageHandler1).handle(any()); } @Test diff --git a/mvnw b/mvnw new file mode 100755 index 0000000..e96ccd5 --- /dev/null +++ b/mvnw @@ -0,0 +1,227 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100755 index 0000000..019bd74 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,143 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index bfccd51..39ef0d2 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ org.axonframework.extensions.reactor axon-reactor-parent - 4.4.3-SNAPSHOT + 4.5-SNAPSHOT axon-reactor axon-reactor-spring-boot-autoconfigure @@ -48,18 +48,18 @@ UTF-8 - 4.4.2 - 3.3.6.RELEASE + 4.4.7 + 3.4.4 - 5.2.5.RELEASE - 2.2.6.RELEASE + 5.3.3 + 2.4.2 1.7.28 2.13.0 - 0.8.5 + 0.8.6 - 5.5.2 - 3.1.0 + 5.7.1 + 3.7.7 @@ -102,13 +102,6 @@ test - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.version} - test - - org.mockito mockito-core @@ -157,7 +150,7 @@ maven-resources-plugin - 3.0.2 + 3.2.0 UTF-8 @@ -168,7 +161,7 @@ maven-compiler-plugin - 3.5.1 + 3.8.1 1.8 1.8 @@ -178,7 +171,7 @@ org.apache.maven.plugins maven-assembly-plugin - 2.6 + 3.3.0 assembly @@ -197,7 +190,7 @@ maven-surefire-plugin - 2.19.1 + 2.22.2 **/*Test.java @@ -213,7 +206,7 @@ maven-javadoc-plugin - 2.10.4 + 3.2.0 attach-javadoc @@ -229,7 +222,7 @@ maven-jar-plugin - 3.0.2 + 3.2.0 @@ -240,7 +233,7 @@ maven-source-plugin - 3.0.1 + 3.2.1 attach-sources