├── .github ├── close-label.yml ├── dependabot.yml ├── release-notes.yml └── workflows │ ├── maven.yml │ └── release-notes.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── pom.xml └── src └── main └── proto ├── admin.proto ├── command.proto ├── common.proto ├── control.proto ├── dcb.proto ├── event.proto ├── persistent-streams.proto └── query.proto /.github/close-label.yml: -------------------------------------------------------------------------------- 1 | "Type: Bug": "Status: Resolved" 2 | "Type: Enhancement": "Status: Resolved" 3 | "Type: Feature": "Status: Resolved" 4 | "Type: Dependency Upgrade": "Status: Resolved" -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: maven 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 5 8 | # Specify labels for pull requests 9 | labels: 10 | - "Type: Dependency Upgrade" 11 | - "Priority 1: Must" 12 | - "Status: In Progress" 13 | # Add reviewers 14 | reviewers: 15 | - "MGathier" 16 | milestone: 7 -------------------------------------------------------------------------------- /.github/release-notes.yml: -------------------------------------------------------------------------------- 1 | releasenotes: 2 | sections: 3 | - title: "Features" 4 | emoji: ":star:" 5 | labels: [ "Type: Feature" ] 6 | - title: "Enhancements" 7 | emoji: ":chart_with_upwards_trend:" 8 | labels: [ "Type: Enhancement" ] 9 | - title: "Bug Fixes" 10 | emoji: ":beetle:" 11 | labels: [ "Type: Bug" ] 12 | - title: "Dependency Upgrade" 13 | emoji: ":hammer_and_wrench:" 14 | labels: [ "Type: Dependency Upgrade" ] 15 | issues: 16 | exclude: 17 | labels: [ "Type: Incorrect Repository", "Type: Question" ] 18 | contributors: 19 | exclude: 20 | names: [ "dependabot" ] 21 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Axon Server API 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - axon-server-api-*.*.x 8 | - feature/dcb 9 | workflow_dispatch: 10 | 11 | jobs: 12 | build: 13 | name: Test and Build on JDK 11 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v2 20 | 21 | - name: Set up JDK 11 22 | uses: actions/setup-java@v1.4.3 23 | with: 24 | java-version: 11 25 | server-id: central 26 | server-username: MAVEN_USERNAME 27 | server-password: MAVEN_PASSWORD 28 | 29 | - name: Cache .m2 30 | uses: actions/cache@v4.2.3 31 | with: 32 | path: ~/.m2/repository 33 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 34 | restore-keys: | 35 | ${{ runner.os }}-maven 36 | 37 | - name: Maven 38 | run: | 39 | mvn -B -U clean verify 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 42 | 43 | - name: Deploy to Sonatype 44 | if: github.github.head_ref == null && success() 45 | run: | 46 | mvn -B -U deploy -DskipTests=true 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 49 | MAVEN_USERNAME: ${{ secrets.SONATYPE_TOKEN_ID }} 50 | MAVEN_PASSWORD: ${{ secrets.SONATYPE_TOKEN_PASS }} 51 | 52 | - name: Notify success to Slack 53 | if: success() 54 | env: 55 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 56 | uses: voxmedia/github-action-slack-notify-build@v1.1.2 57 | with: 58 | channel_id: C015XFURSJU 59 | status: SUCCESS 60 | color: good 61 | 62 | - name: Notify failure to Slack 63 | if: failure() 64 | env: 65 | SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} 66 | uses: voxmedia/github-action-slack-notify-build@v1.1.2 67 | with: 68 | channel_id: C015XFURSJU 69 | status: FAILED 70 | color: danger 71 | 72 | - name: Trigger plugin API build 73 | if: github.github.head_ref == null && success() 74 | uses: actions/github-script@v6 75 | with: 76 | github-token: ${{ secrets.PAT_TOKEN }} 77 | script: | 78 | await github.rest.actions.createWorkflowDispatch({ 79 | owner: 'AxonIQ', 80 | repo: 'axon-server-plugin-api', 81 | workflow_id: 'maven.yml', 82 | ref: 'master' 83 | }) 84 | -------------------------------------------------------------------------------- /.github/workflows/release-notes.yml: -------------------------------------------------------------------------------- 1 | # Trigger the workflow on milestone events 2 | on: 3 | milestone: 4 | types: [ closed ] 5 | name: Milestone Closure 6 | jobs: 7 | create-release-notes: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout code 11 | uses: actions/checkout@master 12 | - name: Create Release Notes Markdown 13 | uses: docker://decathlon/release-notes-generator-action:2.1.0 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 16 | OUTPUT_FOLDER: temp_release_notes 17 | USE_MILESTONE_TITLE: "true" 18 | - name: Get the name of the created Release Notes file and extract Version 19 | run: | 20 | RELEASE_NOTES_FILE=$(ls temp_release_notes/*.md | head -n 1) 21 | echo "RELEASE_NOTES_FILE=$RELEASE_NOTES_FILE" >> $GITHUB_ENV 22 | VERSION=$(echo ${{ github.event.milestone.title }} | cut -d' ' -f2) 23 | echo "VERSION=$VERSION" >> $GITHUB_ENV 24 | - name: Create a Draft Release Notes on GitHub 25 | id: create_release 26 | uses: actions/create-release@v1 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 29 | with: 30 | tag_name: axon-server-extension-api-${{ env.VERSION }} 31 | release_name: Axon Server Extension API v${{ env.VERSION }} 32 | body_path: ${{ env.RELEASE_NOTES_FILE }} 33 | draft: true 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | *.iml 3 | *.iws 4 | *.ipr 5 | .idea/ 6 | .settings/ 7 | .classpath 8 | .project 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AxonServer API Specification 2 | 3 | This module contains the protobuf definitions of the services and messages provided by 4 | AxonServer. 5 | 6 | The API definitions are structured around 6 files: 7 | 8 | - `admin.proto` - contains services and messages to monitor and control Axon Server 9 | - `common.proto` - contains messages commonly used throughout the services 10 | - `control.proto` - contains services and messages to monitor and control application components 11 | - `command.proto` - contains the service and message definitions specific to the dispatching and handling of commands. 12 | - `event.proto` - contains services and messages for publishing and consuming events 13 | - `query.proto` - contains services and messages for dispatching and handling queries 14 | 15 | ## Building a client 16 | 17 | ### Generating stubs 18 | 19 | Based on the protobuf files, stubs can be generated for several languages and platforms. Visit 20 | the [gRPC quick start](https://www.grpc.io/docs/quickstart/) page for your language. 21 | 22 | ### Attaching security headers 23 | 24 | In all communication to AxonServer Enterprise, the client will need to provide the name of the Context it belongs to. 25 | This context is added as a header to each request. The key of the header is `AxonIQ-Context`, the value is the 26 | ascii-encoded name of the Context. 27 | 28 | If security is enabled on AxonServer, a security header also needs to attached to each request. The key of that header is 29 | `AxonIQ-Access-Token`, and the value is the ascii-encoded token which identifies the client. 30 | 31 | ### Connecting to AxonServer 32 | 33 | In a cluster of AxonServer nodes, not every node has the same role. That means that not every node may be suitable 34 | to serve as a connection counterpart to every application. Therefore, connecting to AxonServer is a 35 | two-step process. 36 | 37 | The first step is to establish a connection with an "admin" node. These nodes have detailed information about the layout 38 | of the entire cluster. Typically, several nodes act as "admin" node. Your client will need to connect to just one 39 | of them. 40 | 41 | The first call to the Admin node is the `PlatformService.GetPlatformServer`, defined in the `control.proto` file. In the request, 42 | you pass information about the client trying to connect. The tags are optional, and may provide hints to the AxonServer 43 | cluster about connection preferences the application may have. The result provides connection details of the AxonServer 44 | node the client should defer its connection to. In case the `same_connection` flag is `true`, the client may use the 45 | existing connection for further communication. Otherwise, the existing connection must be closed, and a connection must 46 | be set up using the provided hostname and port. 47 | 48 | Well-behaved clients will always set up a two-way instruction stream using the `PlatformService.OpenStream` rpc. This is 49 | a two-way streaming rpc, which allows AxonServer to provide instructions to the client, for example to notify it of a 50 | node shutting down, or a request to connect to another instance, to better balance connections across the cluster. 51 | 52 | Finally, depending on the responsibilities of the client, it can register command handlers, query handler, open event 53 | streams, and send messages. 54 | 55 | ### Flow control 56 | 57 | AxonServer uses flow-control to ensure clients are not flooded with more messages than they can handle. For historic 58 | reasons, flow control is explicitly implemented on the RPC level. Whenever, messages are streamed from AxonServer to a 59 | client, the client must indicate how many messages the client can ingest before the Server node needs to wait for more 60 | "permits" to be allocated. 61 | 62 | Permits are cumulative. When opening a connection to subscribe a command handler, for example, and providing 500 63 | permits, AxonServer may send up to 500 messages without waiting in between. If, after receiving 100 messages, 500 more 64 | permits are sent, the total available permits for AxonServer is 900. 65 | 66 | It is highly recommended to only refresh permits after messages are consumed from any internal buffers. This helps 67 | ensure these buffers never fill up beyond expected proportions. 68 | 69 | When AxonServer has messages to send to a node that doesn't have any permits available, AxonServer will buffer them on 70 | the server side. However, those buffers are also limited. Once they fill up, depending on AxonServer settings, either 71 | new messages will be rejected (sending errors to the clients dispatching them), or AxonServer will start adjusting its 72 | routing properties to reduce the load on that specific client. 73 | 74 | ### Forward and backward compatibility considerations 75 | 76 | Protobuf messages, by design, account for forward and backwards compatibility. The serialized form of messages contain 77 | just enough information to make sure a client can successfully consume the message. However, to assign meaning to these 78 | elements, the proto files are required. 79 | 80 | AxonServer takes backwards and forwards compatibility into account, too. The binary format of messages will be 81 | compatible with future versions of AxonServer. Typically, elements may be deprecated in minor versions, but will only 82 | be removed in the next major release of an API. 83 | 84 | However, new versions of AxonServer may provide instructions to clients that a certain version of the client does not 85 | understand. In that case, the client may simply ignore these instructions. Similarly, a client must not assume that the 86 | server understands all instructions, as a client may be talking to an older version of AxonServer, too. 87 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 20 | 4.0.0 21 | io.axoniq 22 | axon-server-api 23 | 2025.1.0-SNAPSHOT 24 | Axon Server API 25 | Public API for communication with AxonServer 26 | 27 | 2018 28 | https://www.axoniq.io 29 | 30 | 31 | Apache 2.0 32 | http://www.apache.org/licenses/LICENSE-2.0 33 | 34 | 35 | 36 | GitHub 37 | https://github.com/AxonIQ/axon-server-api/issues 38 | 39 | 40 | 0.7.0 41 | 42 | 43 | 44 | 45 | 46 | src/main/proto 47 | 48 | 49 | 50 | 51 | maven-release-plugin 52 | 2.5.3 53 | 54 | forked-path 55 | true 56 | false 57 | 58 | 59 | 60 | org.sonatype.central 61 | central-publishing-maven-plugin 62 | ${central-publishing-maven-plugin.version} 63 | true 64 | 65 | central 66 | 67 | 68 | 69 | 70 | 71 | 72 | scm:git:https://github.com/AxonIQ/axon-server-api.git 73 | scm:git:https://github.com/AxonIQ/axon-server-api.git 74 | https://github.com/AxonIQ/axon-server-api.git 75 | HEAD 76 | 77 | 78 | 79 | 80 | Allard Buijze 81 | allard.buijze@axoniq.io 82 | AxonIQ 83 | https://axoniq.io 84 | 85 | Project Lead 86 | 87 | 88 | 89 | Marc Gathier 90 | marc.gathier@axoniq.io 91 | AxonIQ 92 | https://axoniq.io 93 | 94 | Developer 95 | 96 | 97 | 98 | 99 | 100 | 101 | release-sign-artifacts 102 | 103 | 104 | performRelease 105 | true 106 | 107 | 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-gpg-plugin 113 | 3.0.1 114 | 115 | 116 | sign-artifacts 117 | verify 118 | 119 | 120 | sign 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /src/main/proto/admin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.admin; 3 | import "google/protobuf/empty.proto"; 4 | import "common.proto"; 5 | import "control.proto"; 6 | option java_multiple_files = true; 7 | 8 | //************************ ContextAdminService ***************************** 9 | service ContextAdminService { 10 | 11 | rpc CreateContext(CreateContextRequest) returns (stream google.protobuf.Empty) ; 12 | 13 | rpc UpdateContextProperties(UpdateContextPropertiesRequest) returns (stream google.protobuf.Empty) ; 14 | 15 | rpc DeleteContext(DeleteContextRequest) returns (stream google.protobuf.Empty) ; 16 | 17 | rpc GetContext(GetContextRequest) returns (ContextOverview) ; 18 | 19 | rpc GetContexts(google.protobuf.Empty) returns (stream ContextOverview) ; 20 | 21 | rpc SubscribeContextUpdates(google.protobuf.Empty) returns (stream ContextUpdate) ; 22 | 23 | } 24 | 25 | service ReplicationGroupAdminService { 26 | 27 | rpc GetNodes (google.protobuf.Empty) returns (stream NodeOverview) {} 28 | 29 | rpc CreateReplicationGroup(CreateReplicationGroupRequest) returns (stream google.protobuf.Empty); 30 | 31 | rpc GetReplicationGroups(google.protobuf.Empty) returns (stream ReplicationGroupOverview); 32 | 33 | rpc GetReplicationGroup(GetReplicationGroupRequest) returns (ReplicationGroupOverview); 34 | 35 | rpc DeleteReplicationGroup(DeleteReplicationGroupRequest) returns (stream google.protobuf.Empty) ; 36 | 37 | rpc AddNodeToReplicationGroup(JoinReplicationGroup) returns (stream google.protobuf.Empty) ; 38 | 39 | rpc RemoveNodeFromReplicationGroup(LeaveReplicationGroup) returns (stream google.protobuf.Empty) ; 40 | 41 | } 42 | 43 | message CreateContextRequest { 44 | string name = 1; 45 | string replicationGroupName = 2; 46 | map meta_data = 3; 47 | bool dcbContext = 4; 48 | } 49 | 50 | message UpdateContextPropertiesRequest { 51 | string name = 1; 52 | map meta_data = 3; 53 | } 54 | 55 | message DeleteContextRequest { 56 | string name = 1; 57 | bool preserveEventStore = 2; 58 | } 59 | 60 | message GetContextRequest { 61 | string name = 1; 62 | } 63 | 64 | message ContextOverview { 65 | string name = 1; 66 | ReplicationGroupOverview replicationGroup = 2; 67 | map meta_data = 3; 68 | int64 pendingSince = 4; 69 | bool changePending = 5; 70 | bool dcbContext = 6; 71 | } 72 | 73 | message ContextUpdate { 74 | string context = 1; 75 | ContextUpdateType type = 2; 76 | } 77 | 78 | enum ContextUpdateType { 79 | 80 | /* new context has been created. */ 81 | CREATED = 0; 82 | 83 | /* context has been removed */ 84 | DELETED = 1; 85 | 86 | /* context has been updated */ 87 | UPDATED = 2; 88 | } 89 | 90 | message CreateReplicationGroupRequest { 91 | string name = 1; 92 | repeated ReplicationGroupMember members = 2; 93 | int64 pendingSince = 3; 94 | bool changePending = 4; 95 | } 96 | 97 | message ReplicationGroupOverview { 98 | string name = 1; 99 | repeated ReplicationGroupMember members = 2; 100 | int64 pendingSince = 3; 101 | bool changePending = 4; 102 | repeated string contexts = 5; 103 | } 104 | 105 | message DeleteReplicationGroupRequest { 106 | string name = 1; 107 | bool preserveEventStore = 2; 108 | } 109 | 110 | message ReplicationGroupMember { 111 | string node_name = 1; 112 | string host = 2; 113 | int32 port = 3; 114 | Role role = 4; 115 | bool pendingDelete = 5; 116 | } 117 | 118 | enum Role { 119 | ROLE_PRIMARY = 0; 120 | ROLE_ACTIVE_BACKUP = 2; 121 | ROLE_PASSIVE_BACKUP = 3; 122 | ROLE_MESSAGING_ONLY = 4; 123 | ROLE_SECONDARY = 5; 124 | } 125 | 126 | message GetReplicationGroupRequest { 127 | string name = 1; 128 | } 129 | 130 | message JoinReplicationGroup { 131 | string replication_group_name = 1; 132 | string node_name = 2; 133 | Role role = 3; 134 | } 135 | 136 | message LeaveReplicationGroup { 137 | string replication_group_name = 1; 138 | string node_name = 2; 139 | bool preserveEventStore = 3; 140 | } 141 | 142 | message ReplicationGroupContext { 143 | string replication_group_name = 1; 144 | string context_name = 2; 145 | map meta_data = 3; 146 | } 147 | 148 | //************************ ApplicationAdminService ***************************** 149 | service ApplicationAdminService { 150 | rpc CreateOrUpdateApplication(ApplicationRequest) returns (Token); 151 | 152 | rpc DeleteApplication(ApplicationId) returns (stream google.protobuf.Empty); 153 | 154 | rpc GetApplication(ApplicationId) returns (ApplicationOverview); 155 | 156 | rpc GetApplications(google.protobuf.Empty) returns (stream ApplicationOverview); 157 | 158 | rpc RefreshToken(ApplicationId) returns (Token); 159 | 160 | rpc GetConnectedApplicationsByContext(ContextId) returns (ConnectedApplicationOverview); 161 | } 162 | 163 | message ApplicationRequest { 164 | string applicationName = 1; 165 | string description = 2; 166 | string token = 3; 167 | repeated ApplicationContextRole rolesPerContext = 4; 168 | map meta_data = 5; 169 | } 170 | 171 | message ApplicationContextRole { 172 | string context = 1; 173 | repeated string roles = 2; 174 | } 175 | 176 | message Token { 177 | string token = 1; 178 | } 179 | 180 | message ApplicationId { 181 | string applicationName = 1; 182 | } 183 | 184 | message ApplicationOverview { 185 | string applicationName = 1; 186 | string description = 2; 187 | repeated ApplicationContextRole rolesPerContext = 3; 188 | map meta_data = 4; 189 | } 190 | 191 | message ContextId { 192 | string contextName = 1; 193 | } 194 | 195 | message ConnectedApplicationOverview { 196 | repeated string nodes = 1; 197 | repeated ClientApplication applications = 2; 198 | } 199 | 200 | message ClientApplication { 201 | string name = 1; 202 | repeated Client clients = 2; 203 | repeated string commands = 3; 204 | repeated QueryInfo queries = 4; 205 | } 206 | 207 | message Client { 208 | string name = 1; 209 | string node = 2; 210 | repeated io.axoniq.axonserver.grpc.control.EventProcessorInfo processors = 3; 211 | } 212 | 213 | message QueryInfo { 214 | string request = 1; 215 | repeated string responseTypes = 2; 216 | } 217 | 218 | //************************ UserAdminService ***************************** 219 | service UserAdminService { 220 | 221 | rpc CreateOrUpdateUser(CreateOrUpdateUserRequest) returns (stream google.protobuf.Empty); 222 | 223 | rpc DeleteUser(DeleteUserRequest) returns (stream google.protobuf.Empty); 224 | 225 | rpc GetUsers(google.protobuf.Empty) returns (stream UserOverview); 226 | 227 | } 228 | 229 | message CreateOrUpdateUserRequest { 230 | string userName = 1; 231 | string password = 2; 232 | repeated UserRoleRequest userRoles = 3; 233 | } 234 | 235 | message DeleteUserRequest { 236 | string userName = 1; 237 | } 238 | 239 | message UserRoleRequest { 240 | string role = 1; 241 | string context = 2; 242 | } 243 | 244 | message UserRoleOverview { 245 | string role = 1; 246 | string context = 2; 247 | } 248 | 249 | message UserOverview { 250 | string userName = 1; 251 | bool enabled = 2; 252 | repeated UserRoleOverview userRoles = 3; 253 | } 254 | 255 | //***************************** Event Processor Admin Service *************************** 256 | service EventProcessorAdminService { 257 | /*The following api return a stream of Empty to allow the server to complete the stream without any result.*/ 258 | 259 | /* Request to pause an event processor */ 260 | rpc PauseEventProcessor(EventProcessorIdentifier) returns (AdminActionResult); 261 | /* Request to start an event processor */ 262 | rpc StartEventProcessor(EventProcessorIdentifier) returns (AdminActionResult); 263 | /* Request to split the largest segment of a streaming event processor */ 264 | rpc SplitEventProcessor(EventProcessorIdentifier) returns (AdminActionResult); 265 | /* Request to merge the smallest two segments of a streaming event processor */ 266 | rpc MergeEventProcessor(EventProcessorIdentifier) returns (AdminActionResult); 267 | /* Request to move the specified segment of a streaming event processor to the desired destination */ 268 | rpc MoveEventProcessorSegment(MoveSegment) returns (AdminActionResult); 269 | /* Retrieves all event processors registered in an Axon Server cluster */ 270 | rpc GetAllEventProcessors(google.protobuf.Empty) returns (stream EventProcessor); 271 | /* Retrieves all event processors registered in an Axon Server cluster for the specified component*/ 272 | rpc GetEventProcessorsByComponent(Component) returns (stream EventProcessor); 273 | rpc LoadBalanceProcessor(LoadBalanceRequest) returns (stream google.protobuf.Empty); 274 | rpc SetAutoLoadBalanceStrategy(LoadBalanceRequest) returns (stream google.protobuf.Empty); 275 | rpc GetBalancingStrategies(google.protobuf.Empty) returns (stream LoadBalancingStrategy); 276 | } 277 | 278 | message AdminActionResult { 279 | Result result = 1; 280 | } 281 | 282 | enum Result { 283 | /* The handler confirmed that the action was executed successfully */ 284 | SUCCESS = 0; 285 | /* The handler has accepted the result, no result will be returned */ 286 | ACCEPTED = 1; 287 | } 288 | 289 | message EventProcessorIdentifier { 290 | /* the name of the processor */ 291 | string processor_name = 1; 292 | 293 | /* the identifier of the token store this event processor is using */ 294 | string token_store_identifier = 2; 295 | 296 | /* optional parameter to pass in the context name to indicate where the processor is located */ 297 | string context_name = 3; 298 | } 299 | 300 | message MoveSegment { 301 | /* the identifier of the event processor */ 302 | EventProcessorIdentifier event_processor = 1; 303 | 304 | /* the id of the segment to move */ 305 | int32 segment = 2; 306 | 307 | /* the desired destination for the segment */ 308 | string target_client_id = 3; 309 | } 310 | 311 | message EventProcessor { 312 | /* the identifier of the event processor */ 313 | EventProcessorIdentifier identifier = 1; 314 | 315 | /* the event processor mode (subscribing, tracking, pooled) */ 316 | string mode = 2; 317 | 318 | /* true if the event processor is streaming, false otherwise */ 319 | bool isStreaming = 3; 320 | 321 | /* client instances that subscribed the event processor */ 322 | repeated EventProcessorInstance client_instance = 4; 323 | 324 | /* current load balancing strategy name for the event processor */ 325 | string load_balancing_strategy_name = 5; 326 | } 327 | 328 | message EventProcessorInstance { 329 | /* the client identifier */ 330 | string client_id = 1; 331 | /* true if the client instance of the event processor is running, false otherwise */ 332 | bool isRunning = 2; 333 | /* the max number of segments that this client can claim*/ 334 | int32 max_capacity = 3; 335 | /* status of all segments claimed by the client */ 336 | repeated EventProcessorSegment claimed_segment = 4; 337 | } 338 | 339 | message EventProcessorSegment { 340 | /* the identifier of the segment */ 341 | int32 id = 1; 342 | 343 | /* the fractional unit representing the size of the segment*/ 344 | int32 one_part_of = 2; 345 | 346 | /* the id of the client that claimed the segment */ 347 | string claimed_by = 3; 348 | 349 | /* true if the segment has ever reached the head of the stream since it was started, false otherwise */ 350 | bool is_caughtUp = 4; 351 | 352 | /* true if the segment is replaying, false otherwise */ 353 | bool is_replaying = 5; 354 | 355 | /* the approximate position of the token */ 356 | int64 token_position = 6; 357 | 358 | /* true if the segment is in an error loop, false otherwise */ 359 | bool is_in_error = 7; 360 | 361 | /* the error description, if the segment is in error */ 362 | string error = 8; 363 | } 364 | 365 | message LoadBalanceRequest { 366 | EventProcessorIdentifier processor = 1; 367 | string strategy = 2; 368 | } 369 | 370 | message LoadBalancingStrategy { 371 | string strategy = 1; 372 | string label = 2; 373 | } 374 | 375 | /* Message containing connection information for an AxonServer Node */ 376 | message NodeOverview { 377 | 378 | /* The host name to use when connecting to this node */ 379 | string host_name = 1; 380 | 381 | /* The port number for gRPC connections */ 382 | int32 grpc_port = 2; 383 | 384 | /* The port number for HTTP connections */ 385 | int32 http_port = 3; 386 | 387 | /* The unique name of the node to connect with, for purpose of debugging */ 388 | string node_name = 4; 389 | 390 | /* List of replication groups that belongs to this node */ 391 | repeated string replication_groups = 5; 392 | 393 | /* List of tags associated with this node */ 394 | map tags = 6; 395 | } 396 | 397 | /* AuthenticationService, allows to use Axon Server as authentication provider */ 398 | service AuthenticationService { 399 | /* Authenticate a user, returns the user's roles */ 400 | rpc AuthenticateUser(AuthenticateUserRequest) returns (UserRoles); 401 | 402 | /* Authenticate based on an application token, returns the application's roles */ 403 | rpc AuthenticateToken(Token) returns (ApplicationRoles); 404 | } 405 | 406 | message AuthenticateUserRequest { 407 | string userName = 1; 408 | string password = 2; 409 | } 410 | 411 | message ApplicationRoles { 412 | string applicationName = 1; 413 | repeated ContextRole applicationRole = 2; 414 | } 415 | 416 | message ContextRole { 417 | string role = 1; 418 | string context = 2; 419 | } 420 | 421 | message UserRoles { 422 | string userName = 1; 423 | repeated ContextRole userRoles = 3; 424 | } 425 | -------------------------------------------------------------------------------- /src/main/proto/command.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.command; 3 | import "common.proto"; 4 | option java_multiple_files = true; 5 | 6 | /* The CommandService defines the gRPC requests necessary for subscribing command handlers, and dispatching commands. */ 7 | service CommandService { 8 | 9 | /* Opens a stream allowing clients to register command handlers and receive commands. */ 10 | rpc OpenStream (stream CommandProviderOutbound) returns (stream CommandProviderInbound) { 11 | } 12 | 13 | /* Dispatches the given command, returning the result of command execution */ 14 | rpc Dispatch (Command) returns (CommandResponse) { 15 | } 16 | } 17 | 18 | /* An instruction from the components that provides the Command Handler towards AxonServer. */ 19 | message CommandProviderOutbound { 20 | 21 | /* The instruction for AxonServer */ 22 | oneof request { 23 | 24 | /* Instruction to subscribe this component as handler of a specific type of command */ 25 | CommandSubscription subscribe = 1; 26 | 27 | /* Instruction to unsubscribe this component as handler of a specific type of command */ 28 | CommandSubscription unsubscribe = 2; 29 | 30 | /* Instruction to increase the number of instructions AxonServer may send to this component */ 31 | FlowControl flow_control = 3; 32 | 33 | /* Sends a result of Command processing */ 34 | CommandResponse command_response = 4; 35 | 36 | /* Acknowledgement of previously sent instruction via inbound stream */ 37 | InstructionAck ack = 5; 38 | } 39 | 40 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via inbound stream */ 41 | string instruction_id = 6; 42 | } 43 | 44 | /* An instruction or confirmation from AxonServer towards the component that provides the Command Handler */ 45 | message CommandProviderInbound { 46 | /* The instruction from AxonServer for this component */ 47 | oneof request { 48 | 49 | /* Acknowledgement of previously sent instruction via outbound stream */ 50 | InstructionAck ack = 1; 51 | 52 | /* A command for this component to process */ 53 | Command command = 2; 54 | } 55 | 56 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via outbound stream */ 57 | string instruction_id = 3; 58 | } 59 | 60 | /* A message representing a Command that needs to be routed to a component capable of handling it */ 61 | message Command { 62 | 63 | /* The unique identifier of the Command Message */ 64 | string message_identifier = 1; 65 | 66 | /* The name of the command, used for routing it to a destination capable of handling it */ 67 | string name = 2; 68 | 69 | /* The time at which the command was dispatched */ 70 | int64 timestamp = 3; 71 | 72 | /* The payload of the Command, providing details on the instructions for the recipient */ 73 | SerializedObject payload = 4; 74 | 75 | /* Meta Data entries of the Command Message, providing contextual information to the recipient */ 76 | map meta_data = 5; 77 | 78 | /* Instructions for AxonServer when routing this Command Message */ 79 | repeated ProcessingInstruction processing_instructions = 6; 80 | 81 | /* The unique identifier of the component dispatching this message */ 82 | string client_id = 7; 83 | 84 | /* The name/type of the component dispatching this message */ 85 | string component_name = 8; 86 | } 87 | 88 | /* Message representing the result of Command Handler execution */ 89 | message CommandResponse { 90 | 91 | /* The unique identifier of the response message */ 92 | string message_identifier = 1; 93 | 94 | /* An error code describing the error, if any */ 95 | string error_code = 2; 96 | 97 | /* A detailed description of the error */ 98 | ErrorMessage error_message = 3; 99 | 100 | /* The payload to provide as a result to the dispatcher */ 101 | SerializedObject payload = 4; 102 | 103 | /* Any meta data entries providing contextual information back to the dispatcher */ 104 | map meta_data = 5; 105 | 106 | /* Instructions for AxonServer when routing this Command Response Message */ 107 | repeated ProcessingInstruction processing_instructions = 6; 108 | 109 | /* The unique identifier of the Command Message for which this is the response */ 110 | string request_identifier = 7; 111 | } 112 | 113 | /* Message describing a component's capability of handling a command type */ 114 | message CommandSubscription { 115 | /* A unique identifier for this subscription. This identifier is returned in Acknowledgements to allow 116 | pipelining of subscription messages */ 117 | string message_id = 1; 118 | 119 | /* The name of the command the component can handle */ 120 | string command = 2; 121 | 122 | /* The name/type of the component handling the command */ 123 | string component_name = 3; 124 | 125 | /* The unique identifier of the component instance subscribing */ 126 | string client_id = 4; 127 | 128 | /* A number that represents the client's relative load capacity compared to other clients. 129 | This information is interpreted by Axon Server in relation to the other connected nodes' values. 130 | Used to balance the dispatching of commands. If set to 0, Axon Server consider 100 as default value.*/ 131 | int32 load_factor = 5; 132 | } 133 | -------------------------------------------------------------------------------- /src/main/proto/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc; 3 | import "google/protobuf/any.proto"; 4 | option java_multiple_files = true; 5 | 6 | /* Describes a serialized object */ 7 | message SerializedObject { 8 | 9 | /* The type identifier of the serialized object. */ 10 | string type = 1; 11 | 12 | /* The revision of the serialized form of the given type. */ 13 | string revision = 2; 14 | 15 | /* The actual data representing the object in serialized form. */ 16 | bytes data = 3; 17 | } 18 | 19 | /* The value of a MetaData entry. */ 20 | message MetaDataValue { 21 | 22 | /* The data of the MetaData entry, depending on the type of data it contains. */ 23 | oneof data { 24 | 25 | /* The text value of the Meta Data entry. */ 26 | string text_value = 1; 27 | 28 | /* The numeric value of the Meta Data entry. */ 29 | sint64 number_value = 2; 30 | 31 | /* The boolean value of the Meta Data entry. */ 32 | bool boolean_value = 3; 33 | 34 | /* The floating point value of the Meta Data entry. */ 35 | double double_value = 4; 36 | 37 | /* The binary value of the Meta Data entry. */ 38 | SerializedObject bytes_value = 5; 39 | } 40 | } 41 | 42 | /* An instruction for routing components when routing or processing a message. */ 43 | message ProcessingInstruction { 44 | 45 | /* The type of processing message. */ 46 | ProcessingKey key = 1; 47 | 48 | /* The value associated with the processing key. */ 49 | MetaDataValue value = 2; 50 | } 51 | 52 | /* An enumeration of possible keys for processing instructions. */ 53 | enum ProcessingKey { 54 | 55 | /* key indicating that the attached value should be used for consistent routing. */ 56 | ROUTING_KEY = 0; 57 | 58 | /* key indicating that the attached value indicates relative priority of this message. */ 59 | PRIORITY = 1; 60 | 61 | /* key indicating that the accompanied message has a finite validity. The attached value contains the number of milliseconds. */ 62 | TIMEOUT = 2; 63 | 64 | /* key indicating that the requester expects at most the given number of results from this message. Use -1 for unlimited. */ 65 | NR_OF_RESULTS = 3; 66 | 67 | // do not reuse reserved number to ensure forward and backward compatibility 68 | reserved 4, 5, 6; 69 | 70 | /* key indicating whether Axon Server supports streaming. */ 71 | SERVER_SUPPORTS_STREAMING = 7; 72 | 73 | /* key indicating whether Client supports streaming. */ 74 | CLIENT_SUPPORTS_STREAMING = 8; 75 | } 76 | 77 | /* Message containing details of an error */ 78 | message ErrorMessage { 79 | 80 | /* A human readable message explaining the error */ 81 | string message = 1; 82 | 83 | /* A description of the location (client component, server) where the error occurred */ 84 | string location = 2; 85 | 86 | /* A collection of messages providing more details about root causes of the error */ 87 | repeated string details = 3; 88 | 89 | /* An Error Code identifying the type of error */ 90 | string error_code = 4; 91 | } 92 | 93 | /* Message used for Flow Control instruction, providing the counterpart with additional permits for sending messages */ 94 | message FlowControl { 95 | 96 | reserved 1; 97 | 98 | /* The ClientID of the component providing additional permits */ 99 | string client_id = 2; 100 | 101 | /* The number of permits to provide */ 102 | int64 permits = 3; 103 | } 104 | 105 | /* Message describing instruction acknowledgement */ 106 | message InstructionAck { 107 | 108 | /* The identifier of the instruction */ 109 | string instruction_id = 1; 110 | 111 | /* Indicator whether the instruction was acknowledged successfully */ 112 | bool success = 2; 113 | 114 | /* Set if instruction acknowledgement failed. */ 115 | ErrorMessage error = 3; 116 | } 117 | 118 | /* Message describing the result of the execution of an instruction*/ 119 | message InstructionResult { 120 | 121 | /* The identifier of the instruction */ 122 | string instruction_id = 1; 123 | 124 | /* Indicator whether the instruction was processed successfully */ 125 | bool success = 2; 126 | 127 | /* Cause of instruction handling failure. */ 128 | ErrorMessage error = 3; 129 | } 130 | 131 | /* Defines status values for a scheduled task */ 132 | enum TaskStatus { 133 | // Task is scheduled for execution 134 | SCHEDULED = 0; 135 | // Task execution completed successfully 136 | COMPLETED = 1; 137 | // Task execution failed with non transient exception 138 | FAILED = 2; 139 | // Task execution is in progress 140 | RUNNING = 3; 141 | // Task execution is in progress 142 | CANCELLED = 4; 143 | } 144 | 145 | message Component { 146 | string component = 1; 147 | } 148 | 149 | message Principal { 150 | string user = 1; 151 | } -------------------------------------------------------------------------------- /src/main/proto/control.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.control; 3 | import "common.proto"; 4 | option java_multiple_files = true; 5 | 6 | /* Service describing operations for connecting to the AxonServer platform. 7 | 8 | Clients are expected to use this service on any of the Platform's Admin nodes to obtain connection information of the 9 | node that it should set up the actual connection with. On that second node, the clients should open an instruction 10 | stream (see OpenStream), so that AxonServer and the client application can exchange information and instructions. 11 | */ 12 | service PlatformService { 13 | 14 | /* Obtains connection information for the Server that a Client should use for its connections. */ 15 | rpc GetPlatformServer (ClientIdentification) returns (PlatformInfo) { 16 | } 17 | 18 | /* Opens an instruction stream to the Platform, allowing AxonServer to provide management instructions to the application */ 19 | rpc OpenStream (stream PlatformInboundInstruction) returns (stream PlatformOutboundInstruction) { 20 | } 21 | } 22 | 23 | /* An instruction from Application Node to the AxonServer platform */ 24 | message PlatformInboundInstruction { 25 | /* The actual instruction to send */ 26 | oneof request { 27 | 28 | /* Information about the client being connected. 29 | This information is used by AxonServer to monitor the topology of connected applications. 30 | */ 31 | ClientIdentification register = 1; 32 | 33 | /* Information about Processors defined in the application. 34 | This information is used by Axon Server to monitor the progress of Event Processors across instances. 35 | */ 36 | EventProcessorInfo event_processor_info = 2; 37 | 38 | /* This heartbeat is used by AxonServer in order to check if the connection is still alive*/ 39 | Heartbeat heartbeat = 3; 40 | 41 | /* Acknowledgement of previously sent instruction via outbound stream */ 42 | InstructionAck ack = 4; 43 | 44 | /* The result of the execution of an instruction */ 45 | InstructionResult result = 6; 46 | } 47 | 48 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via outbound stream */ 49 | string instruction_id = 5; 50 | } 51 | 52 | /* An instruction or information from the AxonServer Platform to the Application Node */ 53 | message PlatformOutboundInstruction { 54 | 55 | /* The actual instruction or information */ 56 | oneof request { 57 | 58 | /* Information provided by AxonServer which provides information about the AxonServer node the application is connected with */ 59 | NodeInfo node_notification = 1; 60 | 61 | /* A request from AxonServer to the Application to migrate its connection to another node. 62 | Clients SHOULD honor this request by closing their current connection, and using the GetPlatformServer RPC 63 | to request a new destination. 64 | */ 65 | RequestReconnect request_reconnect = 3; 66 | 67 | /* Instruction from AxonServer to Pause a Streaming Event Processor. */ 68 | EventProcessorReference pause_event_processor = 4; 69 | 70 | /* Instruction from AxonServer to Start a Streaming Event Processor. */ 71 | EventProcessorReference start_event_processor = 5; 72 | 73 | /* Instruction from AxonServer to Release a specific segment in a Streaming Event Processor */ 74 | EventProcessorSegmentReference release_segment = 6; 75 | 76 | /* A request from AxonServer for status information of a specific Streaming Event Processor */ 77 | EventProcessorReference request_event_processor_info = 7; 78 | 79 | /* Instruction to split a Segment in a Streaming Event Processor */ 80 | EventProcessorSegmentReference split_event_processor_segment = 8; 81 | 82 | /* Instruction to merge two Segments in a Streaming Event Processor */ 83 | EventProcessorSegmentReference merge_event_processor_segment = 9; 84 | 85 | /* This heartbeat is used by AxonFramework in order to check if the connection is still alive*/ 86 | Heartbeat heartbeat = 10; 87 | 88 | /* Acknowledgement of previously sent instruction via inbound stream */ 89 | InstructionAck ack = 11; 90 | } 91 | 92 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via inbound stream */ 93 | string instruction_id = 12; 94 | } 95 | 96 | /* Message send when AxonServer requests the client to re-establish its connection with the Platform */ 97 | message RequestReconnect { 98 | } 99 | 100 | /* Message containing connection information of the node to Connect with */ 101 | message PlatformInfo { 102 | 103 | /* The connection details of the node the client should connect with */ 104 | NodeInfo primary = 1; 105 | 106 | /* Flag indicating that the connection may be reused to connect. When true, the client _may_ reuse the connection 107 | established for the GetPlatformServer request for subsequent requests. 108 | */ 109 | bool same_connection = 2; 110 | } 111 | 112 | /* Message containing connection information for an AxonServer Node */ 113 | message NodeInfo { 114 | 115 | /* The host name to use when connecting to this node */ 116 | string host_name = 1; 117 | 118 | /* The port number for gRPC connections */ 119 | int32 grpc_port = 2; 120 | 121 | /* The port number for HTTP connections */ 122 | int32 http_port = 3; 123 | 124 | /* The version identifier of the API */ 125 | int32 version = 4; 126 | 127 | /* The unique name of the node to connect with, for purpose of debugging */ 128 | string node_name = 5; 129 | } 130 | 131 | /* Message containing details about the Client Application */ 132 | message ClientIdentification { 133 | 134 | /* A unique identifier for this client instance. Is used to distinguish different instances of the same component */ 135 | string client_id = 1; 136 | 137 | /* The name of the component. Several instances of the same component should share this name */ 138 | string component_name = 2; 139 | 140 | /* Any tags associated with the client, which may provide hints and preferences for setting up connections */ 141 | map tags = 3; 142 | 143 | /* Axon framework version used by the client application instance*/ 144 | string version = 4; 145 | } 146 | 147 | /* Message containing information about the status of an Event Processor */ 148 | message EventProcessorInfo { 149 | 150 | /* Message containing information about the status of a Segment of a Streaming Event Processor */ 151 | message SegmentStatus { 152 | /* The ID of the Segment for which the status is reported */ 153 | int32 segment_id = 1; 154 | 155 | /* Indicates whether the Segment has "Caught Up" with the Head of the Event Stream */ 156 | bool caught_up = 2; 157 | 158 | /* Indicates whether the Segment is "Replaying" historic events after a Reset. */ 159 | bool replaying = 3; 160 | 161 | /* The fraction this segment processes. A fraction of 2 means 1/2, 4 means 1/4, etc.*/ 162 | int32 one_part_of = 4; 163 | 164 | /* The approximate position of the token in the stream. */ 165 | int64 token_position = 5; 166 | 167 | /* Information about the error state of the Segment, if applicable. */ 168 | string error_state = 6; 169 | } 170 | 171 | /* The logical name of this processor. */ 172 | string processor_name = 1; 173 | 174 | /* The mode in which this processor is reading Events, for example: 'Tracking' or 'Subscribing' */ 175 | string mode = 2; 176 | 177 | /* The number of threads currently actively processing Events */ 178 | int32 active_threads = 3; 179 | 180 | /* Flag indicating whether the processor is running */ 181 | bool running = 4; 182 | 183 | /* Flag indicating whether the processor, when stopped, did so because of an irrecoverable Error */ 184 | bool error = 5; 185 | 186 | /* Status details of each of the Segments for which Events are being processed. This is only provided by Streaming 187 | Event Processors. 188 | */ 189 | repeated SegmentStatus segment_status = 6; 190 | 191 | /* The number of threads the processor has available to assign to Segments. 192 | Will report 0 if all threads are assigned a Segment. 193 | */ 194 | int32 available_threads = 7; 195 | 196 | /* The Token Store Identifier if available. This is only provided by Streaming Event Processors.*/ 197 | string token_store_identifier = 8; 198 | 199 | /* Flag indicating whether the processor is a Streaming Event Processor. 200 | This dictates whether streaming operations, like split and merge, are supported by this processor. 201 | */ 202 | bool is_streaming_processor = 9; 203 | 204 | /* current load balancing strategy name for the event processor */ 205 | string load_balancing_strategy_name = 10; 206 | } 207 | 208 | /* Message providing reference to an Event Processor */ 209 | message EventProcessorReference { 210 | 211 | /* The name of the Event Processor */ 212 | string processor_name = 1; 213 | } 214 | 215 | /* Message providing reference to a Segment of an Event Processor */ 216 | message EventProcessorSegmentReference { 217 | 218 | /* The name of the Event Processor */ 219 | string processor_name = 1; 220 | 221 | /* The identifier of the Segment */ 222 | int32 segment_identifier = 2; 223 | } 224 | 225 | message Heartbeat { 226 | } -------------------------------------------------------------------------------- /src/main/proto/dcb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.event.dcb; 3 | option java_multiple_files = true; 4 | 5 | /* EXPERIMENTAL: Service providing Event Store RPCs supporting DCB. */ 6 | service DcbEventStore { 7 | 8 | /* Appends new events to the store. */ 9 | rpc Append (stream AppendEventsRequest) returns (AppendEventsResponse); 10 | 11 | /* Provides a finite stream of events based on the passed SourceEventsRequest. */ 12 | rpc Source (SourceEventsRequest) returns (stream SourceEventsResponse); 13 | 14 | /* Provides an infinite stream of events based on the passed StreamEventsRequest. */ 15 | rpc Stream (StreamEventsRequest) returns (stream StreamEventsResponse); 16 | 17 | /* Gets the current _head_ of the Event Store. The _head_ points to the sequence of the first event to be appended. */ 18 | rpc GetHead (GetHeadRequest) returns (GetHeadResponse); 19 | 20 | /* Gets the current _tail_ of the Event Store. The _tail_ points to the sequence of the first event stored. */ 21 | rpc GetTail (GetTailRequest) returns (GetTailResponse); 22 | 23 | /* Returns the lowest sequence of an event with a timestamp equal to or higher than the given timestamp. The HEAD is 24 | returned if no events exist with a timestamp equal to or higher than the given timestamp. 25 | 26 | N.B. Axon Server does not assign timestamps to events. The timestamps used for fulfilling this RPC are timestamps 27 | provided by the client. It could happen that there are events after the returned sequence that have an earlier 28 | timestamp. Axon Server does not reject appends if timestamps of events are not monotonically increasing. */ 29 | rpc GetSequenceAt (GetSequenceAtRequest) returns (GetSequenceAtResponse); 30 | 31 | /* Assigns tags to the event identified by its sequence. */ 32 | rpc AddTags (AddTagsRequest) returns (AddTagsResponse); 33 | 34 | /* Removes tags from the event identified by its sequence. */ 35 | rpc RemoveTags (RemoveTagsRequest) returns (RemoveTagsResponse); 36 | 37 | /* Gets tags for the event identified by its sequence. */ 38 | rpc GetTags (GetTagsRequest) returns (GetTagsResponse); 39 | } 40 | 41 | /* EXPERIMENTAL: Service providing Snapshot Store RPCs. */ 42 | service DcbSnapshotStore { 43 | 44 | /* Adds a snapshot to the snapshot store. */ 45 | rpc Add (AddSnapshotRequest) returns (AddSnapshotResponse); 46 | 47 | /* Deletes a snapshot from the snapshot store. */ 48 | rpc Delete (DeleteSnapshotsRequest) returns (DeleteSnapshotsResponse); 49 | 50 | /* Retrieves snapshots from the snapshot store. */ 51 | rpc List (ListSnapshotsRequest) returns (stream ListSnapshotsResponse); 52 | 53 | /* Gets the latest snapshot based on the request from the snapshot store. */ 54 | rpc GetLast (GetLastSnapshotRequest) returns (GetLastSnapshotResponse); 55 | } 56 | 57 | /* The event message. */ 58 | message Event { 59 | 60 | /* The unique identifier of the event. */ 61 | string identifier = 1; 62 | 63 | /* The timestamp of the event. */ 64 | int64 timestamp = 2; 65 | 66 | /* The name of the event. */ 67 | string name = 3; 68 | 69 | /* The version of the event. */ 70 | string version = 4; 71 | 72 | /* The payload of the event. */ 73 | bytes payload = 5; 74 | 75 | /* The metadata of the event. */ 76 | map metadata = 6; 77 | } 78 | 79 | /* The tag. Describes an event with more details. Usually using concepts from the Domain. */ 80 | message Tag { 81 | 82 | /* The key of the tag. */ 83 | bytes key = 1; 84 | 85 | /* The value of the tag. */ 86 | bytes value = 2; 87 | } 88 | 89 | /* The event described in more details by a list of tags. */ 90 | message TaggedEvent { 91 | 92 | /* The event. */ 93 | Event event = 1; 94 | 95 | /* List of tags describing the given event in more details. */ 96 | repeated Tag tag = 2; 97 | } 98 | 99 | /* The event retrieved from the event store with its corresponding sequence. */ 100 | message SequencedEvent { 101 | 102 | /* The sequence of the event. */ 103 | int64 sequence = 1; 104 | 105 | /* The event. */ 106 | Event event = 2; 107 | } 108 | 109 | /* The message representing the request to append events to the event store. */ 110 | message AppendEventsRequest { 111 | 112 | /* The condition used to check the validity of this request. If omitted, events will be appended unconditionally. */ 113 | ConsistencyCondition condition = 1; 114 | 115 | /* A list of tagged events to be appended to the event store if the condition is met. 116 | These events are considered as a transaction - they are either all appended or none of them are appended. 117 | The event store will index the events based on provided tags for future faster retrieval. */ 118 | repeated TaggedEvent event = 2; 119 | } 120 | 121 | /* The response of a successful append events request. If there was an issue with the append events request, 122 | the stream will complete with an error. */ 123 | message AppendEventsResponse { 124 | 125 | /* The sequence of the first event stored in the event store. 126 | Corresponding to the list of events (a transaction) passed in the AppendEventsRequest. */ 127 | int64 sequence_of_the_first_event = 1; 128 | 129 | /* The number of events appended. Matches the number of events passed in the AppendEventsRequest. */ 130 | int32 transaction_size = 2; 131 | 132 | /* The consistency marker which may be used for a subsequent append events requests. Do note that during the time this 133 | consistency marker may get far behind the head of the event store which will increase the time needed for the append 134 | events request to be validated. If you don't plan to do subsequent append events requests in a "short" period of time, 135 | use the Source RPC to refresh the consistency marker. */ 136 | int64 consistency_marker = 3; 137 | } 138 | 139 | /* The request to source events from the event store. It results in a finite stream of events completed by 140 | the event store. It may also be cancelled by the client. Only events matching the given criteria 141 | (a provided list of criterions) will be present in the stream. The stream is capped by the HEAD of the event store. */ 142 | message SourceEventsRequest { 143 | 144 | /* An inclusive sequence of the first event to be included in the resulting stream. */ 145 | int64 from_sequence = 1; 146 | 147 | /* The criteria consisting of the list of criterions. If at least one of these criterions is met, 148 | the criteria is met. */ 149 | repeated Criterion criterion = 2; 150 | } 151 | 152 | /* The response to the SourceEventsRequest. It consists either of an event (with its corresponding sequence) or a 153 | consistency marker. The consistency marker should be used in a following AppendEventsRequest related to the criteria used in the SourceEventsRequest this response originates from. */ 154 | message SourceEventsResponse { 155 | oneof result { 156 | 157 | /* The event matching the criteria with its corresponding sequence. */ 158 | SequencedEvent event = 1; 159 | 160 | /* The consistency marker to be used for the following append related to the same criteria. */ 161 | int64 consistency_marker = 2; 162 | } 163 | } 164 | 165 | /* The condition for an AppendEventsRequest. Consists of the consistency marker and the criteria 166 | (a list of criterions). */ 167 | message ConsistencyCondition { 168 | 169 | /* The sequence used to start checking for the consistency of an append. If there are events with a sequence greater 170 | or equal than the consistency marker and those are matching the given criteria, the condition is not met and the transaction 171 | is rejected. Otherwise, it is accepted. */ 172 | int64 consistency_marker = 1; 173 | 174 | /* The criteria. Consists of a list of criterions. If a single criterion is met, the whole criteria is met. */ 175 | repeated Criterion criterion = 2; 176 | } 177 | 178 | /* The integral part of the criteria. */ 179 | message Criterion { 180 | 181 | /* The criterion based on event tags and event names. */ 182 | TagsAndNamesCriterion tags_and_names = 1; 183 | } 184 | 185 | /* The criterion based on event tags and event names. The event meets this criterion if ALL tags from this criterion 186 | are present in the tags of the event AND if the event name is present in one of the names of the this criterion. */ 187 | message TagsAndNamesCriterion { 188 | 189 | /* A list of event names. The event meets this criterion if its name is in one of the names in this list. */ 190 | repeated string name = 1; 191 | 192 | /* A list of event tags. The event meets this criterion if it contains all the tags from this list. It meets the 193 | criterion if it contains more than provided list here, but it MUST contain all from the list. */ 194 | repeated Tag tag = 2; 195 | } 196 | 197 | /* The request to provide an infinite stream of events from the event store. The client may cancel the stream at any 198 | time. */ 199 | message StreamEventsRequest { 200 | 201 | /* The inclusive sequence to start streaming from. */ 202 | int64 from_sequence = 1; 203 | 204 | /* The criteria used to filter out events. Represented by a list of criterions. If at least one is met, the whole 205 | criteria is met. */ 206 | repeated Criterion criterion = 2; 207 | } 208 | 209 | /* The response to the StreamEventsRequest. */ 210 | message StreamEventsResponse { 211 | 212 | /* The event with its corresponding sequence. */ 213 | SequencedEvent event = 1; 214 | } 215 | 216 | /* The request to retrieve the current HEAD of the event store. */ 217 | message GetHeadRequest { 218 | 219 | } 220 | 221 | /* The current HEAD of the event store. */ 222 | message GetHeadResponse { 223 | 224 | /* The sequence of the current head. Points to the position of the first event to be appended. The HEAD of an empty 225 | event store is 0. */ 226 | int64 sequence = 1; 227 | } 228 | 229 | /* The request to retrieve the current TAIL of the event store. */ 230 | message GetTailRequest { 231 | 232 | } 233 | 234 | /* The current TAIL of the event store. */ 235 | message GetTailResponse { 236 | 237 | /* The sequence of the first event in the event store. 0 for an empty event store. 0 for a non-truncated event store. 238 | Non-zero for a truncated event store. */ 239 | int64 sequence = 1; 240 | } 241 | 242 | /* The request to get the sequence of the event whose timestamp is the same as the timestamp provided in the request. 243 | If there are no events with the exact timestamp, then the sequence of the first one after the provided timestamp is 244 | returned. If the provided timestamp is greater that the sequence of the last event in the event store, 245 | the HEAD is returned. */ 246 | message GetSequenceAtRequest { 247 | 248 | /* The timestamp. */ 249 | int64 timestamp = 1; 250 | } 251 | 252 | /* The sequence of the event approximately close to the provided timestamp. */ 253 | message GetSequenceAtResponse { 254 | 255 | /* The sequence of the event. */ 256 | int64 sequence = 1; 257 | } 258 | 259 | /* The request to add tags to the event. */ 260 | message AddTagsRequest { 261 | 262 | /* The sequence of the event whose tags list will be expanded with the tags from the request. */ 263 | int64 sequence = 1; 264 | 265 | /* The tags to be added to the event. If the event already contains a tag from the same list 266 | (with the same key and the value) the new one will be ignored. */ 267 | repeated Tag tag = 2; 268 | } 269 | 270 | /* The response indicating a successful addition of tags to the event. */ 271 | message AddTagsResponse { 272 | 273 | } 274 | 275 | /* The request to remove tags from the event. */ 276 | message RemoveTagsRequest { 277 | 278 | /* The sequence of the event whose tags should be removed. */ 279 | int64 sequence = 1; 280 | 281 | /* Tags to be removed. If the event is not tagged with listed tags, they are skipped. */ 282 | repeated Tag tag = 2; 283 | } 284 | 285 | /* The response indicating a successful removal of tags for the event. */ 286 | message RemoveTagsResponse { 287 | 288 | } 289 | 290 | /* The request to retrieve tags of the event. */ 291 | message GetTagsRequest { 292 | 293 | /* The sequence of the event whose tags should be retrieved. */ 294 | int64 sequence = 1; 295 | } 296 | 297 | /* The response containing tags of an event. */ 298 | message GetTagsResponse { 299 | 300 | /* The tags associated to the event. */ 301 | repeated Tag tag = 1; 302 | } 303 | 304 | /* The snapshot. */ 305 | message Snapshot { 306 | 307 | /* The name of the snapshot. */ 308 | string name = 1; 309 | 310 | /* The revision of the snapshot. */ 311 | string revision = 2; 312 | 313 | /* The payload of the snapshot. */ 314 | bytes payload = 3; 315 | } 316 | 317 | /* The request to add the snapshot to the snapshot store. */ 318 | message AddSnapshotRequest { 319 | 320 | /* The key this snapshot is added to. */ 321 | bytes key = 1; 322 | 323 | /* The sequence of the snapshot. Usually linked to the sequence of the event in the event store up to which 324 | the snapshot is taken. */ 325 | int64 sequence = 2; 326 | 327 | /* If set to true, older snapshots for the same key are pruned. */ 328 | bool prune = 3; 329 | 330 | /* The snapshot. */ 331 | Snapshot snapshot = 4; 332 | } 333 | 334 | /* The response indicating the successful addition of the snapshot. */ 335 | message AddSnapshotResponse { 336 | 337 | } 338 | 339 | /* The request to delete the snapshot from the snapshot store. */ 340 | message DeleteSnapshotsRequest { 341 | 342 | /* The key the snapshot is identified by. */ 343 | bytes key = 1; 344 | 345 | /* The inclusive bottom bound sequence of the snapshot to start the deletion. */ 346 | int64 from_sequence = 2; 347 | 348 | /* The exclusive upper bound sequence of the snapshot to end the deletion. */ 349 | int64 to_sequence = 3; 350 | } 351 | 352 | /* The response indicating the successful deletion of the snapshot. */ 353 | message DeleteSnapshotsResponse { 354 | 355 | } 356 | 357 | /* The request to retrieve all snapshots from the snapshot store based on the key and sequence bounds. */ 358 | message ListSnapshotsRequest { 359 | 360 | /* The key of the snapshot. */ 361 | bytes key = 1; 362 | 363 | /* The inclusive bottom bound sequence used to filter out snapshots. */ 364 | int64 from_sequence = 2; 365 | 366 | /* The exclusive upper bound sequence used to filter out snapshots. */ 367 | int64 to_sequence = 3; 368 | } 369 | 370 | /* The response to the ListSnapshotRequest. */ 371 | message ListSnapshotsResponse { 372 | 373 | /* The key of the snapshot. */ 374 | bytes key = 1; 375 | 376 | /* The sequence of the snapshot. */ 377 | int64 sequence = 2; 378 | 379 | /* The snapshot. */ 380 | Snapshot snapshot = 3; 381 | } 382 | 383 | /* The request to retrieve the snapshot with the highest sequence from the snapshot store. */ 384 | message GetLastSnapshotRequest { 385 | 386 | /* The key of the snapshot. */ 387 | bytes key = 1; 388 | } 389 | 390 | /* The response to GetLatestSnapshotRequest. */ 391 | message GetLastSnapshotResponse { 392 | 393 | /* The key of the snapshot. */ 394 | bytes key = 1; 395 | 396 | /* The sequence of the snapshot. */ 397 | int64 sequence = 2; 398 | 399 | /* The snapshot. */ 400 | Snapshot snapshot = 3; 401 | } -------------------------------------------------------------------------------- /src/main/proto/event.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.event; 3 | import "common.proto"; 4 | import "google/protobuf/empty.proto"; 5 | option java_multiple_files = true; 6 | 7 | /* Service providing operations against the EventStore functionality of Axon Server */ 8 | service EventStore { 9 | 10 | // Accepts a stream of Events returning a Confirmation when completed. 11 | rpc AppendEvent (stream Event) returns (Confirmation) { 12 | } 13 | 14 | // Accepts a Snapshot event returning a Confirmation when completed. 15 | rpc AppendSnapshot (Event) returns (Confirmation) { 16 | } 17 | 18 | // Retrieves the Events for a given aggregate. Results are streamed rather than returned at once. 19 | rpc ListAggregateEvents (GetAggregateEventsRequest) returns (stream Event) { 20 | } 21 | 22 | // Retrieves the Snapshots for a given aggregate. Results are streamed rather than returned at once. 23 | rpc ListAggregateSnapshots (GetAggregateSnapshotsRequest) returns (stream Event) { 24 | } 25 | 26 | /* Retrieves the Events from a given tracking token. However, if several GetEventsRequests are sent in the stream 27 | only first one will create the tracker, others are used for increasing number of permits or blacklisting. Results 28 | are streamed rather than returned at once. */ 29 | rpc ListEvents (stream GetEventsRequest) returns (stream EventWithToken) { 30 | } 31 | 32 | // Gets the highest sequence number for a specific aggregate. 33 | rpc ReadHighestSequenceNr (ReadHighestSequenceNrRequest) returns (ReadHighestSequenceNrResponse) { 34 | } 35 | 36 | // Performs a query on the event store, returns a stream of results. Input is a stream to allow flow control from the 37 | // client 38 | rpc QueryEvents (stream QueryEventsRequest) returns (stream QueryEventsResponse) { 39 | } 40 | 41 | // Retrieves the first token available in event store (typically 0). Returns 0 when no events in store. 42 | rpc GetFirstToken (GetFirstTokenRequest) returns (TrackingToken) { 43 | } 44 | 45 | // Retrieves the last committed token in event store. Returns -1 when no events in store. 46 | rpc GetLastToken (GetLastTokenRequest) returns (TrackingToken) { 47 | } 48 | 49 | // Retrieves the token of the first token of an event from specified time in event store. Returns -1 when no events in store. 50 | rpc GetTokenAt (GetTokenAtRequest) returns (TrackingToken) { 51 | } 52 | } 53 | 54 | /* Service to use AxonServer as a provider of an EventScheduler */ 55 | service EventScheduler { 56 | // Schedule the given event for publication at the given time}. The returned ScheduleToken can be used to cancel the planned publication. 57 | rpc ScheduleEvent (ScheduleEventRequest) returns (ScheduleToken) { 58 | } 59 | // Cancel a scheduled event and schedule another in its place. 60 | rpc RescheduleEvent (RescheduleEventRequest) returns (ScheduleToken) { 61 | } 62 | // Cancel the publication of a scheduled event. If the events has already been published, this method does nothing. 63 | rpc CancelScheduledEvent (CancelScheduledEventRequest) returns (InstructionAck) { 64 | } 65 | } 66 | 67 | /* Service to transform events in an event store */ 68 | service EventTransformationService { 69 | 70 | // Returns the list of all transformations. 71 | rpc Transformations(google.protobuf.Empty) returns (stream Transformation) { 72 | } 73 | 74 | // Starts a new transformation. 75 | rpc StartTransformation(StartTransformationRequest) returns (TransformationId) { 76 | } 77 | 78 | // Adds requests to transform an event to a transformation. 79 | rpc TransformEvents(stream TransformRequest) returns (stream TransformRequestAck) { 80 | } 81 | 82 | // Cancels a transformation before it is applied. 83 | rpc CancelTransformation(TransformationId) returns (stream google.protobuf.Empty) { 84 | } 85 | 86 | // Applies the changes from a transformation in the event store. 87 | rpc ApplyTransformation(ApplyTransformationRequest) returns (stream google.protobuf.Empty) { 88 | } 89 | 90 | // Deletes old versions of events updated by a transformation. 91 | rpc Compact(CompactionRequest) returns (stream google.protobuf.Empty) { 92 | } 93 | } 94 | 95 | /* Request to compact event store. */ 96 | message CompactionRequest { 97 | } 98 | 99 | /* The transformation data. */ 100 | message Transformation { 101 | 102 | // The identifier of the transformation. 103 | TransformationId transformationId = 1; 104 | 105 | // The state of the transformation 106 | TransformationState state = 2; 107 | 108 | // The sequence of the last transformation action stored. Needed for checking sequential consistency of requests. 109 | int64 sequence = 3; 110 | 111 | // The bounded context in which this transformation is being executed. 112 | string context = 4; 113 | 114 | // The description of the transformation. 115 | string description = 5; 116 | 117 | // The timestamp at which the transformation was applied. Set to -1 if the transformation was not applied. 118 | int64 applied_at = 6; 119 | 120 | // The username of user who requested the transformation to be applied. Empty if the transformation was not applied. 121 | string apply_requester = 7; 122 | 123 | // The version of the transformation. The sequence 124 | int32 version = 8; 125 | } 126 | 127 | /* The state of the transformation. */ 128 | enum TransformationState { 129 | // The transformation is opened, able to receive request to transform events, or to be applied or cancelled. 130 | ACTIVE = 0; 131 | // The transformation has been cancelled. This a final state. 132 | CANCELLED = 1; 133 | // The transformation is in progress of applying its actions to the event store. 134 | APPLYING = 2; 135 | // The transformation has been applied to the event store. This a final state. 136 | APPLIED = 3; 137 | } 138 | 139 | /* Request to start a transformation */ 140 | message StartTransformationRequest { 141 | /* A description of the purpose of this transformation, for reference only */ 142 | string description = 1; 143 | } 144 | 145 | /* Request to apply a transformation */ 146 | message ApplyTransformationRequest { 147 | /* The identification of the transformation */ 148 | TransformationId transformation_id = 1; 149 | /* The sequence of the last entry in this transformation */ 150 | int64 last_sequence = 2; 151 | } 152 | 153 | /* Message containing one event to transform within a transformation */ 154 | message TransformRequest { 155 | /* The identification of the transformation */ 156 | TransformationId transformation_id = 1; 157 | /* The sequence of the current transformation */ 158 | int64 sequence = 2; 159 | oneof request { 160 | /* Replaces the content of an event with the new content */ 161 | TransformedEvent replace_event = 3; 162 | /* Deletes the content of an event */ 163 | DeletedEvent delete_event = 4; 164 | } 165 | } 166 | 167 | /* Replaces the content of an event with the new content */ 168 | message TransformedEvent { 169 | /* The global index of the event to replace */ 170 | int64 token = 1; 171 | /* The new content of the event */ 172 | Event event = 2; 173 | } 174 | 175 | /* Deletes the content of an event */ 176 | message DeletedEvent { 177 | /* The global index of the event to clear */ 178 | int64 token = 1; 179 | } 180 | 181 | /* Uniquely identifies a transformation */ 182 | message TransformationId { 183 | // The value of the identifier. 184 | string id = 1; 185 | } 186 | 187 | /* Acknowledgement that event with given token has been transformed successfully */ 188 | message TransformRequestAck { 189 | 190 | /* The sequence of the transformation request */ 191 | int64 sequence = 1; 192 | } 193 | 194 | 195 | /* Request message to schedule an event */ 196 | message ScheduleEventRequest { 197 | /* timestamp when to publish the event */ 198 | int64 instant = 1; 199 | /* the event to publish */ 200 | Event event = 2; 201 | } 202 | 203 | /* Request message to reschedule an event */ 204 | message RescheduleEventRequest { 205 | /* optional token of scheduled event to cancel */ 206 | string token = 1; 207 | /* timestamp when to publish the event */ 208 | int64 instant = 2; 209 | /* the event to publish */ 210 | Event event = 3; 211 | } 212 | 213 | /* Request message to cancel an event */ 214 | message CancelScheduledEventRequest { 215 | /* token of scheduled event to cancel */ 216 | string token = 1; 217 | } 218 | 219 | /* Token to manage a scheduled event */ 220 | message ScheduleToken { 221 | /* Field defining the token identifier */ 222 | string token = 1; 223 | } 224 | 225 | /* Request message to receive the first Token (Tail Token) of the Event Stream */ 226 | message GetFirstTokenRequest { 227 | } 228 | 229 | /* Request message to receive the last Token (Head Token) of the Event Stream */ 230 | message GetLastTokenRequest { 231 | } 232 | 233 | /* Request message to receive the Token that starts streaming events from the given timestamp */ 234 | message GetTokenAtRequest { 235 | 236 | /* Timestamp expressed as milliseconds since epoch */ 237 | int64 instant = 1; 238 | } 239 | 240 | /* Message containing the information necessary to track the position of events in the Event Stream */ 241 | message TrackingToken { 242 | 243 | /* The value of the Token */ 244 | int64 token = 1; 245 | } 246 | 247 | /* Message wrapping an Event and a Tracking Token */ 248 | message EventWithToken { 249 | 250 | /* The Token representing the position of this Event in the Stream */ 251 | int64 token = 1; 252 | 253 | /* The actual Event Message */ 254 | Event event = 2; 255 | } 256 | 257 | /* Message providing the parameters for executing a Query against AxonServer. */ 258 | message QueryEventsRequest { 259 | 260 | /* The query to execute against the Event Stream */ 261 | string query = 1; 262 | 263 | /* The number of results AxonServer may send before new permits need to be provided */ 264 | int64 number_of_permits = 2; 265 | 266 | /* Whether to keep the query running against incoming events once the Head of the Stream is reached */ 267 | bool live_events = 3; 268 | 269 | /* Indicates whether to force querying events from the leader node of an Axon Server. Forcing reads from leader 270 | * reduces the staleness of the data read, but also puts extra burden on the leader, reducing overall scalability. 271 | *

