├── .gitignore ├── .readthedocs.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── .DS_Store ├── _static │ └── index.css ├── advanced │ ├── bigfile.md │ ├── fabric.md │ ├── index.rst │ ├── port.md │ └── upgrade.md ├── conf.py ├── faq │ ├── blockchain.md │ ├── index.rst │ └── weevent.md ├── history │ ├── changelog.md │ └── index.rst ├── image │ ├── Governance-multi-view.png │ ├── Governance-ui.png │ ├── IoTScarino.png │ ├── WeEventArchitecture.png │ ├── WeventTopView.png │ ├── port.png │ ├── processor │ │ ├── ruledetails.png │ │ ├── rulelist.png │ │ ├── selectWhereCondition.png │ │ ├── setRule.png │ │ └── setRuleContent.png │ ├── weevent-logo.png │ └── workflow.png ├── index.rst ├── install │ ├── environment.md │ ├── index.rst │ ├── module │ │ ├── broker.md │ │ ├── gateway.md │ │ ├── governance.md │ │ ├── index.rst │ │ └── processor.md │ ├── property.md │ └── quickinstall.md ├── introduction │ ├── architecture.md │ ├── core.md │ ├── getting-start.md │ └── index.rst ├── protocol │ ├── errorcode.md │ ├── index.rst │ ├── jsonrpc.md │ ├── mqtt.md │ ├── restful.md │ ├── stomp.md │ ├── weevent-client-sdk.md │ ├── weevent-core-sdk.md │ ├── weevent-file-sdk.md │ ├── weevent-jms-sdk.md │ └── weevent-sample.md └── scarino │ ├── classic.md │ ├── index.rst │ └── iot.md └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /build/ 3 | /logs/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | /out/ 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /nbdist/ 26 | /.nb-gradle/ 27 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | build: 9 | os: ubuntu-22.04 10 | tools: 11 | python: "3.7" 12 | 13 | # Build documentation in the docs/ directory with Sphinx 14 | sphinx: 15 | configuration: docs/conf.py 16 | 17 | # Build documentation with MkDocs 18 | #mkdocs: 19 | # configuration: mkdocs.yml 20 | 21 | # Optionally build your docs in additional formats such as PDF and ePub 22 | # formats: all 23 | 24 | # Optionally set the version of Python and requirements required to build your docs 25 | python: 26 | install: 27 | - requirements: requirements.txt 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # 贡献指南 2 | 3 | 欢迎,提前感谢你的帮助和支持!请遵循以下指南 :+1: 4 | 5 | ## 成为贡献者 6 | 7 | ### 提交特性/修复问题 8 | 9 | **Note:** 请先填写`issue`,在进入`Pull`请求之前,获得充分的反馈! 10 | 11 | - 请确保是一个公开讨论的问题 12 | - 如果没有进行公开讨论,请提交一个问题,以便你投入时间和精力之前,我们进行讨论。 13 | - 在创建问题时,请遵循GitHub显示的指南,以便我们获得足够信息是关于你的提案。 14 | - 提交`PR`后,请邀请`Reviewers`进行`review`。只有`review`过的代码,才可能被合入。 15 | 16 | 17 | ### 审查PR 18 | 19 | 为WeEvent做出贡献的另一个非常有用的方法,审查其他人的`Pull`请求。获得多人的反馈非常有帮助,减少`Pull Request`做出最终决定的总时间。 20 | 21 | ### 编写文档 22 | 23 | 我们的文档位于[docs](https://weeventdoc.readthedocs.io/zh_CN/latest/)目录中的GitHub上。你看到一个错字或其他方法来改善它吗?随意编辑并提交拉取请求! 24 | 25 | ### 提供帮助 26 | 27 | 可以做的最简单的事情,就是帮助我们推动发展,并对我们的进展产生影响,帮助、支持在WeEvent中遇到困难的人。 28 | 29 | 你可以在这里回复 [issues on Github](https://github.com/WeBankBlockchain/WeEvent/issues) 30 | 31 | ### 测试 32 | 33 | 我们的目标是(接近)100%测试覆盖率,因此请确保您的测试尽可能覆盖多的代码。 34 | 35 | 36 | 再次感谢您成为WeEvent社区的贡献者 :tada:! 37 | 38 | Cheers 39 | 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Hold Liable 3 | Trademark Use 4 | Apache License 5 | Version 2.0, January 2004 6 | http://www.apache.org/licenses/ 7 | 8 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 9 | 10 | 1. Definitions. 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, 13 | and distribution as defined by Sections 1 through 9 of this document. 14 | 15 | "Licensor" shall mean the copyright owner or entity authorized by 16 | the copyright owner that is granting the License. 17 | 18 | "Legal Entity" shall mean the union of the acting entity and all 19 | other entities that control, are controlled by, or are under common 20 | control with that entity. For the purposes of this definition, 21 | "control" means (i) the power, direct or indirect, to cause the 22 | direction or management of such entity, whether by contract or 23 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 24 | outstanding shares, or (iii) beneficial ownership of such entity. 25 | 26 | "You" (or "Your") shall mean an individual or Legal Entity 27 | exercising permissions granted by this License. 28 | 29 | "Source" form shall mean the preferred form for making modifications, 30 | including but not limited to software source code, documentation 31 | source, and configuration files. 32 | 33 | "Object" form shall mean any form resulting from mechanical 34 | transformation or translation of a Source form, including but 35 | not limited to compiled object code, generated documentation, 36 | and conversions to other media types. 37 | 38 | "Work" shall mean the work of authorship, whether in Source or 39 | Object form, made available under the License, as indicated by a 40 | copyright notice that is included in or attached to the work 41 | (an example is provided in the Appendix below). 42 | 43 | "Derivative Works" shall mean any work, whether in Source or Object 44 | form, that is based on (or derived from) the Work and for which the 45 | editorial revisions, annotations, elaborations, or other modifications 46 | represent, as a whole, an original work of authorship. For the purposes 47 | of this License, Derivative Works shall not include works that remain 48 | separable from, or merely link (or bind by name) to the interfaces of, 49 | the Work and Derivative Works thereof. 50 | 51 | "Contribution" shall mean any work of authorship, including 52 | the original version of the Work and any modifications or additions 53 | to that Work or Derivative Works thereof, that is intentionally 54 | submitted to Licensor for inclusion in the Work by the copyright owner 55 | or by an individual or Legal Entity authorized to submit on behalf of 56 | the copyright owner. For the purposes of this definition, "submitted" 57 | means any form of electronic, verbal, or written communication sent 58 | to the Licensor or its representatives, including but not limited to 59 | communication on electronic mailing lists, source code control systems, 60 | and issue tracking systems that are managed by, or on behalf of, the 61 | Licensor for the purpose of discussing and improving the Work, but 62 | excluding communication that is conspicuously marked or otherwise 63 | designated in writing by the copyright owner as "Not a Contribution." 64 | 65 | "Contributor" shall mean Licensor and any individual or Legal Entity 66 | on behalf of whom a Contribution has been received by Licensor and 67 | subsequently incorporated within the Work. 68 | 69 | 2. Grant of Copyright License. Subject to the terms and conditions of 70 | this License, each Contributor hereby grants to You a perpetual, 71 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 72 | copyright license to reproduce, prepare Derivative Works of, 73 | publicly display, publicly perform, sublicense, and distribute the 74 | Work and such Derivative Works in Source or Object form. 75 | 76 | 3. Grant of Patent License. Subject to the terms and conditions of 77 | this License, each Contributor hereby grants to You a perpetual, 78 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 79 | (except as stated in this section) patent license to make, have made, 80 | use, offer to sell, sell, import, and otherwise transfer the Work, 81 | where such license applies only to those patent claims licensable 82 | by such Contributor that are necessarily infringed by their 83 | Contribution(s) alone or by combination of their Contribution(s) 84 | with the Work to which such Contribution(s) was submitted. If You 85 | institute patent litigation against any entity (including a 86 | cross-claim or counterclaim in a lawsuit) alleging that the Work 87 | or a Contribution incorporated within the Work constitutes direct 88 | or contributory patent infringement, then any patent licenses 89 | granted to You under this License for that Work shall terminate 90 | as of the date such litigation is filed. 91 | 92 | 4. Redistribution. You may reproduce and distribute copies of the 93 | Work or Derivative Works thereof in any medium, with or without 94 | modifications, and in Source or Object form, provided that You 95 | meet the following conditions: 96 | 97 | (a) You must give any other recipients of the Work or 98 | Derivative Works a copy of this License; and 99 | 100 | (b) You must cause any modified files to carry prominent notices 101 | stating that You changed the files; and 102 | 103 | (c) You must retain, in the Source form of any Derivative Works 104 | that You distribute, all copyright, patent, trademark, and 105 | attribution notices from the Source form of the Work, 106 | excluding those notices that do not pertain to any part of 107 | the Derivative Works; and 108 | 109 | (d) If the Work includes a "NOTICE" text file as part of its 110 | distribution, then any Derivative Works that You distribute must 111 | include a readable copy of the attribution notices contained 112 | within such NOTICE file, excluding those notices that do not 113 | pertain to any part of the Derivative Works, in at least one 114 | of the following places: within a NOTICE text file distributed 115 | as part of the Derivative Works; within the Source form or 116 | documentation, if provided along with the Derivative Works; or, 117 | within a display generated by the Derivative Works, if and 118 | wherever such third-party notices normally appear. The contents 119 | of the NOTICE file are for informational purposes only and 120 | do not modify the License. You may add Your own attribution 121 | notices within Derivative Works that You distribute, alongside 122 | or as an addendum to the NOTICE text from the Work, provided 123 | that such additional attribution notices cannot be construed 124 | as modifying the License. 125 | 126 | You may add Your own copyright statement to Your modifications and 127 | may provide additional or different license terms and conditions 128 | for use, reproduction, or distribution of Your modifications, or 129 | for any such Derivative Works as a whole, provided Your use, 130 | reproduction, and distribution of the Work otherwise complies with 131 | the conditions stated in this License. 132 | 133 | 5. Submission of Contributions. Unless You explicitly state otherwise, 134 | any Contribution intentionally submitted for inclusion in the Work 135 | by You to the Licensor shall be under the terms and conditions of 136 | this License, without any additional terms or conditions. 137 | Notwithstanding the above, nothing herein shall supersede or modify 138 | the terms of any separate license agreement you may have executed 139 | with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade 142 | names, trademarks, service marks, or product names of the Licensor, 143 | except as required for reasonable and customary use in describing the 144 | origin of the Work and reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or 147 | agreed to in writing, Licensor provides the Work (and each 148 | Contributor provides its Contributions) on an "AS IS" BASIS, 149 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 150 | implied, including, without limitation, any warranties or conditions 151 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 152 | PARTICULAR PURPOSE. You are solely responsible for determining the 153 | appropriateness of using or redistributing the Work and assume any 154 | risks associated with Your exercise of permissions under this License. 155 | 156 | 8. Limitation of Liability. In no event and under no legal theory, 157 | whether in tort (including negligence), contract, or otherwise, 158 | unless required by applicable law (such as deliberate and grossly 159 | negligent acts) or agreed to in writing, shall any Contributor be 160 | liable to You for damages, including any direct, indirect, special, 161 | incidental, or consequential damages of any character arising as a 162 | result of this License or out of the use or inability to use the 163 | Work (including but not limited to damages for loss of goodwill, 164 | work stoppage, computer failure or malfunction, or any and all 165 | other commercial damages or losses), even if such Contributor 166 | has been advised of the possibility of such damages. 167 | 168 | 9. Accepting Warranty or Additional Liability. While redistributing 169 | the Work or Derivative Works thereof, You may choose to offer, 170 | and charge a fee for, acceptance of support, warranty, indemnity, 171 | or other liability obligations and/or rights consistent with this 172 | License. However, in accepting such obligations, You may act only 173 | on Your own behalf and on Your sole responsibility, not on behalf 174 | of any other Contributor, and only if You agree to indemnify, 175 | defend, and hold each Contributor harmless for any liability 176 | incurred by, or claims asserted against, such Contributor by reason 177 | of your accepting any such warranty or additional liability. 178 | 179 | END OF TERMS AND CONDITIONS 180 | 181 | APPENDIX: How to apply the Apache License to your work. 182 | 183 | To apply the Apache License to your work, attach the following 184 | boilerplate notice, with the fields enclosed by brackets "{}" 185 | replaced with your own identifying information. (Don't include 186 | the brackets!) The text should be enclosed in the appropriate 187 | comment syntax for the file format. We also recommend that a 188 | file or class name and description of purpose be included on the 189 | same "printed page" as the copyright notice for easier 190 | identification within third-party archives. 191 | 192 | Copyright 2016 Conor Svensson 193 | 194 | Licensed under the Apache License, Version 2.0 (the "License"); 195 | you may not use this file except in compliance with the License. 196 | You may obtain a copy of the License at 197 | 198 | http://www.apache.org/licenses/LICENSE-2.0 199 | 200 | Unless required by applicable law or agreed to in writing, software 201 | distributed under the License is distributed on an "AS IS" BASIS, 202 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 203 | See the License for the specific language governing permissions and 204 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## WeEvent文档项目 2 | WeEvent是微众银行的一个[开源项目](https://github.com/WeBankBlockchain/WeEvent)。WeEvent-docs是WeEvent的文档仓库。会生成为[在线文档](https://weeventdoc.readthedocs.io/zh_CN/latest)。 3 | 4 | ### 贡献说明 5 | WeEvent爱贡献者!请阅读我们的[贡献文档](https://github.com/WeBankBlockchain/WeEvent-docs/blob/master/CONTRIBUTING.md),了解如何贡献代码,并提交你的贡献。 6 | 7 | 希望在您的帮助下WeEvent继续前进。 8 | 9 | 10 | ### 社区 11 | - 联系我们:weevent@webank.com 12 | -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/.DS_Store -------------------------------------------------------------------------------- /docs/_static/index.css: -------------------------------------------------------------------------------- 1 | .rst-content code.literal{ 2 | color: dimgray; 3 | } -------------------------------------------------------------------------------- /docs/advanced/bigfile.md: -------------------------------------------------------------------------------- 1 | ## 大文件传输 2 | 3 | 因为`WeEvent`的事件是会持久化存储在区块链上的,区块链对交易的大小有一定的限制。`WeEvent`现在支持的事件内容最大值为`10K`。这个阈值在大部分场景下是能够满足要求的。`WeEvent`也支持传输`GB`级别的大文件。 4 | 5 | 大文件的数据内容本身不上链,只是通过区块链的`p2p`网络从发布方传输到订阅方,文件传输完毕后可以将这个动作作为一个事件上链。 6 | 7 | ### 功能集成 8 | 9 | 大文件传输因为涉及到文件的分片上传和下载,以及可能出现的断点续传,所以该功能只在`Java File SDK`中提供。`Java File SDK`的集成和使用参见[WeEvent File SDK](../protocol/weevent-file-sdk.md)。 10 | 11 | ### 权限控制 12 | 13 | 默认情况下,发布方上传的文件,这个群组里的所有节点都可以订阅到。为了能在群组内指定文件的接收方,即只有被授权过的节点才能订阅文件。我们通过在`Topic`主题维度上配置公私钥来解决身份识别和授权认证的问题。 14 | 15 | 1. 为文件接收方生成公私钥文件 16 | 17 | 可以使用IWeEventFileClient.genPemFile接口生成PME格式的公私钥。 18 | 也可以通过`FISCO-BCOS`提供的脚本[生成公私钥](https://raw.githubusercontent.com/FISCO-BCOS/console/master/tools/get_account.sh)。 19 | 20 | 2. 生成公私钥文件后,接收方使用私钥文件`*.pem`来开启文件传输通道,发送方使用公钥文件`*.public.pem`来开启文件传输通道。 21 | 22 | - 代码样例 23 | 24 | ```java 25 | public static void main(String[] args) { 26 | try { 27 | FiscoConfig fiscoConfig = new FiscoConfig(); 28 | fiscoConfig.load(""); 29 | 30 | // 构建WeEventFileClient,其中receivePath为接收方收到文件存储的位置 31 | IWeEventFileClient weEventFileClient = IWeEventFileClient.build("1", "./logs", 1024 * 1024, fiscoConfig); 32 | 33 | // 接收方加载生成的"*.pem"私钥文件 34 | PathMatchingResourcePatternResolver resolver4Receiver = new PathMatchingResourcePatternResolver(); 35 | Resource resource4Receiver = resolver4Receiver.getResource("classpath:" + "0x2809a9902e47d6fcaabe6d0183855d9201c93af1.pem"); 36 | 37 | String topicName = "com.weevent.file"; 38 | // 订阅文件,接收到的文件存到"./logs"目录中 39 | weEventFileClient.openTransport4Receiver(topicName, new IWeEventFileClient.FileListener() { 40 | @Override 41 | public void onFile(String topicName, String fileName) { 42 | log.info("+++++++topic name: {}, file name: {}", topicName, fileName); 43 | } 44 | 45 | @Override 46 | public void onException(Throwable e) { 47 | e.printStackTrace(); 48 | } 49 | }, resource4Receiver.getInputStream()); 50 | 51 | // 发送方加载生成的"*.pem"私钥文件 52 | PathMatchingResourcePatternResolver resolver4Sender = new PathMatchingResourcePatternResolver(); 53 | Resource resource4Sender = resolver4Sender.getResource("classpath:" + "0x2809a9902e47d6fcaabe6d0183855d9201c93af1.public.pem"); 54 | weEventFileClient.openTransport4Sender(topicName, resource4Sender.getInputStream()); 55 | 56 | // handshake time delay for web3sdk 57 | Thread.sleep(1000*10); 58 | 59 | // 发送文件"src/main/resources/log4j2.xml" 60 | FileChunksMeta fileChunksMeta = weEventFileClient.publishFile(topicName, 61 | new File("src/main/resources/log4j2.xml").getAbsolutePath(), true); 62 | 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | ``` 68 | 69 | ### 读写FTP服务 70 | 71 | 大文件传输功能支持将FTP服务器上的文件发布出去,接收方收到文件后将文件存储到FTP服务器指定目录中。读写FTP服务器时所用的目录为FTP用户主目录下的相对路径。 72 | 1. 使用FTP信息(host、port、username、password等)构造WeEventFileClient。 73 | 2. 发布订阅FTP服务器中的文件与普通发布订阅区别只在于所指定的文件目录,请确保FTP服务器中相应目录或文件已存在。 74 | 75 | - 代码样例 76 | 77 | ```java 78 | public static void main(String[] args) { 79 | try { 80 | // FTP连接信息,工作目录./test 81 | FtpInfo ftpInfo = new FtpInfo("127.0.0.1", 21, "ftpuser", "123456", "./test"); 82 | // 当使用ftp信息构造WeEventFileClient时,默认读写FTP服务器中用户主目录下的文件 83 | IWeEventFileClient weEventFileClient = IWeEventFileClient.build("1", "./receiver", ftpInfo, 1024 * 1024, fiscoConfig); 84 | 85 | String topicName = "com.weevent.file"; 86 | // 发送FTP服务器上的文件./test/sender/foo.txt 87 | weEventFileClient.openTransport4Sender(topicName); 88 | FileChunksMeta fileChunksMeta = weEventFileClient.publishFile(topicName, "./sender/foo.txt", true); 89 | System.out.println(fileChunksMeta.toString()); 90 | 91 | // 订阅文件接收到文件后,写到FTP服务器"./test/receiver"目录下 92 | weEventFileClient.openTransport4Receiver(topicName, new IWeEventFileClient.FileListener() { 93 | @Override 94 | public void onFile(String topicName, String fileName) { 95 | log.info("+++++++topic name: {}, file name: {}", topicName, fileName); 96 | } 97 | 98 | @Override 99 | public void onException(Throwable e) { 100 | e.printStackTrace(); 101 | } 102 | }); 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | } 106 | } 107 | ``` -------------------------------------------------------------------------------- /docs/advanced/fabric.md: -------------------------------------------------------------------------------- 1 | ## 适配Fabric 2 | 3 | `WeEvent`支持区块链`Fabric 1.4`。以下安装以`CentOS 7.2`为例。 4 | 5 | ### 前置条件 6 | - 安装`weevent-broker`, 具体安装步骤[weevent-broker章节](../install/module/broker.html) 7 | 8 | 以`weevent-broker`安装到 `/usr/local/weevent/weevent-broker-1.3.0` 目录为例。 9 | 10 | 11 | - 安装`Fabric 1.4`区块链节点(以官网`Fabric Samples`安装为例), 12 | 13 | 具体安装步骤, 请参见[Fabric安装](https://hyperledger-fabric.readthedocs.io/en/latest/install.html)。 14 | 15 | 以`Fabric 1.4`安装到 `/usr/local/fabric/fabric-sample` 目录为例。 16 | 17 | ### 修改Fabric的配置文件 18 | - 配置`Fabric`节点的证书文件 19 | 20 | - 配置`WeEvent`访问区块链 21 | 22 | ```shell 23 | $ cd /usr/local/weevent/weevent-broker-1.3.0/ 24 | $ vi ./conf/weevent.properties 25 | ``` 26 | 27 | 修改`broker.blockchain.type`配置项为:`broker.blockchain.type=fabric`。 28 | 29 | - 配置证书文件 30 | 31 | 将`Fabric`目录`/usr/local/fabric/fabric-sample/first-network/crypto-config/`所有文件, 32 | 33 | 拷贝到`weevent-broker`安装目录下`/conf/fabric/crypto-config/`里。 34 | 35 | - 区块链节点配置文件fabric.properties 36 | 37 | ```shell 38 | $ vi ./conf/fabric/fabric.properties 39 | ``` 40 | 41 | - 修改配置项 42 | ``` 43 | chain.organizations.user.keyfile=fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/xxx_sk 44 | chain.peer.address=127.0.0.1:7051 45 | chain.orderer.address=127.0.0.1:7050 46 | ``` 47 | 48 | 替换`127.0.0.1`为部署Fabric节点的ip (`peer`端口默认为7051,`orderer`端口默认为7050) 49 | 50 | - 部署系统合约 51 | 52 | 运行脚本`./deploy-fabric-topic-control.sh `部署合约。例如: 53 | 54 | ```shell 55 | $ ./deploy-fabric-topic-control.sh deploy 56 | begin deploy topic and topicController contract. 57 | begin add topic into topicController contract. 58 | deploy contract success. 59 | ``` 60 | 61 | ### 重启服务 62 | 63 | - 停止服务 64 | 65 | ```shell 66 | $ ./broker.sh stop 67 | stop broker success 68 | remove the crontab job success 69 | ``` 70 | 71 | - 启动服务 72 | 73 | ```shell 74 | $ ./broker.sh start 75 | start broker success (PID=89054) 76 | add the crontab job success 77 | ``` 78 | 79 | ### RESTful请求样例 80 | - 创建Topic,发布事件 81 | 82 | ```shell 83 | $ curl "http://localhost:8080/weevent/rest/open?topic=com.weevent.test&groupId=mychannel" 84 | [1] 16414 85 | $ true 86 | $ curl "http://localhost:8080/weevent/rest/publish?topic=com.weevent.test&groupId=mychannel&content=123456&weevent-format=json" 87 | $ {"status":"SUCCESS","topic":"com.weevent.test","eventId":"317e7c4c-301009-6705"} 88 | ``` 89 | 90 | ### 代码样例 91 | 92 | `API`里所有的`groupId`就是`Fabric`的`channelname`, 以发布事件为例: 93 | 94 | ```java 95 | public class Rest { 96 | public static void main(String[] args) { 97 | System.out.println("This is WeEvent restful sample."); 98 | try { 99 | SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 100 | RestTemplate rest = new RestTemplate(requestFactory); 101 | 102 | // ensure topic exist "com.weevent.test" 103 | String topic = "com.weevent.test"; 104 | ResponseEntity> rsp = rest.exchange("http://localhost:7000/weevent-broker/rest/open?topic={topic}&groupId={groupId}", HttpMethod.GET, null, new ParameterizedTypeReference>() { 105 | }, topic, "mychannel"); 106 | 107 | System.out.println(rsp.getBody().getData()); 108 | // publish event to topic "com.weevent.test" 109 | SendResult sendResult = rest.getForEntity("http://localhost:8080/weevent/rest/publish?topic={topic}&groupId={groupId}&content={content}", 110 | SendResult.class, 111 | topic, 112 | "mychannel", 113 | "hello weevent".getBytes(StandardCharsets.UTF_8)).getBody(); 114 | System.out.println(sendResult.getStatus()); 115 | System.out.println(sendResult.getEventId()); 116 | } catch (RestClientException e) { 117 | e.printStackTrace(); 118 | } 119 | } 120 | } 121 | ``` 122 | 123 | -------------------------------------------------------------------------------- /docs/advanced/index.rst: -------------------------------------------------------------------------------- 1 | 进阶内容 2 | ========================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :caption: Contents: 7 | 8 | /advanced/port 9 | /advanced/upgrade 10 | /advanced/fabric 11 | /advanced/bigfile 12 | -------------------------------------------------------------------------------- /docs/advanced/port.md: -------------------------------------------------------------------------------- 1 | ## 服务访问 2 | 3 | ### 默认端口映射 4 | 5 | ![](../image/port.png) 6 | 7 | ### 更多说明 8 | 9 | - 业务程序统一从前置的API Gateway接入,通过端口8080访问。 10 | 11 | `RESTful`协议的访问`URL`为 `http://localhost:8080/weevent-broker/rest`。 12 | 13 | `JsonRPC`协议的访问`URL`为 `http://localhost:8080/weevent-broker/jsonrpc`。 14 | 15 | `STOMP`协议基于`WebSocket`的 访问`URL`为`ws://localhost:8080/weevent-broker/stomp`,如果是基于`SockJS`则为`http://localhost:8080/weevent-broker/sockjs`。 16 | 17 | `MQTT`协议基于`WebSocket`的访问`URL`为`ws://localhost:8080/weevent-broker/mqtt`。 18 | 19 | - API Gateway也支持HTTPS访问,端口为443。 20 | 21 | 客户端无论使用`HTTP`还是`HTTPS`访问,`API Gateway`都是通过`HTTP`来访问后端服务。 22 | 23 | - 以上说明全是指默认端口, 所有端口都支持自定义配置 24 | 25 | -------------------------------------------------------------------------------- /docs/advanced/upgrade.md: -------------------------------------------------------------------------------- 1 | ## 服务升级 2 | 3 | ### Solidity合约升级 4 | 5 | `WeEvent`从`1.1.0`版本开始,支持区块链数据的平滑升级,包括`Solidity`合约和`CRUD`表等。升级后的服务支持向后兼容,可以透明的访问历史数据。 6 | 7 | 每个版本中自带的合约部署脚本`./broker/deploy-topic-control.sh`同时也是区块链数据升级脚本。并且该脚本允许重复执行。 8 | 9 | ```shell 10 | $ cd ./broker; ./deploy-topic-control.sh 11 | 2019-11-08 22:13:07 topic control address in every group: 12 | topic control address in group: 1 13 | version: 10 address: 0x23df89a2893120f686a4aa03b41acf6836d11e5d new: true 14 | ``` 15 | 16 | `new`字段`true`表示合约是本次部署的,`false`表示合约已经存在。 17 | 18 | ### Java程序升级 19 | 20 | 正常情况下,`Java`程序升级替换对应`Jar`包即可。 21 | 22 | 遇到数据库结构需要升级时,会在有需要的版本里携带升级脚本。`WeEvent`会始终坚持升级对用户透明的策略。 -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/stable/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | # import os 16 | import sys 17 | import os 18 | import shlex 19 | sys.path.insert(0, os.path.abspath('.')) 20 | 21 | 22 | # -- Project information ----------------------------------------------------- 23 | 24 | project = 'WeEvent' 25 | copyright = '2020, WeEvent' 26 | author = 'WeEvent' 27 | 28 | # The short X.Y version 29 | version = '' 30 | # The full version, including alpha/beta/rc tags 31 | release = '' 32 | 33 | # -- General configuration --------------------------------------------------- 34 | 35 | # If your documentation needs a minimal Sphinx version, state it here. 36 | # 37 | # needs_sphinx = '1.0' 38 | 39 | # Add any Sphinx extension module names here, as strings. They can be 40 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 41 | # ones. 42 | extensions = [ 43 | 'sphinx.ext.autodoc', 44 | 'sphinx.ext.doctest', 45 | 'sphinx.ext.intersphinx', 46 | 'sphinx.ext.todo', 47 | 'sphinx.ext.coverage', 48 | 'sphinx.ext.mathjax', 49 | 'sphinx.ext.ifconfig', 50 | 'sphinx.ext.viewcode', 51 | 'sphinx.ext.githubpages', 52 | 'sphinx_markdown_tables', 53 | ] 54 | 55 | # Add any paths that contain templates here, relative to this directory. 56 | templates_path = ['_templates'] 57 | 58 | # The suffix(es) of source filenames. 59 | # You can specify multiple suffix as a list of string: 60 | import recommonmark 61 | from recommonmark.parser import CommonMarkParser 62 | from recommonmark.transform import AutoStructify 63 | source_parsers = { 64 | '.md': 'recommonmark.parser.CommonMarkParser', 65 | } 66 | # 67 | source_suffix = ['.rst', '.md'] 68 | source_suffix = '.rst' 69 | 70 | # The master toctree document. 71 | master_doc = 'index' 72 | 73 | # The language for content autogenerated by Sphinx. Refer to documentation 74 | # for a list of supported languages. 75 | # 76 | # This is also used if you do content translation via gettext catalogs. 77 | # Usually you set "language" from the command line for these cases. 78 | language = 'zh_CN' 79 | html_search_language = 'utf-8' 80 | # List of patterns, relative to source directory, that match files and 81 | # directories to ignore when looking for source files. 82 | # This pattern also affects html_static_path and html_extra_path . 83 | exclude_patterns = [] 84 | 85 | # The name of the Pygments (syntax highlighting) style to use. 86 | # pygments_style = 'sphinx' 87 | pygments_style = None 88 | 89 | 90 | # -- Options for HTML output ------------------------------------------------- 91 | 92 | # The theme to use for HTML and HTML Help pages. See the documentation for 93 | # a list of builtin themes. 94 | # 95 | # html_theme = 'alabaster' 96 | # add cristic 97 | import sphinx_rtd_theme 98 | html_theme = "sphinx_rtd_theme" 99 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 100 | 101 | github_doc_root = 'https://github.com/WeBankBlockchain/WeEvent-docs' 102 | def setup(app): 103 | app.add_config_value('recommonmark_config', { 104 | 'url_resolver': lambda url: github_doc_root + url, 105 | 'auto_toc_tree_section': 'Contents', 106 | 'enable_eval_rst': True, 107 | }, True) 108 | 109 | app.add_transform(AutoStructify) 110 | app.add_stylesheet('css/custom.css') 111 | app.add_javascript('js/readthedocs-analytics.js') 112 | 113 | # Theme options are theme-specific and customize the look and feel of a theme 114 | # further. For a list of options available for each theme, see the 115 | # documentation. 116 | # 117 | # html_theme_options = {} 118 | 119 | # Add any paths that contain custom static files (such as style sheets) here, 120 | # relative to this directory. They are copied after the builtin static files, 121 | # so a file named "default.css" will overwrite the builtin "default.css". 122 | #html_static_path = ['_static'] 123 | 124 | # Custom sidebar templates, must be a dictionary that maps document names 125 | # to template names. 126 | # 127 | # The default sidebars (for documents that don't match any pattern) are 128 | # defined by theme itself. Builtin themes are using these templates by 129 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 130 | # 'searchbox.html']``. 131 | # 132 | # html_sidebars = {} 133 | 134 | 135 | # -- Options for HTMLHelp output --------------------------------------------- 136 | 137 | # Output file base name for HTML help builder. 138 | htmlhelp_basename = 'WeEventdoc' 139 | 140 | 141 | # -- Options for LaTeX output ------------------------------------------------ 142 | 143 | latex_elements = { 144 | # The paper size ('letterpaper' or 'a4paper'). 145 | # 146 | # 'papersize': 'letterpaper', 147 | 148 | # The font size ('10pt', '11pt' or '12pt'). 149 | # 150 | # 'pointsize': '10pt', 151 | 152 | # Additional stuff for the LaTeX preamble. 153 | # 154 | # 'preamble': '', 155 | 156 | # Latex figure (float) alignment 157 | # 158 | # 'figure_align': 'htbp', 159 | } 160 | 161 | # Grouping the document tree into LaTeX files. List of tuples 162 | # (source start file, target name, title, 163 | # author, documentclass [howto, manual, or own class]). 164 | latex_documents = [ 165 | (master_doc, 'WeEvent.tex', 'WeEvent Documentation', 166 | 'cristic', 'manual'), 167 | ] 168 | 169 | 170 | # -- Options for manual page output ------------------------------------------ 171 | 172 | # One entry per manual page. List of tuples 173 | # (source start file, name, description, authors, manual section). 174 | man_pages = [ 175 | (master_doc, 'WeEvent', 'WeEvent Documentation', 176 | [author], 1) 177 | ] 178 | 179 | 180 | # -- Options for Texinfo output ---------------------------------------------- 181 | 182 | # Grouping the document tree into Texinfo files. List of tuples 183 | # (source start file, target name, title, author, 184 | # dir menu entry, description, category) 185 | texinfo_documents = [ 186 | (master_doc, 'WeEvent', 'WeEvent Documentation', 187 | author, 'WeEvent', 'One line description of project.', 188 | 'Miscellaneous'), 189 | ] 190 | 191 | 192 | # -- Options for Epub output ------------------------------------------------- 193 | 194 | # Bibliographic Dublin Core info. 195 | epub_title = project 196 | epub_author = author 197 | epub_publisher = author 198 | epub_copyright = copyright 199 | 200 | # The unique identifier of the text. This can be a ISBN number 201 | # or the project homepage. 202 | # 203 | # epub_identifier = '' 204 | 205 | # A unique identification for the text. 206 | # 207 | # epub_uid = '' 208 | 209 | # A list of files that should not be packed into the epub file. 210 | epub_exclude_files = ['search.html'] 211 | 212 | import sphinx_rtd_theme 213 | html_theme = "sphinx_rtd_theme" 214 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 215 | 216 | # -- Extension configuration ------------------------------------------------- 217 | 218 | # -- Options for intersphinx extension --------------------------------------- 219 | 220 | # Example configuration for intersphinx: refer to the Python standard library. 221 | intersphinx_mapping = {'https://docs.python.org/': None} 222 | 223 | # -- Options for todo extension ---------------------------------------------- 224 | # If true, `todo` and `todoList` produce output, else they produce nothing. 225 | todo_include_todos = True 226 | 227 | # workaround: text in table cell not to wrap 228 | html_static_path = ['_static'] 229 | 230 | html_context = { 231 | "display_github": True, # Integrate GitHub 232 | "github_repo": "WeEvent-docs", # Repo name 233 | "github_user": "WeBankBlockchain", 234 | "github_version": "master", # Version 235 | "conf_py_path": "/docs/", # Path in the checkout to the docs root 236 | } 237 | -------------------------------------------------------------------------------- /docs/faq/blockchain.md: -------------------------------------------------------------------------------- 1 | ## 区块链 2 | `WeEvent`使用区块链`FISCO-BCOS`作为数据存储和持久化机制。这里列举的是`WeEvent`访问`FISCO-BCOS`节点可能出现的问题。关于`FISCO-BCOS`更多FAQ,参见[FISCO-BCOS FAQ](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/faq.html) 。 3 | 4 | - `FISCO-BCOS`节点推荐的组网方式? 5 | 6 | 基于节点容灾备份的考虑,建议每个机构至少部署2个`FISCO-BCOS`节点,分布在不同的机器甚至网段上。例如:3个机构间通过一条链互联,则至少应该部署3 * 2 = 6个区块链节点。 7 | 8 | 9 | - 怎么查看`FISCO-BCOS`节点状态? 10 | 11 | 通过`FISCO-BCOS`提供的命令行工具`monitor.sh` 12 | 13 | ```bash 14 | $ ./monitor.sh 15 | {"id":67,"jsonrpc":"2.0","result":"0x299"} 16 | {"id":68,"jsonrpc":"2.0","result":"0x1767"} 17 | [2019-03-28 16:15:43] OK! 0.0.0.0:8545 is working properly: height 0x299 view 0x1767 18 | [2019-03-28 16:15:43] # log parser min, 2019-03-28 16:14 19 | {"id":67,"jsonrpc":"2.0","result":"0x299"} 20 | {"id":68,"jsonrpc":"2.0","result":"0x1767"} 21 | [2019-03-28 16:15:44] OK! 0.0.0.0:8546 is working properly: height 0x299 view 0x1767 22 | [2019-03-28 16:15:44] # log parser min, 2019-03-28 16:14 23 | {"id":67,"jsonrpc":"2.0","result":"0x299"} 24 | {"id":68,"jsonrpc":"2.0","result":"0x1767"} 25 | [2019-03-28 16:15:44] OK! 0.0.0.0:8547 is working properly: height 0x299 view 0x1767 26 | [2019-03-28 16:15:44] # log parser min, 2019-03-28 16:14 27 | {"id":67,"jsonrpc":"2.0","result":"0x299"} 28 | {"id":68,"jsonrpc":"2.0","result":"0x1768"} 29 | [2019-03-28 16:15:44] OK! 0.0.0.0:8548 is working properly: height 0x299 view 0x1768 30 | ``` 31 | 32 | - 为什么会出现`activeConnections isEmpty`错误? 33 | 34 | `WeEvent`到`FISCO-BCOS`节点的连接有异常,一般是网络不通引起的。 35 | 36 | ``` 37 | 2019-01-03 14:18:27.507 [pool-6] ERROR ChannelConnections(ChannelConnections.java:161) - activeConnections isEmpty 38 | 2019-01-03 14:18:28.061 [pool-6] ERROR Service(Service.java:488) - system error 39 | java.lang.Exception: activeConnections isEmpty 40 | at org.bcos.channel.handler.ChannelConnections.randomNetworkConnection(ChannelConnections.java:162) ~[web3sdk-v1.2.6.jar:?] 41 | at org.bcos.channel.client.Service.asyncSendEthereumMessage(Service.java:460) ~[web3sdk-v1.2.6.jar:?] 42 | at org.bcos.channel.client.Service.sendEthereumMessage(Service.java:290) ~[web3sdk-v1.2.6.jar:?] 43 | ... 44 | ``` 45 | 46 | - 节点证书异常 47 | 48 | ``` 49 | =====INIT ECDSA KEYPAIR From private key=== 50 | 2019-03-25 10:27:17.624 ERROR [nioEventLoopGroup-2-1] [ChannelHandler.java:147 org.bcos.channel.handler.ChannelHandler.exceptionCaught] network error 51 | io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: General SSLEngine problem 52 | ... 53 | io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) 54 | at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) 55 | at java.lang.Thread.run(Thread.java:745) 56 | ``` 57 | 58 | 请检查并且更新证书。 59 | -------------------------------------------------------------------------------- /docs/faq/index.rst: -------------------------------------------------------------------------------- 1 | FAQ 2 | ========================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | /faq/weevent 8 | /faq/blockchain -------------------------------------------------------------------------------- /docs/faq/weevent.md: -------------------------------------------------------------------------------- 1 | ## WeEvent 2 | 3 | 关于`WeEvent`使用的一些常见问题和答案都会整理归档到这里。 4 | 5 | 简单的接口调用异常一般从错误码中就可以得到答案[WeEvent错误码](../protocol/errorcode.html) 。有任何意见和建议,欢迎你参与`WeEvent`项目讨论[Issues](https://github.com/WeBankBlockchain/WeEvent/issues) 。 6 | 7 | - 怎么部署`WeEvent`和`FISCO-BCOS`? 8 | 9 | 建议将`WeEvent`和`FISCO-BCOS`节点部署在同一网段/逻辑区,比如`DMZ`区。 10 | 11 | - `WeEvent`的服务访问授权机制是怎么样的? 12 | 13 | `WeEvent`访问权限控制基于`HTTPS` + `IP`白名单,`STOMP`和`MQTT`协议还支持协议定义的账号/密码机制。 14 | 15 | - 如何选择各种接入协议,`RESTful`、`JsonRPC`、`STOMP`还是`MQTT`? 16 | 17 | - 协议之间的区别 18 | 19 | `STOMP`协议是`WeEvent`推荐协议,关于订阅发布的所有特性,以及未来的扩展功能都会支持。 20 | 21 | `JsonRPC`协议是对`STOMP`协议标准功能集的一个补充。 22 | 23 | `RESTful`主要是给`Web`开发使用,内置的`Governance`模块就有大量使用。 24 | 25 | `MQTT`主要面向物联网`IoT`设备的接入。 26 | 27 | - Java程序 28 | 29 | - 如果是`Spring`服务,有内置的`org.springframework.boot:spring-boot-starter-websocket`支持,推荐使用`STOMP`。 30 | - 如果是其他`Java`程序,建议使用`WeEvent`提供的`Java SDK`。 31 | 32 | - 其他语言 33 | - 生产者`Producer`建议使用`RESTful`/`JsonRPC` ,简单方便。 34 | - 消费者`Consumer`因为涉及到事件的持续`Push`,建议使用`STOMP`协议接入。 35 | 36 | - `WeEvent`服务的高可用性方案是怎么样的? 37 | 38 | `WeEvent`除了订阅之外的功能,都是无状态的请求,通过`Cluster`集群的多实例负载均衡来保证高可用性。订阅功能按是否为长连接分成两类: 39 | 40 | - 使用短链接的协议,比如`JsonRPC`/`RESTful` 41 | 短链接协议都是无状态请求。通过负载均衡路由到任意的服务实例上执行即可。 42 | 43 | - 使用长连接的协议,比如`STOMP`/`MQTT` 44 | 这部分功能基于长连接,订阅上下文以连接为中心,连接关闭则订阅会自动关闭。 45 | 46 | - `WeEvent`怎么处理发布事件的去重? 47 | 48 | `WeEvent`不处理发布事件的去重。 49 | 50 | 当服务超时或者机器宕机时,一般的逻辑是重试,这种策略很容易出现重复请求。但是整个业务系统内,不只在`WeEevnt`服务的边界会出现这种情况,任何一个服务边界都会出现。 建议业务统一处理,比如在事件内容里带一个唯一ID`UUID`,消费的时候使用`UUID`字段来判断该事件是否已经处理过。 51 | ```eval_rst 52 | .. important:: 53 | - EventID不是用来去重的,同一事件每成功发布一次,都会生成不同的EventID。 54 | ``` 55 | - 服务状态检查脚本`check-service.sh`出现`"deploy contract failed"` 56 | - 检查`WeEvent`到`FISCO-BCOS`的连接及其配置。 57 | - 检查`FISCO-BCOS`节点是否正常出块。 58 | 59 | - `WeEvent`事件内容支持的最大长度是多少? 60 | 61 | 事件内容最大长度为10 K字节 `Byte`, 字符集编码为`UTF8`。 62 | 63 | - `WeEvent`到区块链`FISCO-BCOS`节点之间的网络故障怎么处理? 64 | 65 | 建议为`WeEvent`配置2个属于不同网段的`FISCO-BCOS`节点。这样`WeEvent`服务会随机选用一个可用的节点使用,做到一定程度的网络容灾。 66 | 67 | - 怎么使用通配符进行订阅 68 | `WeEvent`支持通配符按层次订阅,和`MQTT`的定义完全一致。包括层次分隔符"/",单层通配符"+",多层通配符"#"。例如,“#”可以订阅到系统内所有的主题。“com/+”可以订阅到主题“com/weevent”和“com/test“,但是无法订阅到“com/weevent/abc”。“com/#”则可以订阅到上述三个主题。详情请参见[MQTT协议](http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html)。 69 | 70 | - 服务启动时为什么会出现Failed to initialize the client-side SSLContext错误? 71 | 72 | ``` 73 | javax.net.ssl.SSLException: Failed to initialize the client-side SSLContext: Input stream not contain valid certificates 74 | ``` 75 | 76 | 这个问题涉及到`JDK`加密算法的实现。`Oracle JDK`里带了这个算法实现,`Open JDK`直到 1.9版本才有。所以在`CentOS`系统中,如果使用 `Open JDK 1.9`以下版本,`WeEvent`启动时会出现以下异常。请升级`Open JDK`版本到1.9或者使用`Oracle JDK`。 77 | 78 | 79 | 80 | 81 | - 如何切换数据库 82 | 83 | 目前WeEvent默认的是H2数据库,`application-prod.properties`中默认数据库配置如下 84 | 85 | ``` 86 | spring.datasource.url=jdbc:h2:./WeEvent_governance 87 | spring.datasource.driver-class-name=org.h2.Driver 88 | spring.datasource.username=root 89 | spring.datasource.password=123456 90 | ``` 91 | 92 | 如果要切换成Mysql数据库,改成下面这样,其中`url、username、password` 修改成需要连接的数据库配置。 93 | 94 | ``` 95 | spring.datasource.url=jdbc:mysql://127.0.0.1:3306/WeEvent_governance?useUnicode=true&characterEncoding=utf-8&useSSL=false 96 | spring.datasource.driver-class-name=org.mariadb.jdbc.Driver 97 | spring.datasource.username=root 98 | spring.datasource.password=123456 99 | ``` 100 | ```eval_rst 101 | .. important:: 102 | - Mysql数据库要赋予配置账号创建库表的权限。 103 | ``` 104 | ``` 105 | >> grant all privileges on *.* to 'root'@'%' identified by '123456'; 106 | >> flush privileges; 107 | ``` 108 | -------------------------------------------------------------------------------- /docs/history/changelog.md: -------------------------------------------------------------------------------- 1 | ## 版本历史 2 | 参见[github项目发布列表](https://github.com/WeBankBlockchain/WeEvent/releases)。 3 | 4 | -------------------------------------------------------------------------------- /docs/history/index.rst: -------------------------------------------------------------------------------- 1 | 版本说明 2 | ========================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | 7 | /history/changelog -------------------------------------------------------------------------------- /docs/image/Governance-multi-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/Governance-multi-view.png -------------------------------------------------------------------------------- /docs/image/Governance-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/Governance-ui.png -------------------------------------------------------------------------------- /docs/image/IoTScarino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/IoTScarino.png -------------------------------------------------------------------------------- /docs/image/WeEventArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/WeEventArchitecture.png -------------------------------------------------------------------------------- /docs/image/WeventTopView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/WeventTopView.png -------------------------------------------------------------------------------- /docs/image/port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/port.png -------------------------------------------------------------------------------- /docs/image/processor/ruledetails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/processor/ruledetails.png -------------------------------------------------------------------------------- /docs/image/processor/rulelist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/processor/rulelist.png -------------------------------------------------------------------------------- /docs/image/processor/selectWhereCondition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/processor/selectWhereCondition.png -------------------------------------------------------------------------------- /docs/image/processor/setRule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/processor/setRule.png -------------------------------------------------------------------------------- /docs/image/processor/setRuleContent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/processor/setRuleContent.png -------------------------------------------------------------------------------- /docs/image/weevent-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/weevent-logo.png -------------------------------------------------------------------------------- /docs/image/workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WeBankBlockchain/WeEvent-docs/ef3c7b73e481a9e26171453f7891f206b8ce47eb/docs/image/workflow.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. WeEvent documentation master file, created by 2 | sphinx-quickstart on Wed Oct 31 11:05:34 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ======= 7 | ############################################################## 8 | WeEvent文档 9 | ############################################################## 10 | 11 | 12 | .. image:: image/weevent-logo.png 13 | :alt: weevent-logo.png 14 | 15 | ---- 16 | 17 | 什么是 WeEvent? 18 | ======================== 19 | 20 | 21 | WeEvent是一套分布式事件驱动架构,实现了可信、可靠、高效的跨机构、跨平台事件通知机制。 22 | 23 | WeEvent由微众银行自主研发并完全开源,秉承分布式商业模式中对等合作、智能协同、价值共享的设计理念,致力于提升机构间合作效率,降低合作成本,同时打通应用程序、物联网、云服务和私有服务等不同平台,最终在不改变已有商业系统的开发语言、接入协议的情况下,做到跨机构、跨平台的事件通知与处理。 24 | 25 | 26 | `WeEvent官网 `_ 27 | 28 | 29 | 👏 欢迎大家贡献和分享 `github地址 `_ 30 | 31 | 32 | .. toctree:: 33 | :maxdepth: 1 34 | 35 | /introduction/index 36 | /install/index 37 | /protocol/index 38 | /scarino/index 39 | /advanced/index 40 | /history/changelog.md 41 | /faq/index 42 | 微众银行参与和建立的所有区块链项目 -------------------------------------------------------------------------------- /docs/install/environment.md: -------------------------------------------------------------------------------- 1 | ## 系统要求 2 | 3 | ### 配置说明 4 | 5 | | 配置 | 最低配置 | 推荐配置 | 6 | | -------- | ----------------- | ------------------------------------------------------------ | 7 | | CPU | 1核 1.5GHz | 4核 2.4GHz | 8 | | 内存 | 2G | 4GB | 9 | | 带宽 | 1M | 5M | 10 | | Java | Java(TM) 1.8 | 推荐`Oralce JDK`,如果是1.8.0.231及以上版本,在使用时都需要配置`jvm`参数` -Djdk.tls.namedGroups="secp256k1"`
如果在`CentOS`中使用`Open JDK`,请先升级到`1.9` | 11 | | 操作系统 | 能正常运行JVM即可 | 快速安装Bash脚本在以下环境测试通过:
`CentOS7.2`、`Ubuntu16.04`、`RedHat7.4`
`Java`服务在以下环境测试通过:
`CentOS7.2`、`Ubuntu16.04`、`RedHat7.4`、`Windows7` | 12 | 13 | ### 第三方软件 14 | 15 | | 软件名 | 推荐版本 | 是否可选 | 16 | | ---------- | ----------------- | -------- | 17 | | FISCO-BCOS | 2.2.0 | 必选 | 18 | | Zookeeper | 3.5.5及其以上版本 | 可选 | 19 | | Mysql | 5.7及其以上版本 | 可选 | 20 | -------------------------------------------------------------------------------- /docs/install/index.rst: -------------------------------------------------------------------------------- 1 | ========================================= 2 | 安装部署 3 | ========================================= 4 | 5 | 本章节主要介绍WeEvent的安装部署。WeEvent部署安装分为快速安装和详细安装。 6 | 7 | 快速安装:通过Docker镜像或者Bash安装,可以搭建一个WeEvent基础环境,可以方便用户体验核心功能。 8 | 9 | 详细安装:在生产环境中,建议用户参考详细安装,部署全部功能,保证系统高效和稳定。 10 | 11 | 12 | .. toctree:: 13 | :maxdepth: 1 14 | 15 | /install/environment 16 | /install/quickinstall 17 | /install/module/index 18 | /install/property 19 | /install/download 20 | -------------------------------------------------------------------------------- /docs/install/module/broker.md: -------------------------------------------------------------------------------- 1 | ## Broker模块 2 | 3 | 如果是第一次安装`WeEvent`,参见这里的[系统要求](../environment.html) 。以下安装以`CentOS 7.2`为例。 4 | 5 | 因为区块链使用的加密算法很多`OpenJDK`版本没有提供。所以在各`Java`启动脚本里有设置`JAVA_HOME`变量让用户设置符合要求的`JDK`。 6 | 7 | ### 前置条件 8 | 9 | - Zookeeper服务 10 | 11 | 必选配置。服务注册和发现会使用到。 12 | 13 | 推荐使用`Zookeeper 3.5.5`及其以上版本。具体安装步骤,请参见[Zookeeper安装](https://zookeeper.apache.org/doc/r3.5.7/zookeeperStarted.html)。 14 | 15 | - 区块链FISCO-BCOS节点 16 | 17 | 必选配置。Broker通过区块链`FISCO-BCOS`持久化数据。 18 | 19 | 20 | ### 获取安装包 21 | 22 | 从`github`下载安装包[weevent-broker-1.6.0.tar.gz](https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-broker-1.6.0.tar.gz),并且解压到`/usr/local/weevent/`下。 23 | 24 | ``` shell 25 | $ cd /usr/local/weevent/ 26 | $ wget https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-broker-1.6.0.tar.gz 27 | $ tar -zxf weevent-broker-1.6.0.tar.gz 28 | ``` 29 | 30 | 31 | 解压后的目录如下: 32 | 33 | ``` 34 | $ cd ./weevent-broker-1.6.0 35 | $ tree -L 1 36 | . 37 | |-- apps 38 | |-- broker.sh 39 | |-- check-service.sh 40 | |-- conf 41 | |-- deploy-fabric-topic-control.sh 42 | |-- deploy-topic-control.sh 43 | |-- gen-cert-key.sh 44 | `-- lib 45 | ``` 46 | 47 | ### 修改配置文件 48 | 49 | - 配置Zookeeper服务 50 | 51 | 可选配置。`./conf/application-prod.properties`中`spring.cloud.zookeeper`配置项。 52 | 53 | ```ini 54 | # spring cloud zookeeper 55 | spring.cloud.zookeeper.enabled=true 56 | spring.cloud.zookeeper.connect-string=127.0.0.1:2181 57 | ``` 58 | 59 | - 区块链FISCO-BCOS节点 60 | 61 | - 区块链节点配置文件fisco.yml 62 | 63 | 修改`nodes=127.0.0.1:20200`配置项,`nodes`为区块链节点`channel`访问入口。 64 | 65 | - 访问节点的证书文件 66 | 67 | 2.x版本的证书文件`ca.crt`、`sdk.crt`、`sdk.key`放在`./conf/conf`目录下。 68 | 69 | 国密版需要的证书文件`gmca.crt、gmensdk.crt、gmensdk.key、gmsdk.crt、gmsdk.key` 。 70 | 71 | 证书目录在FiscoBcos安装目录下`nodes/127.0.0.1/sdk/`, 可直接将该目录下所有内容拷贝到 `./conf/conf`下。 72 | 73 | ``` 74 | cp -rf fisco安装路径/nodes/127.0.0.1/sdk/* ./conf/conf 75 | ``` 76 | 77 | 证书文件生成及获取请参见[FISCO-BCOS 2.x安装](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html#id1) 及 [FISCO-BCOS SDK配置说明 ](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html)。 78 | 79 | - 部署系统合约 80 | 81 | 运行脚本`./deploy-topic-control.sh `部署合约。例如: 82 | 83 | ```shell 84 | $ ./deploy-topic-control.sh 85 | 2020-03-06 10:33:37 topic control address in every group: 86 | topic control address in group: 1 87 | version: 10 address: 0x23df89a2893120f686a4aa03b41acf6836d11e5d new: true 88 | topic control address in group: 2 89 | version: 10 address: 0x23df89a2893120f686a4aa03b41acf6836d11e5d new: true 90 | ``` 91 | 92 | 脚本会检查之前是否部署过合约,重复执行只是显示已有数据。 93 | 94 | - 配置Broker监听端口 95 | 96 | 可选配置。`./conf/application-prod.properties`中`server.port`配置项,默认监听端口`7000`,根据业务需要配置。 97 | 98 | - 配置IP白名单 99 | 100 | 可选配置。`./conf/weevent.properties`中配置了值就会开启白名单验证。 101 | 102 | ```ini 103 | # 配置ip白名单,多个ip使用分号分割 示例:127.0.0.1;127.0.0.2 104 | ip.check.white-table=${ip} 105 | ``` 106 | 107 | `ip.check.white-table`默认为空,允许任何客户端`IP`访问。 108 | 109 | - 配置STOMP 110 | 111 | 可选配置。`./conf/weevent.properties`中`stomp.*`配置项。 112 | 113 | ```ini 114 | # 发送心跳时间间隔 单位:秒 115 | stomp.heartbeats=30 116 | ``` 117 | 118 | - 配置`MQTT Broker` 119 | 120 | 可选配置。配置文件`./conf/weevent.properties`中`mqtt.*`配置项。 121 | 122 | ```ini 123 | # MQTT over tcp端口 124 | mqtt.broker.tcp.port=7001 125 | # 心跳时间 单位:秒 126 | mqtt.broker.keepalive=60 127 | ``` 128 | 129 | - 启动用户身份认证、权限控制 130 | 131 | 可选配置,默认不开启,目前支持MQTT协议,后续会扩展支持其他协议。需要在DB里配置用户名密码,可通过外部工具处理,后续提供接口增删。 132 | 133 | ```properties 134 | spring.security.user.auth=false 135 | spring.security.user.topic.auth=false 136 | ``` 137 | 138 | 更多系统详细配置参见[配置说明](../property.html) 139 | 140 | ### 服务启停 141 | 142 | 通过`./broker.sh start`命令启动服务,正常启动如下: 143 | 144 | ```shell 145 | $ ./broker.sh start 146 | start weevent-broker success (PID=89054) 147 | add the crontab job success 148 | ``` 149 | 150 | 通过`./broker.sh stop`命令停止服务。 151 | 152 | 进程启动后,会自动加入集群,同时添加`crontab`监控任务`./broker.sh monitor`。 153 | 154 | -------------------------------------------------------------------------------- /docs/install/module/gateway.md: -------------------------------------------------------------------------------- 1 | ## Gateway模块 2 | 3 | `Gateway`模块作为`WeEvent`服务的统一访问入口,提供负载均衡、限流和熔断等功能。 4 | 5 | 如果是第一次安装`WeEvent`,参见这里的[系统要求](../environment.html) 。以下安装以`CentOS 7.2`为例。 6 | 7 | 因为区块链使用的加密算法很多`OpenJDK`版本没有提供。所以在各`Java`启动脚本里有设置`JAVA_HOME`变量让用户设置符合要求的`JDK`。 8 | 9 | ### 前置条件 10 | 11 | - Zookeeper服务 12 | 13 | 必选配置。服务注册和发现会使用到。 14 | 15 | 推荐使用`Zookeeper 3.5.5`及其以上版本。具体安装步骤,请参见[Zookeeper安装](https://zookeeper.apache.org/doc/r3.5.7/zookeeperStarted.html)。 16 | 17 | 18 | ### 获取安装包 19 | 20 | 从`github`下载安装包[weevent-gateway-1.6.0.tar.gz](https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-gateway-1.6.0.tar.gz),并且解压到`/usr/local/weevent/`下。 21 | 22 | ``` shell 23 | $ cd /usr/local/weevent/ 24 | $ wget https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-gateway-1.6.0.tar.gz 25 | $ tar -zxf weevent-gateway-1.6.0.tar.gz 26 | ``` 27 | 28 | 解压后的目录如下: 29 | 30 | ``` 31 | $ cd ./weevent-gateway-1.6.0 32 | $ tree -L 1 33 | . 34 | |-- apps 35 | |-- gateway.sh 36 | |-- check-service.sh 37 | |-- conf 38 | `-- lib 39 | ``` 40 | 41 | ### 修改配置文件 42 | 43 | - 配置Zookeeper服务 44 | 45 | 可选配置。`./conf/application-prod.properties`中`spring.cloud.zookeeper`配置项。 46 | 47 | ```ini 48 | # spring cloud zookeeper 49 | spring.cloud.zookeeper.enabled=true 50 | spring.cloud.zookeeper.connect-string=127.0.0.1:2181 51 | ``` 52 | 53 | 54 | 55 | 更多系统详细配置参见[配置说明](../property.html) 56 | 57 | ### 服务启停 58 | 59 | 通过`./gateway.sh start`命令启动服务,正常启动如下: 60 | 61 | ```shell 62 | $ ./gateway.sh start 63 | start weevent-gateway success (PID=89059) 64 | add the crontab job success 65 | ``` 66 | 67 | 通过`./gateway.sh stop`命令停止服务。 68 | 69 | 进程启动后,同时添加`crontab`监控任务`./gateway.sh monitor`。 70 | 71 | -------------------------------------------------------------------------------- /docs/install/module/governance.md: -------------------------------------------------------------------------------- 1 | ## Governance模块 2 | 如果是第一次安装`WeEvent`,参见这里的[系统要求](../environment.html) 。以下安装以`CentOS 7.2`为例。 3 | 4 | 因为区块链使用的加密算法很多`OpenJDK`版本没有提供。所以在各`Java`启动脚本里有设置`JAVA_HOME`变量让用户设置符合要求的`JDK`。 5 | 6 | ### 前置条件 7 | 8 | - Zookeeper服务 9 | 10 | 必选配置。服务注册和发现会使用到。 11 | 12 | 推荐使用`Zookeeper 3.5.5`及其以上版本。具体安装步骤,请参见[Zookeeper安装](https://zookeeper.apache.org/doc/r3.5.7/zookeeperStarted.html)。 13 | 14 | - Broker模块 15 | 16 | 必选配置,通过`Broker`访问区块链。 17 | 18 | 具体安装步骤,请参见[Broker模块安装](./broker.html)。 19 | 20 | - Mysql数据库 21 | 22 | 可选配置。支持`Mysql`存储数据,如果不配置则使用内置的`H2`数据库。如果要使用Mysql数据库,需要做一个 23 | 24 | 切换,切换步骤,请参考[FAQ](https://weeventdoc.readthedocs.io/zh_CN/latest/faq/weevent.html)。 25 | 26 | 推荐安装`Mysql 5.7+`版本。具体安装步骤,安装请参见[Mysql安装](http://dev.mysql.com/downloads/mysql/) 。 27 | 28 | - Processor模块 29 | 可选配置。通过`Processor`触发规则引擎。 30 | 具体安装步骤,请参见[Processor模块安装](./processor.html)。 31 | 32 | 33 | ### 获取安装包 34 | 35 | 从`github`下载安装包[weevent-governance-1.6.0.tar.gz](https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-governance-1.6.0.tar.gz),并且解压到`/usr/local/weevent/`下。 36 | 37 | ```shell 38 | $ cd /usr/local/weevent/ 39 | $ wget https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-governance-1.6.0.tar.gz 40 | $ tar -xvf weevent-governance-1.6.0.tar.gz 41 | ``` 42 | 43 | 44 | 解压后的目录结构如下 45 | 46 | ``` 47 | $ cd ./weevent-governance-1.6.0 48 | $ tree -L 1 49 | . 50 | |-- apps 51 | |-- check-service.sh 52 | |-- conf 53 | |-- governance.sh 54 | |-- html 55 | |-- init-governance.sh 56 | |-- lib 57 | ``` 58 | 59 | ### 修改配置文件 60 | 61 | - 配置Zookeeper服务 62 | 63 | 可选配置。`./conf/application-prod.properties`中`spring.cloud.zookeeper`配置项。 64 | 65 | ```ini 66 | # spring cloud zookeeper 67 | spring.cloud.zookeeper.enabled=true 68 | spring.cloud.zookeeper.connect-string=127.0.0.1:2181 69 | ``` 70 | 71 | - 配置端口 72 | 73 | 在配置文件`./conf/application-prod.properties`中,`Governance` 的服务端口`server.port` ,默认`7009`。 74 | 75 | ``` 76 | server.port=7009 77 | ``` 78 | 79 | - 区块链FISCO-BCOS节点(复制Broker模块中,配置连接FISCO-BCOS节点的配置文件以及相关证书) 80 | 81 | - 区块链节点配置文件fisco.yml 82 | 83 | 修改`nodes=127.0.0.1:20200`配置项,`nodes`为区块链节点`channel`访问入口。 84 | 85 | - 访问节点的证书文件 86 | 87 | 2.x版本的证书文件`ca.crt`、`sdk.crt`、`sdk.key`放在`./conf/conf`目录下,国密的证书放在`./conf/conf/gm`目录下。详细参考[FISCO-BCOS SDK配置说明](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html)。 88 | 89 | - governance支持配置多个节点 90 | 91 | 配置文件`governance.properties` 示例如下,可以体验节点之间传文件等。 92 | 93 | ```properties 94 | nodeAddressList[0]=127.0.0.1:20200 95 | nodeAddressList[1]=127.0.0.1:20201 96 | nodeAddressList[2]=127.0.0.1:20202,127.0.0.1:20203 97 | ``` 98 | 99 | 100 | 101 | 102 | ### 初始化数据库 103 | 104 | 执行脚本`init-governance.sh` 初始化数据库,成功输出如下。否则,用户需要检查数据库配置是否正常。 105 | 106 | ```shell 107 | $ ./init-governance.sh 108 | init governance db success 109 | ``` 110 | 111 | ### 服务启停 112 | 113 | 通过`./governance.sh start`命令启动服务,正常启动如下: 114 | 115 | ```shell 116 | $ ./governance.sh start 117 | start weevent-governance success (PID=53926) 118 | add the crontab job success 119 | ``` 120 | 121 | 122 | 通过`./governance.sh stop`命令停止服务。 123 | 124 | 进程启动后,会自动添加`crontab`监控任务`./governance.sh monitor`。 125 | 126 | 127 | ### 服务访问 128 | 129 | 服务启动后通过 http://127.0.0.1:8080/weevent-governance/# 访问governance服务,默认用户名为:admin,默认密码为:123456 130 | 131 | 132 | ### 多视图管理 133 | 134 | `Governance`支持同时管理多个`WeEvent`服务和区块链网络, 配置界面如下。 135 | 136 | ![Governance-multi-view.png](../../image/Governance-multi-view.png) 137 | 138 | 139 | ### 其他 140 | 推荐安装`Processor`。具体安装步骤,请参见[Processor模块安装](./processor.html)。 141 | 142 | -------------------------------------------------------------------------------- /docs/install/module/index.rst: -------------------------------------------------------------------------------- 1 | 详细安装 2 | ---------- 3 | 本章节主要介绍WeEvent模块的详细安装,用户可以根据自身需要,继续探索和学习详细模块,一般在生产环境需实例部署,需要使用该方式安装。 4 | 5 | Broker是WeEvent的核心子模块,负责事件的发布订阅以及对区块链FISCO-BCOS的访问。 6 | 7 | Governance为用户提供一个事件治理的Web管理端。支持事件治理、区块链节点分析、系统监控预警、大文件传输等。 8 | 9 | Processor为用户提供时序流分析和事件联动。 10 | 11 | Gateway实现接入请求的负载均衡、限流和熔断。 12 | 13 | 服务支持主流的Linux发行版,如CentOS、Ubuntu 、Redhat。 14 | 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | /install/module/broker 20 | /install/module/governance 21 | /install/module/processor 22 | /install/module/gateway -------------------------------------------------------------------------------- /docs/install/module/processor.md: -------------------------------------------------------------------------------- 1 | 2 | ## Processor模块 3 | 4 | 如果是第一次安装`WeEvent`,参见这里的[系统要求](../environment.html) 。以下安装以`CentOS 7.2`为例。 5 | 6 | 因为区块链使用的加密算法很多`OpenJDK`版本没有提供。所以在各`Java`启动脚本里有设置`JAVA_HOME`变量让用户设置符合要求的`JDK`。 7 | 8 | #### 前置条件 9 | - Zookeeper服务 10 | 11 | 必选配置。服务注册和发现会使用到。 12 | 13 | 推荐使用`Zookeeper 3.5.5`及其以上版本。具体安装步骤,请参见[Zookeeper安装](https://zookeeper.apache.org/doc/r3.5.7/zookeeperStarted.html)。 14 | 15 | 16 | - Broker模块 17 | 18 | 必选配置,通过`Broker`访问区块链。 19 | 20 | 具体安装步骤,请参见[Broker模块安装](./broker.html)。 21 | - Governance模块 22 | 23 | 具体安装步骤,请参见[Governance模块安装](./governance.html)。 24 | 25 | 26 | - Mysql数据库 27 | 28 | 可选配置。支持`Mysql`存储数据,如果不配置则使用内置的`H2`数据库。如果要使用Mysql数据库,需要做一个 29 | 切换,切换步骤,请参考[FAQ](https://weeventdoc.readthedocs.io/zh_CN/latest/faq/weevent.html)。 30 | 31 | 推荐安装`Mysql 5.7+`版本。具体安装步骤,安装请参见[Mysql安装](http://dev.mysql.com/downloads/mysql/) 。 32 | 33 | ### 获取安装包 34 | 35 | 从`github`下载安装包[weevent-processor-1.6.0.tar.gz](https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-processor-1.6.0.tar.gz),并且解压到`/usr/local/weevent/`下。 36 | 37 | ```shell 38 | $ cd /usr/local/weevent/ 39 | $ wget https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-processor-1.6.0.tar.gz 40 | $ tar -xvf weevent-processor-1.6.0.tar.gz 41 | ``` 42 | 43 | 44 | 解压后的目录结构如下 45 | 46 | ``` 47 | $ cd ./weevent-processor-1.6.0 48 | $ tree -L 1 49 | . 50 | |-- apps 51 | |-- check-service.sh 52 | |-- conf 53 | |-- cep_rule.sql 54 | |-- init-processor.sh 55 | |-- processor.sh 56 | |-- lib 57 | ``` 58 | 59 | ### 修改配置文件 60 | - 配置Zookeeper服务 61 | 62 | 可选配置。`./conf/application-prod.properties`中`spring.cloud.zookeeper`配置项。 63 | 64 | ```ini 65 | # spring cloud zookeeper 66 | spring.cloud.zookeeper.enabled=true 67 | spring.cloud.zookeeper.connect-string=127.0.0.1:2181 68 | ``` 69 | 70 | - 配置端口 71 | 72 | 在配置文件`./conf/application-prod.properties`中,`Processor` 的服务端口`server.port` ,默认`7008`。 73 | 74 | ``` 75 | server.port=7008 76 | ``` 77 | 78 | - 配置文件processor.properties 79 | 80 | - `org.quartz.scheduler.instanceName` 当前Schedule name,用户可以修改 81 | - `org.quartz.dataSource` 数据库名称,默认为`WeEvent_processor`,用户可以修改 82 | 83 | - 初始化数据库, 84 | 85 | 执行脚本`init-processor.sh` ,成功输出如下。否则,用户需要检查配置项是否正常。 86 | 87 | ```shell 88 | $ ./init-processor.sh 89 | init processor db success 90 | ``` 91 | 92 | #### 服务启停 93 | 94 | 通过`./processor.sh start`命令启动服务,正常启动如下: 95 | 96 | ```shell 97 | $ ./processor.sh start 98 | start weevent-processor success (PID=53927) 99 | add the crontab job success 100 | ``` 101 | 102 | 通过`./processor.sh stop`命令停止服务。 103 | 104 | 进程启动后,会自动添加`crontab`监控任务`./processor.sh monitor`。 105 | 106 | ### 界面展示 107 | 108 | 1. 创建规则 109 | 110 | ``` 111 | { 112 | "ruleName":"alarm", 113 | "type":"json", 114 | "payload":{ 115 | "temperate":30, 116 | "humidity":0.5 117 | } 118 | "ruleDescription": "" 119 | } 120 | ``` 121 | 122 | - ruleName: 支持英文字母、数字、下划线、连字符 123 | - type:该规则处理数据的格式,目前只支持JSON格式 124 | - payload: 规则的内容 125 | - ruleDescription: 对规则的补充描述 126 | 127 | ![processor-set1.png](../../image/processor/setRule.png) 128 | 129 | 130 | 131 | 2. 设置触发 132 | 133 | JSON数据可以映射为虚拟的表,其中Key对应表的列,Value对应列值,这样就可以使用SQL处理。为便于理解,我们将数据流转的一条规则抽象为一条SQL表达(类试MySQL语法): 134 | 135 | ![详细说明图](../../image/processor/selectWhereCondition.png) 136 | 137 | 例如某环境传感器用于火灾预警,可以采集温度、湿度及气压数据,上报数据内容如下: 138 | 139 | ``` 140 | { 141 | "temperature":25.1, 142 | "humidity":65, 143 | "type":"warning", 144 | "range":"higher", 145 | "date": "2019-10-22" 146 | } 147 | ``` 148 | 149 | 假定温度大于38,湿度小于40时,需要触发报警,可以编写如下的SQL语句: 150 | 151 | ``` 152 | SELECT temperature, deviceName FROM ProductA WHERE temperature > 38 and humidity < 40 153 | ``` 154 | 当上报的数据中,温度大于38且湿度小于40时,会触发该规则,并且解析数据中的温度、设备名称,用于进一步处理。 155 | 156 | - 触发条件 `(temperature > 38 and humidity < 40)` 157 | - Topic:自定义和通配符 158 | - MySQL 说明: 159 | JSON数据格式 160 | SELECT语句中的字段,可以使用上报消息的payload解析结果,即JSON中的键值,也可以使用SQL内置的函数,比如deviceName。 161 | 支持*,不支持子SQL查询。 162 | 163 | FROM 164 | FROM 可以填写Topic。Topic中的设备名(deviceName),用于匹配需要处理的设备消息Topic。当有符合Topic规则的消息到达时,消息的payload数据以JSON格式解析,并根据SQL语句进行处理(如果消息格式不合法,将忽略此消息)。 165 | 166 | WHERE 167 | 规则触发条件,条件表达式。不支持子SQL查询。WHERE中可以使用的字段和SELECT语句一致,当接收到对应Topic的消息时,WHERE语句的结果会作为是否触发规则的判断条件。`WHERE temperature > 38 and humidity < 40` 表示温度大于38且湿度小于40时,才会触发该规则,执行配置。 168 | 169 | - 可以进条件查询` >、<、>=、<=、<>、!=` ,具体详情见本章最后章节。 170 | 171 | ![processor-set2.png](../../image/processor/setRuleContent.png) 172 | 173 | 3. 规则详情展示 174 | 175 | 用户可以继续编辑规则的规则描述、`SELECT`、`FROM`、`WHERE`。 176 | 177 | ![processor-show.png](../../image/processor/ruledetails.png) 178 | 179 | 180 | 181 | 4. 规则列表展示 182 | 183 | 用户可以查询规则、创建规则、编辑规则、启动规则、停止规则、删除规则。并且通过规则的状态可查看该规则的运行状态及命中次数等信息。 184 | 185 | ![processor-list.png](../../image/processor/rulelist.png) 186 | 187 | 188 | 189 | 190 | #### 命中逻辑说明 191 | 192 | - 文本字段 vs. 数值字段 193 | 194 | ``` 195 | SELECT * FROM Websites WHERE country='CN'; 196 | ``` 197 | 198 | - 支持的类型 运算符 199 | 200 | | = | 等于 | 201 | | ---- | ------------------------------- | 202 | | <> | 不等于。注释:在 SQL 的一些版本中,该操作符可被写成 != | 203 | | > | 大于 | 204 | | < | 小于 | 205 | | >= | 大于等于 | 206 | | <= | 小于等于 | 207 | 208 | 209 | 数字类型 210 | 211 | ``` 212 | temperature=29; 213 | temperature>29; 214 | temperature>=29; 215 | temperature<29; 216 | temperature<=29; 217 | temperature<>29; 218 | ``` 219 | 220 | 文本类型 221 | 222 | ``` 223 | SELECT * FROM Websites WHERE facilicty-charater="warning"; 224 | ``` 225 | 226 | - AND & OR 运算符 227 | 228 | 如果第一个条件和第二个条件都成立,则 and 运算符显示一条记录。 229 | 230 | 如果第一个条件和第二个条件中只要有一个成立,则 or 运算符显示一条记录。 231 | 232 | ``` 233 | SELECT * FROM Websites WHERE facilicty-charater="warning" and temperature > 50; 234 | 235 | SELECT * FROM Websites WHERE temperature > 35 or facilicty-charater=="warning" ; 236 | ``` 237 | 238 | - 非聚合类的内置函数 239 | - 数字计算abs(绝对值),ceil,floor ,round 240 | ``` 241 | SELECT * FROM Websites WHERE abs(temperature) > 50; 242 | 243 | SELECT * FROM Websites WHERE ceil(temperature) > 50; 244 | 245 | SELECT * FROM Websites WHERE floor(temperature) > 50; 246 | 247 | SELECT * FROM Websites WHERE round(temperature) > 50; 248 | ``` 249 | 250 | - 字符串拼接substring,concat,trim,lcase 251 | 252 | ``` 253 | SELECT * FROM Websites WHERE range.substring(6)=="warning-001"; 254 | 255 | SELECT * FROM Websites WHERE range.substring(5,10)=="test"; 256 | 257 | SELECT * FROM Websites WHERE range.concat(type)=="higherwarning"; 258 | 259 | SELECT * FROM Websites WHERE range.trim()=="higher"; 260 | 261 | SELECT * FROM Websites WHERE lcase(range)=="higher"; 262 | ``` 263 | 264 | - 内置时间 265 | 266 | 267 | 时间选取now, currentDate,currentTime 268 | ``` 269 | SELECT * FROM Websites WHERE date >= currentDate; 270 | ``` 271 | 272 | -------------------------------------------------------------------------------- /docs/install/property.md: -------------------------------------------------------------------------------- 1 | ## 配置说明 2 | ### Broker 配置 3 | 4 | `Broker`服务主要有三类配置,`Spring Boot `进程配置、区块链`FISCO-BCOS`节点配置、`WeEvent`服务配置。 5 | 6 | - Spring Boot进程配置 7 | 8 | 配置文件`./broker/conf/application-prod.properties`,这个是`Spring Boot`标准配置文件,一般不需要修改。细节请参见[Spring Boot文档](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#appendix) 。 9 | 10 | | 配置项 | 默认值 | 配置说明 | 11 | | ------------------------------------- | ------------------------------------------------------------ | ---------------- | 12 | | server.port | 7000 | spring监听端口 | 13 | | server.servlet.context-path | /weevent | spring上下文路径 | 14 | | spring.autoconfigure.exclude | org.springframework.boot.autoconfigure.
security.servlet.SecurityAutoConfiguration | 默认不开启 | 15 | | spring.security.user.name | user | 默认不开启 | 16 | | spring.security.user.password | 123456 | 默认不开启 | 17 | | spring.cloud.zookeeper.enabled | true | ZK访问 | 18 | | spring.cloud.zookeeper.connect-string | 127.0.0.1:2181 | ZK节点 | 19 | 20 | 用户访问授权通过用户密码`spring.security.user`配置,对所有的接入协议`RESTFul`、`Json RPC`、`STOMP`、`MQTT`都会生效。配置项生效后,`RESTFul`和`Json RPC`需要是使用`http base authorization`访问。`STOMP`访问需要设置`header`项`login`和`passcode`,`MQTT`访问需要设置`username`和`password`。 21 | 22 | - 区块链FISCO-BCOS节点配置 23 | 24 | 配置文件`./broker/conf/fisco.yml`, 与governance依赖的配置文件`fisco.yml`相同。 25 | 26 | 改配置文件分为两部分,`weevent core config`和 `fisco bcos sdk config`部分,前者是weevent配置,后者是完全依照[FISCO-BCOS SDK 配置说明](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html) 配置。 27 | 28 | ```yaml 29 | ################ weevent core config ################ 30 | 31 | version: 2.0 32 | orgId: fisco 33 | 34 | timeout: 10000 35 | poolSize: 10 36 | maxPoolSize: 200 37 | keepAliveSeconds: 10 38 | 39 | consumerHistoryMergeBlock: 8 40 | consumerIdleTime: 1000 41 | 42 | 43 | ################ fisco bcos sdk config ################ 44 | # https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html 45 | 46 | #cryptoMaterial: 47 | # certPath: "conf" 48 | # caCert: "conf/ca.crt" 49 | # sslCert: "conf/sdk.crt" 50 | # sslKey: "conf/sdk.key" 51 | # enSslCert: "conf/gm/gmensdk.crt" 52 | # enSslKey: "conf/gm/gmensdk.key" 53 | 54 | account: 55 | # ECDSA_TYPE 56 | accountAddress: "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3" 57 | # SM_TYPE 58 | # accountAddress: "0x4278900c23e4b364ba6202a24682d99be9ff8cbc" 59 | # accountFileFormat: "pem" 60 | # accountFilePath: "" 61 | keyStoreDir: "account" 62 | # password: "" 63 | 64 | #amop: 65 | # - publicKeys: [ "conf/amop/consumer_public_key_1.pem" ] 66 | # topicName: "PrivateTopic1" 67 | # - password: "123456" 68 | # privateKey: "conf/amop/consumer_private_key.p12" 69 | # topicName: "PrivateTopic2" 70 | 71 | 72 | network: 73 | peers: 74 | - "127.0.0.1:20200" 75 | 76 | threadPool: 77 | channelProcessorThreadSize: "16" 78 | maxBlockingQueueSize: "102400" 79 | receiptProcessorThreadSize: "16" 80 | ``` 81 | 82 | ```eval_rst 83 | .. note:: 84 | - account.accountAddress为发起交易的账户地址,在`keyStoreDir`目录下存放该账户的私钥,也可以自己重新生成私钥替换,但需保持固定地址,因为topic管理等有权限控制,其他账户无权限。详细逻辑可参考`weevent-core/src/main/java/com/webank/weevent/core/fisco/web3sdk/v2/solc10/solidity`合约实现。 85 | ``` 86 | 87 | 88 | 89 | | 配置项 | 默认值 | 配置说明 | 90 | | ---------------------------- | -------------------- | --------------------------------------- | 91 | | version | 2.0 | FISCO-BCOS版本,支持2.x | 92 | | orgId | fisco | 机构名,按机构实际名称填写即可 | 93 | | timeout | 10000 | 交易执行超时时间,单位毫秒 | 94 | | poolSize | 10 | 最小线程数 | 95 | | maxPoolSize | 100 | 最大线程数 | 96 | | keepAliveSeconds | 10 | 线程空闲时间,单位秒 | 97 | | consumerIdleTime | 1000 | 区块链新增块事件检测周期,单位毫秒 | 98 | | consumerHistoryMergeBlock | 8 | 事件过滤的区块范围 | 99 | 100 | 101 | 102 | 103 | - WeEvent服务配置 104 | 105 | 配置文件`./broker/conf/weevent.properties`。 106 | 107 | | 配置项 | 默认值 | 配置说明 | 108 | | ------------------------------------ | ------ | ------------------------------------------------------------ | 109 | | ip.check.white-table | | IP白名单。多个`IP`地址,以";"分割。
默认为空时表示允许任何客户端访问。 | 110 | | block.chain.type | fisco | 区块链类别,fisco或fabric | 111 | | stomp.heartbeats | 30 | stomp心跳间隔,单位秒 | 112 | | mqtt.broker.tcp.port | 7001 | 使用tcp访问MQTT的端口,默认不开启 | 113 | | mqtt.broker.keepalive | 60 | mqtt连接空闲时间,单位秒 | 114 | | mqtt.broker.security.ssl | false | mqtt是否开启ssl | 115 | | mqtt.broker.security.ssl.client_auth | false | mqtt ssl是否开启双向认证 | 116 | | mqtt.broker.security.ssl.ca_cert | | ssl ca证书 | 117 | | mqtt.broker.security.ssl.server_cert | | 服务端证书 | 118 | | mqtt.broker.security.ssl.server_key | | 服务端私钥 | 119 | 120 | ### Governance 121 | 122 | - 配置文件`./governance/conf/application-prod.properties`。 123 | 124 | | 配置项 | 默认值 | 配置说明 | 125 | | ---------------------------------------- | ------------------------------------------------------------ | -------------------------- | 126 | | server.port | 7009 | spring监听端口 | 127 | | spring.datasource.url | jdbc:mysql://127.0.0.1:3306/governance?useUnicode=true&characterEncoding=utf-8&useSSL=false | 数据源 | 128 | | spring.datasource.driver-class-name | org.mariadb.jdbc.Driver | 驱动类 | 129 | | spring.datasource.username | xxxx | 数据库账号用户名 | 130 | | spring.datasource.password | yyyy | 数据库账号密码 | 131 | | spring.datasource.type | org.apache.commons.dbcp2.BasicDataSource | 数据源类型 | 132 | | spring.datasource.dbcp2.max-wait-millis | 10000 | 数据库连接池最长等待时间ms | 133 | | spring.datasource.dbcp2.min-idle | 5 | 数据库连接池最小空闲 | 134 | | spring.datasource.dbcp2.initial-size | 5 | 数据库连接池初始大小 | 135 | | spring.datasource.dbcp2.validation-query | SELECT '1' | 数据库连接池验证查询 | 136 | 137 | - 配置文件`./governance/conf/governance.properties` 138 | 139 | | 配置项 | 默认值 | 配置说明 | 140 | | --------------- | ------ | ------------------------------------------------------------ | 141 | | nodeAddressList | | 数组,可连接多个不同节点,需要与fisco.yml里配置的节点证书相同 | 142 | 143 | ### Processor 配置 144 | 145 | - 配置文件`./processor/conf/application-prod.properties` 。 146 | 147 | | 配置项 | 默认值 | 说明 | 148 | | --------------------------------------- | ----------------- | ------------- | 149 | | server.port | 7008 | 默认端口 | 150 | | spring.datasource.url | jdbc:mysql://127.0.0.1:3306/WeEvent_processor | JDBC连接串 | 151 | | spring.datasource.driverClassName | org.mariadb.jdbc.Driver | 连接驱动 | 152 | | spring.jpa.database | mysql | 类型 | 153 | | spring.datasource.username | root | 数据库用户 | 154 | | spring.datasource.password | 123456 | 数据库密码 | 155 | 156 | - 配置文件`./processor/conf/processor.properties`。 157 | 158 | | 配置项 | 默认值 | 说明 | 159 | | --------------------------------------- | ----------------- | ------------- | 160 | | quartz.schedule.name | schedule | quartz标识名称 | 161 | | org.quartz.scheduler.instanceName | test | scheduler名称 | 162 | | org.quartz.dataSource.WeEvent_processor | WeEvent_processor | 连接quartz数据库名称 | 163 | | org.quartz.threadPool.threadCount | 20 | 进程数据 | 164 | | org.quartz.threadPool.threadPriority | 5 | 进行优先级 | 165 | 166 | 167 | ```eval_rst 168 | .. note:: 169 | - `org.quartz.dataSource.*` 配置的数据库信息需要和org.quartz.jobStore.dataSource配置的数据源信息一致。 170 | ``` 171 | 172 | ### 国密配置 173 | 174 | 前提条件:区块链为国密版本。 175 | 176 | 配置方式与[FISCO-BCOS SDK配置](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html)方式一致: 177 | 178 | 1. 将国密证书放到 `classpath/conf/gm`目录下(fisco-bcos sdk会自动检查链是国密还是非国密版本)。 179 | 2. `fisco.yml`中`account.accountAddress`字段改为国密账户地址,并将该账户私钥文件放到 `keyStoreDir`目录下。WeEvent默认已有账户,若使用新账户直接替换账户地址和私钥文件即可。 -------------------------------------------------------------------------------- /docs/install/quickinstall.md: -------------------------------------------------------------------------------- 1 | ## 快速安装 2 | 3 | 快速安装是为了方便用户搭建开发和测试环境,在单台机器上快速部署`WeEvent`服务。提供`Docker`镜像、Bash脚本两种安装方式。 4 | 5 | 如果是第一次安装`WeEvent`,参见这里的[系统要求](./environment.html) 。以下安装过程以`Centos 7.2`为例。 6 | 7 | ### Docker镜像安装 8 | 9 | ```bash 10 | $ docker pull weevent/weevent:1.6.0; docker run -d -p 8080:8080 -p 7001:7001 weevent/weevent:1.6.0 /root/run.sh 11 | ``` 12 | 13 | `WeEvent`的镜像里包括了`FISCO-BCOS`网络,`WeEvent`服务的各个子模块以及各种依赖。 14 | 15 | 16 | ### Bash安装 17 | 18 | 需要的一些基础工具`yum install wget tree tar netstat`。 19 | 20 | - 获取安装包 21 | 22 | 从`github`下载安装包[weevent-1.6.0.tar.gz](https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-1.6.0.tar.gz),并且解压到`/tmp/` 。 23 | 24 | ```shell 25 | $ cd /tmp/ 26 | $ wget https://github.com/WeBankBlockchain/WeEvent/releases/download/v1.6.0/weevent-1.6.0.tar.gz 27 | $ tar -zxf weevent-1.6.0.tar.gz 28 | ``` 29 | 30 | 解压后目录结构如下: 31 | 32 | ```shell 33 | $ cd weevent-1.6.0/ 34 | $ tree -L 2 35 | . 36 | ├── bin 37 | │   ├── start-all.sh 38 | │   └── stop-all.sh 39 | ├── config.properties 40 | ├── fisco.yml 41 | ├── install-all.sh 42 | ├── modules 43 | │   ├── broker 44 | │ ├── gateway 45 | │   ├── governance 46 | │   ├── lib 47 | │   ├── processor 48 | │ └── zookeeper 49 | ``` 50 | 51 | - 修改配置config.properties 52 | 53 | 默认配置文件`./config.properties`如下: 54 | 55 | ```properties 56 | #java jdk environment 57 | JAVA_HOME=/usr/local/jdk1.8.0_191 58 | 59 | # Required module 60 | # support 2.x 61 | fisco-bcos.version=2.0 62 | # The path of FISCO-BCOS 2.x that contain certificate file ca.crt/sdk.crt/sdk.key 63 | fisco-bcos.node_path=~/fisco/nodes/127.0.0.1/sdk 64 | 65 | # Required module 66 | gateway.port=8080 67 | zookeeper.default=true 68 | zookeeper.connect-string=127.0.0.1:2181 69 | 70 | # Required module 71 | broker.port=7000 72 | 73 | # Optional module 74 | governance.enable=false 75 | governance.port=7009 76 | #support both h2 and mysql, default h2 77 | database.type=h2 78 | #mysql.ip=127.0.0.1 79 | #mysql.port=3306 80 | #mysql.user=xxx 81 | #mysql.password=yyy 82 | 83 | # Optional module 84 | processor.enable=false 85 | processor.port=7008 86 | ``` 87 | 88 | 配置说明 : 89 | 90 | - JDK变量`JAVA_HOME` 91 | 92 | 因为区块链使用的加密算法很多`OpenJDK`版本没有提供。所以这里特别让用户设置符合要求的`JDK`。 93 | 94 | - 区块链FISCO-BCOS 95 | 96 | - `fisco-bcos.version` 97 | 98 | 支持`2.0`及其以上版本。 99 | 100 | - `fisco-bcos.node_path` 101 | 102 | 区块链节点的访问证书、私钥存放目录,`FISCO-BCOS 2.x`一般目录为`~/fisco/nodes/127.0.0.1/sdk`。 103 | 104 | 如果`WeEvent`服务和区块链节点不在同一台机器上,需要把上述目录下文件拷贝到`WeEvent`所在机器的当前目录如 `./conf`目录下,并设置`fisco-bcos.node_path=./conf` 。 **注意**:`fisco-bcos.node_path`目录结构需与节点证书目录`~/fisco/nodes/127.0.0.1/sdk`结构一致,同时不要包含其他文件, 安装时会将`fisco-bcos.node_path`目录下所有内容拷贝到每个模块子目录下。 105 | 106 | 以下为标准版和国密版依赖的证书文件及目录结构: 107 | 108 | ```bash 109 | $ tree fisco/nodes/127.0.0.1/sdk/ 110 | fisco/nodes/127.0.0.1/sdk/ 111 | ├── ca.crt 112 | ├── sdk.crt 113 | └── sdk.key 114 | 115 | $ tree fisco_gm/nodes/127.0.0.1/sdk/ 116 | fisco_gm/nodes/127.0.0.1/sdk/ 117 | └── gm 118 |    ├── gmca.crt 119 |    ├── gmensdk.crt 120 |    ├── gmensdk.key 121 |    ├── gmsdk.crt 122 |    └── gmsdk.key 123 | ``` 124 | 125 | - Gateway 126 | 127 | - 监听端口`gateway.port` 128 | 129 | - `zookeeper`配置 130 | 131 | `zookeeper.default=true`,值为`true`表示使用`zookeeper.connect-string`里配置的端口,在本机安装`zookeeper`服务使用。 132 | 133 | `zookeeper.default=false`,值为`false`表示使用`zookeeper.connect-string`的配置去连接用户已有的`zookeeper`服务。 134 | 135 | - Broker监听端口`broker.port` 136 | 137 | - Governance模块配置 138 | 139 | - `governance.enable`是否安装`Governance`模块,默认为`false`不安装 140 | - 监听端口`governance.port` 141 | - 默认使用内置的`H2`数据库,也支持`Mysql`配置`mysql.*` 142 | 143 | - Processor模块配置 144 | 145 | - `proceessor.enable`是否安装`Proceessor`模块,默认为`false`不安装 146 | - 监听端口`processor.port` 147 | 148 | - 修改配置fisco.yml 149 | 150 | 配置说明:该配置字段`fisco bcos sdk config`部分与FiscoBcos SDK配置一致,详细配置说明参考 [FiscoBcos SDK配置说明](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html) ,安装时关注字段为节点配置。 151 | 152 | ```yaml 153 | network: 154 | peers: 155 | - "127.0.0.1:20200" 156 | - "127.0.0.1:20201" 157 | ``` 158 | 159 | 160 | ```eval_rst 161 | .. note:: 162 | - 多数情况下以上配置只需修改`config.properties`中证书路径`fisco-bcos.node_path`和`fisco.yml`中`network.peers`连接的节点地址即可运行。其他字段可按照自己实际需求进行修改配置。 163 | ``` 164 | 165 | 166 | 167 | - 一键安装 168 | 169 | 以安装到目录`/usr/local/weevent/`为例。 170 | 171 | ```shell 172 | $ ./install-all.sh -p /usr/local/weevent/ 173 | ``` 174 | 175 | 正常安装后,输出有如下关键字: 176 | 177 | ``` 178 | 7000 port is okay 179 | 8080 port is okay 180 | 2181 port is okay 181 | param ok 182 | install module zookeeper 183 | install module gateway 184 | install gateway success 185 | install module broker 186 | install broker success 187 | ``` 188 | 189 | 目标安装路径`/usr/local/weevent/`的结构如下: 190 | 191 | ```shell 192 | $ cd /usr/local/weevent/ 193 | $ tree -L 1 194 | . 195 | |-- broker 196 | |-- lib 197 | |-- gateway 198 | |-- start-all.sh 199 | |-- stop-all.sh 200 | |-- zookeeper 201 | ``` 202 | 203 | - 启停服务 204 | - 启动服务 205 | 206 | 在服务安装目录下`/usr/local/weevent`,通过`start-all.sh`命令启动所有服务 ,正常启动如下: 207 | 208 | ```shell 209 | $ ./start-all.sh 210 | ZooKeeper JMX enabled by default 211 | Using config: /usr/local/weevent/zookeeper/apache-zookeeper-3.6.1-bin/bin/../conf/zoo.cfg 212 | Starting zookeeper ... STARTED 213 | start weevent-broker success (PID=3642) 214 | add the crontab job success 215 | start weevent-gateway success (PID=3643) 216 | add the crontab job success 217 | ``` 218 | 219 | 如果安装了governance服务,默认访问链接为:http://127.0.0.1:8080/weevent-governance/# ,默认用户名为:admin,默认密码为:123456 220 | 221 | - 停止所有服务的命令`./stop-all.sh`。 222 | 223 | - 卸载服务 224 | 225 | 所有服务停止后,直接删除目录即可。 226 | 227 | 228 | 229 | 快速安装作为一种简易安装方式,默认使用内置的`H2`数据库。并且所有子服务都是单实例的,生产环境中建议多实例部署。各子模块详细部署参见[Broker模块部署](./module/broker.html)和[Governance模块部署](./module/governance.html)。 230 | -------------------------------------------------------------------------------- /docs/introduction/architecture.md: -------------------------------------------------------------------------------- 1 | ## 架构说明 2 | 3 | `WeEvent`服务使用[Spring Boot](https://spring.io/projects/spring-boot)框架开发。业务集成上,既支持直接加载独立的`JAR`包使用服务,例如`weevent-core.jar `、`weevent-file.jar`等。也支持通过代理服务来提供功能,例如`weevent-broker`、`weevent-governance`、`weevent-processor`。 4 | 5 | ### 各子块服务简介 6 | 7 | - weevent-broker 8 | 9 | `WeEvent`的事件代理模块,提供核心的事件发布订阅`Pub`/`Sub`以及`Topic`管理功能。 10 | 11 | `weevent-broker`就是`weevent-core.jar `的服务化,以支持各种协议接入。 12 | 13 | - weevent-governance 14 | 15 | `WeEvent`的事件治理模块,提供一个`Web`管理端。支持区块链信息浏览、`Topic`事件治理、流计算、大文件传输等。 16 | 17 | 使用数据库持久化相关数据,支持`H2`和`Mysql`。 18 | 19 | - weevent-processor 20 | 21 | 是`weevent-governance`实时流计算功能中,规则引擎的分布式运行容器。 22 | 23 | - API Gateway 24 | 25 | `WeEvent`服务对外统一的访问入口,负责接入请求的负载均衡、限流、熔断等。 26 | 27 | - FISCO-BCOS 28 | 29 | `WeEvent`的事件永久存储在区块链上。推荐使用[FISCO-BCOS](https://github.com/FISCO-BCOS/FISCO-BCOS),也支持`Fabric 1.4`。 30 | 31 | ### 系统架构 32 | 33 | ![](../image/WeEventArchitecture.png) 34 | 35 | -------------------------------------------------------------------------------- /docs/introduction/core.md: -------------------------------------------------------------------------------- 1 | ## 核心概念 2 | 3 | `WeEvent`是一个基于区块链实现的事件中间件服务,面向用户提供事件发布订阅`Publish/Subscribe`功能。发布到`WeEvent`上的事件永久存储,不可篡改,支持事后跟踪和审计。 4 | 生产者`Producer`通过`WeEvent`代理服务发布事件,事件内容会被记录到区块链如`FISCO-BCOS`上,消费者`Consumer`从`WeEvent`订阅事件。订阅成功后,只要生产者发布事件,消费者都会及时得到通知。 5 | 6 | ![](../image/WeventTopView.png) 7 | 8 | `WeEvent`提供两种部署方案:一种是直接将`Jar`包集成进业务进程,集成过程参见[集成weevent-core.jar](../protocol/weevent-core-sdk.html);一种是以独立服务部署,业务通过接入这个代理服务访问各种功能,部署过程参见[WeEvent快速安装](../install/quickinstall.html)。两种方式各有优劣,可以自由选择。`WeEvent`独立服务有多种接入方式,生产者`Producer`和消费者`Consumer`可以是后台服务、前端网页、`IoT`设备、甚至单片机。 9 | 10 | ### 事件(Event) 11 | 事件`Event`可以简单理解成业务层面的一个消息。一般是终端用户或设备触发。 12 | 13 | 通常一个事件包含四个部分的信息,事件`ID`、内容、可选的自定义属性以及关联的主题。 14 | 15 | 事件内容对`WeEvent`是透明的,业务可以存放任何数据,例如字符型的`Json`、`XML`,或者二进制的`Protocol Buffer`等。在`Java`中映射为字节数组`byte[]`,完整的`Java`映射类参见[WeEvent.java](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-client/src/main/java/com/webank/weevent/client/WeEvent.java)。 16 | 17 | ### 主题(Topic) 18 | 业务上一般把数据结构相同,属于同类型的事件归属于同一主题`Topic`。 19 | 20 | 每个主题`Topic`逻辑上都有彼此独立的队列。主题之间是完全隔离的,发布、存储、通知都不会互相影响。 21 | 22 | ### 发布事件(Publish) 23 | 生产者`Producer`往某个主题发布事件,`WeEvent`会将事件永久存储在区块链`FISCO-BCOS`上,不可篡改,支持事后审核。 24 | 25 | 事件发布成功后`WeEvent`会返回一个事件ID`EventID` ,事件ID代表该事件且具有唯一性。 26 | 27 | ### 订阅事件(Subscribe) 28 | 消费者`Consumer`订阅某个主题后,当有生产者往该主题发布事件,消费者会及时收到事件通知。 29 | 30 | 订阅成功时`WeEvent`会返回一个的订阅ID`SubscriptionID`,代表完成一次订阅,订阅ID具有唯一性。 31 | 32 | 除了实时订阅最新的事件,`WeEvent`也支持从最开始或者从某个历史事件`EventID`之后启动订阅。 33 | 34 | ### 取消订阅(Unsubscribe) 35 | 消费者通过订阅ID`SubscriptionID` 取消一个订阅后,不会再收到该主题的事件通知。 36 | -------------------------------------------------------------------------------- /docs/introduction/getting-start.md: -------------------------------------------------------------------------------- 1 | ## Getting Start 2 | 3 | ### 使用WeEvent服务 4 | 5 | 选好所需要的版本,一般推荐[最新版本](https://github.com/WeBankBlockchain/WeEvent/releases)。选择`Docker`镜像或者通过`Bash`脚本一键安装。详情参见[WeEvent快速安装](../install/quickinstall.html)。 6 | 7 | ### 参与WeEvent开发 8 | 9 | 想参与`WeEvent`开发或者体验未正式发布的特性,需要从源码开始,流程如下: 10 | 11 | - 下载[github源码](https://github.com/WeBankBlockchain/WeEvent) 12 | 13 | ```bash 14 | $ git clone https://github.com/WeBankBlockchain/WeEvent.git 15 | ``` 16 | 17 | 通过`IDE`打开`Gradle`工程,推荐`IntelliJ IDEA`。 18 | 19 | - 配置区块链 20 | 21 | 默认支持`FISCO-BCOS 2.x`,也可以通过配置切换到`Fabric 1.4`。 22 | 23 | - FISCO-BCOS 2.x 24 | 25 | 在配置文件`./weevent-broker/src/main/resources/fisco.yml`里配置: 26 | 27 | 区块链版本`version=2.0` 28 | 29 | 节点访问`channel`端口`nodes=...` 30 | 31 | 然后将节点访问证书`ca.crt`、`sdk.crt`、`sdk.key`放到目录下`./weevent-broker/src/main/resources/`。 32 | 33 | - Fabric 1.4 34 | 35 | 具体内容详见[适配Fabric](https://weeventdoc.readthedocs.io/zh_CN/latest/advanced/fabric.html)。 36 | 37 | ```eval_rst 38 | .. note:: 39 | - 区块链配置在两个代码模块weevent-core和weevent-broker里都有涉及到。都需要配置。 40 | ``` 41 | - 部署系统合约 42 | 43 | `weevent-core`和`weevent-broker`模块关于区块链的配置相同。 44 | 45 | 通过运行`./weevent-core/src/main/java/com/webank/weevent/core/fisco/util/Web3sdkUtils.java`来部署`WeEvent`内置合约。 46 | 47 | - 运行服务及代码样例 48 | 49 | 启动`Broker`服务`./weevent-broker/src/main/java/com/webank/weevent/broker/BrokerApplication.java`。 50 | 51 | 然后体验各种功能样例`./weevent-broker/src/test/java/com/webank/weevent/broker/sample`。 52 | 53 | - 编译打包服务 54 | 55 | ```bash 56 | $ cd ./weevent-build; ./package.sh 57 | Usage: 58 | package master: ./package.sh --version 1.6.0 59 | package tag: ./package.sh --tag v1.6.0 --version 1.6.0 60 | package local: ./package.sh --tag local --version 1.6.0 61 | ``` 62 | 63 | 支持编译`master`最新代码,某个`tag`代码,以及本地的代码。 64 | 65 | 编译环境依赖`git`,`git bash`, `gradle 4.10`,`java 1.8`,`nodejs 10.16`。 66 | 67 | - 安装包一键安装服务 68 | 69 | 详情参见[WeEvent快速安装](../install/quickinstall.html)。 70 | 71 | 72 | 欢迎参与`WeEvent`项目[issues](https://github.com/WeBankBlockchain/WeEvent/issues)。 73 | 74 | -------------------------------------------------------------------------------- /docs/introduction/index.rst: -------------------------------------------------------------------------------- 1 | ========================================= 2 | WeEvent简介 3 | ========================================= 4 | 5 | 6 | .. toctree:: 7 | :maxdepth: 1 8 | 9 | /introduction/core.md 10 | /introduction/architecture.md 11 | /introduction/getting-start.md 12 | -------------------------------------------------------------------------------- /docs/protocol/errorcode.md: -------------------------------------------------------------------------------- 1 | ## 错误码 2 | ### 错误码说明 3 | 4 | 所有错误以检查异常的形式抛出,通过异常类`BrokerException`的 `getCode()`和`getMessage()`方法获取详细信息。 5 | 6 | ### 错误码区间 7 | 8 | 按错误是发生在客户端还是服务端分为两类。 9 | 10 | - 客户端错误码在(100000, 200000)之间,为用户输入错误。一般通过检查输入参数或者接口调用的方式就能解决这类问题。 11 | - 服务端错误码在(200000, 300000)之间,一般是服务环境变化引起的错误。请按照FAQ列表排查,或者联系`WeEvent`技术支持。 12 | 13 | 错误码文件,请参见[ErrorCode.java](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-client/src/main/java/com/webank/weevent/client/ErrorCode.java) 。 14 | 15 | -------------------------------------------------------------------------------- /docs/protocol/index.rst: -------------------------------------------------------------------------------- 1 | 接入说明 2 | ========================================= 3 | WeEvent服务用Java Spring Boot框架实现。 4 | 提供了RESTful、JsonRPC、STOMP风格的协议接入,为方便物联网IOT设备的使用,提供了内置MQTT协议的支持。 5 | 同时为Java业务接入提供了Java SDK客户端,SDK不依赖Spring框架。 6 | 7 | 当然也可以不依赖任何服务,直接以weevent-core.jar包将核心的发布订阅功能集成到业务服务里。 8 | 9 | .. toctree:: 10 | :maxdepth: 1 11 | 12 | /protocol/weevent-core-sdk 13 | /protocol/weevent-file-sdk 14 | /protocol/stomp 15 | /protocol/restful 16 | /protocol/jsonrpc 17 | /protocol/mqtt 18 | /protocol/weevent-client-sdk 19 | /protocol/weevent-jms-sdk 20 | /protocol/errorcode 21 | /protocol/weevent-sample 22 | -------------------------------------------------------------------------------- /docs/protocol/jsonrpc.md: -------------------------------------------------------------------------------- 1 | ## JsonRPC 2 | 3 | 相比`RESTful`规范,`JsonRPC`是更符合后台开发习惯的文本协议,`Java`代码映射也更加简单。 4 | 5 | `JsonRPC`和`RESTful`都是对`STOMP`协议的一个补充,支持`WeEvent`主题的`CRUD`管理等功能以及事件发布。 6 | 7 | ### 协议说明 8 | 9 | - `JsonRPC`和`RESTful`实现的功能和参数都相同,只是不同的承载协议,可以自由选择使用。 10 | 11 | - `WeEvent` 使用`JsonRPC 2.0` [协议规范 ](https://www.jsonrpc.org/specification) 。 12 | 13 | - `JsonRPC`的传输对象使用`Jackson`库进行序列化。对于字符数组`byte[]`,`Jackson`会先使用`Base64`进行编解码。 14 | 15 | - 调用异常时返回的信息如下 16 | 17 | ```json 18 | { 19 | "jsonrpc": "2.0", 20 | "id": "1", 21 | "error": { 22 | "code": 100101, 23 | "message": "topic not exist" 24 | } 25 | } 26 | ``` 27 | 28 | 29 | ### 代码样例 30 | 31 | ```java 32 | public class JsonRPC { 33 | public static void main(String[] args) { 34 | System.out.println("This is WeEvent json rpc sample."); 35 | try { 36 | URL remote = new URL("http://localhost:8080/weevent-broker/jsonrpc"); 37 | // init jsonrpc client 38 | JsonRpcHttpClient client = new JsonRpcHttpClient(remote); 39 | // init IBrokerRpc object 40 | IBrokerRpc rpc = ProxyUtil.createClientProxy(client.getClass().getClassLoader(), IBrokerRpc.class, client); 41 | // open topic 42 | rpc.open("com.weevent.test", WeEvent.DEFAULT_GROUP_ID); 43 | // publish event 44 | SendResult sendResult = rpc.publish("com.weevent.test", WeEvent.DEFAULT_GROUP_ID, "hello WeEvent".getBytes(StandardCharsets.UTF_8), new HashMap<>()); 45 | System.out.println(sendResult); 46 | }catch (MalformedURLException | BrokerException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | ``` 52 | 53 | 上述样例演示了使用`JsonRPC`如何创建主题和发布事件。完整代码,请参见[JsonRPC代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-broker/src/test/java/com/webank/weevent/sample/JsonRPC.java) 。 54 | 55 | ### 接口说明 56 | 57 | `JsonRPC`接口包括两大类功能:一类是主题`Topic`的`CRUD`管理,包括`open`、`close`、`exist`、`state`、`list`;一类是事件发布`publish` 。 58 | 59 | #### 创建Topic 60 | - 请求 61 | ```shell 62 | $ curl -H"Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"open","params":{"topic":"com.weevent.test","groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 63 | ``` 64 | - 应答 65 | ```json 66 | { 67 | "jsonrpc": "2.0", 68 | "id": "1", 69 | "result": "true" 70 | } 71 | ``` 72 | 73 | - 说明 74 | 75 | - topic:主题。`ascii`值在`[32,128]`之间。支持通配符按层次订阅,因'+'、'#'为通配符的关键字故不能为topic的一部分,详情参见[MQTT通配符](http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html) 。 76 | 77 | - groupId:群组`Id`,`fisco-bcos 2.0+`版本支持多群组功能,2.0以下版本不支持该功能可以不传。 78 | 79 | 可以重复`open`,也是返回`true` 80 | 81 | 82 | #### 关闭Topic 83 | 84 | - 请求 85 | ```shell 86 | $ curl -H"Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"close","params":{"topic":"com.weevent.test","groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 87 | ``` 88 | - 应答 89 | ```json 90 | { 91 | "jsonrpc": "2.0", 92 | "id": "1", 93 | "result": "true" 94 | } 95 | ``` 96 | 97 | 98 | #### 检查Topic是否存在 99 | - 请求 100 | ```shell 101 | $ curl -H"Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"exist","params":{"topic":"com.weevent.test","groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 102 | ``` 103 | - 应答 104 | ```json 105 | { 106 | "jsonrpc": "2.0", 107 | "id": "1", 108 | "result": "true" 109 | } 110 | ``` 111 | 112 | #### 发布事件 113 | - 请求 114 | ```shell 115 | $ curl -H "Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"publish","params":{"topic":"com.weevent.test","groupId":"1","content":"MTIzNDU2","extensions":{"weevent-format": "json","weevent-userId":"3924261998"}}}' http://localhost:8080/weevent-broker/jsonrpc 116 | ``` 117 | - 应答 118 | ```json 119 | { 120 | "jsonrpc": "2.0", 121 | "id": "1", 122 | "result": { 123 | "topic": "com.weevent.test", 124 | "status": "SUCCESS", 125 | "eventId": "2cf24dba-10-123" 126 | } 127 | } 128 | ``` 129 | - 说明: 130 | 131 | - content:`MTIzNDU2`是`123456`进行`Base64`编码后的值。 132 | 133 | - extensions:用户自定义数据以`weevent-`开头。可选参数。 134 | 135 | - result : 返回字段`result` ,是一个`WeEvent`对象的序列化,可查看WeEvent对象。“status”:“SUCCESS”表示成功。”eventId“:"2cf24dba-10-123"表示发布事件成功ID。 136 | 137 | #### 获取Event详情 138 | - 请求 139 | ```shell 140 | $ curl -H"Content-Type: application/json" -d '{"id":"1","jsonrpc":"2.0","method":"getEvent","params":{"eventId":"2cf24dba-59-1124","groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 141 | ``` 142 | - 应答 143 | ```json 144 | { 145 | "jsonrpc": "2.0", 146 | "id": "1", 147 | "result": { 148 | "topic": "hello", 149 | "content": "MTIzNDU2", 150 | "extensions":{ 151 | "weevent-format": "json", 152 | "weevent-plus": { 153 | "timestamp":1591326142038, 154 | "height":168, 155 | "txHash":"0x5c9fc570c1ac35f85382f38aa7d88ff038deb5865b971af34b6828fc6c23b5e9", 156 | "sender":"0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3" 157 | } 158 | }, 159 | "eventId": "2cf24dba-59-1124" 160 | } 161 | } 162 | ``` 163 | 164 | 165 | 166 | 167 | ```eval_rst 168 | .. note:: 169 | - 以下管理端接口,业务程序里一般用不到,可以直接安装Goverance模块来使用这部分功能。 170 | ``` 171 | #### 当前Topic列表 172 | - 请求 173 | ```shell 174 | $ curl -H"Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"list","params":{"pageIndex":0,"pageSize":10,"groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 175 | ``` 176 | - 应答 177 | ```json 178 | { 179 | "jsonrpc": "2.0", 180 | "id": "1", 181 | "result": { 182 | "total": 51, 183 | "pageIndex": 1, 184 | "pageSize": 10, 185 | "topicInfoList": [ 186 | { 187 | "topicName": "123456", 188 | "topicAddress": "0x420f853b49838bd3e9466c85a4cc3428c960dde2", 189 | "senderAddress": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3", 190 | "createdTimestamp": 1548211117753 191 | } 192 | ] 193 | } 194 | } 195 | ``` 196 | 197 | - 说明 198 | 199 | - total:`Topic`的总数量 200 | 201 | - pageIndex::查询第几页,从0开始 202 | 203 | - pageSize: 分页大小(0,100),默认每页10条数据。 204 | 205 | - topicInfoList:`Topic` 详细信息列表 206 | 207 | #### 查询某个Topic详情 208 | - 请求 209 | ```shell 210 | $ curl -H"Content-Type: application/json" -d'{"id":"1","jsonrpc":"2.0","method":"state","params":{"topic":"com.weevent.test","groupId":"1"}}' http://localhost:8080/weevent-broker/jsonrpc 211 | ``` 212 | - 应答 213 | ```json 214 | { 215 | "jsonrpc": "2.0", 216 | "id": "1", 217 | "result": { 218 | "topicName": "com.weevent.test", 219 | "topicAddress": "0x171befab4c1c7e0d33b5c3bd932ce0112d4caecd", 220 | "senderAddress": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3", 221 | "createdTimestamp": 1548328570965, 222 | "sequenceNumber": 9, 223 | "blockNumber": 2475 224 | } 225 | } 226 | ``` 227 | 228 | - 说明 229 | 230 | - topicAddress: `Topic`区块链上的合约地址。 231 | 232 | - createdTimestamp:`Topic`创建的时间。 233 | 234 | - sequenceNumber:已发布事件数。 235 | 236 | - blockNumber:最新已发布事件的区块高度。 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /docs/protocol/mqtt.md: -------------------------------------------------------------------------------- 1 | ## MQTT 2 | `WeEvent`服务支持`MQTT Broker`功能。任何支持`MQTT`协议的IoT设备及客户端都能连接到`WeEvent`,并进行消息发布及订阅。 3 | 4 | ### 协议介绍 5 | 6 | - `MQTT`是物联网`IoT`中的主流接入协议,协议具体内容参见[http://mqtt.org/](http://mqtt.org/) 。 7 | - `WeEvent`支持`MQTT 3.1.1` 8 | 9 | ```eval_rst 10 | .. note:: 11 | - 暂不支持QoS=2的消息级别。 12 | ``` 13 | 14 | ### 开启TCP服务 15 | 16 | `weevent-broker`默认支持`MQTT over WebSocket`,`MQTT over TCP`需要额外开启。修改配置文件`./conf/weevent.properties`,然后重新启动服务。 17 | 18 | ```ini 19 | #mqtt tcp server 20 | mqtt.broker.port=7001 21 | ``` 22 | 23 | ### 样例演示 24 | 25 | 样例演示需依赖`Mosquitto`客户端,请根据链接(`https://mosquitto.org/download/`)进行下载安装。更多客户端参见[MQTT第三方库](https://github.com/mqtt/mqtt.github.io/wiki/libraries)。 26 | 27 | - IoT设备发布事件 28 | 29 | 发送消息前需创建主题`com.weevent.test`,请参考[创建Topic](./restful.html)。 30 | 31 | ```shell 32 | $ mosquitto_pub -h localhost -p 7000 -q 1 -t "com.weevent.test" -m "{\"timestamp\":133345566,\"key\":\"temperature\",\"value\":10.0}" 33 | ``` 34 | 35 | - IoT设备订阅事件 36 | 37 | ```shell 38 | $ mosquitto_sub -h localhost -p 7000 -q 1 -t "com.weevent.test" 39 | {"eventId":"317e7c4c-1-24","extensions":{},"topic":"com.weevent.test","content":[123,34,116,105,109,101,115,116,97,109,112,34,58,49,51,51,51,52,53,53,54,54,44,34,107,101,121,34,58,34,116,101,109,112,101,114,97,116,117,114,101,34,44,34,118,97,108,117,101,34,58,49,48,46,48,125]} 40 | ``` -------------------------------------------------------------------------------- /docs/protocol/restful.md: -------------------------------------------------------------------------------- 1 | ## RESTful 2 | `RESTful`作为一种软件架构风格、设计风格,在Web应用上非常流行。基于这个风格设计的软件可以更简洁,`REST` 接口可以直接在浏览器上测试,给开发和测试过程带来很多便利。 3 | 4 | `RESTful`都是对`STOMP`协议的一个补充,支持`WeEvent`主题的`CRUD`管理等功能以及事件发布。 5 | 6 | ### 协议说明 7 | 8 | - `HTTP`方法可以使用`GET`和`POST`,并且统一使用`UTF8`字符集。 9 | 10 | - 输入参数为`Query String`格式,注意使用`UrlEncode`。 11 | 12 | - 应答的`HTTP`状态码是 `200`,输出参数统一是`json`格式,`Content-type: application/json`。 13 | 14 | - 调用异常时,返回异常信息`BrokerException`。 15 | 16 | ```json 17 | {"code": 200202, "message":"the transaction does not correctly executed."} 18 | ``` 19 | 20 | ### 代码样例 21 | 22 | ```java 23 | public class Rest { 24 | public static void main(String[] args) { 25 | System.out.println("This is WeEvent restful sample."); 26 | try { 27 | SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 28 | RestTemplate rest = new RestTemplate(requestFactory); 29 | 30 | // ensure topic exist "com.weevent.test" 31 | String topic = "com.weevent.test"; 32 | ResponseEntity> rsp = rest.exchange("http://localhost:7000/weevent-broker/rest/open?topic={topic}&groupId={groupId}", HttpMethod.GET, null, new ParameterizedTypeReference>() { 33 | }, topic, WeEvent.DEFAULT_GROUP_ID); 34 | System.out.println(rsp.getBody().getData()); 35 | 36 | // publish event to topic "com.weevent.test" 37 | SendResult sendResult = rest.getForEntity("http://localhost:7000/weevent-broker/rest/publish?topic={topic}&groupId={groupId}&content={content}", 38 | SendResult.class, 39 | topic, 40 | WeEvent.DEFAULT_GROUP_ID, 41 | "hello WeEvent".getBytes(StandardCharsets.UTF_8)).getBody(); 42 | System.out.println(sendResult); 43 | } catch (RestClientException e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | } 48 | ``` 49 | 完整的代码,请参见[RESTful代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-broker/src/test/java/com/webank/weevent/sample/Rest.java) 。 50 | 51 | 52 | ### 接口说明 53 | 54 | `RESTful`接口包括两大类功能:一类是主题`Topic`的`CRUD`管理,包括`open`、`close`、`exist`、`state`、`list`;一类是事件发布`publish`。 55 | 56 | #### 创建Topic 57 | - 请求 58 | 59 | ```shell 60 | $ curl "http://localhost:8080/weevent-broker/rest/open?topic=com.weevent.test&groupId=1" 61 | ``` 62 | 63 | 64 | - 应答 65 | 66 | ```json 67 | { 68 | "code": "0", 69 | "message": "success", 70 | "data": "true" 71 | } 72 | ``` 73 | 74 | 75 | - 说明 76 | 77 | - topic:主题。`ascii`值在`[32,128]`之间。支持通配符按层次订阅,因'+'、'#'为通配符的关键字故不能为topic的一部分,详情参见[MQTT通配符](http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html) 。 78 | 79 | - groupId: `FISCO-BCOS`群组`Id`。默认的群组`1`可以不传,其他接口类似。 80 | 81 | 重复`open`返回`true` 。 82 | 83 | #### 关闭Topic 84 | - 请求 85 | 86 | ```shell 87 | $ curl "http://localhost:8080/weevent-broker/rest/close?topic=com.weevent.test&groupId=1" 88 | ``` 89 | 90 | 91 | - 应答 92 | 93 | ```json 94 | { 95 | "code": "0", 96 | "message": "success", 97 | "data": "true" 98 | } 99 | ``` 100 | 101 | #### 检查Topic是否存在 102 | - 请求 103 | 104 | ```shell 105 | $ curl "http://localhost:8080/weevent-broker/rest/exist?topic=com.weevent.test&groupId=1" 106 | ``` 107 | 108 | 109 | - 应答 110 | 111 | ```json 112 | { 113 | "code": "0", 114 | "message": "success", 115 | "data": "true" 116 | } 117 | ``` 118 | 119 | #### 发布事件 120 | - 请求 121 | 122 | ```shell 123 | $ curl "http://localhost:8080/weevent-broker/rest/publish?topic=com.weevent.test&groupId=1&content=123456&weevent-format=json" 124 | ``` 125 | 126 | 127 | - 应答 128 | 129 | ```json 130 | { 131 | "topic": "com.weevent.test", 132 | "eventId": "2cf24dba-59-1124", 133 | "status": "SUCCESS" 134 | } 135 | ``` 136 | 137 | 138 | - 说明 139 | 140 | - content :用户自定义数据。需要特别注意`content`需进行`UrlEncode`编码,`GET`方法支持的`QueryString`最大长度为1024字节。 141 | 142 | - weevent-format:可选参数。用户自定义拓展,以`weevent-`开头。 143 | 144 | - status:`SUCCESS`,说明是发布成功,`eventId`是对应的事件ID。 145 | 146 | #### 获取Event详情 147 | 148 | - 请求 149 | 150 | ```shell 151 | $ curl "http://localhost:8080/weevent-broker/rest/getEvent?eventId=2cf24dba-59-1124&groupId=1" 152 | ``` 153 | 154 | - 应答 155 | 156 | ```json 157 | { 158 | "code":0, 159 | "message":"success", 160 | "data": { 161 | "topic": "hello", 162 | "content": "MTIzNDU2", 163 | "extensions": { 164 | "weevent-format": "json", 165 | "weevent-plus": { 166 | "timestamp":1591326142038, 167 | "height":168, 168 | "txHash":"0x5c9fc570c1ac35f85382f38aa7d88ff038deb5865b971af34b6828fc6c23b5e9", 169 | "sender":"0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3" 170 | } 171 | }, 172 | "eventId": "2cf24dba-59-1124" 173 | } 174 | } 175 | ``` 176 | - 说明 177 | - eventId:事件ID 178 | - content:事件内容,`MTIzNDU2`是`123456`的`Base64`之后的值。 179 | - extensions:用户自定义拓展数据。 180 | 181 | ```eval_rst 182 | .. note:: 183 | - 以下管理端接口,业务程序里一般用不到,可以直接安装Goverance模块来使用这部分功能。 184 | ``` 185 | #### 当前Topic列表 186 | - 请求 187 | 188 | ```shell 189 | $ curl "http://localhost:8080/weevent-broker/rest/list?pageIndex=0&pageSize=10&groupId=1" 190 | ``` 191 | 192 | 193 | - 应答 194 | 195 | ```json 196 | { 197 | "code":0, 198 | "message":"success", 199 | "data": { 200 | "total": 50, 201 | "pageIndex": 1, 202 | "pageSize": 10, 203 | "topicInfoList": [ 204 | { 205 | "topicName": "123456", 206 | "topicAddress": "0x420f853b49838bd3e9466c85a4cc3428c960dde2", 207 | "senderAddress": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3", 208 | "createdTimestamp": 1548211117753 209 | } 210 | ] 211 | } 212 | } 213 | ``` 214 | 215 | 216 | - 说明 217 | - total:`Topic`的总数量。 218 | - pageIndex:表示查询第几页,从0开始 。 219 | - pageSize:分页大小(0,100),超出这默认每页10个数据。 220 | - topicInfoList:`Topic` 详细信息列表。 221 | 222 | 223 | 224 | #### 查询某个Topic详情 225 | - 请求 226 | 227 | ```shell 228 | $ curl "http://localhost:8080/weevent-broker/rest/state?topic=com.weevent.test&groupId=1" 229 | ``` 230 | 231 | 232 | - 应答 233 | 234 | ```json 235 | { 236 | "code":0, 237 | "message":"success", 238 | "data": { 239 | "topicName": "com.weevent.test", 240 | "topicAddress": "0x171befab4c1c7e0d33b5c3bd932ce0112d4caecd", 241 | "senderAddress": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3", 242 | "createdTimestamp": 1548328570965, 243 | "sequenceNumber": 9, 244 | "blockNumber": 2475, 245 | "lastTimestamp":1591326142038, 246 | "lastSender":null, 247 | "lastBlock":null 248 | } 249 | } 250 | ``` 251 | 252 | 253 | - 说明 254 | - topicName : 事件名称 255 | - topicAddress : `Topic` 区块链上的合约地址 256 | - createdTimestamp :`Topic` 创建的时间 257 | - sequenceNumber:已发布事件数。 258 | - blockNumber:最新已发布事件的区块高度。 259 | 260 | #### 获取群组列表 261 | - 请求 262 | 263 | ```shell 264 | $ curl "http://localhost:8080/weevent-broker/admin/listGroup" 265 | ``` 266 | 267 | 268 | - 应答 269 | 270 | ```json 271 | { 272 | "code": 0, 273 | "message": "success", 274 | "data":[ 275 | "1","2" 276 | ] 277 | } 278 | ``` 279 | 280 | #### 获取 节点ip数组 281 | - 请求 282 | ```shell 283 | $ curl "http://localhost:8080/weevent-broker/admin/listNodes" 284 | ``` 285 | 286 | - 应答 287 | 288 | ```json 289 | { 290 | "code": 0, 291 | "message": "success", 292 | "data": [ 293 | "127.0.0.1:7000" 294 | ] 295 | } 296 | ``` 297 | - 说明 298 | 299 | - data:节点ip数组。 300 | 301 | #### 获取订阅列表 302 | - 请求 303 | ```shell 304 | $ curl "http://localhost:8080/weevent-broker/admin/listSubscription?nodeInstances=127.0.0.1:7000" 305 | ``` 306 | 307 | - 应答 308 | 309 | ```json 310 | { 311 | "code": 0, 312 | "message": "success", 313 | "data": { 314 | "127.0.0.1:7000": [{ 315 | "interfaceType": "stomp", 316 | "notifiedEventCount": "0", 317 | "notifyingEventCount": "0", 318 | "notifyTimeStamp": "2020-03-16 15:09:22", 319 | "topicName": "com.weevent.test", 320 | "subscribeId": "041b2b7b-1ec3-47c9-9cf3-2f40a0a17f5a", 321 | "remoteIp": "192.168.0.107", 322 | "createTimeStamp": "2020-03-16 15:09:22", 323 | "groupId": "1" 324 | }] 325 | } 326 | } 327 | ``` 328 | - 说明 329 | - interfaceType:监听请求类型 `RESTful`、`JsonRPC`、`MQTT` 、`STOMP`。 330 | - notifyingEventCount:待通知事件的数量。 331 | - notifiedEventCount:已通知事件数量 332 | - notifyTimeStamp:最近通知事件时间戳。 333 | - subscribeId:订阅ID 334 | - topicName :事件主题。 335 | 336 | #### 获取版本信息 337 | - 请求 338 | ```shell 339 | $ curl "http://localhost:8080/weevent-broker/admin/getVersion" 340 | ``` 341 | 342 | - 应答 343 | 344 | ```json 345 | { 346 | "code": 0, 347 | "message":"success", 348 | "data": 349 | { 350 | "weEventVersion": "1.6.0", 351 | "gitCommitTimeStamp": "2020-09-02 18:30:14", 352 | "gitBranch": "master", 353 | "gitCommitHash": "f42ceeb" 354 | } 355 | } 356 | ``` 357 | - 说明 358 | - weEventVersion:`WeEvent`版本号。 359 | - gitCommitTimeStamp:`WeEvent`最近一次提交git的时间。 360 | - gitBranch:`WeEvent`构建分支。 361 | - gitCommitHash:`WeEvent`最近一次提交git的CommitHash。 362 | 363 | 364 | #### 获取节点个数、区块数量、交易数量 365 | - 请求 366 | ```shell 367 | $ curl "http://localhost:8080/weevent-broker/admin/group/general?groupId=1" 368 | ``` 369 | 370 | - 应答 371 | 372 | ```json 373 | { 374 | "code": 0, 375 | "message": "success", 376 | "data": { 377 | "nodeCount": "4", 378 | "latestBlock": "100", 379 | "transactionCount": "5260" 380 | } 381 | } 382 | ``` 383 | - 说明 384 | - nodeCount:节点个数。 385 | - latestBlock:区块数量。 386 | - transactionCount:交易数量。 387 | 388 | #### 获取区块链交易列表 389 | - 请求 390 | ```shell 391 | $ curl "http://localhost:8080/weevent-broker/admin/transaction/transList?groupId=1&pageNumber=1&pageSize=10" 392 | ``` 393 | 394 | - 应答 395 | 396 | ```json 397 | { 398 | "code": 0, 399 | "message": "success", 400 | "data": { 401 | "total": 1, 402 | "pageIndex": 1, 403 | "pageSize": 10, 404 | "pageData": [{ 405 | "blockNumber": 5364, 406 | "blockTimestamp": "2019-10-15 14:48:01", 407 | "createTime": null, 408 | "modifyTime": null, 409 | "transFrom": "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3", 410 | "transHash": "0xb3585cf385a595e5af425d360693e6759d8db5c1a98ebb46277b38c014ec8626", 411 | "transTo": "0xa40c864c28ee8b07dc2eeab4711e3161fc87e1e2" 412 | }] 413 | } 414 | } 415 | ``` 416 | - 说明 417 | - total:当前区块交易总条数。 418 | - pageIndex:页码。 419 | - pageSize:页面展示条数。 420 | - blockNumber:区块高度。 421 | - blockTimestamp:区块交易时间。 422 | - createTime:创建时间。 423 | - modifyTime:修改时间。 424 | - transFrom: 发送者的地址。 425 | - transHash:交易哈希。 426 | - transTo:接收者的地址。 427 | 428 | 429 | #### 获取交易哈希列表 430 | - 请求 431 | ```shell 432 | $ curl "http://localhost:8080/weevent-broker/admin/block/blockList?groupId=1&pageNumber=1&pageSize=10" 433 | ``` 434 | 435 | - 应答 436 | 437 | ```json 438 | { 439 | "code": 0, 440 | "message": "success", 441 | "data": { 442 | "total": 1, 443 | "pageIndex": 1, 444 | "pageSize": 10, 445 | "pageData": [{ 446 | "blockNumber": 5364, 447 | "blockTimestamp": "2019-10-15 14:48:01", 448 | "createTime": null, 449 | "modifyTime": null, 450 | "pkHash": "0x382d17374619233978c2f5c8dfc88fea1bb70af52ea824c8ec99982d66b455cd", 451 | "sealer": "0x3", 452 | "sealerIndex": 1, 453 | "transCount": 1 454 | }] 455 | } 456 | } 457 | ``` 458 | - 说明 459 | - total: 区块总数。 460 | - pageIndex:页码。 461 | - pageSize:页面展示条数。 462 | - blockNumber:区块高度。 463 | - blockTimestamp:区块交易时间。 464 | - createTime:创建时间。 465 | - modifyTime:修改时间。 466 | - pkHash:区块哈希。 467 | - sealer:共识节点序号。 468 | - sealerIndex:节点序号为index的nodeId。 469 | - transCount:交易次数。 470 | 471 | #### 获取区块链节点列表 472 | - 请求 473 | ```shell 474 | $ curl "http://localhost:8080/weevent-broker/admin/node/nodeList?groupId=1&pageNumber=1&pageSize=10" 475 | ``` 476 | 477 | - 应答 478 | 479 | ```json 480 | { 481 | "code": 0, 482 | "message": "success", 483 | "data": { 484 | "total": 1, 485 | "pageIndex": 1, 486 | "pageSize": 10, 487 | "pageData": [{ 488 | "nodeId": "543095f2a4a7ec910c4d62fcde2754871c559d375fba9a11aab94cb7c7ae8eef8f55250558a7412d14f11faeb7d31c55cec36746ce5644c749a4674888fe46eb", 489 | "nodeName": null, 490 | "pbftView": 23, 491 | "nodeType": "sealer", 492 | "blockNumber": 5364, 493 | "createTime": null, 494 | "modifyTime": null, 495 | "nodeActive": 1 496 | }] 497 | } 498 | } 499 | ``` 500 | - 说明 501 | - total: 节点总数。 502 | - pageIndex:页码。 503 | - pageSize:页面展示条数。 504 | - nodeId:节点id。 505 | - nodeName:节点名称。 506 | - pbftView:PBFT视图。 507 | - nodeType:节点类型。 508 | - blockNumber:区块高度。 509 | - nodeActive:节点运行状态。 510 | - createTime:创建时间。 511 | - modifyTime:修改时间。 512 | -------------------------------------------------------------------------------- /docs/protocol/stomp.md: -------------------------------------------------------------------------------- 1 | ## STOMP 2 | `STOMP`是面向流文本的消息传输协议`Streaming Text Oriented Messaging Protocol`,是 `WebSocket` 通信标准的一部分,属于业务层的控制协议`Wire protocol`,[协议规范](https://stomp.github.io/stomp-specification-1.1.html)。在通常的发布订阅语义之上,它通过 `begin`、 `commit`、`rollback` 事物序列以及`ack`确认机制来提供消息可靠的投递。由于协议简单且易于实现,几乎所有的编程语言都有 STOMP 的客户端实现。 3 | 4 | 可以通过`STOMP`协议访问`WeEvent`的发布订阅相关功能。 5 | 6 | ### 协议说明 7 | 8 | - 支持STOMP协议的`1.1`、`1.2`版本。暂时不支持消息确认`ACK`和事务`Transaction`语义。 9 | 10 | - 传输协议方面,同时支持`STOMP Over WebSocket`和`STOMP Over SockJS`。 11 | 12 | ### JavaScript语言 13 | 前端面直接访问`WeEvent`,推荐使用开源库[stompjs](https://github.com/stomp-js/stompjs),该库支持STOMP协议的`1.1`、`1.2`的版本。使用`stompjs` +` sockjs`的组合效果更好。 14 | 15 | ### Java语言 16 | #### Spring Boot 环境 17 | 加入`Spring Boot`的依赖,以`gradle` 为例: 18 | 19 | ```groovy 20 | implementation("org.springframework.boot:spring-boot-starter-websocket") 21 | ``` 22 | `Spring`从`4.0`开始引入`spring-websocket`模块,支持`STOMP`,建议使用`Spring Boot 2.0.0`以上版本。 23 | 24 | #### 代码样例 25 | 26 | **第一步:创建链接** 27 | 28 | ```java 29 | // standard web socket transport 30 | WebSocketClient webSocketClient = new StandardWebSocketClient(); 31 | WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient); 32 | 33 | // MappingJackson2MessageConverter 34 | stompClient.setMessageConverter(new StringMessageConverter()); 35 | stompClient.setTaskScheduler(taskScheduler); // for heartbeats 36 | ListenableFuture f = stompClient.connect("ws://localhost:8080/weevent-broker/stomp", getWebsocketSessionHandlerAdapter()); 37 | StompSession stompSession = f.get(); 38 | ``` 39 | 40 | - 心跳说明 41 | 42 | `WeEvent`使用单向心跳机制,客户端发送心跳,服务端不发心跳。默认时间间隔为`30s` 。 43 | 44 | - 修改心跳方案。 45 | 46 | 配置心跳时间间隔:修改配置文件`./broker/conf/weevent.properties`,`stomp.heartbeats=30`。 47 | - 传输协议方面 48 | `STOMP Over WebSocket`使用`ws://localhost:8080/weevent-broker/stomp` 49 | `STOMP Over SockJS`使用`ws://localhost:8080/weevent-broker/sockjs` 50 | 51 | **第二步:发布事件** 52 | 53 | ```java 54 | StompHeaders header = new StompHeaders(); 55 | header.setDestination("com.weevent.test"); 56 | header.set("groupId", WeEvent.DEFAULT_GROUP_ID); 57 | StompSession.Receiptable receiptable = stompSession.send(header, "hello WeEvent"); 58 | log.info("send result, receipt id: {}", receiptable.getReceiptId()); 59 | ``` 60 | 61 | 说明: 62 | - `Topic` 为`com.weevent.test`。用户可以获取到`Receiptable`,并且通过`receiptable.getReceiptId()`,可以获取相应的回执。 63 | - `groupId`为群组`Id`,`fisco-bcos 2.0+`版本支持多群组功能,2.0以下版本不支持该功能可以不传。 64 | - `weevent-format`为用户自定义拓展默认以`weevent-`开头。可选参数。 65 | 66 | **第三步:订阅事件** 67 | 68 | ```java 69 | StompHeaders header = new StompHeaders(); 70 | header.setDestination(topic); 71 | header.set("groupId", WeEvent.DEFAULT_GROUP_ID); 72 | header.set("eventId", WeEvent.OFFSET_LAST); 73 | 74 | StompSession.Subscription subscription = stompSession.subscribe(header, new StompFrameHandler() { 75 | @Override 76 | public Type getPayloadType(StompHeaders headers) { 77 | return String.class; 78 | } 79 | 80 | @Override 81 | public void handleFrame(StompHeaders headers, Object payload) { 82 | logger.info("subscribe handleFrame, header: {} payload: {}", headers, payload); 83 | } 84 | }); 85 | ``` 86 | 87 | 说明: 88 | 89 | - `topic` 订阅的主题。支持通配符按层次订阅,参见[MQTT通配符](http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html) 。 90 | - 配置`eventId`,如需要取历史数据,则需要设置。如果不设置,则默认为取最新内容。 91 | - `weevent-format`为用户自定义拓展默认以`weevent-`开头。可选参数。 92 | - `StompFrameHandler` ,对`StompFrame`和`StompHeaders`进行处理的方法。 93 | 94 | 上述样例完整的代码,请参见[STOMP代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-broker/src/test/java/com/webank/weevent/broker/sample/Stomp.java) 。 95 | 96 | #### Spring环境 97 | 98 | - 依赖说明 99 | 100 | ```groovy 101 | implementation("org.springframework:spring-messaging:5.1.2.RELEASE") 102 | implementation("org.springframework:spring-websocket:5.1.2.RELEASE") 103 | ``` 104 | 105 | - 代码实现和上面`spring boot`一样 106 | 107 | #### 其他语言的适配 108 | 109 | 各种语言的开源`STOMP`客户端,参见[https://stomp.github.io/implementations.html](https://stomp.github.io/implementations.html)。 110 | 111 | -------------------------------------------------------------------------------- /docs/protocol/weevent-client-sdk.md: -------------------------------------------------------------------------------- 1 | ## Java Client SDK 2 | `WeEvent`支持`RESTful`、`JsonRPC`、`STOMP`、`MQTT`等协议,方便各种语言的接入和适配。 3 | 4 | 同时为`Java`语言提供了独立的客户端`SDK`。其他语言`SDK`在规划中,欢迎大家贡献代码,[WeEvent代码仓库](https://github.com/WeBankBlockchain/WeEvent) 。 5 | 6 | ### 集成SDK 7 | 8 | - gradle依赖 9 | ```groovy 10 | implement 'com.webank.weevent:weevent-client:1.6.0' 11 | ``` 12 | - maven依赖 13 | ```xml 14 | 15 | com.webank.weevent 16 | weevent-client 17 | 1.6.0 18 | 19 | ``` 20 | 21 | ### API接口 22 | ```java 23 | public interface IWeEventClient { 24 | String defaultBrokerUrl = "http://localhost:8080/weevent-broker"; 25 | 26 | /** 27 | * builder class 28 | */ 29 | class Builder { 30 | // broker url 31 | private String brokerUrl = defaultBrokerUrl; 32 | // group id 33 | private String groupId = WeEvent.DEFAULT_GROUP_ID; 34 | // stomp's account&password 35 | private String userName = ""; 36 | private String password = ""; 37 | // rpc timeout, ms 38 | private int timeout = 5000; 39 | 40 | public Builder brokerUrl(String brokerUrl) { 41 | this.brokerUrl = brokerUrl; 42 | return this; 43 | } 44 | 45 | public Builder groupId(String groupId) { 46 | this.groupId = groupId; 47 | return this; 48 | } 49 | 50 | public Builder userName(String userName) { 51 | this.userName = userName; 52 | return this; 53 | } 54 | 55 | public Builder password(String password) { 56 | this.password = password; 57 | return this; 58 | } 59 | 60 | public Builder timeout(int timeout) { 61 | this.timeout = timeout; 62 | return this; 63 | } 64 | 65 | public IWeEventClient build() throws BrokerException { 66 | return new WeEventClient(this.brokerUrl, this.groupId, this.userName, this.password, this.timeout); 67 | } 68 | } 69 | 70 | /** 71 | * Open a topic 72 | * 73 | * @param topic topic name 74 | * @return true if success 75 | * @throws BrokerException broker exception 76 | */ 77 | boolean open(String topic) throws BrokerException; 78 | 79 | /** 80 | * Close a topic. 81 | * 82 | * @param topic topic name 83 | * @return true if success 84 | * @throws BrokerException broker exception 85 | */ 86 | boolean close(String topic) throws BrokerException; 87 | 88 | /** 89 | * Check a topic is exist or not. 90 | * 91 | * @param topic topic name 92 | * @return true if exist 93 | * @throws BrokerException broker exception 94 | */ 95 | boolean exist(String topic) throws BrokerException; 96 | 97 | /** 98 | * Publish an event to topic. 99 | * 100 | * @param weEvent WeEvent(String topic, byte[] content, Map extensions) 101 | * @return send result, SendResult.SUCCESS if success, and SendResult.eventId 102 | * @throws BrokerException broker exception 103 | */ 104 | SendResult publish(WeEvent weEvent) throws BrokerException; 105 | 106 | /** 107 | * Publish an event to topic in asynchronous way. 108 | * 109 | * @param weEvent WeEvent(String topic, byte[] content, Map extensions) 110 | * @return send result, SendResult.SUCCESS if success, and SendResult.eventId 111 | * @throws BrokerException broker exception 112 | */ 113 | CompletableFuture publishAsync(WeEvent weEvent) throws BrokerException; 114 | 115 | /** 116 | * Interface for event notify callback 117 | */ 118 | interface EventListener { 119 | /** 120 | * Called while new event arrived. 121 | * 122 | * @param event the event 123 | */ 124 | void onEvent(WeEvent event); 125 | 126 | /** 127 | * Called while raise exception. 128 | * 129 | * @param e the e 130 | */ 131 | void onException(Throwable e); 132 | } 133 | 134 | /** 135 | * Subscribe events from topic. 136 | * 137 | * @param topic topic name 138 | * @param offset from next event after this offset(an event id), WeEvent.OFFSET_FIRST if from head of queue, WeEvent.OFFSET_LAST if from tail of queue 139 | * @param extension extension params 140 | * @param listener notify interface 141 | * @return subscription Id 142 | * @throws BrokerException invalid input param 143 | */ 144 | String subscribe(String topic, String offset, Map extension, @NonNull EventListener listener) throws BrokerException; 145 | 146 | /** 147 | * Subscribe events from topic. 148 | * 149 | * @param topics topic list 150 | * @param offset from next event after this offset(an event id), WeEvent.OFFSET_FIRST if from head of queue, WeEvent.OFFSET_LAST if from tail of queue 151 | * @param extension extension params 152 | * @param listener notify interface 153 | * @return subscription Id 154 | * @throws BrokerException invalid input param 155 | */ 156 | String subscribe(String[] topics, String offset, Map extension, @NonNull EventListener listener) throws BrokerException; 157 | 158 | /** 159 | * Unsubscribe an exist subscription subscribed by subscribe interface. 160 | * The consumer will no longer receive messages from broker after this. 161 | * 162 | * @param subscriptionId invalid input 163 | * @return success if true 164 | * @throws BrokerException broker exception 165 | */ 166 | boolean unSubscribe(String subscriptionId) throws BrokerException; 167 | 168 | /** 169 | * List all topics in WeEvent's broker. 170 | * 171 | * @param pageIndex page index, from 0 172 | * @param pageSize page size, [10, 100) 173 | * @return topic list 174 | * @throws BrokerException broker exception 175 | */ 176 | TopicPage list(Integer pageIndex, Integer pageSize) throws BrokerException; 177 | 178 | /** 179 | * Get a topic information. 180 | * 181 | * @param topic topic name 182 | * @return topic information 183 | * @throws BrokerException broker exception 184 | */ 185 | TopicInfo state(String topic) throws BrokerException; 186 | 187 | /** 188 | * Get an event information. 189 | * 190 | * @param eventId event id 191 | * @return WeEvent 192 | * @throws BrokerException broker exception 193 | */ 194 | WeEvent getEvent(String eventId) throws BrokerException; 195 | } 196 | ``` 197 | 198 | ### 代码样例 199 | 200 | ```java 201 | public static void main(String[] args) { 202 | try { 203 | IWeEventClient client = IWeEventClient.builder().brokerUrl("http://localhost:8080/weevent-broker").groupId(WeEvent.DEFAULT_GROUP_ID).build(); 204 | 205 | String topicName = "com.weevent.test"; 206 | // open 一个"com.weevent.test"的主题 207 | client.open(topicName); 208 | 209 | // 发送hello WeEvent 210 | WeEvent weEvent = new WeEvent(topicName, "hello WeEvent".getBytes()); 211 | SendResult sendResult = client.publish(weEvent); 212 | System.out.println(sendResult); 213 | } catch (BrokerException e) { 214 | e.printStackTrace(); 215 | } 216 | } 217 | ``` 218 | 219 | 完整的代码请参见[Java Client SDK代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-broker/src/test/java/com/webank/weevent/broker/sample/JavaSDK.java) 。 220 | -------------------------------------------------------------------------------- /docs/protocol/weevent-core-sdk.md: -------------------------------------------------------------------------------- 1 | ## Java Core SDK 2 | 本节介绍如何将核心的发布订阅功能以`jar`包形式直接集成到业务服务里。 3 | 4 | ### 前置条件 5 | 6 | - 区块链FISCO-BCOS节点 7 | 8 | 必选配置。`WeEvent`通过区块链`FISCO-BCOS`持久化数据。 9 | 10 | 具体安装步骤,请参见[FISCO-BCOS安装](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html)。 11 | 12 | ### 集成SDK 13 | 14 | - gradle依赖 15 | ```groovy 16 | implement 'com.webank.weevent:weevent-core:1.6.0' 17 | ``` 18 | - maven依赖 19 | ```xml 20 | 21 | com.webank.weevent 22 | weevent-core 23 | 1.6.0 24 | 25 | ``` 26 | 27 | ### API接口 28 | ```java 29 | public class FiscoBcosInstance { 30 | private FiscoBcosDelegate fiscoBcosDelegate; 31 | 32 | public FiscoBcosInstance(FiscoConfig config) throws BrokerException { 33 | this.fiscoBcosDelegate = new FiscoBcosDelegate(); 34 | this.fiscoBcosDelegate.initProxy(config); 35 | } 36 | 37 | /** 38 | * build a producer 39 | * 40 | * @return IProducer producer handler 41 | */ 42 | public IProducer buildProducer() { 43 | return new FiscoBcosBroker4Producer(this.fiscoBcosDelegate); 44 | } 45 | 46 | /** 47 | * build a consumer 48 | * 49 | * @return IConsumer consumer handler 50 | */ 51 | public IConsumer buildConsumer() { 52 | return new FiscoBcosBroker4Consumer(this.fiscoBcosDelegate); 53 | } 54 | } 55 | ``` 56 | 57 | ### 代码样例 58 | 59 | ```java 60 | public static void main(String[] args) { 61 | try { 62 | String topicName = "com.weevent.test"; 63 | FiscoConfig fiscoConfig = new FiscoConfig(); 64 | // 默认从classpath里读取配置文件fisco.yml 65 | fiscoConfig.load(""); 66 | 67 | // 获取FISCO实例 68 | FiscoBcosInstance fiscoBcosInstance = new FiscoBcosInstance(fiscoConfig); 69 | 70 | // 创建生产者 71 | IProducer iProducer = fiscoBcosInstance.buildProducer(); 72 | iProducer.startProducer(); 73 | 74 | // 创建topic 75 | iProducer.open(topicName, WeEvent.DEFAULT_GROUP_ID); 76 | 77 | // 生产者发布事件 78 | WeEvent weEvent = new WeEvent(topicName, "hello weevent".getBytes()); 79 | SendResult sendResult = iProducer.publish(weEvent, WeEvent.DEFAULT_GROUP_ID, fiscoConfig.getWeb3sdkTimeout()); 80 | System.out.println(sendResult); 81 | 82 | // 创建消费者 83 | IConsumer iConsumer = fiscoBcosInstance.buildConsumer(); 84 | iConsumer.startConsumer(); 85 | 86 | // 消费者订阅消息 87 | String subscriptionId = iConsumer.subscribe(topicName, WeEvent.DEFAULT_GROUP_ID, WeEvent.OFFSET_LAST, new HashMap<>(), new IConsumer.ConsumerListener() { 88 | @Override 89 | public void onEvent(String subscriptionId, WeEvent event) { 90 | // 回调后的业务处理 91 | } 92 | 93 | @Override 94 | public void onException(Throwable e) { 95 | } 96 | }); 97 | 98 | // 取消订阅 99 | iConsumer.unSubscribe(subscriptionId); 100 | } catch (BrokerException e) { 101 | e.printStackTrace(); 102 | } 103 | } 104 | ``` 105 | 106 | 以上样例将发布者和订阅者放在一起只是为了方便示例,业务实际场景一般在不同的进程。 107 | 完整的代码请参见[Java Core SDK代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-core/src/test/java/com/webank/weevent/core/FiscoBcosInstanceTest.java) 。 108 | 109 | ### 关于配置文件 110 | 111 | 以上样例中使用到的配置文件`fisco.yml`,内容如下: 112 | 113 | ```yaml 114 | ################ weevent core config ################ 115 | 116 | version: 2.0 117 | orgId: fisco 118 | 119 | timeout: 10000 120 | poolSize: 10 121 | maxPoolSize: 200 122 | keepAliveSeconds: 10 123 | 124 | consumerHistoryMergeBlock: 8 125 | consumerIdleTime: 1000 126 | 127 | 128 | ################ fisco bcos sdk config ################ 129 | # https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/sdk/java_sdk/configuration.html 130 | 131 | #cryptoMaterial: 132 | # certPath: "conf" 133 | # caCert: "conf/ca.crt" 134 | # sslCert: "conf/sdk.crt" 135 | # sslKey: "conf/sdk.key" 136 | # enSslCert: "conf/gm/gmensdk.crt" 137 | # enSslKey: "conf/gm/gmensdk.key" 138 | 139 | account: 140 | # ECDSA_TYPE 141 | accountAddress: "0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3" 142 | # SM_TYPE 143 | # accountAddress: "0x4278900c23e4b364ba6202a24682d99be9ff8cbc" 144 | # accountFileFormat: "pem" 145 | # accountFilePath: "" 146 | keyStoreDir: "account" 147 | # password: "" 148 | 149 | #amop: 150 | # - publicKeys: [ "conf/amop/consumer_public_key_1.pem" ] 151 | # topicName: "PrivateTopic1" 152 | # - password: "123456" 153 | # privateKey: "conf/amop/consumer_private_key.p12" 154 | # topicName: "PrivateTopic2" 155 | 156 | 157 | network: 158 | peers: 159 | - "127.0.0.1:20200" 160 | 161 | threadPool: 162 | channelProcessorThreadSize: "16" 163 | maxBlockingQueueSize: "102400" 164 | receiptProcessorThreadSize: "16" 165 | ``` 166 | 167 | - 将上面文件放入`classpath`下面。通过默认方式`FiscoConfig.load("")`即可加载。 168 | 169 | ### 初始化部署合约 170 | 171 | 安装完区块链网络后,需要先初始化部署`WeEvent`内置合约(一般称为`Topic Control`合约)才能使用`WeEvent`。 172 | 173 | 集成好`weevent-core.Jar`,设置好配置文件`fisco.yml`及其访问节点的证书后。执行`Jar`包里的方法部署合约: 174 | 175 | ```shell 176 | $ java -classpath "./conf:./lib/*:../lib/*" com.webank.weevent.core.fisco.util.Web3sdkUtils 177 | 2020-06-05 11:08:36 topic control address in every group: 178 | topic control address in group: 1 179 | EchoAddress(version=10, address=0x23df89a2893120f686a4aa03b41acf6836d11e5d, isNew=false) 180 | ``` 181 | 182 | 其中`./conf`为`fisco.yml`所在目录,`./lib`为`weevent-core.Jar`及其依赖所在目录。 183 | 184 | 这个方法可重入,重复执行时只是简单显示一下数据。屏幕输出`new`为`true`表示合约是本次部署,`false`表示是之前部署的合约。 185 | -------------------------------------------------------------------------------- /docs/protocol/weevent-file-sdk.md: -------------------------------------------------------------------------------- 1 | ## Java File SDK 2 | 本节介绍如何将大文件传输功能以`jar`包形式直接集成到业务服务里。 3 | ### 前置条件 4 | 5 | - 区块链FISCO-BCOS节点 6 | 7 | 必选配置。`WeEvent`通过区块链`FISCO-BCOS`的P2P网络发布和订阅文件。 8 | 9 | 具体安装步骤,请参见[FISCO-BCOS安装](https://fisco-bcos-documentation.readthedocs.io/zh_CN/latest/docs/installation.html)。 10 | 11 | ### 集成SDK 12 | 13 | - gradle依赖 14 | ```groovy 15 | implement 'com.webank.weevent:weevent-file:1.6.0' 16 | ``` 17 | - maven依赖 18 | ```xml 19 | 20 | com.webank.weevent 21 | weevent-file 22 | 1.6.0 23 | 24 | ``` 25 | 26 | ### API接口 27 | ```java 28 | public interface IWeEventFileClient { 29 | static IWeEventFileClient build(String groupId, String filePath, int fileChunkSize, FiscoConfig fiscoConfig) { 30 | return new WeEventFileClient(groupId, filePath, fileChunkSize, fiscoConfig); 31 | } 32 | 33 | static IWeEventFileClient build(String groupId, String filePath, FtpInfo ftpInfo, int fileChunkSize, FiscoConfig fiscoConfig) { 34 | return new WeEventFileClient(groupId, filePath, ftpInfo, fileChunkSize, fiscoConfig); 35 | } 36 | 37 | /** 38 | * open transport for sender. 39 | * 40 | * @param topic topic name 41 | */ 42 | void openTransport4Sender(String topic); 43 | 44 | /** 45 | * open transport for authentication sender. 46 | * 47 | * @param topic topic name 48 | * @param publicPem public pem InputStream 49 | * @throws BrokerException broker exception 50 | */ 51 | void openTransport4Sender(String topic, InputStream publicPem) throws BrokerException; 52 | 53 | /** 54 | * open transport for authentication sender. 55 | * 56 | * @param topic topic name 57 | * @param publicPem public pem path string 58 | * @throws BrokerException broker exception 59 | * @throws BrokerException BrokerException 60 | */ 61 | void openTransport4Sender(String topic, String publicPem) throws BrokerException, IOException; 62 | 63 | /** 64 | * Publish a file to topic. 65 | * The file's data DO NOT stored in block chain. Yes, it's not persist, may be deleted sometime after subscribe notify. 66 | * 67 | * @param topic binding topic 68 | * @param localFile local file to be send 69 | * @param overwrite if receiver has this file, overwrite it? 70 | * @return send result, SendResult.SUCCESS if success, and return SendResult.eventId 71 | * @throws BrokerException broker exception 72 | * @throws IOException IOException 73 | */ 74 | FileChunksMeta publishFile(String topic, String localFile, boolean overwrite) throws BrokerException, IOException; 75 | 76 | /** 77 | * open transport for receiver. 78 | * 79 | * @param topic topic name 80 | * @param fileListener notify interface 81 | * @throws BrokerException broker exception 82 | */ 83 | void openTransport4Receiver(String topic, FileListener fileListener) throws BrokerException; 84 | 85 | /** 86 | * open transport for authentication receiver. 87 | * 88 | * @param topic topic name 89 | * @param fileListener notify interface 90 | * @param privatePem private key pem InputStream 91 | * @throws BrokerException broker exception 92 | */ 93 | void openTransport4Receiver(String topic, FileListener fileListener, InputStream privatePem) throws BrokerException; 94 | 95 | /** 96 | * open transport for authentication receiver. 97 | * 98 | * @param topic topic name 99 | * @param fileListener notify interface 100 | * @param privatePem private key pem path string 101 | * @throws IOException IOException 102 | * @throws BrokerException BrokerException 103 | */ 104 | void openTransport4Receiver(String topic, FileListener fileListener, String privatePem) throws IOException, BrokerException; 105 | 106 | 107 | /** 108 | * Interface for file notify callback 109 | */ 110 | interface FileListener { 111 | /** 112 | * Called while new file arrived. 113 | * 114 | * @param topicName topic name 115 | * @param fileName file name 116 | */ 117 | void onFile(String topicName, String fileName); 118 | 119 | /** 120 | * Called while raise exception. 121 | * 122 | * @param e the e 123 | */ 124 | void onException(Throwable e); 125 | } 126 | 127 | /** 128 | * close transport. 129 | * 130 | * @param topic topic name 131 | */ 132 | void closeTransport(String topic); 133 | 134 | /** 135 | * query transport status. 136 | * 137 | * @param topic topic name 138 | * @return FileTransportStats 139 | */ 140 | FileTransportStats status(String topic); 141 | 142 | /** 143 | * list received files. 144 | * 145 | * @param topic topic name 146 | * @return FileChunksMeta list 147 | * @throws BrokerException broker exception 148 | */ 149 | List listFiles(String topic) throws BrokerException; 150 | 151 | /** 152 | * sign a file transport event. 153 | * 154 | * @param fileChunksMeta fileChunksMeta 155 | * @return send result and eventId 156 | * @throws BrokerException broker exception 157 | */ 158 | SendResult sign(FileChunksMeta fileChunksMeta) throws BrokerException; 159 | 160 | /** 161 | * verify a file transport event. 162 | * 163 | * @param eventId eventId return by sign 164 | * @param groupId group id 165 | * @return file and block information 166 | * @throws BrokerException broker exception 167 | */ 168 | FileChunksMetaPlus verify(String eventId, String groupId) throws BrokerException; 169 | 170 | /** 171 | * get DiskFiles. 172 | * 173 | * @return DiskFiles 174 | */ 175 | DiskFiles getDiskFiles(); 176 | 177 | /** 178 | * generate pem key pair. 179 | * 180 | * @param filePath output pem file path 181 | * @throws BrokerException BrokerException 182 | */ 183 | void genPemFile(String filePath) throws BrokerException; 184 | 185 | /** 186 | * Check if the receiver end has a file. 187 | * 188 | * @param fileName file name 189 | * @param topic topic name 190 | * @param groupId group id 191 | * @return is file exist 192 | * @throws BrokerException BrokerException 193 | */ 194 | boolean isFileExist(String fileName, String topic, String groupId) throws BrokerException; 195 | } 196 | ``` 197 | 198 | ### 代码样例 199 | 200 | ```java 201 | public static void main(String[] args) { 202 | try { 203 | FiscoConfig fiscoConfig = new FiscoConfig(); 204 | fiscoConfig.load(""); 205 | 206 | IWeEventFileClient weEventFileClient = IWeEventFileClient.build("1", "./logs", 1024 * 1024, fiscoConfig); 207 | String topicName = "com.weevent.file"; 208 | 209 | // 订阅文件,接收到的文件存到"./logs"目录中 210 | weEventFileClient.openTransport4Receiver(topicName, new IWeEventFileClient.FileListener() { 211 | @Override 212 | public void onFile(String topicName, String fileName) { 213 | // 接收到文件,业务处理中 214 | } 215 | 216 | @Override 217 | public void onException(Throwable e) { 218 | e.printStackTrace(); 219 | } 220 | }); 221 | 222 | // 发布文件"log4j2.xml" 223 | weEventFileClient.openTransport4Sender(topicName); 224 | FileChunksMeta fileChunksMeta = weEventFileClient.publishFile(topicName, 225 | new File("src/main/resources/log4j2.xml").getAbsolutePath(), true); 226 | 227 | // 对文件传输事件上链(可选) 228 | SendResult sendResult = weEventFileClient.sign(fileChunksMeta); 229 | 230 | // 验证文件传输事件(可选) 231 | FileChunksMetaPlus fileChunksMetaPlus = weEventFileClient.verify(sendResult.getEventId(), this.groupId); 232 | 233 | } catch (Exception e) { 234 | e.printStackTrace(); 235 | } 236 | } 237 | ``` 238 | -------------------------------------------------------------------------------- /docs/protocol/weevent-jms-sdk.md: -------------------------------------------------------------------------------- 1 | ## Java JMS SDK 2 | 本节介绍如何以符合`JMS`规范,将核心的发布订阅功能以`jar`包形式直接集成到业务服务里。 3 | 4 | ### 前置条件 5 | 6 | - Broker模块 7 | 8 | 必选配置,通过`Broker`访问区块链。 9 | 10 | 具体安装步骤,请参见[Broker模块安装](../install/module/broker.html)。 11 | 12 | ### 集成SDK 13 | 14 | - gradle依赖 15 | ```groovy 16 | implement 'com.webank.weevent:weevent-jms:1.6.0' 17 | ``` 18 | - maven依赖 19 | ```xml 20 | 21 | com.webank.weevent 22 | weevent-jms 23 | 1.6.0 24 | 25 | ``` 26 | 27 | ### 代码样例 28 | 29 | ```java 30 | public static void main(String[] args) throws JMSException, InterruptedException { 31 | private final static String topicName = "com.weevent.test"; 32 | private final static String defaultBrokerUrl = "http://localhost:7000/weevent-broker"; 33 | 34 | // get topic connection 35 | TopicConnectionFactory connectionFactory = new WeEventConnectionFactory(defaultBrokerUrl); 36 | TopicConnection connection = connectionFactory.createTopicConnection(); 37 | 38 | // start connection 39 | connection.start(); 40 | // create session 41 | TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 42 | 43 | // create topic 44 | Topic topic = session.createTopic(topicName); 45 | 46 | // create subscriber 47 | TopicSubscriber subscriber = session.createSubscriber(topic); 48 | // create publisher 49 | TopicPublisher publisher = session.createPublisher(topic); 50 | 51 | // create listener 52 | subscriber.setMessageListener(message -> { 53 | BytesMessage msg = (BytesMessage) message; 54 | try { 55 | byte[] data = new byte[(int) msg.getBodyLength()]; 56 | msg.readBytes(data); 57 | System.out.println("received: " + new String(data, StandardCharsets.UTF_8)); 58 | } catch (JMSException e) { 59 | e.printStackTrace(); 60 | } 61 | }); 62 | 63 | // send message 64 | BytesMessage msg = session.createBytesMessage(); 65 | msg.writeBytes(("hello WeEvent").getBytes(StandardCharsets.UTF_8)); 66 | publisher.publish(msg); 67 | 68 | System.out.print("send done."); 69 | 70 | Thread.sleep(3000L); 71 | connection.close(); 72 | } 73 | ``` 74 | 75 | 完整的代码请参见[Java JMS SDK代码样例](https://github.com/WeBankBlockchain/WeEvent/blob/master/weevent-jms/src/test/java/com/webank/weevent/jms/JMSSample.java) 。 76 | -------------------------------------------------------------------------------- /docs/protocol/weevent-sample.md: -------------------------------------------------------------------------------- 1 | ## WeEvent-Sample 2 | `WeEvent-Sample`以命令行的形式,提供创建`topic`,发布订阅,查看容量等功能的体验。 3 | 4 | ### 前置条件 5 | 6 | 已经安装、部署成功,并启动`WeEvent`服务,`WeEvent`服务[快速安装](../install/quickinstall.md), 7 | 8 | ### 下载`WeEvent-Sample` 9 | 10 | ```shell 11 | $ cd /tmp/ 12 | $ git clone https://github.com/WeBankBlockchain/WeEvent-Sample.git 13 | ``` 14 | 15 | ### 配置与构建 16 | - 修改配置 17 | 18 | 修改连接broker服务的url地址 (快速安装部署`WeEvent`服务的url) 19 | 20 | ```shell 21 | $ cd /tmp/WeEvent-Sample 22 | $ vi /tmp/WeEvent-Sample/src/main/resources/application.properties 23 | ``` 24 | 25 | - 构建 26 | ```shell 27 | $ chmod +x *.sh gradlew && dos2unix *.sh gradlew 28 | $ ./build.sh 29 | ``` 30 | 31 | 构建成功后,输出有如下关键字: 32 | ``` 33 | begin to build WeEvent-Sample. 34 | build WeEvent-Sample success. 35 | ``` 36 | 37 | ### 命令行方式使用 38 | 39 | - 查看群组`groupId`列表 40 | ```shell 41 | $ ./command.sh listGroup 42 | $ listGroup result: {"code":0,"message":"success","data":["1","2","3"]} 43 | ``` 44 | 45 | - 创建`topic` 46 | 47 | ```shell 48 | $ ./command.sh open 1 com.weevent.test 49 | $ open topic:[com.weevent.test] success. 50 | ``` 51 | - 命令行参数说明: 52 | 53 | - 1 : 代表群组`id`,参考查看群组`groupId`列表返回的群组列表 54 | - com.weevent.test : `topic`名称 55 | 56 | - 订阅`topic` 57 | 58 | ```shell 59 | $ ./command.sh subscribe 1 com.weevent.test 60 | $ subscribe topic:[com.weevent.test] success, subscribeId:9904ac30-2cef-48c7-b72a-fc7c460cc3ed 61 | ``` 62 | 63 | - 发布事件 64 | 65 | 说明:发布和订阅存在于不同的客户端,所以这里需要重新开一个新的窗口。 66 | 67 | ```shell 68 | $ cd /tmp/WeEvent-Sample 69 | $ ./command.sh publish 1 com.weevent.test hello 70 | $ publish event by topic:[com.weevent.test] success, sendResult:SendResult(status=SUCCESS, topic=com.weevent.test, eventId=317e7c4c-9-42) 71 | ``` 72 | 73 | 订阅方的客户端会收到发布的事件 74 | ```shell 75 | $ received event: WeEvent{topic='com.weevent.test', content.length=5, eventID='317e7c4c-9-42', extensions={weevent-plus={"timestamp":1596794003341,"height":42,"txHash":"0x74c00fe18074a023eb32331737eeef49e28d8c05058392b02f1d0ae114cef45a","sender":"0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3"}}} 76 | $ event content: hello 77 | ``` 78 | 79 | - 命令行参数说明: 80 | 81 | - 1 : 代表群组`id`,参考查看群组`groupId`列表返回的群组列表 82 | - com.weevent.test : `topic`名称 83 | - hello : 发布事件的内容 84 | 85 | - 查看事件详情 86 | ```shell 87 | $ ./command.sh getEvent 1 317e7c4c-9-42 88 | $ getEvent success, event:WeEvent{topic='com.weevent.test', content.length=5, eventID='317e7c4c-9-42', extensions={weevent-plus={"timestamp":1596794003341,"height":42,"txHash":"0x74c00fe18074a023eb32331737eeef49e28d8c05058392b02f1d0ae114cef45a","sender":"0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3"}}} 89 | ``` 90 | 91 | - 命令行参数说明: 92 | 93 | - 1 : 代表群组`id`,参考查看群组`groupId`列表返回的群组列表 94 | - 317e7c4c-9-42 : `eventId`,发布事件成功后,会返回该事件的`eventId` 95 | 96 | - 查看`topic`详情 97 | ```shell 98 | $ ./command.sh status 1 com.weevent.test 99 | $ get topic info success, topicInfo:TopicInfo(topicName=com.weevent.test, topicAddress=null, senderAddress=0x64fa644d2a694681bd6addd6c5e36cccd8dcdde3, createdTimestamp=1596681636529, sequenceNumber=9, blockNumber=42, lastTimestamp=1596794003341, lastSender=null, lastBlock=null) 100 | ``` 101 | 102 | - 查看节点容量 103 | ```shell 104 | $ ./command.sh general 1 105 | $ general result: {"code":0,"message":"success","data":{"nodeCount":4,"transactionCount":42,"latestBlock":42}} 106 | ``` 107 | 108 | - 文件传输 109 | 110 | 说明:发送方和订阅方存在于不同的客户端,所以这里需要重新开一个新的窗口。需要提前开启订阅,发送方才能发送文件 111 | 112 | 接收方开启订阅,等待发送方发送文件 113 | ```shell 114 | $ ./command.sh receiveFile 1 com.weevent.test 115 | ``` 116 | 117 | 发送方发送文件 118 | ```shell 119 | $ cd /tmp/WeEvent-Sample 120 | $ ./command.sh sendFile 1 com.weevent.test test.txt 121 | $ sendFile success, fileChunksMeta:{"fileId":"bbd8a9be0ba24103a6e39b9ebcd40502","fileName":"test.txt","fileSize":59,"fileMd5":"53cacd61992b21b9cd2d52ad5628ec52","topic":"com.weevent.test","groupId":"1","overwrite":true,"chunkSize":1048576,"chunkNum":1,"chunkStatus":"AQ==","startTime":1605166915} 122 | ``` 123 | 124 | 订阅方的客户端会收到发送方的文件,接收方收到的文件默认存放在 ./received 路径下,可以修改 125 | ```shell 126 | $ ./command.sh receiveFile 1 com.weevent.test 127 | $ ./received/test.txt 128 | ``` 129 | 130 | - 命令行参数说明: 131 | 132 | - 1 : 代表群组`id`,参考查看群组`groupId`列表返回的群组列表 133 | - com.weevent.test : `topic`名称 134 | - test.txt : `filePath`发送方需发送的文件路径 135 | -------------------------------------------------------------------------------- /docs/scarino/classic.md: -------------------------------------------------------------------------------- 1 | ## 典型场景 2 | `WeEvent`作为一个事件中间件,属于`MOM`编程实践的一部分。理论上,使用传统消息队列`Message Queue`的场景,都可以使用`WeEvent`代替。`WeEvent`支持的多种接入协议如`STOMP`协议,也使这种切换变的更简单和方便。 3 | 4 | 相比传统`MQ`,`WeEvent`是去中心化的,更加关注信任,访问安全,数据不可篡改等特性。非常适合应用在跨组织,跨机构的合作。 5 | 6 | - 传统MQ模式如何转到WeEvent 7 | 8 | `WeEvent`的发布订阅机制、`API`定义、访问协议(如`STOMP`)和传统的`MQ`是一致的。很容易切换。 9 | 10 | - 传统RPC模式如何转到WeEvent 11 | 12 | 一个种方案是,业务程序做一些调整,以适应`MOM`编程范式; 13 | 14 | 另一种改动比较小的方案是,在数据库上建立`trigger`,从数据库这一层将数据及其变化桥接到`WeEvent`上来。 15 | 16 | - 区块链合约与传统编程语言的结合 17 | 18 | 现有技术条件下,区块链合约开发和传统编程之间还存在裂痕。虽然各种区块链技术都有针对传统编程语言的适配,使得在`Java`、`JavaScript`、`GO`、`Python`中调用合约变成可能。但是在合约代码里想调用/通知到传统语言的服务还是很困难。使用`WeEvent`可以简化从合约到传统服务的数据流。 19 | 20 | -------------------------------------------------------------------------------- /docs/scarino/index.rst: -------------------------------------------------------------------------------- 1 | 应用场景 2 | ========================================= 3 | 4 | .. toctree:: 5 | :maxdepth: 1 6 | :caption: Contents: 7 | 8 | /scarino/classic 9 | /scarino/iot -------------------------------------------------------------------------------- /docs/scarino/iot.md: -------------------------------------------------------------------------------- 1 | ## 物联网接入 2 | 物联网 + 区块链,一个可信任的万物互联数据平台。 3 | 4 | 在`5G`时代,网络质量特别是延迟已经不是问题。通过`WeEvent`完全可以做到`IoT`设备间端到端的数据通知和触达,无需经过`IoT`厂商的各自内部后台服务的路由转发。 5 | 6 | 例如,A公司的`IoT`设备可以直接在终端通过接入`WeEvent`发布事件,任何其他感兴趣公司的`IoT`设备直接在终端上通过接入`WeEvent`订阅该事件。以此达到设备间的互联互通。同时在`WeEvent`的管理端`Governance`上,通过`CEP`模块自助编辑各种`IFTTT`事件流。 7 | 8 | ![IoTScarino.png](../image/IoTScarino.png) -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | docutils == 0.16 2 | sphinx == 2.2.0 3 | sphinx-rtd-theme == 0.5.2 4 | sphinx-copybutton == 0.2.6 5 | sphinx-version-warning == 1.1.2 6 | sphinx-markdown-tables == 0.0.17 7 | sphinxcontrib-mermaid == 0.6.0 8 | recommonmark == 0.5.0 9 | sphinx-notfound-page == 0.1 10 | commonmarkextensions == 0.0.5 11 | commonmark == 0.8.1 12 | git-lfs 13 | Jinja2<3.1 14 | myst-parser == 0.13.0 15 | pyyaml --------------------------------------------------------------------------------