272 | * This property has no effect on connections to AxonServer SE. 273 | *

274 | */ 275 | bool force_read_from_leader = 4; 276 | 277 | /* If true, snapshots will be queried instead of events */ 278 | bool query_snapshots = 5; 279 | 280 | /* Query from this context, not from the default context of the connection */ 281 | string context_name = 6; 282 | } 283 | 284 | /* A message describing a response to a Query request */ 285 | message QueryEventsResponse { 286 | /* The actual contents of this response */ 287 | oneof data { 288 | /* Provided when the response contains the names of the columns the response contains. This message typically arrives first. */ 289 | ColumnsResponse columns = 1; 290 | 291 | /* Provided when the response message contains results of the Query */ 292 | RowResponse row = 2; 293 | 294 | /* Provided when all historic events have been included in the query results */ 295 | Confirmation files_completed = 3; 296 | } 297 | } 298 | 299 | /* Message containing the names of the columns returned in a Query */ 300 | message ColumnsResponse { 301 | 302 | /* The names of the columns provided in the query */ 303 | repeated string column = 1; 304 | } 305 | 306 | /* Message providing Query Result data */ 307 | message RowResponse { 308 | 309 | /* The values which, when combined, uniquely update this row. Any previously received values with the same identifiers should be replaced with this value */ 310 | repeated QueryValue id_values = 1; 311 | 312 | /* The sorting values to use when sorting this response compared to the others. */ 313 | repeated QueryValue sort_values = 2; 314 | 315 | /* The actual data values for each of the columns, as a column name -> value mapping */ 316 | map values = 3; 317 | } 318 | 319 | /* Describes the combination of an Aggregate Identifier and first expected Sequence number when opening an Aggregate-specific Event Stream */ 320 | message ReadHighestSequenceNrRequest { 321 | /* The Identifier of the Aggregate for which to load events */ 322 | string aggregate_id = 1; 323 | 324 | /* The Sequence Number of the first event expected */ 325 | int64 from_sequence_nr = 3; 326 | } 327 | 328 | /* The highest Sequence Number found for the provided request*/ 329 | message ReadHighestSequenceNrResponse { 330 | 331 | /* The sequence number of the latest event */ 332 | int64 to_sequence_nr = 1; 333 | } 334 | 335 | /* A confirmation to a request from the client */ 336 | message Confirmation { 337 | 338 | /* True when successful, otherwise false */ 339 | bool success = 1; 340 | } 341 | 342 | /* Request describing the desire to read events for a specific Aggregate */ 343 | message GetAggregateEventsRequest { 344 | 345 | /* The identifier of the aggregate to read events for */ 346 | string aggregate_id = 1; 347 | 348 | /* The sequence number of the first event to receive */ 349 | int64 initial_sequence = 2; 350 | 351 | /* Whether a snapshot may be returned as first element in the stream */ 352 | bool allow_snapshots = 3; 353 | 354 | /* The maximum sequence number (inclusive) of the events to retrieve, 0 means up to last event */ 355 | int64 max_sequence = 4; 356 | 357 | /* Hint for a minimum token to search events from */ 358 | int64 min_token = 5; 359 | } 360 | 361 | /* Request message to retrieve Snapshot Events for a specific Aggregate instance */ 362 | message GetAggregateSnapshotsRequest { 363 | 364 | /* The identifier to fetch the snapshots for */ 365 | string aggregate_id = 1; 366 | 367 | /* The minimal sequence number of the snapshots to retrieve */ 368 | int64 initial_sequence = 2; 369 | 370 | /* The maximum sequence number of the snapshots to retrieve */ 371 | int64 max_sequence = 3; 372 | 373 | /* The maximum number of results to stream */ 374 | int32 max_results = 4; 375 | } 376 | 377 | /* Request message to open an Event Stream from the Event Store. */ 378 | message GetEventsRequest { 379 | 380 | /* The token to start streaming from */ 381 | int64 tracking_token = 1; 382 | 383 | /* The number of messages the server may send before it needs to wait for more permits */ 384 | int64 number_of_permits = 2; 385 | 386 | /* The unique identifier of this client instance. Used for monitoring. */ 387 | string client_id = 3; 388 | 389 | /* The component name of this client instance. Used for monitoring. */ 390 | string component_name = 4; 391 | 392 | /* The name of the processor requesting this stream. Used for monitoring. */ 393 | string processor = 5; 394 | 395 | /* An enumeration of payload types that need to be blacklisted. The Server will stop sending messages of these 396 | types in order to reduce I/O. Note that the Server may occasionally send a blacklisted message to prevent 397 | time-outs and stale tokens on clients. 398 | */ 399 | repeated PayloadDescription blacklist = 6; 400 | 401 | /* Indicates whether to force reading events from the leader node of an Axon Server. Forcing reads from leader 402 | * reduces the staleness of the data read, but also puts extra burden on the leader, reducing overall scalability. 403 | *

404 | * This property has no effect on connections to AxonServer SE. 405 | *

406 | */ 407 | bool force_read_from_leader = 7; 408 | } 409 | 410 | /* Message containing the information of an Event */ 411 | message Event { 412 | 413 | /* The unique identifier of this event */ 414 | string message_identifier = 1; 415 | 416 | /* The identifier of the Aggregate instance that published this event, if any */ 417 | string aggregate_identifier = 2; 418 | 419 | /* The sequence number of the Event in the Aggregate instance that published it, if any */ 420 | int64 aggregate_sequence_number = 3; 421 | 422 | /* The Type of the Aggregate instance that published this Event, if any */ 423 | string aggregate_type = 4; 424 | 425 | /* The timestamp of the Event */ 426 | int64 timestamp = 5; 427 | 428 | /* The Payload of the Event */ 429 | SerializedObject payload = 6; 430 | 431 | /* The Meta Data of the Event */ 432 | map meta_data = 7; 433 | 434 | /* Flag indicating whether the Event is a snapshot Event */ 435 | bool snapshot = 8; 436 | } 437 | 438 | /* Value used in Query Responses to represent a value in its original type */ 439 | message QueryValue { 440 | 441 | /* The actual value, which can be one of string, 64 bit signed integer, boolean or 64 bits floating point */ 442 | oneof data { 443 | 444 | /* The text value */ 445 | string text_value = 1; 446 | 447 | /* The (64 bits) integer value */ 448 | sint64 number_value = 2; 449 | 450 | /* The boolean value */ 451 | bool boolean_value = 3; 452 | 453 | /* The (64 bits) floating point value */ 454 | double double_value = 4; 455 | } 456 | } 457 | 458 | /* Description of a Payload Type */ 459 | message PayloadDescription { 460 | 461 | /* The type identifier of the Payload */ 462 | string type = 1; 463 | 464 | /* The revision of the Payload Type */ 465 | string revision = 2; 466 | } 467 | -------------------------------------------------------------------------------- /src/main/proto/persistent-streams.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.streams; 3 | import "event.proto"; 4 | import "google/protobuf/empty.proto"; 5 | option java_multiple_files = true; 6 | 7 | /* Service providing operations for persistent event streams, event streams where Axon Server keeps 8 | track of the progress. All operations require a header (AxonIQ-Context) to be passed with each request to define 9 | the context. 10 | */ 11 | service PersistentStreamService { 12 | /* Creates a persistent stream if it does not exist. */ 13 | rpc CreateStream( CreateStreamRequest) returns (CreateStreamResponse) { 14 | 15 | } 16 | /* Open a persistent event stream connection from a client. Creates the stream if it does not exist. */ 17 | rpc OpenStream(stream StreamRequest) returns (stream StreamSignal) { 18 | 19 | } 20 | 21 | /* Deletes a persistent event stream. All existing connections to the stream are closed. */ 22 | rpc DeleteStream(DeleteStreamRequest) returns (stream google.protobuf.Empty) { 23 | 24 | } 25 | 26 | /* Change properties of a persistent event stream. */ 27 | rpc UpdateStream(UpdateStreamRequest) returns (stream google.protobuf.Empty) { 28 | 29 | } 30 | 31 | /* Returns a list of all persistent event streams defined (for the context). For each event stream it returns 32 | the progress per segment. */ 33 | rpc ListStreams(ListStreamsRequest) returns (stream StreamStatus) { 34 | 35 | } 36 | 37 | /* Resets the position of a persistent stream. */ 38 | rpc ResetStream(ResetStreamRequest) returns (stream google.protobuf.Empty) { 39 | 40 | } 41 | } 42 | 43 | /* request to list the persistent streams for a context */ 44 | message ListStreamsRequest { 45 | 46 | } 47 | /* Contains the current status of a persistent stream */ 48 | message StreamStatus { 49 | string stream_id = 1; /* the unique identification of the persistent stream */ 50 | string stream_name = 2; /* a name for the persistent stream */ 51 | SequencingPolicy sequencing_policy = 3; /* the policy used to distribute events across segments. */ 52 | string filter = 4; /* an expression to filter events, same syntax as used for ad-hoc queries on the event store */ 53 | repeated SegmentPosition segments = 5; /* the last confirmed position per segment */ 54 | } 55 | 56 | /* Contains the position per segment */ 57 | message SegmentPosition { 58 | int32 segment = 1; /* the segment number */ 59 | int64 position = 2; /* the last confirmed position */ 60 | string client_id = 3; /* the connected client, empty if there is no client connected to this segment */ 61 | string error = 4; /* optional error reported by the client for this segment */ 62 | } 63 | 64 | /* Request to set up a connection to a stream. Clients should first submit an OpenRequest on this connection 65 | to connect to a stream and can then submit Acknowledgement messages to report progress. */ 66 | message StreamRequest { 67 | oneof request { 68 | Open open = 1; /* the initial message to connect to a stream */ 69 | ProgressAcknowledgement acknowledgeProgress = 2; /* sends progress in processing events to Axon Server */ 70 | Requests requests = 3; /* request a number of messages for a segment */ 71 | SegmentError error = 4; /* notifies an error */ 72 | } 73 | } 74 | 75 | /* Request to create a persistent stream */ 76 | message CreateStreamRequest { 77 | string stream_id = 1; /* the unique identification of the stream */ 78 | InitializationProperties initialization_properties = 2; /* properties to create the stream if it does not exist */ 79 | } 80 | 81 | /* Response for a create stream request */ 82 | message CreateStreamResponse { 83 | CreateResult result = 1; /* the result (created or already existing) */ 84 | } 85 | 86 | 87 | /* Request to notify Axon Server of an error on a persistent stream segment */ 88 | message SegmentError { 89 | int32 segment = 1; /* the segment number */ 90 | string error = 2; /* the error that occurred while processing the events for this segment */ 91 | } 92 | 93 | /* Request to delete a persistent stream */ 94 | message DeleteStreamRequest { 95 | string stream_id = 1; /* the unique identification of the stream */ 96 | } 97 | 98 | message ResetStreamRequest { 99 | string stream_id = 1; /* the unique identification of the stream */ 100 | ResetStreamConfiguration options = 2; 101 | } 102 | 103 | /* Request to update the properties of a persistent stream */ 104 | message UpdateStreamRequest { 105 | string stream_id = 1; /* the unique identification of the stream */ 106 | int32 segments = 2; /* Request to change the number of segments */ 107 | string stream_name = 3; /* Request to change the name of the stream */ 108 | } 109 | 110 | 111 | /* Request to open a connection to a persistent stream */ 112 | message Open { 113 | string stream_id = 1; /* the unique identification of the stream */ 114 | string client_id = 2; /* the unique identification of the client */ 115 | InitializationProperties initialization_properties = 3; /* properties to create the stream if it does not exist */ 116 | } 117 | 118 | /* Properties to create the stream if it does not exist */ 119 | message InitializationProperties { 120 | int32 segments = 1; /* the initial number of segments */ 121 | int64 initial_position = 2; /* the position in the event store to start reading from */ 122 | SequencingPolicy sequencing_policy = 3; /* the sequencing policy */ 123 | string filter = 4; /* an expression to filter events, same syntax as used for ad-hoc queries on the event store */ 124 | string stream_name = 5; /* a name for the persistent stream */ 125 | } 126 | 127 | /* Defines the policy used to distribute events across segments. The policy name must be known on the server. */ 128 | message SequencingPolicy { 129 | string policy_name = 1; /* the name of the sequencing policy */ 130 | repeated string parameter = 2; /* optional list of parameters used by the sequencing policy */ 131 | } 132 | 133 | /* Message to report progress of event processing for a specific segment in a stream */ 134 | message ProgressAcknowledgement { 135 | int32 segment = 1; /* the segment number */ 136 | int64 position = 2; /* the position of the last processed event */ 137 | } 138 | 139 | message Requests { 140 | int32 segment = 1; /* the segment number */ 141 | int32 requests = 2; /* the number of messages to request */ 142 | } 143 | 144 | /* Message sent by Axon Server to the client stream connection */ 145 | message StreamSignal { 146 | int32 segment = 1; /* the segment number */ 147 | oneof type { 148 | PersistentStreamEvent event = 2; /* an event to process in the client */ 149 | bool closed = 3; /* indicates that the segment is closed by Axon Server */ 150 | OpenSegment open = 4; /* segment assigned to the client */ 151 | } 152 | } 153 | 154 | /* Event sent on a persistent stream segment */ 155 | message PersistentStreamEvent { 156 | io.axoniq.axonserver.grpc.event.EventWithToken event = 1; /* an event to process in the client */ 157 | bool replay = 2; /* indicates that the event is sent again after a reset stream */ 158 | } 159 | 160 | 161 | /* Message to prepare client for events on a specific segment */ 162 | message OpenSegment { 163 | } 164 | 165 | /* Message to provide parameters for resetting a persistent stream */ 166 | message ResetStreamConfiguration { 167 | oneof type { 168 | google.protobuf.Empty head = 1; /* indicates reset to head */ 169 | google.protobuf.Empty tail = 2; /* indicates reset to tail */ 170 | int64 datetime = 3; /* timestamp in epoch milliseconds */ 171 | int64 position = 4; /* global index (inclusive) */ 172 | } 173 | } 174 | 175 | /* result of create stream */ 176 | enum CreateResult { 177 | created = 0; 178 | already_exists = 1; 179 | } -------------------------------------------------------------------------------- /src/main/proto/query.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package io.axoniq.axonserver.grpc.query; 3 | import "common.proto"; 4 | option java_multiple_files = true; 5 | 6 | /* Service providing operations for the Query Messaging component of AxonServer */ 7 | service QueryService { 8 | 9 | /* Opens a Query- and Instruction stream to AxonServer. */ 10 | rpc OpenStream (stream QueryProviderOutbound) returns (stream QueryProviderInbound) { 11 | } 12 | 13 | /* Sends a point-to-point or scatter-gather Query */ 14 | rpc Query (QueryRequest) returns (stream QueryResponse) { 15 | } 16 | 17 | /* Opens a Subscription Query */ 18 | rpc Subscription (stream SubscriptionQueryRequest) returns (stream SubscriptionQueryResponse) { 19 | } 20 | } 21 | 22 | /* Message containing Query related instructions for Axon Server */ 23 | message QueryProviderOutbound { 24 | 25 | /* The actual instruction to send */ 26 | oneof request { 27 | 28 | /* Registers a Query Handler with AxonServer */ 29 | QuerySubscription subscribe = 1; 30 | 31 | /* Unregisters a Query Handler with AxonServer */ 32 | QuerySubscription unsubscribe = 2; 33 | 34 | /* Grant permits to AxonServer to send a number of messages to the client */ 35 | FlowControl flow_control = 3; 36 | 37 | /* Sends a Response to a Query received via the inbound stream */ 38 | QueryResponse query_response = 4; 39 | 40 | /* Indicator that all responses for Query have been sent */ 41 | QueryComplete query_complete = 5; 42 | 43 | /* Sends a response for a Subscription Query that has been received via the inbound stream */ 44 | SubscriptionQueryResponse subscription_query_response = 6; 45 | 46 | /* Acknowledgement of previously sent instruction via inbound stream */ 47 | InstructionAck ack = 7; 48 | } 49 | 50 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via inbound stream */ 51 | string instruction_id = 8; 52 | } 53 | 54 | /* Queries or Query related instructions from AxonServer for the connected application */ 55 | message QueryProviderInbound { 56 | 57 | /* The actual query or instruction */ 58 | oneof request { 59 | 60 | /* Acknowledgement of previously sent instruction via outbound stream */ 61 | InstructionAck ack = 1; 62 | 63 | /* Represents an incoming Query, for which this component is expected to provide a response */ 64 | QueryRequest query = 2; 65 | 66 | /* Represents an incoming Subscription Query, for which this component is expected to provide a response and updates */ 67 | SubscriptionQueryRequest subscription_query_request = 3; 68 | 69 | /* Indicator that receiver is no more interested in updates of this query */ 70 | QueryReference query_cancel = 5; 71 | 72 | /* Indicator that receiver should send more updates of this query */ 73 | QueryFlowControl query_flow_control = 6; 74 | } 75 | 76 | /* Instruction identifier. If this identifier is set, this instruction will be acknowledged via outbound stream */ 77 | string instruction_id = 4; 78 | } 79 | 80 | message QueryReference { 81 | 82 | /* The identifier of the query request. */ 83 | string request_id = 1; 84 | } 85 | 86 | /* Message indicating that query has been completed. */ 87 | message QueryComplete { 88 | 89 | /* A unique identifier for this message */ 90 | string message_id = 1; 91 | 92 | /* The identifier of the incoming query to complete */ 93 | string request_id = 2; 94 | } 95 | 96 | /* Message indicating that consumer is requesting more messages from producer. */ 97 | message QueryFlowControl { 98 | 99 | /* The identifier of the incoming query to complete */ 100 | QueryReference query_reference = 1; 101 | 102 | /* Number of messages requested */ 103 | int64 permits = 2; 104 | } 105 | 106 | /* Message representing an incoming Query */ 107 | message QueryRequest { 108 | 109 | /* The message ID of the incoming Query */ 110 | string message_identifier = 1; 111 | 112 | /* The name of the Query to execute */ 113 | string query = 2; 114 | 115 | /* The timestamp of the Query creation */ 116 | int64 timestamp = 3; 117 | 118 | /* A payload accompanying the Query */ 119 | SerializedObject payload = 4; 120 | 121 | /* Meta Data providing contextual information of the Query */ 122 | map meta_data = 5; 123 | 124 | /* An object describing the expectations of the Response Type */ 125 | SerializedObject response_type = 6; 126 | 127 | /* Any instructions for components Routing or Handling the Query */ 128 | repeated ProcessingInstruction processing_instructions = 7; 129 | 130 | /* The unique identifier of the client instance dispatching the query */ 131 | string client_id = 8; 132 | 133 | /* The Name of the Component dispatching the query */ 134 | string component_name = 9; 135 | } 136 | 137 | /* Message that represents the Response to a Query */ 138 | message QueryResponse { 139 | /* The unique identifier of the Response Message */ 140 | string message_identifier = 1; 141 | 142 | /* An Error Code identifying the type of error, if any */ 143 | string error_code = 2; 144 | 145 | /* A detailed description of the error, if any */ 146 | ErrorMessage error_message = 3; 147 | 148 | /* The Payload of the Response Message */ 149 | SerializedObject payload = 4; 150 | 151 | /* Any Meta Data describing the context of the Response Message */ 152 | map meta_data = 5; 153 | 154 | /* Any instructions for components Routing or Handling the Response Message */ 155 | repeated ProcessingInstruction processing_instructions = 6; 156 | 157 | /* The unique identifier of the Query to which this is a response */ 158 | string request_identifier = 7; 159 | 160 | /* Some numbers are reserved for internal use for additional properties between AxonServer nodes */ 161 | reserved 15; 162 | } 163 | 164 | /* Message that represents a Subscription Query */ 165 | message SubscriptionQuery { 166 | 167 | /* A unique identifier for this subscription */ 168 | string subscription_identifier = 1; 169 | 170 | /* The number of messages the Server may send before needing to await additional permits */ 171 | int64 number_of_permits = 2; 172 | 173 | /* The Query describing the desire for information */ 174 | QueryRequest query_request = 3; 175 | 176 | /* A description of the type of Object expected as Update Responses */ 177 | SerializedObject update_response_type = 4; 178 | } 179 | 180 | /* A message containing an Update of a Query Subscription Response */ 181 | message QueryUpdate { 182 | 183 | /* The unique identifier of this Update */ 184 | string message_identifier = 2; 185 | 186 | /* The object representing the Update */ 187 | SerializedObject payload = 3; 188 | 189 | /* Meta Data providing contextual information of the Update */ 190 | map meta_data = 4; 191 | 192 | /* The identifier of the Client instance providing the Update */ 193 | string client_id = 5; 194 | 195 | /* The Component Name of the Client providing the Update */ 196 | string component_name = 6; 197 | 198 | /* An Error Code identifying the type of error, if any */ 199 | string error_code = 7; 200 | 201 | /* A detailed description of the error, if any */ 202 | ErrorMessage error_message = 8; 203 | } 204 | 205 | /* Message indicating that all relevant Updates have been sent for a Subscription Query, and that no further Updates are available */ 206 | message QueryUpdateComplete { 207 | 208 | /* The identifier of the Client instance providing the Update */ 209 | string client_id = 2; 210 | 211 | /* The Component Name of the Client providing the Update */ 212 | string component_name = 3; 213 | } 214 | 215 | /* Message indicating that an Error occurred and that no Updates will be sent for a Subscription Query */ 216 | message QueryUpdateCompleteExceptionally { 217 | 218 | /* The identifier of the Client instance providing the Update */ 219 | string client_id = 2; 220 | 221 | /* The Component Name of the Client providing the Update */ 222 | string component_name = 3; 223 | 224 | /* The Code describing the type of Error that occurred */ 225 | string error_code = 5; 226 | 227 | /* A detailed description of the error, if available */ 228 | ErrorMessage error_message = 6; 229 | } 230 | 231 | /* Message describing possible interactions for a Subscription Query */ 232 | message SubscriptionQueryRequest { 233 | 234 | /* The actual request. The Subscription Query is opened using a `subscribe`, which opens the flow of updates. Once 235 | successful, the `get_initial_result` retrieves the initial result of the subscription. For the server to send 236 | more updates than the initial number of permits, use the `flow_control` request to send more permits. 237 | */ 238 | oneof request { 239 | 240 | /* Start a Subscription Query with the given details. */ 241 | SubscriptionQuery subscribe = 1; 242 | 243 | /* Ends a previously started Subscription Query with the given details */ 244 | SubscriptionQuery unsubscribe = 2; 245 | 246 | /* Requests the initial result of a subscription query to be sent. This should always be done after opening the 247 | subscription query itself, to remove concurrency conflicts with Update messages. 248 | */ 249 | SubscriptionQuery get_initial_result = 3; 250 | 251 | /* Allows the Server to provide additional Updates to be sent. Only the `number_of_permits` field needs to be 252 | set on this message. 253 | */ 254 | SubscriptionQuery flow_control = 4; 255 | } 256 | } 257 | 258 | /* Represents a Response Message for a Subscription Query */ 259 | message SubscriptionQueryResponse { 260 | 261 | /* The unique identifier for this message */ 262 | string message_identifier = 1; 263 | 264 | /* The identifier of the subscription query this is a response for */ 265 | string subscription_identifier = 2; 266 | 267 | /* The actual response. The `initial_result` message is sent as a response to `get_initial_result`. An `update` 268 | messages is sent for each update available for the query, even before the Initial Result is supplied. The 269 | `complete` or `complete_exceptionally` are sent when the publishing side completed the Subscription Query, 270 | either regularly (`complete`) or because an error occurred (`complete_exceptionally`). 271 | */ 272 | oneof response { 273 | 274 | /* Provides an Initial Response */ 275 | QueryResponse initial_result = 3; 276 | 277 | /* Provides an Update Response */ 278 | QueryUpdate update = 4; 279 | 280 | /* Indicates the Query is complete, and no more Updates will be sent */ 281 | QueryUpdateComplete complete = 5; 282 | 283 | /* Indicates the Query failed exceptionally, and no more Updates will be sent */ 284 | QueryUpdateCompleteExceptionally complete_exceptionally = 6; 285 | } 286 | } 287 | 288 | /* Message containing details of a Registration of a Query Handler in a component*/ 289 | message QuerySubscription { 290 | 291 | /* The unique identifier of this Message */ 292 | string message_id = 1; 293 | 294 | /* The name of the Query the Handler is subscribed to */ 295 | string query = 2; 296 | 297 | /* The type of Result this Handler produces */ 298 | string result_name = 3; 299 | 300 | /* The name of the Component containing the Query Handler */ 301 | string component_name = 4; 302 | 303 | /* The unique identifier of the Client Instance containing the Query Handler */ 304 | string client_id = 5; 305 | 306 | /* Deprecated field - nr_of_handlers */ 307 | reserved 6; 308 | } 309 | --------------------------------------------------------------------------------