├── .dependency_license ├── .editorconfig ├── .github └── workflows │ ├── editorconfig.yml │ ├── license.yml │ └── tests.yml ├── .gitignore ├── APACHE-2.0.txt ├── CC-BY-4.0.txt ├── DCO.txt ├── LICENSE ├── README.md ├── conf ├── gremlin-server.yaml ├── janusgraph-foundationdb-es-server.properties ├── janusgraph-foundationdb.properties └── janusgraph.sh ├── install.sh ├── pom.xml └── src ├── assembly └── dep.xml ├── main └── java │ └── org │ └── janusgraph │ └── diskstorage │ └── foundationdb │ ├── FoundationDBConfigOptions.java │ ├── FoundationDBKeyValueStore.java │ ├── FoundationDBRangeQuery.java │ ├── FoundationDBRecordAsyncIterator.java │ ├── FoundationDBRecordIterator.java │ ├── FoundationDBStoreManager.java │ └── FoundationDBTx.java └── test ├── java └── org │ └── janusgraph │ ├── FoundationDBContainer.java │ ├── blueprints │ ├── FoundationDBGraphComputerProvider.java │ ├── FoundationDBGraphProvider.java │ ├── FoundationDBMultiQueryGraphProvider.java │ ├── process │ │ ├── FoundationDBJanusGraphComputerTest.java │ │ ├── FoundationDBJanusGraphMultiQueryProcessTest.java │ │ ├── FoundationDBJanusGraphProcessTest.java │ │ └── FoundationDBProcessStandardSuite.java │ └── structure │ │ └── FoundationDBJanusGraphStructureTest.java │ ├── diskstorage │ └── foundationdb │ │ ├── FoundationDBFixedLengthKCVSTest.java │ │ ├── FoundationDBKeyValueTest.java │ │ ├── FoundationDBLogTest.java │ │ └── FoundationDBVariableLengthKCVSTest.java │ └── graphdb │ ├── database │ └── management │ │ └── FoundationDBManagementTest.java │ └── foundationdb │ ├── FoundationDBGraphConcurrentTest.java │ ├── FoundationDBGraphPerformanceMemoryTest.java │ ├── FoundationDBGraphTest.java │ ├── FoundationDBOLAPTest.java │ ├── FoundationDBOperationCountingTest.java │ └── FoundationDBPartitionGraphTest.java └── resources ├── fdb └── empty └── log4j.properties /.dependency_license: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | \.gitignore, Apache-2.0 16 | README.md, Apache-2.0 17 | DCO.txt, Apache-2.0 18 | pom.xml, Apache-2.0 19 | src/assembly/dep.xml, Apache-2.0 20 | src/test/resources/fdb/empty, Apache-2.0 21 | CC-BY-4.0.txt, Apache-2.0 22 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | root = true 16 | 17 | [*] 18 | charset = utf-8 19 | indent_style = space 20 | end_of_line = lf 21 | insert_final_newline = true 22 | trim_trailing_whitespace = true 23 | 24 | [*.java] 25 | indent_size = 4 26 | 27 | [*.xml] 28 | indent_size = 4 29 | insert_final_newline = false 30 | 31 | [*.sh] 32 | indent_size = 4 33 | 34 | [*.{yml,yaml}] 35 | indent_size = 2 36 | -------------------------------------------------------------------------------- /.github/workflows/editorconfig.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: Editorconfig 16 | 17 | on: 18 | pull_request: {} 19 | 20 | jobs: 21 | check: 22 | runs-on: ubuntu-20.04 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v2 26 | - name: Run editorconfig 27 | uses: docker://mstruebing/editorconfig-checker 28 | -------------------------------------------------------------------------------- /.github/workflows/license.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: License Validation 16 | 17 | on: 18 | pull_request: {} 19 | 20 | jobs: 21 | weasel: 22 | runs-on: ubuntu-20.04 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v2 26 | - name: Run weasel 27 | uses: docker://licenseweasel/weasel:v0.4 28 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | name: Tests 16 | 17 | on: 18 | pull_request: {} 19 | push: { branches: [ master ] } 20 | 21 | jobs: 22 | test-matrix: 23 | runs-on: ubuntu-20.04 24 | strategy: 25 | matrix: 26 | getrangemode: [list, iterator] 27 | tests: ["**/diskstorage/**", "**/graphdb/**"] 28 | steps: 29 | - uses: actions/checkout@v2 30 | - uses: actions/cache@v1 31 | with: 32 | path: ~/.m2/repository 33 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 34 | restore-keys: | 35 | ${{ runner.os }}-maven- 36 | - uses: actions/setup-java@v1 37 | with: 38 | java-version: 1.8 39 | - run: wget https://www.foundationdb.org/downloads/6.2.22/ubuntu/installers/foundationdb-clients_6.2.22-1_amd64.deb && sudo dpkg -i foundationdb-clients_6.2.22-1_amd64.deb 40 | - run: mvn clean install -Dgetrangemode=${{ matrix.getrangemode }} -Dtest="${{ matrix.tests }}" 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Compiled class file 3 | *.class 4 | 5 | # Log file 6 | *.log 7 | 8 | 9 | # Package Files # 10 | *.jar 11 | *.war 12 | *.ear 13 | *.zip 14 | *.tar.gz 15 | *.rar 16 | 17 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 18 | hs_err_pid* 19 | 20 | target/ 21 | .idea 22 | *.iml 23 | 24 | jub*.xml 25 | 26 | -------------------------------------------------------------------------------- /APACHE-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /CC-BY-4.0.txt: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | -------------------------------------------------------------------------------- /DCO.txt: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 1 Letterman Drive 6 | Suite D4700 7 | San Francisco, CA, 94129 8 | 9 | Everyone is permitted to copy and distribute verbatim copies of this 10 | license document, but changing it is not allowed. 11 | 12 | 13 | Developer's Certificate of Origin 1.1 14 | 15 | By making a contribution to this project, I certify that: 16 | 17 | (a) The contribution was created in whole or in part by me and I 18 | have the right to submit it under the open source license 19 | indicated in the file; or 20 | 21 | (b) The contribution is based upon previous work that, to the best 22 | of my knowledge, is covered under an appropriate open source 23 | license and I have the right under that license to submit that 24 | work with modifications, whether created in whole or in part 25 | by me, under the same open source license (unless I am 26 | permitted to submit under a different license), as indicated 27 | in the file; or 28 | 29 | (c) The contribution was provided directly to me by some other 30 | person who certified (a), (b) or (c) and I have not modified 31 | it. 32 | 33 | (d) I understand and agree that this project and the contribution 34 | are public and that a record of the contribution (including all 35 | personal information I submit with it, including my sign-off) is 36 | maintained indefinitely and may be redistributed consistent with 37 | this project or the open source license(s) involved. 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The JanusGraph project uses the following two licenses: 2 | 3 | * Apache Software License 2.0 (APACHE-2.0), the full terms of which can be found 4 | in the file APACHE-2.0.txt in the root of this repository, and included below 5 | * Creative Commons Attribution 4.0 International (CC-BY-4.0), the full terms of 6 | which can be found in the file CC-BY-4.0.txt in the root of this repository, 7 | and included below 8 | 9 | The JanusGraph FoundationDB driver is distributed under the following licenses, 10 | and contributions are accepted accordingly: 11 | 12 | * APACHE-2.0 license for code, including code samples in docs 13 | * CC-BY-4.0 license for documentation 14 | 15 | For convenience, copies of APACHE-2.0 and CC-BY-4.0 are included verbatim below. 16 | 17 | /==============================================================================\ 18 | | APACHE-2.0 | 19 | \==============================================================================/ 20 | 21 | Apache License 22 | Version 2.0, January 2004 23 | http://www.apache.org/licenses/ 24 | 25 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 26 | 27 | 1. Definitions. 28 | 29 | "License" shall mean the terms and conditions for use, reproduction, 30 | and distribution as defined by Sections 1 through 9 of this document. 31 | 32 | "Licensor" shall mean the copyright owner or entity authorized by 33 | the copyright owner that is granting the License. 34 | 35 | "Legal Entity" shall mean the union of the acting entity and all 36 | other entities that control, are controlled by, or are under common 37 | control with that entity. For the purposes of this definition, 38 | "control" means (i) the power, direct or indirect, to cause the 39 | direction or management of such entity, whether by contract or 40 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 41 | outstanding shares, or (iii) beneficial ownership of such entity. 42 | 43 | "You" (or "Your") shall mean an individual or Legal Entity 44 | exercising permissions granted by this License. 45 | 46 | "Source" form shall mean the preferred form for making modifications, 47 | including but not limited to software source code, documentation 48 | source, and configuration files. 49 | 50 | "Object" form shall mean any form resulting from mechanical 51 | transformation or translation of a Source form, including but 52 | not limited to compiled object code, generated documentation, 53 | and conversions to other media types. 54 | 55 | "Work" shall mean the work of authorship, whether in Source or 56 | Object form, made available under the License, as indicated by a 57 | copyright notice that is included in or attached to the work 58 | (an example is provided in the Appendix below). 59 | 60 | "Derivative Works" shall mean any work, whether in Source or Object 61 | form, that is based on (or derived from) the Work and for which the 62 | editorial revisions, annotations, elaborations, or other modifications 63 | represent, as a whole, an original work of authorship. For the purposes 64 | of this License, Derivative Works shall not include works that remain 65 | separable from, or merely link (or bind by name) to the interfaces of, 66 | the Work and Derivative Works thereof. 67 | 68 | "Contribution" shall mean any work of authorship, including 69 | the original version of the Work and any modifications or additions 70 | to that Work or Derivative Works thereof, that is intentionally 71 | submitted to Licensor for inclusion in the Work by the copyright owner 72 | or by an individual or Legal Entity authorized to submit on behalf of 73 | the copyright owner. For the purposes of this definition, "submitted" 74 | means any form of electronic, verbal, or written communication sent 75 | to the Licensor or its representatives, including but not limited to 76 | communication on electronic mailing lists, source code control systems, 77 | and issue tracking systems that are managed by, or on behalf of, the 78 | Licensor for the purpose of discussing and improving the Work, but 79 | excluding communication that is conspicuously marked or otherwise 80 | designated in writing by the copyright owner as "Not a Contribution." 81 | 82 | "Contributor" shall mean Licensor and any individual or Legal Entity 83 | on behalf of whom a Contribution has been received by Licensor and 84 | subsequently incorporated within the Work. 85 | 86 | 2. Grant of Copyright License. Subject to the terms and conditions of 87 | this License, each Contributor hereby grants to You a perpetual, 88 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 89 | copyright license to reproduce, prepare Derivative Works of, 90 | publicly display, publicly perform, sublicense, and distribute the 91 | Work and such Derivative Works in Source or Object form. 92 | 93 | 3. Grant of Patent License. Subject to the terms and conditions of 94 | this License, each Contributor hereby grants to You a perpetual, 95 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 96 | (except as stated in this section) patent license to make, have made, 97 | use, offer to sell, sell, import, and otherwise transfer the Work, 98 | where such license applies only to those patent claims licensable 99 | by such Contributor that are necessarily infringed by their 100 | Contribution(s) alone or by combination of their Contribution(s) 101 | with the Work to which such Contribution(s) was submitted. If You 102 | institute patent litigation against any entity (including a 103 | cross-claim or counterclaim in a lawsuit) alleging that the Work 104 | or a Contribution incorporated within the Work constitutes direct 105 | or contributory patent infringement, then any patent licenses 106 | granted to You under this License for that Work shall terminate 107 | as of the date such litigation is filed. 108 | 109 | 4. Redistribution. You may reproduce and distribute copies of the 110 | Work or Derivative Works thereof in any medium, with or without 111 | modifications, and in Source or Object form, provided that You 112 | meet the following conditions: 113 | 114 | (a) You must give any other recipients of the Work or 115 | Derivative Works a copy of this License; and 116 | 117 | (b) You must cause any modified files to carry prominent notices 118 | stating that You changed the files; and 119 | 120 | (c) You must retain, in the Source form of any Derivative Works 121 | that You distribute, all copyright, patent, trademark, and 122 | attribution notices from the Source form of the Work, 123 | excluding those notices that do not pertain to any part of 124 | the Derivative Works; and 125 | 126 | (d) If the Work includes a "NOTICE" text file as part of its 127 | distribution, then any Derivative Works that You distribute must 128 | include a readable copy of the attribution notices contained 129 | within such NOTICE file, excluding those notices that do not 130 | pertain to any part of the Derivative Works, in at least one 131 | of the following places: within a NOTICE text file distributed 132 | as part of the Derivative Works; within the Source form or 133 | documentation, if provided along with the Derivative Works; or, 134 | within a display generated by the Derivative Works, if and 135 | wherever such third-party notices normally appear. The contents 136 | of the NOTICE file are for informational purposes only and 137 | do not modify the License. You may add Your own attribution 138 | notices within Derivative Works that You distribute, alongside 139 | or as an addendum to the NOTICE text from the Work, provided 140 | that such additional attribution notices cannot be construed 141 | as modifying the License. 142 | 143 | You may add Your own copyright statement to Your modifications and 144 | may provide additional or different license terms and conditions 145 | for use, reproduction, or distribution of Your modifications, or 146 | for any such Derivative Works as a whole, provided Your use, 147 | reproduction, and distribution of the Work otherwise complies with 148 | the conditions stated in this License. 149 | 150 | 5. Submission of Contributions. Unless You explicitly state otherwise, 151 | any Contribution intentionally submitted for inclusion in the Work 152 | by You to the Licensor shall be under the terms and conditions of 153 | this License, without any additional terms or conditions. 154 | Notwithstanding the above, nothing herein shall supersede or modify 155 | the terms of any separate license agreement you may have executed 156 | with Licensor regarding such Contributions. 157 | 158 | 6. Trademarks. This License does not grant permission to use the trade 159 | names, trademarks, service marks, or product names of the Licensor, 160 | except as required for reasonable and customary use in describing the 161 | origin of the Work and reproducing the content of the NOTICE file. 162 | 163 | 7. Disclaimer of Warranty. Unless required by applicable law or 164 | agreed to in writing, Licensor provides the Work (and each 165 | Contributor provides its Contributions) on an "AS IS" BASIS, 166 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 167 | implied, including, without limitation, any warranties or conditions 168 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 169 | PARTICULAR PURPOSE. You are solely responsible for determining the 170 | appropriateness of using or redistributing the Work and assume any 171 | risks associated with Your exercise of permissions under this License. 172 | 173 | 8. Limitation of Liability. In no event and under no legal theory, 174 | whether in tort (including negligence), contract, or otherwise, 175 | unless required by applicable law (such as deliberate and grossly 176 | negligent acts) or agreed to in writing, shall any Contributor be 177 | liable to You for damages, including any direct, indirect, special, 178 | incidental, or consequential damages of any character arising as a 179 | result of this License or out of the use or inability to use the 180 | Work (including but not limited to damages for loss of goodwill, 181 | work stoppage, computer failure or malfunction, or any and all 182 | other commercial damages or losses), even if such Contributor 183 | has been advised of the possibility of such damages. 184 | 185 | 9. Accepting Warranty or Additional Liability. While redistributing 186 | the Work or Derivative Works thereof, You may choose to offer, 187 | and charge a fee for, acceptance of support, warranty, indemnity, 188 | or other liability obligations and/or rights consistent with this 189 | License. However, in accepting such obligations, You may act only 190 | on Your own behalf and on Your sole responsibility, not on behalf 191 | of any other Contributor, and only if You agree to indemnify, 192 | defend, and hold each Contributor harmless for any liability 193 | incurred by, or claims asserted against, such Contributor by reason 194 | of your accepting any such warranty or additional liability. 195 | 196 | END OF TERMS AND CONDITIONS 197 | 198 | APPENDIX: How to apply the Apache License to your work. 199 | 200 | To apply the Apache License to your work, attach the following 201 | boilerplate notice, with the fields enclosed by brackets "[]" 202 | replaced with your own identifying information. (Don't include 203 | the brackets!) The text should be enclosed in the appropriate 204 | comment syntax for the file format. We also recommend that a 205 | file or class name and description of purpose be included on the 206 | same "printed page" as the copyright notice for easier 207 | identification within third-party archives. 208 | 209 | Copyright 2012-2013 Aurelius LLC 210 | 211 | Licensed under the Apache License, Version 2.0 (the "License"); 212 | you may not use this file except in compliance with the License. 213 | You may obtain a copy of the License at 214 | 215 | http://www.apache.org/licenses/LICENSE-2.0 216 | 217 | Unless required by applicable law or agreed to in writing, software 218 | distributed under the License is distributed on an "AS IS" BASIS, 219 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 220 | See the License for the specific language governing permissions and 221 | limitations under the License. 222 | 223 | /==============================================================================\ 224 | | CC-BY-4.0 | 225 | \==============================================================================/ 226 | 227 | Attribution 4.0 International 228 | 229 | ======================================================================= 230 | 231 | Creative Commons Corporation ("Creative Commons") is not a law firm and 232 | does not provide legal services or legal advice. Distribution of 233 | Creative Commons public licenses does not create a lawyer-client or 234 | other relationship. Creative Commons makes its licenses and related 235 | information available on an "as-is" basis. Creative Commons gives no 236 | warranties regarding its licenses, any material licensed under their 237 | terms and conditions, or any related information. Creative Commons 238 | disclaims all liability for damages resulting from their use to the 239 | fullest extent possible. 240 | 241 | Using Creative Commons Public Licenses 242 | 243 | Creative Commons public licenses provide a standard set of terms and 244 | conditions that creators and other rights holders may use to share 245 | original works of authorship and other material subject to copyright 246 | and certain other rights specified in the public license below. The 247 | following considerations are for informational purposes only, are not 248 | exhaustive, and do not form part of our licenses. 249 | 250 | Considerations for licensors: Our public licenses are 251 | intended for use by those authorized to give the public 252 | permission to use material in ways otherwise restricted by 253 | copyright and certain other rights. Our licenses are 254 | irrevocable. Licensors should read and understand the terms 255 | and conditions of the license they choose before applying it. 256 | Licensors should also secure all rights necessary before 257 | applying our licenses so that the public can reuse the 258 | material as expected. Licensors should clearly mark any 259 | material not subject to the license. This includes other CC- 260 | licensed material, or material used under an exception or 261 | limitation to copyright. More considerations for licensors: 262 | wiki.creativecommons.org/Considerations_for_licensors 263 | 264 | Considerations for the public: By using one of our public 265 | licenses, a licensor grants the public permission to use the 266 | licensed material under specified terms and conditions. If 267 | the licensor's permission is not necessary for any reason--for 268 | example, because of any applicable exception or limitation to 269 | copyright--then that use is not regulated by the license. Our 270 | licenses grant only permissions under copyright and certain 271 | other rights that a licensor has authority to grant. Use of 272 | the licensed material may still be restricted for other 273 | reasons, including because others have copyright or other 274 | rights in the material. A licensor may make special requests, 275 | such as asking that all changes be marked or described. 276 | Although not required by our licenses, you are encouraged to 277 | respect those requests where reasonable. More_considerations 278 | for the public: 279 | wiki.creativecommons.org/Considerations_for_licensees 280 | 281 | ======================================================================= 282 | 283 | Creative Commons Attribution 4.0 International Public License 284 | 285 | By exercising the Licensed Rights (defined below), You accept and agree 286 | to be bound by the terms and conditions of this Creative Commons 287 | Attribution 4.0 International Public License ("Public License"). To the 288 | extent this Public License may be interpreted as a contract, You are 289 | granted the Licensed Rights in consideration of Your acceptance of 290 | these terms and conditions, and the Licensor grants You such rights in 291 | consideration of benefits the Licensor receives from making the 292 | Licensed Material available under these terms and conditions. 293 | 294 | 295 | Section 1 -- Definitions. 296 | 297 | a. Adapted Material means material subject to Copyright and Similar 298 | Rights that is derived from or based upon the Licensed Material 299 | and in which the Licensed Material is translated, altered, 300 | arranged, transformed, or otherwise modified in a manner requiring 301 | permission under the Copyright and Similar Rights held by the 302 | Licensor. For purposes of this Public License, where the Licensed 303 | Material is a musical work, performance, or sound recording, 304 | Adapted Material is always produced where the Licensed Material is 305 | synched in timed relation with a moving image. 306 | 307 | b. Adapter's License means the license You apply to Your Copyright 308 | and Similar Rights in Your contributions to Adapted Material in 309 | accordance with the terms and conditions of this Public License. 310 | 311 | c. Copyright and Similar Rights means copyright and/or similar rights 312 | closely related to copyright including, without limitation, 313 | performance, broadcast, sound recording, and Sui Generis Database 314 | Rights, without regard to how the rights are labeled or 315 | categorized. For purposes of this Public License, the rights 316 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 317 | Rights. 318 | 319 | d. Effective Technological Measures means those measures that, in the 320 | absence of proper authority, may not be circumvented under laws 321 | fulfilling obligations under Article 11 of the WIPO Copyright 322 | Treaty adopted on December 20, 1996, and/or similar international 323 | agreements. 324 | 325 | e. Exceptions and Limitations means fair use, fair dealing, and/or 326 | any other exception or limitation to Copyright and Similar Rights 327 | that applies to Your use of the Licensed Material. 328 | 329 | f. Licensed Material means the artistic or literary work, database, 330 | or other material to which the Licensor applied this Public 331 | License. 332 | 333 | g. Licensed Rights means the rights granted to You subject to the 334 | terms and conditions of this Public License, which are limited to 335 | all Copyright and Similar Rights that apply to Your use of the 336 | Licensed Material and that the Licensor has authority to license. 337 | 338 | h. Licensor means the individual(s) or entity(ies) granting rights 339 | under this Public License. 340 | 341 | i. Share means to provide material to the public by any means or 342 | process that requires permission under the Licensed Rights, such 343 | as reproduction, public display, public performance, distribution, 344 | dissemination, communication, or importation, and to make material 345 | available to the public including in ways that members of the 346 | public may access the material from a place and at a time 347 | individually chosen by them. 348 | 349 | j. Sui Generis Database Rights means rights other than copyright 350 | resulting from Directive 96/9/EC of the European Parliament and of 351 | the Council of 11 March 1996 on the legal protection of databases, 352 | as amended and/or succeeded, as well as other essentially 353 | equivalent rights anywhere in the world. 354 | 355 | k. You means the individual or entity exercising the Licensed Rights 356 | under this Public License. Your has a corresponding meaning. 357 | 358 | 359 | Section 2 -- Scope. 360 | 361 | a. License grant. 362 | 363 | 1. Subject to the terms and conditions of this Public License, 364 | the Licensor hereby grants You a worldwide, royalty-free, 365 | non-sublicensable, non-exclusive, irrevocable license to 366 | exercise the Licensed Rights in the Licensed Material to: 367 | 368 | a. reproduce and Share the Licensed Material, in whole or 369 | in part; and 370 | 371 | b. produce, reproduce, and Share Adapted Material. 372 | 373 | 2. Exceptions and Limitations. For the avoidance of doubt, where 374 | Exceptions and Limitations apply to Your use, this Public 375 | License does not apply, and You do not need to comply with 376 | its terms and conditions. 377 | 378 | 3. Term. The term of this Public License is specified in Section 379 | 6(a). 380 | 381 | 4. Media and formats; technical modifications allowed. The 382 | Licensor authorizes You to exercise the Licensed Rights in 383 | all media and formats whether now known or hereafter created, 384 | and to make technical modifications necessary to do so. The 385 | Licensor waives and/or agrees not to assert any right or 386 | authority to forbid You from making technical modifications 387 | necessary to exercise the Licensed Rights, including 388 | technical modifications necessary to circumvent Effective 389 | Technological Measures. For purposes of this Public License, 390 | simply making modifications authorized by this Section 2(a) 391 | (4) never produces Adapted Material. 392 | 393 | 5. Downstream recipients. 394 | 395 | a. Offer from the Licensor -- Licensed Material. Every 396 | recipient of the Licensed Material automatically 397 | receives an offer from the Licensor to exercise the 398 | Licensed Rights under the terms and conditions of this 399 | Public License. 400 | 401 | b. No downstream restrictions. You may not offer or impose 402 | any additional or different terms or conditions on, or 403 | apply any Effective Technological Measures to, the 404 | Licensed Material if doing so restricts exercise of the 405 | Licensed Rights by any recipient of the Licensed 406 | Material. 407 | 408 | 6. No endorsement. Nothing in this Public License constitutes or 409 | may be construed as permission to assert or imply that You 410 | are, or that Your use of the Licensed Material is, connected 411 | with, or sponsored, endorsed, or granted official status by, 412 | the Licensor or others designated to receive attribution as 413 | provided in Section 3(a)(1)(A)(i). 414 | 415 | b. Other rights. 416 | 417 | 1. Moral rights, such as the right of integrity, are not 418 | licensed under this Public License, nor are publicity, 419 | privacy, and/or other similar personality rights; however, to 420 | the extent possible, the Licensor waives and/or agrees not to 421 | assert any such rights held by the Licensor to the limited 422 | extent necessary to allow You to exercise the Licensed 423 | Rights, but not otherwise. 424 | 425 | 2. Patent and trademark rights are not licensed under this 426 | Public License. 427 | 428 | 3. To the extent possible, the Licensor waives any right to 429 | collect royalties from You for the exercise of the Licensed 430 | Rights, whether directly or through a collecting society 431 | under any voluntary or waivable statutory or compulsory 432 | licensing scheme. In all other cases the Licensor expressly 433 | reserves any right to collect such royalties. 434 | 435 | 436 | Section 3 -- License Conditions. 437 | 438 | Your exercise of the Licensed Rights is expressly made subject to the 439 | following conditions. 440 | 441 | a. Attribution. 442 | 443 | 1. If You Share the Licensed Material (including in modified 444 | form), You must: 445 | 446 | a. retain the following if it is supplied by the Licensor 447 | with the Licensed Material: 448 | 449 | i. identification of the creator(s) of the Licensed 450 | Material and any others designated to receive 451 | attribution, in any reasonable manner requested by 452 | the Licensor (including by pseudonym if 453 | designated); 454 | 455 | ii. a copyright notice; 456 | 457 | iii. a notice that refers to this Public License; 458 | 459 | iv. a notice that refers to the disclaimer of 460 | warranties; 461 | 462 | v. a URI or hyperlink to the Licensed Material to the 463 | extent reasonably practicable; 464 | 465 | b. indicate if You modified the Licensed Material and 466 | retain an indication of any previous modifications; and 467 | 468 | c. indicate the Licensed Material is licensed under this 469 | Public License, and include the text of, or the URI or 470 | hyperlink to, this Public License. 471 | 472 | 2. You may satisfy the conditions in Section 3(a)(1) in any 473 | reasonable manner based on the medium, means, and context in 474 | which You Share the Licensed Material. For example, it may be 475 | reasonable to satisfy the conditions by providing a URI or 476 | hyperlink to a resource that includes the required 477 | information. 478 | 479 | 3. If requested by the Licensor, You must remove any of the 480 | information required by Section 3(a)(1)(A) to the extent 481 | reasonably practicable. 482 | 483 | 4. If You Share Adapted Material You produce, the Adapter's 484 | License You apply must not prevent recipients of the Adapted 485 | Material from complying with this Public License. 486 | 487 | 488 | Section 4 -- Sui Generis Database Rights. 489 | 490 | Where the Licensed Rights include Sui Generis Database Rights that 491 | apply to Your use of the Licensed Material: 492 | 493 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 494 | to extract, reuse, reproduce, and Share all or a substantial 495 | portion of the contents of the database; 496 | 497 | b. if You include all or a substantial portion of the database 498 | contents in a database in which You have Sui Generis Database 499 | Rights, then the database in which You have Sui Generis Database 500 | Rights (but not its individual contents) is Adapted Material; and 501 | 502 | c. You must comply with the conditions in Section 3(a) if You Share 503 | all or a substantial portion of the contents of the database. 504 | 505 | For the avoidance of doubt, this Section 4 supplements and does not 506 | replace Your obligations under this Public License where the Licensed 507 | Rights include other Copyright and Similar Rights. 508 | 509 | 510 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 511 | 512 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 513 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 514 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 515 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 516 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 517 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 518 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 519 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 520 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 521 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 522 | 523 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 524 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 525 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 526 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 527 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 528 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 529 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 530 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 531 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 532 | 533 | c. The disclaimer of warranties and limitation of liability provided 534 | above shall be interpreted in a manner that, to the extent 535 | possible, most closely approximates an absolute disclaimer and 536 | waiver of all liability. 537 | 538 | 539 | Section 6 -- Term and Termination. 540 | 541 | a. This Public License applies for the term of the Copyright and 542 | Similar Rights licensed here. However, if You fail to comply with 543 | this Public License, then Your rights under this Public License 544 | terminate automatically. 545 | 546 | b. Where Your right to use the Licensed Material has terminated under 547 | Section 6(a), it reinstates: 548 | 549 | 1. automatically as of the date the violation is cured, provided 550 | it is cured within 30 days of Your discovery of the 551 | violation; or 552 | 553 | 2. upon express reinstatement by the Licensor. 554 | 555 | For the avoidance of doubt, this Section 6(b) does not affect any 556 | right the Licensor may have to seek remedies for Your violations 557 | of this Public License. 558 | 559 | c. For the avoidance of doubt, the Licensor may also offer the 560 | Licensed Material under separate terms or conditions or stop 561 | distributing the Licensed Material at any time; however, doing so 562 | will not terminate this Public License. 563 | 564 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 565 | License. 566 | 567 | 568 | Section 7 -- Other Terms and Conditions. 569 | 570 | a. The Licensor shall not be bound by any additional or different 571 | terms or conditions communicated by You unless expressly agreed. 572 | 573 | b. Any arrangements, understandings, or agreements regarding the 574 | Licensed Material not stated herein are separate from and 575 | independent of the terms and conditions of this Public License. 576 | 577 | 578 | Section 8 -- Interpretation. 579 | 580 | a. For the avoidance of doubt, this Public License does not, and 581 | shall not be interpreted to, reduce, limit, restrict, or impose 582 | conditions on any use of the Licensed Material that could lawfully 583 | be made without permission under this Public License. 584 | 585 | b. To the extent possible, if any provision of this Public License is 586 | deemed unenforceable, it shall be automatically reformed to the 587 | minimum extent necessary to make it enforceable. If the provision 588 | cannot be reformed, it shall be severed from this Public License 589 | without affecting the enforceability of the remaining terms and 590 | conditions. 591 | 592 | c. No term or condition of this Public License will be waived and no 593 | failure to comply consented to unless expressly agreed to by the 594 | Licensor. 595 | 596 | d. Nothing in this Public License constitutes or may be interpreted 597 | as a limitation upon, or waiver of, any privileges and immunities 598 | that apply to the Licensor or You, including from the legal 599 | processes of any jurisdiction or authority. 600 | 601 | 602 | ======================================================================= 603 | 604 | Creative Commons is not a party to its public 605 | licenses. Notwithstanding, Creative Commons may elect to apply one of 606 | its public licenses to material it publishes and in those instances 607 | will be considered the “Licensor.” The text of the Creative Commons 608 | public licenses is dedicated to the public domain under the CC0 Public 609 | Domain Dedication. Except for the limited purpose of indicating that 610 | material is shared under a Creative Commons public license or as 611 | otherwise permitted by the Creative Commons policies published at 612 | creativecommons.org/policies, Creative Commons does not authorize the 613 | use of the trademark "Creative Commons" or any other trademark or logo 614 | of Creative Commons without its prior written consent including, 615 | without limitation, in connection with any unauthorized modifications 616 | to any of its public licenses or any other arrangements, 617 | understandings, or agreements concerning use of licensed material. For 618 | the avoidance of doubt, this paragraph does not form part of the 619 | public licenses. 620 | 621 | Creative Commons may be contacted at creativecommons.org. 622 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FoundationDB Storage Adapter for JanusGraph 2 | 3 | [![Downloads][downloads-shield]][downloads-link] 4 | [![Build Status][actions-shield]][actions-link] 5 | 6 | [actions-shield]: https://img.shields.io/github/workflow/status/JanusGraph/janusgraph-foundationdb/TESTS 7 | [actions-link]: https://github.com/JanusGraph/janusgraph-foundationdb/actions 8 | [downloads-shield]: https://img.shields.io/github/downloads/JanusGraph/janusgraph-foundationdb/total.svg 9 | [downloads-link]: https://github.com/JanusGraph/janusgraph-foundationdb/releases 10 | 11 | [JanusGraph](http://janusgraph.org) is an [Apache TinkerPop](http://tinkerpop.apache.org) enabled graph database that supports a variety of storage and indexing backends. This project adds [FoundationDB](http://foundationdb.org) to the supported list of backends. FoundationDB is a distributed, ACID key-value store. 12 | 13 | # Features 14 | 15 | JanusGraph, coupled with the FoundationDB storage adapter provides the following unique features: 16 | 17 | * High availability 18 | * ACID transactions 19 | 20 | # Compatibility Matrix 21 | 22 | |FDB Storage Adapter|JanusGraph|FoundationDB| 23 | |-:|-:|-:| 24 | |0.1.0|0.5.2|6.2.22| 25 | 26 | # Getting started 27 | 28 | The FoundationDB storage adapter requires a single FoundationDB instance or cluster and the FoundationDB client libraries. Downloads for server and client can be found [here](https://apple.github.io/foundationdb/downloads.html). 29 | 30 | ## Setting up FoundationDB 31 | 32 | Mac install instructions can be found [here](https://apple.github.io/foundationdb/getting-started-mac.html) and Linux [here](https://apple.github.io/foundationdb/getting-started-linux.html). 33 | 34 | ## Installing the adapter from a binary release 35 | Binary releases can be found on [GitHub](http://github.com/JanusGraph/janusgraph-foundationdb/releases). 36 | 37 | This installation procedure will copy the necessary libraries, properties, and Gremlin Server configuration files into your JanusGraph installation. 38 | 39 | 1. Download the JanusGraph [release](https://github.com/JanusGraph/janusgraph/releases) that is compatible up with the FoundationDB storage adapter. 40 | 2. Download the desired FoundationDB storage adapter release. 41 | 3. Unzip the storage adapter zip file and run `./install.sh $YOUR_JANUSGRAPH_INSTALL_DIRECTORY` 42 | 43 | Assuming you have a FoundationDB cluster up and running, you can connect from the Gremlin console by running: 44 | 45 | `gremlin> graph = JanusGraphFactory.open('conf/janusgraph-foundationdb.properties')` 46 | 47 | To start Gremlin Server run `gremlin-server.sh` directly or `bin/janusgraph.sh start` which will also start a local Elasticsearch instance. 48 | 49 | ## Installing from source 50 | 51 | Follow these steps if you'd like to use the latest version built from source. 52 | 1. Clone the repository. 53 | `git clone http://github.com/JanusGraph/janusgraph-foundationdb` 54 | 2. Build the distribution package. 55 | `mvn package -DskipTests` 56 | 3. Follow the binary installation steps starting at step 3. 57 | 58 | # Configuration Options 59 | 60 | |Property|Description|Default| 61 | |-|-|-| 62 | |`storage.fdb.directory`|Name of the JanusGraph storage directory in FoundationDB.|`janusgraph`| 63 | |`storage.fdb.version`|The FoundationDB client version.|`5.2.0`| 64 | |`storage.fdb.cluster-file-path`|The location of the `fdb.cluster` file.|`/etc/foundationdb/fdb.cluster`| 65 | |`storage.fdb.isolation-level`|The three options are `serializable`, `read_committed_no_write`, and `read_committed_with_write`.|`serializable`| 66 | |`storage.fdb.get-range-mode`|The two options are `list` and `iterator`.|`list`| 67 | 68 | ## Isolation Levels 69 | FoundationDB provides serializable isolation under a specific set of [constraints](https://apple.github.io/foundationdb/known-limitations.html#current-limitations). Namely transactions will fail if they take longer than 5 seconds or read/write more than 10,000,000 bytes. This adapter allows the user to relax the how JanusGraph uses FoundationDB transactions and to spread a single JanusGraph transaction over more than one FoundationDB transaction. `read_committed_no_write` allows reads to be spread across more than one transasction, but will fail any writes that are attempted outside of the first transaction period. `read_committed_with_write` allows reads and writes to extend over more than one single transaction. If this option is selected, invariants may be broken and the system will behave similarily to an eventually consistent system. 70 | 71 | ## GetRange Modes 72 | FoundationDB provides asynchronous iterator for [range query](https://apple.github.io/foundationdb/developer-guide.html#range-reads), with the following advantages compared to synchronous iterator: on-demand data stream pulling, better memory efficiency, and better thread parallelism management to support MultiQuery in JanusGraph. When the `get-range-mode` is chosen with option of `iterator`, asynchronous iterator is turned on. The default option of `get-range-mode` is `list` currently, with which synchronous iterator is chosen. 73 | 74 | The `get-range-mode` and the isolation level can be chosen independently in the storage plugin's configuration options. 75 | -------------------------------------------------------------------------------- /conf/gremlin-server.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | host: 0.0.0.0 16 | port: 8182 17 | scriptEvaluationTimeout: 30000 18 | channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer 19 | graphs: 20 | graph: conf/gremlin-server/janusgraph-foundationdb-es-server.properties 21 | scriptEngines: 22 | gremlin-groovy: 23 | plugins: 24 | org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {} 25 | org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {} 26 | org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {} 27 | org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]} 28 | org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/empty-sample.groovy]} 29 | serializers: 30 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} 31 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }} 32 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} 33 | # Older serialization versions for backwards compatibility: 34 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} 35 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} 36 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }} 37 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} 38 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }} 39 | - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }} 40 | processors: 41 | - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }} 42 | - { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }} 43 | metrics: 44 | consoleReporter: {enabled: true, interval: 180000}, 45 | csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv}, 46 | jmxReporter: {enabled: true}, 47 | slf4jReporter: {enabled: true, interval: 180000}, 48 | gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST}, 49 | graphiteReporter: {enabled: false, interval: 180000} 50 | maxInitialLineLength: 4096 51 | maxHeaderSize: 8192 52 | maxChunkSize: 8192 53 | maxContentLength: 65536 54 | maxAccumulationBufferComponents: 1024 55 | resultIterationBatchSize: 64 56 | writeBufferLowWaterMark: 32768 57 | writeBufferHighWaterMark: 65536 58 | -------------------------------------------------------------------------------- /conf/janusgraph-foundationdb-es-server.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | gremlin.graph=org.janusgraph.core.JanusGraphFactory 16 | # JanusGraph configuration sample: FoundationDB 17 | # 18 | # This file connects to a local FoundationDB instance. 19 | # FoundationDB must already be started before starting JanusGraph 20 | # with this file. 21 | 22 | # The primary persistence provider used by JanusGraph. This is required. 23 | # It should be set one of JanusGraph's built-in shorthand names for its 24 | # standard storage backends (shorthands: berkeleyje, cassandrathrift, 25 | # cassandra, astyanax, embeddedcassandra, cql, hbase, foundationdb, 26 | # inmemory) or to the full package and classname of a custom/third-party 27 | # StoreManager implementation. 28 | # 29 | # Default: (no default value) 30 | # Data Type: String 31 | # Mutability: LOCAL 32 | storage.backend=org.janusgraph.diskstorage.foundationdb.FoundationDBStoreManager 33 | 34 | # Whether to enable JanusGraph's database-level cache, which is shared 35 | # across all transactions. Enabling this option speeds up traversals by 36 | # holding hot graph elements in memory, but also increases the likelihood 37 | # of reading stale data. Disabling it forces each transaction to 38 | # independently fetch graph elements from storage before reading/writing 39 | # them. 40 | # 41 | # Default: false 42 | # Data Type: Boolean 43 | # Mutability: MASKABLE 44 | cache.db-cache = false 45 | 46 | # How long, in milliseconds, database-level cache will keep entries after 47 | # flushing them. This option is only useful on distributed storage 48 | # backends that are capable of acknowledging writes without necessarily 49 | # making them immediately visible. 50 | # 51 | # Default: 50 52 | # Data Type: Integer 53 | # Mutability: GLOBAL_OFFLINE 54 | # 55 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in 56 | # JanusGraph's storage backend. After starting the database for the first 57 | # time, this file's copy of this setting is ignored. Use JanusGraph's 58 | # Management System to read or modify this value after bootstrapping. 59 | cache.db-cache-clean-wait = 20 60 | 61 | # Default expiration time, in milliseconds, for entries in the 62 | # database-level cache. Entries are evicted when they reach this age even 63 | # if the cache has room to spare. Set to 0 to disable expiration (cache 64 | # entries live forever or until memory pressure triggers eviction when set 65 | # to 0). 66 | # 67 | # Default: 10000 68 | # Data Type: Long 69 | # Mutability: GLOBAL_OFFLINE 70 | # 71 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in 72 | # JanusGraph's storage backend. After starting the database for the first 73 | # time, this file's copy of this setting is ignored. Use JanusGraph's 74 | # Management System to read or modify this value after bootstrapping. 75 | cache.db-cache-time = 180000 76 | 77 | # Size of JanusGraph's database level cache. Values between 0 and 1 are 78 | # interpreted as a percentage of VM heap, while larger values are 79 | # interpreted as an absolute size in bytes. 80 | # 81 | # Default: 0.3 82 | # Data Type: Double 83 | # Mutability: MASKABLE 84 | cache.db-cache-size = 0.5 85 | 86 | # Connect to an already-running ES instance on localhost 87 | 88 | # The indexing backend used to extend and optimize JanusGraph's query 89 | # functionality. This setting is optional. JanusGraph can use multiple 90 | # heterogeneous index backends. Hence, this option can appear more than 91 | # once, so long as the user-defined name between "index" and "backend" is 92 | # unique among appearances.Similar to the storage backend, this should be 93 | # set to one of JanusGraph's built-in shorthand names for its standard index 94 | # backends (shorthands: lucene, elasticsearch, es, solr) or to the full 95 | # package and classname of a custom/third-party IndexProvider 96 | # implementation. 97 | # 98 | # Default: elasticsearch 99 | # Data Type: String 100 | # Mutability: GLOBAL_OFFLINE 101 | # 102 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in JanusGraph's 103 | # storage backend. After starting the database for the first time, this 104 | # file's copy of this setting is ignored. Use JanusGraph's Management System 105 | # to read or modify this value after bootstrapping. 106 | index.search.backend=elasticsearch 107 | 108 | # The hostname or comma-separated list of hostnames of index backend 109 | # servers. This is only applicable to some index backends, such as 110 | # elasticsearch and solr. 111 | # 112 | # Default: 127.0.0.1 113 | # Data Type: class java.lang.String[] 114 | # Mutability: MASKABLE 115 | index.search.hostname=127.0.0.1 116 | 117 | # The Elasticsearch node.client option is set to this boolean value, and 118 | # the Elasticsearch node.data option is set to the negation of this value. 119 | # True creates a thin client which holds no data. False creates a regular 120 | # Elasticsearch cluster node that may store data. 121 | # 122 | # Default: true 123 | # Data Type: Boolean 124 | # Mutability: GLOBAL_OFFLINE 125 | # 126 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in JanusGraph's 127 | # storage backend. After starting the database for the first time, this 128 | # file's copy of this setting is ignored. Use JanusGraph's Management System 129 | # to read or modify this value after bootstrapping. 130 | index.search.elasticsearch.client-only=true 131 | 132 | # Or start ES inside the JanusGraph JVM 133 | #index.search.backend=elasticsearch 134 | #index.search.directory=db/es 135 | #index.search.elasticsearch.client-only=false 136 | #index.search.elasticsearch.local-mode=true 137 | 138 | # Turn on storage adapter query parallelization 139 | query.batch = true 140 | -------------------------------------------------------------------------------- /conf/janusgraph-foundationdb.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | gremlin.graph=org.janusgraph.core.JanusGraphFactory 17 | # JanusGraph configuration sample: FoundationDB 18 | # 19 | # This file connects to a local FoundationDB instance. 20 | # FoundationDB must already be started before starting JanusGraph 21 | # with this file. 22 | 23 | # The primary persistence provider used by JanusGraph. This is required. 24 | # It should be set one of JanusGraph's built-in shorthand names for its 25 | # standard storage backends (shorthands: berkeleyje, cassandrathrift, 26 | # cassandra, astyanax, embeddedcassandra, cql, hbase, foundationdb, 27 | # inmemory) or to the full package and classname of a custom/third-party 28 | # StoreManager implementation. 29 | # 30 | # Default: (no default value) 31 | # Data Type: String 32 | # Mutability: LOCAL 33 | storage.backend=org.janusgraph.diskstorage.foundationdb.FoundationDBStoreManager 34 | 35 | # Whether to enable JanusGraph's database-level cache, which is shared 36 | # across all transactions. Enabling this option speeds up traversals by 37 | # holding hot graph elements in memory, but also increases the likelihood 38 | # of reading stale data. Disabling it forces each transaction to 39 | # independently fetch graph elements from storage before reading/writing 40 | # them. 41 | # 42 | # Default: false 43 | # Data Type: Boolean 44 | # Mutability: MASKABLE 45 | cache.db-cache = false 46 | 47 | # How long, in milliseconds, database-level cache will keep entries after 48 | # flushing them. This option is only useful on distributed storage 49 | # backends that are capable of acknowledging writes without necessarily 50 | # making them immediately visible. 51 | # 52 | # Default: 50 53 | # Data Type: Integer 54 | # Mutability: GLOBAL_OFFLINE 55 | # 56 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in 57 | # JanusGraph's storage backend. After starting the database for the first 58 | # time, this file's copy of this setting is ignored. Use JanusGraph's 59 | # Management System to read or modify this value after bootstrapping. 60 | cache.db-cache-clean-wait = 20 61 | 62 | # Default expiration time, in milliseconds, for entries in the 63 | # database-level cache. Entries are evicted when they reach this age even 64 | # if the cache has room to spare. Set to 0 to disable expiration (cache 65 | # entries live forever or until memory pressure triggers eviction when set 66 | # to 0). 67 | # 68 | # Default: 10000 69 | # Data Type: Long 70 | # Mutability: GLOBAL_OFFLINE 71 | # 72 | # Settings with mutability GLOBAL_OFFLINE are centrally managed in 73 | # JanusGraph's storage backend. After starting the database for the first 74 | # time, this file's copy of this setting is ignored. Use JanusGraph's 75 | # Management System to read or modify this value after bootstrapping. 76 | cache.db-cache-time = 180000 77 | 78 | # Size of JanusGraph's database level cache. Values between 0 and 1 are 79 | # interpreted as a percentage of VM heap, while larger values are 80 | # interpreted as an absolute size in bytes. 81 | # 82 | # Default: 0.3 83 | # Data Type: Double 84 | # Mutability: MASKABLE 85 | cache.db-cache-size = 0.5 86 | 87 | # Turn on storage adapter query parallelization 88 | query.batch = true 89 | 90 | # The isolation level for the FoundationDB storage adapter. This configuration 91 | # is setup for interactive console sessions so it allows for writes that 92 | # can span more than the lifespan of one single FoundationDB transaction. 93 | # It is recommended that this be set to serializable or read_committed_no_write 94 | # for production scenarios to maintain referential integrity. 95 | storage.fdb.isolation-level=read_committed_with_write 96 | -------------------------------------------------------------------------------- /conf/janusgraph.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2020 JanusGraph Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | # Returns the absolute path of this script regardless of symlinks 19 | abs_path() { 20 | # From: http://stackoverflow.com/a/246128 21 | # - To resolve finding the directory after symlinks 22 | SOURCE="${BASH_SOURCE[0]}" 23 | while [ -h "$SOURCE" ]; do 24 | DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" 25 | SOURCE="$(readlink "$SOURCE")" 26 | [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" 27 | done 28 | echo "$( cd -P "$( dirname "$SOURCE" )" && pwd )" 29 | } 30 | 31 | BIN=`abs_path` 32 | GSRV_CONFIG_TAG=foundationdb-es 33 | : ${ELASTICSEARCH_STARTUP_TIMEOUT_S:=60} 34 | : ${ELASTICSEARCH_SHUTDOWN_TIMEOUT_S:=60} 35 | : ${ELASTICSEARCH_IP:=127.0.0.1} 36 | : ${ELASTICSEARCH_PORT:=9200} 37 | 38 | : ${GSRV_STARTUP_TIMEOUT_S:=60} 39 | : ${GSRV_SHUTDOWN_TIMEOUT_S:=60} 40 | : ${GSRV_IP:=127.0.0.1} 41 | : ${GSRV_PORT:=8182} 42 | 43 | : ${SLEEP_INTERVAL_S:=2} 44 | VERBOSE= 45 | COMMAND= 46 | 47 | # Locate the jps command. Check $PATH, then check $JAVA_HOME/bin. 48 | # This does not need to by cygpath'd. 49 | JPS= 50 | for maybejps in jps "${JAVA_HOME}/bin/jps"; do 51 | type "$maybejps" >/dev/null 2>&1 52 | if [ $? -eq 0 ]; then 53 | JPS="$maybejps" 54 | break 55 | fi 56 | done 57 | 58 | if [ -z "$JPS" ]; then 59 | echo "jps command not found. Put the JDK's jps binary on the command path." >&2 60 | exit 1 61 | fi 62 | 63 | GREMLIN_FRIENDLY_NAME='Gremlin-Server' 64 | GREMLIN_CLASS_NAME=org.apache.tinkerpop.gremlin.server.GremlinServer 65 | ES_FRIENDLY_NAME=Elasticsearch 66 | ES_CLASS_NAME=org.elasticsearch.bootstrap.Elasticsearch 67 | 68 | # wait_for_startup friendly_name host port timeout_s 69 | wait_for_startup() { 70 | local friendly_name="$1" 71 | local host="$2" 72 | local port="$3" 73 | local timeout_s="$4" 74 | 75 | local now_s=`date '+%s'` 76 | local stop_s=$(( $now_s + $timeout_s )) 77 | local status= 78 | 79 | echo -n "Connecting to $friendly_name ($host:$port)" 80 | while [ $now_s -le $stop_s ]; do 81 | echo -n . 82 | $BIN/checksocket.sh $host $port >/dev/null 2>&1 83 | if [ $? -eq 0 ]; then 84 | echo " OK (connected to $host:$port)." 85 | return 0 86 | fi 87 | sleep $SLEEP_INTERVAL_S 88 | now_s=`date '+%s'` 89 | done 90 | 91 | echo " timeout exceeded ($timeout_s seconds): could not connect to $host:$port" >&2 92 | return 1 93 | } 94 | 95 | # wait_for_shutdown friendly_name class_name timeout_s 96 | wait_for_shutdown() { 97 | local friendly_name="$1" 98 | local class_name="$2" 99 | local timeout_s="$3" 100 | 101 | local now_s=`date '+%s'` 102 | local stop_s=$(( $now_s + $timeout_s )) 103 | 104 | while [ $now_s -le $stop_s ]; do 105 | status_class "$friendly_name" $class_name >/dev/null 106 | if [ $? -eq 1 ]; then 107 | # Class not found in the jps output. Assume that it stopped. 108 | return 0 109 | fi 110 | sleep $SLEEP_INTERVAL_S 111 | now_s=`date '+%s'` 112 | done 113 | 114 | echo "$friendly_name shutdown timeout exceeded ($timeout_s seconds)" >&2 115 | return 1 116 | } 117 | 118 | start() { 119 | status_class $ES_FRIENDLY_NAME $ES_CLASS_NAME >/dev/null && status && echo "Stop services before starting" && exit 1 120 | echo "Forking Elasticsearch..." 121 | if [ -n "$VERBOSE" ]; then 122 | "$BIN"/../elasticsearch/bin/elasticsearch -d 123 | else 124 | "$BIN"/../elasticsearch/bin/elasticsearch -d >/dev/null 2>&1 125 | fi 126 | wait_for_startup Elasticsearch $ELASTICSEARCH_IP $ELASTICSEARCH_PORT $ELASTICSEARCH_STARTUP_TIMEOUT_S || { 127 | echo "See $BIN/../log/elasticsearch.log for Elasticsearch log output." >&2 128 | return 1 129 | } 130 | 131 | status_class $GREMLIN_FRIENDLY_NAME $GREMLIN_CLASS_NAME >/dev/null && status && echo "Stop services before starting" && exit 1 132 | echo "Forking Gremlin-Server..." 133 | if [ -n "$VERBOSE" ]; then 134 | "$BIN"/gremlin-server.sh conf/gremlin-server/gremlin-server.yaml & 135 | else 136 | "$BIN"/gremlin-server.sh conf/gremlin-server/gremlin-server.yaml >/dev/null 2>&1 & 137 | fi 138 | wait_for_startup 'Gremlin-Server' $GSRV_IP $GSRV_PORT $GSRV_STARTUP_TIMEOUT_S || { 139 | echo "See $BIN/../log/gremlin-server.log for Gremlin-Server log output." >&2 140 | return 1 141 | } 142 | disown 143 | 144 | echo "Run gremlin.sh to connect." >&2 145 | } 146 | 147 | stop() { 148 | kill_class $GREMLIN_FRIENDLY_NAME $GREMLIN_CLASS_NAME 149 | wait_for_shutdown $GREMLIN_FRIENDLY_NAME $GREMLIN_CLASS_NAME $GSRV_SHUTDOWN_TIMEOUT_S 150 | kill_class $ES_FRIENDLY_NAME $ES_CLASS_NAME 151 | wait_for_shutdown $ES_FRIENDLY_NAME $ES_CLASS_NAME $ELASTICSEARCH_SHUTDOWN_TIMEOUT_S 152 | } 153 | 154 | kill_class() { 155 | local p=`$JPS -l | grep "$2" | awk '{print $1}'` 156 | if [ -z "$p" ]; then 157 | echo "$1 ($2) not found in the java process table" 158 | return 159 | fi 160 | echo "Killing $1 (pid $p)..." >&2 161 | case "`uname`" in 162 | CYGWIN*) taskkill /F /PID "$p" ;; 163 | *) kill "$p" ;; 164 | esac 165 | } 166 | 167 | status_class() { 168 | local p=`$JPS -l | grep "$2" | awk '{print $1}'` 169 | if [ -n "$p" ]; then 170 | echo "$1 ($2) is running with pid $p" 171 | return 0 172 | else 173 | echo "$1 ($2) does not appear in the java process table" 174 | return 1 175 | fi 176 | } 177 | 178 | status() { 179 | status_class $GREMLIN_FRIENDLY_NAME $GREMLIN_CLASS_NAME 180 | status_class $ES_FRIENDLY_NAME $ES_CLASS_NAME 181 | } 182 | 183 | clean() { 184 | echo -n "Are you sure you want to delete all stored data and logs? [y/N] " >&2 185 | read response 186 | if [ "$response" != "y" -a "$response" != "Y" ]; then 187 | echo "Response \"$response\" did not equal \"y\" or \"Y\". Canceling clean operation." >&2 188 | return 0 189 | fi 190 | 191 | if cd "$BIN"/../db 2>/dev/null; then 192 | rm -rf es 193 | echo "Deleted data in `pwd`" >&2 194 | cd - >/dev/null 195 | else 196 | echo 'Data directory does not exist.' >&2 197 | fi 198 | 199 | if cd "$BIN"/../log; then 200 | rm -f elasticsearch*.log 201 | rm -f gremlin-server.log 202 | echo "Deleted logs in `pwd`" >&2 203 | cd - >/dev/null 204 | fi 205 | } 206 | 207 | usage() { 208 | echo "Usage: $0 [options] {start|stop|status|clean}" >&2 209 | echo " start: fork ES, and Gremlin-Server processes" >&2 210 | echo " stop: kill ES, and Gremlin-Server processes" >&2 211 | echo " status: print ES, and Gremlin-Server process status" >&2 212 | echo " clean: permanently delete all graph data (run when stopped)" >&2 213 | echo "Options:" >&2 214 | echo " -v enable logging to console in addition to logfiles" >&2 215 | } 216 | 217 | find_verb() { 218 | if [ "$1" = 'start' -o \ 219 | "$1" = 'stop' -o \ 220 | "$1" = 'clean' -o \ 221 | "$1" = 'status' ]; then 222 | COMMAND="$1" 223 | return 0 224 | fi 225 | return 1 226 | } 227 | 228 | while [ 1 ]; do 229 | if find_verb ${!OPTIND}; then 230 | OPTIND=$(($OPTIND + 1)) 231 | elif getopts 'c:v' option; then 232 | case $option in 233 | c) GSRV_CONFIG_TAG="${OPTARG}";; 234 | v) VERBOSE=yes;; 235 | *) usage; exit 1;; 236 | esac 237 | else 238 | break 239 | fi 240 | done 241 | 242 | if [ -n "$COMMAND" ]; then 243 | $COMMAND 244 | else 245 | usage 246 | exit 1 247 | fi 248 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2018 Expero Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | if [ -z "$*" ]; then 19 | echo "Please provide the path to your JanusGraph install directory" 20 | exit 0 21 | fi 22 | 23 | JANUS_INSTALL_PATH=$1 24 | JANUS_BIN_PATH=${JANUS_INSTALL_PATH}/bin 25 | JANUS_CONF_PATH=${JANUS_INSTALL_PATH}/conf 26 | JANUS_GREMLIN_SERVER_CONF=${JANUS_CONF_PATH}/gremlin-server 27 | 28 | if [ ! -d "$JANUS_INSTALL_PATH" ]; then 29 | echo "Directory ${JANUS_INSTALL_PATH} does not exist" 30 | exit 0 31 | fi 32 | 33 | cp lib/* ${JANUS_INSTALL_PATH}/ext 34 | cp conf/janusgraph-foundationdb.properties ${JANUS_CONF_PATH} 35 | cp conf/janusgraph-foundationdb-es-server.properties ${JANUS_GREMLIN_SERVER_CONF} 36 | 37 | # backup Gremlin server config 38 | mv ${JANUS_GREMLIN_SERVER_CONF}/gremlin-server.yaml ${JANUS_GREMLIN_SERVER_CONF}/gremlin-server.yaml.orig 39 | cp conf/gremlin-server.yaml ${JANUS_GREMLIN_SERVER_CONF}/gremlin-server.yaml 40 | # backup janusgraph.sh 41 | mv ${JANUS_BIN_PATH}/janusgraph.sh ${JANUS_BIN_PATH}/janusgraph.sh.orig 42 | cp conf/janusgraph.sh ${JANUS_BIN_PATH}/janusgraph.sh 43 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.janusgraph 8 | janusgraph-foundationdb 9 | 0.1.0 10 | jar 11 | JanusGraph FoundationDB Storage Adapter 12 | 13 | 14 | 3.8.1 15 | 1.8 16 | 0.5.2 17 | 6.2.22 18 | 3.2.0 19 | false 20 | true 21 | 1.15.3 22 | 23 | 24 | 25 | 26 | Ted Wilmes 27 | twilmes@gmail.com 28 | 29 | 30 | 31 | 32 | 33 | The Apache Software License, Version 2.0 34 | http://www.apache.org/licenses/LICENSE-2.0.txt 35 | 36 | 37 | 38 | 39 | 40 | org.janusgraph 41 | janusgraph-core 42 | ${janusgraph.version} 43 | 44 | 45 | org.janusgraph 46 | janusgraph-backend-testutils 47 | ${janusgraph.version} 48 | test 49 | 50 | 51 | org.janusgraph 52 | janusgraph-test 53 | ${janusgraph.version} 54 | test 55 | 56 | 57 | org.foundationdb 58 | fdb-java 59 | ${foundationdb.version} 60 | 61 | 62 | org.testcontainers 63 | testcontainers 64 | ${testcontainers.version} 65 | test 66 | 67 | 68 | org.testcontainers 69 | junit-jupiter 70 | ${testcontainers.version} 71 | test 72 | 73 | 74 | 75 | 76 | ${basedir}/target 77 | 78 | 79 | maven-compiler-plugin 80 | ${maven.compiler.plugin.version} 81 | 82 | ${jdk.version} 83 | ${jdk.version} 84 | 85 | 86 | 87 | org.apache.maven.plugins 88 | maven-dependency-plugin 89 | ${dependency.plugin.version} 90 | 91 | 92 | copy-dependencies 93 | prepare-package 94 | 95 | copy-dependencies 96 | 97 | 98 | ${project.build.directory}/lib 99 | compile 100 | 101 | 102 | 103 | 104 | 105 | maven-surefire-plugin 106 | 2.22.1 107 | 108 | none 109 | alphabetical 110 | false 111 | 112 | **/*PerformanceTest.java 113 | **/*ConcurrentTest.java 114 | **/*Groovy*Test.java 115 | **/*ComputerTest.java 116 | **/*ProcessTest.java 117 | **/*ProcessPerformanceTest.java 118 | **/*StructureTest.java 119 | 120 | ${test.skip.default} 121 | 122 | 123 | 124 | log4j.configuration 125 | file:${project.build.directory}/test-classes/log4j.properties 126 | 127 | 128 | 129 | 130 | 131 | tinkerpop-test 132 | 133 | test 134 | 135 | test 136 | 137 | false 138 | 1 139 | none 140 | 1 141 | false 142 | 143 | **/*Groovy*Test.java 144 | **/*ComputerTest.java 145 | **/*ProcessTest.java 146 | **/*ProcessPerformanceTest.java 147 | **/*StructureTest.java 148 | 149 | alphabetical 150 | ${test.skip.tp} 151 | 152 | ${project.build.directory} 153 | file:${project.build.directory}/test-classes/log4j.properties 154 | true 155 | 156 | 157 | 158 | 159 | 160 | 161 | maven-assembly-plugin 162 | 2.5.3 163 | 164 | src/assembly/dep.xml 165 | 166 | 167 | 168 | create-archive 169 | package 170 | 171 | single 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /src/assembly/dep.xml: -------------------------------------------------------------------------------- 1 | 2 | distribution 3 | 4 | zip 5 | 6 | 7 | 8 | ${project.basedir} 9 | / 10 | 11 | README* 12 | LICENSE* 13 | install.sh 14 | 15 | 16 | 17 | ${project.basedir}/conf 18 | /conf 19 | 20 | 21 | ${project.build.directory} 22 | /lib 23 | 24 | *.jar 25 | 26 | 27 | 28 | ${project.build.directory}/lib 29 | /lib 30 | 31 | *.jar 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBConfigOptions.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.configuration.ConfigNamespace; 18 | import org.janusgraph.diskstorage.configuration.ConfigOption; 19 | import org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration; 20 | import org.janusgraph.graphdb.configuration.PreInitializeConfigOptions; 21 | 22 | /** 23 | * Configuration options for the FoundationDB storage backend. 24 | * These are managed under the 'fdb' namespace in the configuration. 25 | * 26 | * @author Ted Wilmes (twilmes@gmail.com) 27 | */ 28 | @PreInitializeConfigOptions 29 | public interface FoundationDBConfigOptions { 30 | 31 | ConfigNamespace FDB_NS = new ConfigNamespace( 32 | GraphDatabaseConfiguration.STORAGE_NS, 33 | "fdb", 34 | "FoundationDB storage backend options"); 35 | 36 | ConfigOption DIRECTORY = new ConfigOption<>( 37 | FDB_NS, 38 | "directory", 39 | "The name of the JanusGraph directory in FoundationDB. It will be created if it does not exist.", 40 | ConfigOption.Type.LOCAL, 41 | "janusgraph"); 42 | 43 | ConfigOption VERSION = new ConfigOption<>( 44 | FDB_NS, 45 | "version", 46 | "The version of the FoundationDB cluster.", 47 | ConfigOption.Type.LOCAL, 48 | 620); 49 | 50 | ConfigOption CLUSTER_FILE_PATH = new ConfigOption<>( 51 | FDB_NS, 52 | "cluster-file-path", 53 | "Path to the FoundationDB cluster file", 54 | ConfigOption.Type.LOCAL, 55 | "default"); 56 | 57 | ConfigOption ISOLATION_LEVEL = new ConfigOption<>( 58 | FDB_NS, 59 | "isolation-level", 60 | "Options are serializable, read_committed_no_write, read_committed_with_write", 61 | ConfigOption.Type.LOCAL, 62 | "serializable"); 63 | 64 | ConfigOption GET_RANGE_MODE = new ConfigOption<>( 65 | FDB_NS, 66 | "get-range-mode", 67 | "The mod of executing FDB getRange, either `iterator` or `list`", 68 | ConfigOption.Type.LOCAL, 69 | "list" 70 | ); 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBKeyValueStore.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.KeyValue; 18 | import com.apple.foundationdb.LocalityUtil; 19 | import com.apple.foundationdb.async.AsyncIterator; 20 | import com.apple.foundationdb.async.CloseableAsyncIterator; 21 | import com.apple.foundationdb.directory.DirectorySubspace; 22 | import com.google.common.base.Preconditions; 23 | import org.janusgraph.diskstorage.BackendException; 24 | import org.janusgraph.diskstorage.PermanentBackendException; 25 | import org.janusgraph.diskstorage.StaticBuffer; 26 | import org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction; 27 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KVQuery; 28 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KeyValueEntry; 29 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStore; 30 | import org.janusgraph.diskstorage.util.RecordIterator; 31 | import org.janusgraph.diskstorage.util.StaticArrayBuffer; 32 | import org.slf4j.Logger; 33 | import org.slf4j.LoggerFactory; 34 | 35 | import java.util.ArrayList; 36 | import java.util.Arrays; 37 | import java.util.List; 38 | import java.util.Map; 39 | import java.util.HashMap; 40 | 41 | /** 42 | * @author Ted Wilmes (twilmes@gmail.com) 43 | */ 44 | public class FoundationDBKeyValueStore implements OrderedKeyValueStore, AutoCloseable { 45 | 46 | private static final Logger log = LoggerFactory.getLogger(FoundationDBKeyValueStore.class); 47 | 48 | static final StaticBuffer.Factory ENTRY_FACTORY = (array, offset, limit) -> { 49 | final byte[] bArray = new byte[limit - offset]; 50 | System.arraycopy(array, offset, bArray, 0, limit - offset); 51 | return bArray; 52 | }; 53 | 54 | private final DirectorySubspace db; 55 | private final String name; 56 | private final FoundationDBStoreManager manager; 57 | private boolean isOpen; 58 | 59 | public FoundationDBKeyValueStore(String n, DirectorySubspace data, FoundationDBStoreManager m) { 60 | db = data; 61 | name = n; 62 | manager = m; 63 | isOpen = true; 64 | } 65 | 66 | @Override 67 | public String getName() { 68 | return name; 69 | } 70 | 71 | private static FoundationDBTx getTransaction(StoreTransaction txh) { 72 | Preconditions.checkArgument(txh != null); 73 | return ((FoundationDBTx) txh);//.getTransaction(); 74 | } 75 | 76 | @Override 77 | public synchronized void close() throws BackendException { 78 | if (isOpen) manager.removeDatabase(this); 79 | isOpen = false; 80 | } 81 | 82 | @Override 83 | public StaticBuffer get(StaticBuffer key, StoreTransaction txh) throws BackendException { 84 | FoundationDBTx tx = getTransaction(txh); 85 | try { 86 | byte[] databaseKey = db.pack(key.as(ENTRY_FACTORY)); 87 | log.trace("db={}, op=get, tx={}", name, txh); 88 | final byte[] entry = tx.get(databaseKey); 89 | if (entry != null) { 90 | return getBuffer(entry); 91 | } else { 92 | return null; 93 | } 94 | } 95 | catch (BackendException e) { 96 | log.error ("db={}, op=get, tx={} with exception", name, txh, e); 97 | throw e; 98 | } 99 | catch (Exception e) { 100 | log.error ("db={}, op=get, tx={} with exception", name, txh, e); 101 | throw new PermanentBackendException(e); 102 | } 103 | } 104 | 105 | @Override 106 | public boolean containsKey(StaticBuffer key, StoreTransaction txh) throws BackendException { 107 | return get(key,txh)!=null; 108 | } 109 | 110 | @Override 111 | public void acquireLock(StaticBuffer key, StaticBuffer expectedValue, StoreTransaction txh) throws BackendException { 112 | if (getTransaction(txh) == null) { 113 | log.warn("Attempt to acquire lock with transactions disabled"); 114 | } //else we need no locking 115 | } 116 | 117 | @Override 118 | public void insert(StaticBuffer key, StaticBuffer value, StoreTransaction txh, Integer integer) throws BackendException { 119 | insert(key, value, txh); 120 | } 121 | 122 | @Override 123 | public RecordIterator getSlice(KVQuery query, StoreTransaction txh) throws BackendException { 124 | if (manager.getMode() == FoundationDBStoreManager.RangeQueryIteratorMode.SYNC) { 125 | return getSliceSync(query, txh); 126 | } else { 127 | return getSliceAsync(query, txh); 128 | } 129 | } 130 | 131 | public RecordIterator getSliceSync(KVQuery query, StoreTransaction txh) throws BackendException { 132 | log.trace("beginning db={}, op=getSliceSync, tx={}", name, txh); 133 | 134 | final FoundationDBTx tx = getTransaction(txh); 135 | 136 | try { 137 | final List result = tx.getRange(new FoundationDBRangeQuery(db, query)); 138 | 139 | log.trace("db={}, op=getSliceSync, tx={}, result-count={}", name, txh, result.size()); 140 | 141 | return new FoundationDBRecordIterator(db, result.iterator(), query.getKeySelector()); 142 | 143 | } 144 | catch (BackendException e) { 145 | throw e; 146 | } 147 | catch (Exception e) { 148 | log.error("db={}, op=getSliceSync, tx={} with exception", name, txh, e); 149 | throw new PermanentBackendException(e); 150 | } 151 | } 152 | 153 | 154 | public RecordIterator getSliceAsync(KVQuery query, StoreTransaction txh) throws BackendException { 155 | 156 | log.trace("db={}, op=getSliceAsync, tx={}", name, txh); 157 | 158 | final FoundationDBTx tx = getTransaction(txh); 159 | 160 | try { 161 | final FoundationDBRangeQuery rangeQuery = new FoundationDBRangeQuery(db, query); 162 | final AsyncIterator result = tx.getRangeIter( rangeQuery); 163 | 164 | return new FoundationDBRecordAsyncIterator(db, tx, rangeQuery, result, query.getKeySelector()); 165 | } catch (Exception e) { 166 | log.error("getSliceAsync db={}, tx={} with exception", name, txh, e); 167 | throw new PermanentBackendException(e); 168 | } 169 | } 170 | 171 | 172 | @Override 173 | public Map> getSlices(List queries, StoreTransaction txh) throws BackendException { 174 | if (manager.getMode() == FoundationDBStoreManager.RangeQueryIteratorMode.SYNC) { 175 | return getSlicesSync(queries, txh); 176 | } else { 177 | return getSlicesAsync(queries, txh); 178 | } 179 | } 180 | 181 | public Map> getSlicesSync (List queries, StoreTransaction txh) throws BackendException { 182 | log.trace("beginning db={}, op=getSlicesSync, tx={}", name, txh); 183 | FoundationDBTx tx = getTransaction(txh); 184 | final Map fdbQueries = new HashMap<>(); 185 | 186 | try { 187 | for (final KVQuery q : queries) { 188 | fdbQueries.put(q, new FoundationDBRangeQuery(db, q)); 189 | } 190 | 191 | final Map> unfilteredResultMap = tx.getMultiRange(fdbQueries.values()); 192 | final Map> iteratorMap = new HashMap<>(); 193 | for (Map.Entry> kv : unfilteredResultMap.entrySet()) { 194 | iteratorMap.put(kv.getKey(), 195 | new FoundationDBRecordIterator(db, kv.getValue().iterator(), kv.getKey().getKeySelector())); 196 | } 197 | 198 | return iteratorMap; 199 | } 200 | catch (BackendException e){ 201 | throw e; 202 | } 203 | catch (Exception e) { 204 | log.error("db={}, op=getSlicesSync, tx={} throws exception", name, txh, e); 205 | throw new PermanentBackendException(e); 206 | } 207 | } 208 | 209 | 210 | public Map> getSlicesAsync(List queries, StoreTransaction txh) throws BackendException { 211 | log.trace("beginning db={}, op=getSlicesAsync, tx={}", name, txh); 212 | 213 | FoundationDBTx tx = getTransaction(txh); 214 | final Map> resultMap = new HashMap<>(); 215 | 216 | try { 217 | for (final KVQuery query : queries) { 218 | FoundationDBRangeQuery rangeQuery = new FoundationDBRangeQuery(db, query); 219 | AsyncIterator result = tx.getRangeIter(rangeQuery); 220 | resultMap.put(query, 221 | new FoundationDBRecordAsyncIterator(db, tx, rangeQuery, result, query.getKeySelector())); 222 | } 223 | } catch (Exception e) { 224 | log.error("db={}, getSlicesAsync, tx= {} with exception", name, txh, e); 225 | 226 | throw new PermanentBackendException(e); 227 | } 228 | 229 | 230 | return resultMap; 231 | } 232 | 233 | public void insert(StaticBuffer key, StaticBuffer value, StoreTransaction txh) throws BackendException { 234 | FoundationDBTx tx = getTransaction(txh); 235 | try { 236 | 237 | log.trace("db={}, op=insert, tx={}", name, txh); 238 | tx.set(db.pack(key.as(ENTRY_FACTORY)), value.as(ENTRY_FACTORY)); 239 | } catch (Exception e) { 240 | log.error ("db={}, op=insert, tx={} with exception", name, txh, e); 241 | throw new PermanentBackendException(e); 242 | } 243 | } 244 | 245 | @Override 246 | public void delete(StaticBuffer key, StoreTransaction txh) throws BackendException { 247 | FoundationDBTx tx = getTransaction(txh); 248 | try { 249 | log.trace("db={}, op=delete, tx={}", name, txh); 250 | tx.clear(db.pack(key.as(ENTRY_FACTORY))); 251 | } catch (Exception e) { 252 | log.error("db={}, op=delete, tx={} with exception", name, txh, e); 253 | throw new PermanentBackendException(e); 254 | } 255 | } 256 | 257 | /* this method is not called within JanusGraph, it's used for bulk access in Spark jobs. 258 | For more: Please check: {@link https://github.com/JanusGraph/janusgraph-foundationdb/pull/48#discussion_r498917927} 259 | */ 260 | public List getBoundaryKeys() { 261 | List keys = new ArrayList<>(); 262 | try (CloseableAsyncIterator it = LocalityUtil.getBoundaryKeys(manager.db, db.range().begin, db.range().end)) { 263 | it.forEachRemaining(key -> { 264 | if (key[key.length - 1] != 0x00) { 265 | key = Arrays.copyOf(key, key.length + 1); 266 | } 267 | keys.add(getBuffer(db.unpack(key).getBytes(0))); 268 | }); 269 | } 270 | return keys; 271 | } 272 | 273 | static StaticBuffer getBuffer(byte[] entry) { 274 | return new StaticArrayBuffer(entry); 275 | } 276 | 277 | 278 | } 279 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBRangeQuery.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.KeySelector; 18 | import com.apple.foundationdb.subspace.Subspace; 19 | 20 | import org.janusgraph.diskstorage.StaticBuffer; 21 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KVQuery; 22 | 23 | /** 24 | * @author Florian Grieskamp 25 | */ 26 | public class FoundationDBRangeQuery { 27 | 28 | private final KVQuery originalQuery; 29 | private KeySelector startKeySelector; 30 | private KeySelector endKeySelector; 31 | private final int limit; 32 | 33 | public FoundationDBRangeQuery(Subspace db, KVQuery kvQuery) { 34 | originalQuery = kvQuery; 35 | limit = kvQuery.getLimit(); 36 | 37 | final StaticBuffer keyStart = kvQuery.getStart(); 38 | final StaticBuffer keyEnd = kvQuery.getEnd(); 39 | 40 | byte[] startKey = (keyStart == null) ? 41 | db.range().begin : db.pack(keyStart.as(FoundationDBKeyValueStore.ENTRY_FACTORY)); 42 | byte[] endKey = (keyEnd == null) ? 43 | db.range().end : db.pack(keyEnd.as(FoundationDBKeyValueStore.ENTRY_FACTORY)); 44 | 45 | startKeySelector = KeySelector.firstGreaterOrEqual(startKey); 46 | endKeySelector = KeySelector.firstGreaterOrEqual(endKey); 47 | } 48 | 49 | public void setStartKeySelector(KeySelector startKeySelector) { 50 | this.startKeySelector = startKeySelector; 51 | } 52 | 53 | public void setEndKeySelector(KeySelector endKeySelector) { 54 | this.endKeySelector = endKeySelector; 55 | } 56 | 57 | public KVQuery asKVQuery() { return originalQuery; } 58 | 59 | public KeySelector getStartKeySelector() { return startKeySelector; } 60 | 61 | public KeySelector getEndKeySelector() { return endKeySelector; } 62 | 63 | public int getLimit() { return limit; } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBRecordAsyncIterator.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.FDBException; 18 | import com.apple.foundationdb.KeyValue; 19 | import com.apple.foundationdb.async.AsyncIterator; 20 | import com.apple.foundationdb.subspace.Subspace; 21 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KeySelector; 22 | 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | public class FoundationDBRecordAsyncIterator extends FoundationDBRecordIterator { 27 | 28 | private static final Logger log = LoggerFactory.getLogger(FoundationDBRecordAsyncIterator.class); 29 | 30 | private final FoundationDBTx tx; 31 | private final FoundationDBRangeQuery rangeQuery; 32 | 33 | private AsyncIterator heldEntries; 34 | 35 | protected static final int TRANSACTION_TOO_OLD_CODE = 1007; 36 | 37 | public FoundationDBRecordAsyncIterator( 38 | Subspace ds, 39 | FoundationDBTx tx, 40 | FoundationDBRangeQuery query, 41 | final AsyncIterator result, 42 | KeySelector selector) { 43 | super(ds, result, selector); 44 | 45 | this.tx = tx; 46 | this.rangeQuery = query; 47 | this.heldEntries = result; 48 | } 49 | 50 | private FDBException unwrapException(Throwable err) { 51 | Throwable curr = err; 52 | while (curr != null && !(curr instanceof FDBException)) { 53 | curr = curr.getCause(); 54 | } 55 | if (curr != null) { 56 | return (FDBException) curr; 57 | } else { 58 | return null; 59 | } 60 | } 61 | 62 | @Override 63 | protected void fetchNext() { 64 | while (true) { 65 | try { 66 | super.fetchNext(); 67 | break; 68 | } catch (RuntimeException e) { 69 | 70 | log.info("current async iterator canceled and current transaction could be re-started when conditions meet"); 71 | heldEntries.cancel(); 72 | 73 | Throwable t = e.getCause(); 74 | FDBException fdbException = unwrapException(t); 75 | // Capture the transaction too old error 76 | if (tx.getIsolationLevel() != FoundationDBTx.IsolationLevel.SERIALIZABLE && 77 | fdbException != null && (fdbException.getCode() == TRANSACTION_TOO_OLD_CODE)) { 78 | tx.restart(); 79 | heldEntries = tx.getRangeIter(rangeQuery, fetched); 80 | // Initiate record iterator again, but keep cursor "fetched" not changed. 81 | this.entries = heldEntries; 82 | this.nextKeyValueEntry = null; 83 | } else { 84 | log.error("The throwable is not restartable", t); 85 | throw e; 86 | } 87 | } catch (Exception e) { 88 | log.error("AsyncIterator fetchNext() encountered exception", e); 89 | throw e; 90 | } 91 | } 92 | } 93 | 94 | @Override 95 | public void close() { 96 | heldEntries.cancel(); 97 | } 98 | 99 | @Override 100 | public void remove() { 101 | heldEntries.remove(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBRecordIterator.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.KeyValue; 18 | import com.apple.foundationdb.subspace.Subspace; 19 | import org.janusgraph.diskstorage.StaticBuffer; 20 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KeySelector; 21 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KeyValueEntry; 22 | import org.janusgraph.diskstorage.util.RecordIterator; 23 | 24 | import java.util.Iterator; 25 | import java.util.NoSuchElementException; 26 | 27 | public class FoundationDBRecordIterator implements RecordIterator { 28 | protected final Subspace ds; 29 | protected Iterator entries; 30 | protected final KeySelector selector; 31 | // Keeping track of the entries being scanned, which is different from the selected entries returned to the caller 32 | // due to selector 33 | protected int fetched; 34 | protected KeyValueEntry nextKeyValueEntry; 35 | 36 | public FoundationDBRecordIterator(Subspace ds, final Iterator keyValues, KeySelector selector) { 37 | this.ds = ds; 38 | this.selector = selector; 39 | 40 | entries = keyValues; 41 | fetched = 0; 42 | nextKeyValueEntry = null; 43 | } 44 | 45 | @Override 46 | public boolean hasNext() { 47 | fetchNext(); 48 | return (nextKeyValueEntry != null); 49 | } 50 | 51 | @Override 52 | public KeyValueEntry next() { 53 | if (hasNext()) { 54 | KeyValueEntry result = nextKeyValueEntry; 55 | nextKeyValueEntry = null; 56 | return result; 57 | } 58 | else { 59 | throw new NoSuchElementException(); 60 | } 61 | } 62 | 63 | protected void fetchNext() { 64 | while (nextKeyValueEntry == null && entries.hasNext()) { 65 | KeyValue kv = entries.next(); 66 | fetched++; 67 | StaticBuffer key = FoundationDBKeyValueStore.getBuffer(ds.unpack(kv.getKey()).getBytes(0)); 68 | if (selector.include(key)) { 69 | nextKeyValueEntry = new KeyValueEntry (key, FoundationDBKeyValueStore.getBuffer(kv.getValue())); 70 | } 71 | } 72 | } 73 | 74 | @Override 75 | public void close() { 76 | } 77 | 78 | @Override 79 | public void remove() { 80 | throw new UnsupportedOperationException(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBStoreManager.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.Database; 18 | import com.apple.foundationdb.FDB; 19 | import com.apple.foundationdb.Transaction; 20 | import com.apple.foundationdb.directory.DirectoryLayer; 21 | import com.apple.foundationdb.directory.DirectorySubspace; 22 | import com.apple.foundationdb.directory.PathUtil; 23 | import com.google.common.base.Preconditions; 24 | import org.janusgraph.diskstorage.BackendException; 25 | import org.janusgraph.diskstorage.PermanentBackendException; 26 | import org.janusgraph.diskstorage.BaseTransactionConfig; 27 | import org.janusgraph.diskstorage.StaticBuffer; 28 | import org.janusgraph.diskstorage.common.AbstractStoreManager; 29 | import org.janusgraph.diskstorage.configuration.Configuration; 30 | import org.janusgraph.diskstorage.keycolumnvalue.KeyRange; 31 | import org.janusgraph.diskstorage.keycolumnvalue.StandardStoreFeatures; 32 | import org.janusgraph.diskstorage.keycolumnvalue.StoreFeatures; 33 | import org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction; 34 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KVMutation; 35 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KeyValueEntry; 36 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStoreManager; 37 | import org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration; 38 | 39 | import org.slf4j.Logger; 40 | import org.slf4j.LoggerFactory; 41 | 42 | import java.util.List; 43 | import java.util.Map; 44 | import java.util.concurrent.ConcurrentHashMap; 45 | import java.util.concurrent.ExecutionException; 46 | 47 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.CLUSTER_FILE_PATH; 48 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.DIRECTORY; 49 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.ISOLATION_LEVEL; 50 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.VERSION; 51 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.GET_RANGE_MODE; 52 | import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.GRAPH_NAME; 53 | 54 | /** 55 | * Experimental FoundationDB storage manager implementation. 56 | * 57 | * @author Ted Wilmes (twilmes@gmail.com) 58 | */ 59 | public class FoundationDBStoreManager extends AbstractStoreManager implements OrderedKeyValueStoreManager, AutoCloseable { 60 | 61 | private static final Logger log = LoggerFactory.getLogger(FoundationDBStoreManager.class); 62 | 63 | public enum RangeQueryIteratorMode { ASYNC, SYNC }; 64 | private RangeQueryIteratorMode mode; 65 | 66 | private final Map stores; 67 | 68 | protected FDB fdb; 69 | protected Database db; 70 | protected final StoreFeatures features; 71 | protected DirectorySubspace rootDirectory; 72 | protected final String rootDirectoryName; 73 | protected final FoundationDBTx.IsolationLevel isolationLevel; 74 | 75 | public FoundationDBStoreManager(Configuration configuration) throws BackendException { 76 | super(configuration); 77 | stores = new ConcurrentHashMap<>(); 78 | 79 | fdb = FDB.selectAPIVersion(determineFoundationDbVersion(configuration)); 80 | 81 | rootDirectoryName = determineRootDirectoryName(configuration); 82 | 83 | db = !"default".equals(configuration.get(CLUSTER_FILE_PATH)) ? 84 | fdb.open(configuration.get(CLUSTER_FILE_PATH)) : fdb.open(); 85 | final String isolationLevelStr = configuration.get(ISOLATION_LEVEL); 86 | switch (isolationLevelStr.toLowerCase().trim()) { 87 | case "serializable": 88 | isolationLevel = FoundationDBTx.IsolationLevel.SERIALIZABLE; 89 | break; 90 | case "read_committed_no_write": 91 | isolationLevel = FoundationDBTx.IsolationLevel.READ_COMMITTED_NO_WRITE; 92 | break; 93 | case "read_committed_with_write": 94 | isolationLevel = FoundationDBTx.IsolationLevel.READ_COMMITTED_WITH_WRITE; 95 | break; 96 | default: 97 | throw new PermanentBackendException("Unrecognized isolation level " + isolationLevelStr); 98 | } 99 | 100 | log.info("Isolation level is set to {}", isolationLevel.toString()); 101 | 102 | final String getRangeMode = configuration.get(GET_RANGE_MODE); 103 | switch (getRangeMode.toLowerCase().trim()) { 104 | case "iterator": 105 | mode = RangeQueryIteratorMode.ASYNC; 106 | break; 107 | case "list": 108 | mode = RangeQueryIteratorMode.SYNC; 109 | break; 110 | } 111 | log.info("GetRange mode is specified as: {}, record iterator is with: {}", getRangeMode, mode.toString()); 112 | 113 | 114 | initialize(rootDirectoryName); 115 | 116 | features = new StandardStoreFeatures.Builder() 117 | .orderedScan(true) 118 | .transactional(transactional) 119 | .keyConsistent(GraphDatabaseConfiguration.buildGraphConfiguration()) 120 | .locking(true) 121 | .keyOrdered(true) 122 | .supportsInterruption(false) 123 | .optimisticLocking(true) 124 | .multiQuery(true) 125 | .build(); 126 | 127 | log.info("FoundationDBStoreManager initialized"); 128 | } 129 | 130 | private void initialize(final String directoryName) throws BackendException { 131 | try { 132 | // create the root directory to hold the JanusGraph data 133 | rootDirectory = DirectoryLayer.getDefault().createOrOpen(db, PathUtil.from(directoryName)).get(); 134 | } catch (Exception e) { 135 | throw new PermanentBackendException(e); 136 | } 137 | } 138 | 139 | @Override 140 | public StoreFeatures getFeatures() { 141 | return features; 142 | } 143 | 144 | @Override 145 | public List getLocalKeyPartition() throws BackendException { 146 | throw new UnsupportedOperationException(); 147 | } 148 | 149 | @Override 150 | public StoreTransaction beginTransaction(final BaseTransactionConfig txCfg) throws BackendException { 151 | try { 152 | final Transaction tx = db.createTransaction(); 153 | 154 | final StoreTransaction fdbTx = new FoundationDBTx(db, tx, txCfg, isolationLevel); 155 | 156 | if (log.isTraceEnabled()) { 157 | log.trace("FoundationDB tx created", new TransactionBegin(fdbTx.toString())); 158 | } 159 | 160 | return fdbTx; 161 | } catch (Exception e) { 162 | throw new PermanentBackendException("Could not start FoundationDB transaction", e); 163 | } 164 | } 165 | 166 | @Override 167 | public FoundationDBKeyValueStore openDatabase(String name) throws BackendException { 168 | Preconditions.checkNotNull(name); 169 | if (stores.containsKey(name)) { 170 | return stores.get(name); 171 | } 172 | try { 173 | final DirectorySubspace storeDb = rootDirectory.createOrOpen(db, PathUtil.from(name)).get(); 174 | log.debug("Opened database {}", name /*, new Throwable()*/); 175 | 176 | FoundationDBKeyValueStore store = new FoundationDBKeyValueStore(name, storeDb, this); 177 | stores.put(name, store); 178 | return store; 179 | } catch (Exception e) { 180 | throw new PermanentBackendException("Could not open FoundationDB data store", e); 181 | } 182 | } 183 | 184 | @Override 185 | public void mutateMany(Map mutations, StoreTransaction txh) throws BackendException { 186 | try { 187 | for (Map.Entry mutation : mutations.entrySet()) { 188 | FoundationDBKeyValueStore store = openDatabase(mutation.getKey()); 189 | KVMutation mutationValue = mutation.getValue(); 190 | 191 | if (!mutationValue.hasAdditions() && !mutationValue.hasDeletions()) { 192 | log.debug("Empty mutation set for {}, doing nothing", mutation.getKey()); 193 | } else { 194 | log.debug("Mutating {}", mutation.getKey()); 195 | } 196 | 197 | if (mutationValue.hasAdditions()) { 198 | for (KeyValueEntry entry : mutationValue.getAdditions()) { 199 | store.insert(entry.getKey(), entry.getValue(), txh); 200 | log.trace("Insertion on {}: {}", mutation.getKey(), entry); 201 | } 202 | 203 | log.debug("Total number of insertions: {}", mutationValue.getAdditions().size()); 204 | } 205 | if (mutationValue.hasDeletions()) { 206 | for (StaticBuffer del : mutationValue.getDeletions()) { 207 | store.delete(del, txh); 208 | log.trace("Deletion on {}: {}", mutation.getKey(), del); 209 | } 210 | 211 | log.debug("Total number of deletions: {}", mutationValue.getDeletions().size()); 212 | } 213 | } 214 | } 215 | catch (BackendException e){ 216 | throw e; 217 | } 218 | catch (Exception e) { 219 | throw new PermanentBackendException(e); 220 | } 221 | } 222 | 223 | void removeDatabase(FoundationDBKeyValueStore db) { 224 | if (!stores.containsKey(db.getName())) { 225 | throw new IllegalArgumentException("Tried to remove an unknown database from the storage manager"); 226 | } 227 | String name = db.getName(); 228 | stores.remove(name); 229 | log.debug("Removed database {}", name); 230 | } 231 | 232 | 233 | @Override 234 | public void close() throws BackendException { 235 | if (fdb != null) { 236 | if (!stores.isEmpty()) 237 | throw new IllegalStateException("Cannot shutdown manager since some databases are still open"); 238 | try { 239 | // TODO this looks like a race condition 240 | // Wait just a little bit before closing so that independent transaction threads can clean up. 241 | Thread.sleep(30); 242 | } catch (InterruptedException e) { 243 | // Ignore 244 | } 245 | try { 246 | db.close(); 247 | } catch (Exception e) { 248 | throw new PermanentBackendException("Could not close FoundationDB database", e); 249 | } 250 | } 251 | 252 | log.info("FoundationDBStoreManager closed"); 253 | } 254 | 255 | @Override 256 | public void clearStorage() throws BackendException { 257 | try { 258 | rootDirectory.removeIfExists(db).get(); 259 | } catch (Exception e) { 260 | throw new PermanentBackendException("Could not clear FoundationDB storage", e); 261 | } 262 | 263 | log.info("FoundationDBStoreManager cleared storage"); 264 | } 265 | 266 | @Override 267 | public boolean exists() throws BackendException { 268 | // @todo 269 | try { 270 | return DirectoryLayer.getDefault().exists(db, PathUtil.from(rootDirectoryName)).get(); 271 | } catch (InterruptedException e) { 272 | throw new PermanentBackendException(e); 273 | } catch (ExecutionException e) { 274 | throw new PermanentBackendException(e); 275 | } 276 | } 277 | 278 | @Override 279 | public String getName() { 280 | return getClass().getSimpleName(); 281 | } 282 | 283 | 284 | private static class TransactionBegin extends Exception { 285 | private static final long serialVersionUID = 1L; 286 | 287 | private TransactionBegin(String msg) { 288 | super(msg); 289 | } 290 | } 291 | 292 | private String determineRootDirectoryName(Configuration config) { 293 | if (!config.has(DIRECTORY) && (config.has(GRAPH_NAME))) return config.get(GRAPH_NAME); 294 | return config.get(DIRECTORY); 295 | } 296 | 297 | private int determineFoundationDbVersion(Configuration config) { 298 | return config.get(VERSION); 299 | } 300 | 301 | public RangeQueryIteratorMode getMode() { 302 | return mode; 303 | } 304 | } 305 | -------------------------------------------------------------------------------- /src/main/java/org/janusgraph/diskstorage/foundationdb/FoundationDBTx.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import com.apple.foundationdb.Database; 18 | import com.apple.foundationdb.KeyValue; 19 | import com.apple.foundationdb.Transaction; 20 | import com.apple.foundationdb.FDBException; 21 | import com.apple.foundationdb.KeySelector; 22 | import com.apple.foundationdb.StreamingMode; 23 | import com.apple.foundationdb.async.AsyncIterator; 24 | import org.janusgraph.diskstorage.BackendException; 25 | import org.janusgraph.diskstorage.BaseTransactionConfig; 26 | import org.janusgraph.diskstorage.PermanentBackendException; 27 | import org.janusgraph.diskstorage.common.AbstractStoreTransaction; 28 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.KVQuery; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import java.util.Collection; 33 | import java.util.Collections; 34 | import java.util.List; 35 | import java.util.ArrayList; 36 | import java.util.LinkedList; 37 | import java.util.Map; 38 | import java.util.concurrent.CompletableFuture; 39 | import java.util.concurrent.ConcurrentHashMap; 40 | import java.util.concurrent.CopyOnWriteArrayList; 41 | import java.util.concurrent.ExecutionException; 42 | import java.util.concurrent.atomic.AtomicInteger; 43 | 44 | /** 45 | * @author Ted Wilmes (twilmes@gmail.com) 46 | */ 47 | public class FoundationDBTx extends AbstractStoreTransaction { 48 | 49 | private static final Logger log = LoggerFactory.getLogger(FoundationDBTx.class); 50 | 51 | private volatile Transaction tx; 52 | 53 | private final Database db; 54 | 55 | private final List inserts = Collections.synchronizedList(new ArrayList<>()); 56 | private final List deletions = Collections.synchronizedList(new ArrayList<>()); 57 | 58 | private int maxRuns = 1; 59 | 60 | public enum IsolationLevel {SERIALIZABLE, READ_COMMITTED_NO_WRITE, READ_COMMITTED_WITH_WRITE} 61 | 62 | private final IsolationLevel isolationLevel; 63 | 64 | private final AtomicInteger txCtr = new AtomicInteger(0); 65 | 66 | private static final AtomicInteger transLocalIdCounter = new AtomicInteger(0); 67 | private final int transactionId; 68 | 69 | public FoundationDBTx(Database db, Transaction t, BaseTransactionConfig config, IsolationLevel isolationLevel) { 70 | super(config); 71 | tx = t; 72 | this.db = db; 73 | this.isolationLevel = isolationLevel; 74 | 75 | switch (isolationLevel) { 76 | case SERIALIZABLE: 77 | // no retries 78 | break; 79 | case READ_COMMITTED_NO_WRITE: 80 | case READ_COMMITTED_WITH_WRITE: 81 | maxRuns = 3; 82 | } 83 | 84 | this.transactionId = transLocalIdCounter.incrementAndGet(); 85 | } 86 | 87 | public IsolationLevel getIsolationLevel() { 88 | return isolationLevel; 89 | } 90 | 91 | public synchronized void restart() { 92 | txCtr.incrementAndGet(); 93 | 94 | if (tx != null) { 95 | try { 96 | tx.cancel(); 97 | } catch (IllegalStateException e) { 98 | // 99 | } finally { 100 | try { 101 | tx.close(); 102 | } catch (Exception e) { 103 | log.error("Exception when closing transaction: ", e); 104 | } 105 | } 106 | } else { 107 | log.warn("In execution mode: {} and when restart transaction, encountered FDB transaction object being null", 108 | isolationLevel.name()); 109 | } 110 | 111 | tx = db.createTransaction(); 112 | // Reapply mutations but do not clear them out just in case this transaction also 113 | // times out and they need to be reapplied. 114 | // 115 | // @todo Note that at this point, the large transaction case (tx exceeds 10,000,000 bytes) is not handled. 116 | inserts.forEach(insert -> tx.set(insert.getKey(), insert.getValue())); 117 | deletions.forEach(delete -> tx.clear(delete)); 118 | } 119 | 120 | @Override 121 | public synchronized void rollback() throws BackendException { 122 | super.rollback(); 123 | if (tx == null) { 124 | log.warn("In execution mode: {} and when rollback, encountered FDB transaction object being null", isolationLevel.name()); 125 | return; 126 | } 127 | if (log.isTraceEnabled()) 128 | log.trace("{} rolled back", this.toString(), new FoundationDBTx.TransactionClose(this.toString())); 129 | 130 | try { 131 | tx.cancel(); 132 | tx.close(); 133 | tx = null; 134 | } catch (Exception e) { 135 | throw new PermanentBackendException(e); 136 | } finally { 137 | if (tx != null) { 138 | try { 139 | tx.close(); 140 | } catch (Exception e) { 141 | log.error("Exception when closing transaction:", e); 142 | } 143 | tx = null; 144 | } 145 | } 146 | 147 | log.debug("Transaction rolled back, num_inserts: {}, num_deletes: {}", inserts.size(), deletions.size()); 148 | } 149 | 150 | 151 | private void logFDBException(Throwable t) { 152 | if (t instanceof FDBException) { 153 | FDBException fe = (FDBException) t; 154 | if (log.isDebugEnabled()) { 155 | log.debug("Catch FDBException code= {}, isRetryable={}, isMaybeCommitted={}, " 156 | + "isRetryableNotCommitted={}, isSuccess={}", 157 | fe.getCode(), fe.isRetryable(), 158 | fe.isMaybeCommitted(), fe.isRetryableNotCommitted(), fe.isSuccess()); 159 | } 160 | } 161 | } 162 | 163 | @Override 164 | public synchronized void commit() throws BackendException { 165 | boolean failing = true; 166 | int counter = 0; 167 | 168 | for (int i = 0; i < maxRuns; i++) { 169 | super.commit(); 170 | if (tx == null) { 171 | log.warn("In execution mode: {} and when commit, encountered FDB transaction object being null", isolationLevel.name()); 172 | return; 173 | } 174 | if (log.isTraceEnabled()) 175 | log.trace("{} committed", this.toString(), new FoundationDBTx.TransactionClose(this.toString())); 176 | 177 | try { 178 | if (!inserts.isEmpty() || !deletions.isEmpty()) { 179 | tx.commit().get(); 180 | log.debug("Transaction committed, num_inserts: {}, num_deletes: {}", inserts.size(), deletions.size()); 181 | } else { 182 | // nothing to commit so skip it 183 | tx.cancel(); 184 | } 185 | tx.close(); 186 | tx = null; 187 | failing = false; 188 | break; 189 | } catch (IllegalStateException | ExecutionException e) { 190 | if (tx != null) { 191 | try { 192 | tx.close(); 193 | } catch (Exception ex) { 194 | log.error("Exception when closing transaction: {} ", ex.getMessage()); 195 | } 196 | tx = null; 197 | } 198 | 199 | log.error("Commit encountered exception: {}, i: {}, maxRuns: {}, to be restarted with inserts: {} and deletes: {}", 200 | e.getMessage(), i, maxRuns, inserts.size(), deletions.size()); 201 | 202 | logFDBException(e.getCause()); 203 | if (isolationLevel.equals(IsolationLevel.SERIALIZABLE) || 204 | isolationLevel.equals(IsolationLevel.READ_COMMITTED_NO_WRITE)) { 205 | log.error("Commit failed with inserts: {}, deletes: {}", inserts.size(), deletions.size()); 206 | 207 | // throw the exception that carries the root exception cause 208 | throw new PermanentBackendException("transaction fails to commit", e); 209 | } 210 | 211 | if (i + 1 != maxRuns) { 212 | restart(); 213 | counter++; // increase how many times that the commit has been re-started. 214 | } 215 | 216 | } catch (Exception e) { 217 | 218 | if (tx != null) { 219 | try { 220 | tx.close(); 221 | } catch (Exception ex) { 222 | log.error("Exception when closing transaction: {}", ex.getMessage()); 223 | } 224 | tx = null; 225 | } 226 | 227 | log.error("Commit encountered exception: {} ", e.getMessage()); 228 | throw new PermanentBackendException(e); 229 | } 230 | } 231 | 232 | if (failing) { 233 | log.error("Commit failed with maxRuns: {}, inserts: {}, deletes: {}, total re-starts: {}", 234 | maxRuns, inserts.size(), deletions.size(), counter); 235 | 236 | // Note: even if the commit is retriable and the TemporaryBackendException is thrown here, at the commit(.) 237 | // method of StandardJanusGraph class, the thrown exception will be translated to rollback(.) and then 238 | // throw further JanusGraphException to the application. Thus, it is better to just throw the 239 | // PermanentBackendException here. as at this late commit stage, there is no retry logic defined 240 | // at the StandardJanusGraph class. 241 | // if (isRetriable) 242 | // throw new TemporaryBackendException("Max transaction count exceed but transaction is retriable"); 243 | // else 244 | // throw new PermanentBackendException("Max transaction reset count exceeded"); 245 | throw new PermanentBackendException("transaction fails to commit with max transaction reset count exceeded"); 246 | } 247 | } 248 | 249 | 250 | @Override 251 | public String toString() { 252 | return getClass().getSimpleName() + (null == tx ? "nulltx" : tx.toString()); 253 | } 254 | 255 | private static class TransactionClose extends Exception { 256 | private static final long serialVersionUID = 1L; 257 | 258 | private TransactionClose(String msg) { 259 | super(msg); 260 | } 261 | } 262 | 263 | public byte[] get(final byte[] key) throws PermanentBackendException { 264 | for (int i = 0; i < maxRuns; i++) { 265 | try { 266 | return this.tx.get(key).get(); 267 | } catch (ExecutionException e) { 268 | log.error("get encountered ExecutionException: {}, with number of retries: {}", e.getMessage(), i); 269 | 270 | logFDBException(e.getCause()); 271 | if (i + 1 != maxRuns) { 272 | this.restart(); 273 | } else { 274 | throw new PermanentBackendException("Max transaction reset count exceeded with final exception", e); 275 | } 276 | } catch (Exception e) { 277 | log.error("get encountered other exception: {}, with number of retries: {} ", e.getMessage(), i); 278 | 279 | throw new PermanentBackendException(e); 280 | } 281 | } 282 | 283 | throw new PermanentBackendException("Max transaction reset count exceeded"); 284 | } 285 | 286 | 287 | public List getRange(final FoundationDBRangeQuery query) throws PermanentBackendException { 288 | for (int i = 0; i < maxRuns; i++) { 289 | final int startTxId = txCtr.get(); 290 | try { 291 | List result = 292 | tx.getRange(query.getStartKeySelector(), query.getEndKeySelector(), query.getLimit()).asList().get(); 293 | return result != null ? result : Collections.emptyList(); 294 | } catch (ExecutionException e) { 295 | log.error("getRange encountered ExecutionException: {}, with number of retries: {}", e.getMessage(), i); 296 | 297 | logFDBException(e.getCause()); 298 | 299 | if (txCtr.get() == startTxId) { 300 | log.debug("getRange tx-counter: {} and start tx-id: {} agree with each other, with exception: {} before restart", 301 | txCtr.get(), startTxId, e.getMessage()); 302 | 303 | if (i + 1 != maxRuns) { 304 | this.restart(); 305 | log.debug("Transaction restarted with iteration: {} and maxRuns: {} ", i, maxRuns); 306 | } else { 307 | throw new PermanentBackendException("Max transaction reset count exceeded with final exception", e); 308 | } 309 | } else { 310 | log.debug("getRange tx-counter: {} and start tx-id: {} not agree with each other", txCtr.get(), startTxId); 311 | } 312 | } catch (Exception e) { 313 | log.error("getRange encountered other exception: {}, with number of retries: {}", e.getMessage(), i); 314 | 315 | throw new PermanentBackendException(e); 316 | } 317 | } 318 | 319 | throw new PermanentBackendException("Max transaction reset count exceeded"); 320 | 321 | } 322 | 323 | public AsyncIterator getRangeIter(FoundationDBRangeQuery query) { 324 | final int limit = query.asKVQuery().getLimit(); 325 | return tx.getRange(query.getStartKeySelector(), query.getEndKeySelector(), limit, 326 | false, StreamingMode.WANT_ALL).iterator(); 327 | } 328 | 329 | public AsyncIterator getRangeIter(FoundationDBRangeQuery query, final int skip) { 330 | // Avoid using KeySelector(byte[] key, boolean orEqual, int offset) directly as stated in KeySelector.java 331 | // that client code will not generally call this constructor. 332 | final int limit = query.asKVQuery().getLimit(); 333 | KeySelector begin = query.getStartKeySelector().add(skip); 334 | KeySelector end = query.getEndKeySelector(); 335 | return tx.getRange(begin, end, limit - skip, false, StreamingMode.WANT_ALL).iterator(); 336 | } 337 | 338 | public synchronized Map> getMultiRange(final Collection queries) 339 | throws PermanentBackendException { 340 | Map> resultMap = new ConcurrentHashMap<>(); 341 | final List retries = new CopyOnWriteArrayList<>(queries); 342 | 343 | int counter = 0; 344 | for (int i = 0; i < maxRuns; i++) { 345 | counter++; 346 | 347 | if (retries.size() > 0) { 348 | 349 | List immutableRetries = new ArrayList<>(retries); 350 | 351 | final List>> futures = new LinkedList<>(); 352 | 353 | final int startTxId = txCtr.get(); 354 | 355 | // Introduce the immutable list for iteration purpose, rather than having the dynamic list 356 | // retries to be the iterator. 357 | for (FoundationDBRangeQuery q : immutableRetries) { 358 | final KVQuery query = q.asKVQuery(); 359 | 360 | CompletableFuture> f = tx.getRange(q.getStartKeySelector(), 361 | q.getEndKeySelector(), query.getLimit()).asList() 362 | .whenComplete((res, th) -> { 363 | if (th == null) { 364 | log.debug("(before) get range succeeded with current size of retries: {}, thread id: {}, tx id: {}", 365 | retries.size(), Thread.currentThread().getId(), transactionId); 366 | 367 | // retries's object type is: Object[], not KVQuery. 368 | retries.remove(q); 369 | 370 | log.debug("(after) get range succeeded with current size of retries: {}, thread id: {}, tx id: {}", 371 | retries.size(), Thread.currentThread().getId(), transactionId); 372 | 373 | if (res == null) { 374 | res = Collections.emptyList(); 375 | } 376 | resultMap.put(query, res); 377 | 378 | } else { 379 | logFDBException(th.getCause()); 380 | 381 | // The restart here will bring the code into deadlock, as restart() is a 382 | // synchronized method and the thread to invoke this method is from a worker thread 383 | // that serves the completable future call, which is different from the thread that 384 | // invokes the getMultiRange call (this method) and getMultiRange is also a synchronized 385 | // call. 386 | // if (startTxId == txCtr.get()) 387 | // this.restart(); 388 | resultMap.put(query, Collections.emptyList()); 389 | 390 | log.debug("Encountered exception with: {}", th.getCause().getMessage()); 391 | } 392 | }); 393 | 394 | futures.add(f); 395 | } 396 | 397 | CompletableFuture allFuturesDone = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); 398 | // When some of the Future encounters exception, map will ignore it. we need count as the action! 399 | // allFuturesDone.thenApply(v -> futures.stream().map(CompletableFuture::join).collect(Collectors.toList())); 400 | try { 401 | allFuturesDone.join(); 402 | } catch (Exception ex) { 403 | log.error("Multi-range query encountered transient exception in some futures: {}", ex.getCause().getMessage()); 404 | } 405 | 406 | log.debug("get range succeeded with current size of retries: {}, thread id: {}, tx id: {}", 407 | retries.size(), Thread.currentThread().getId(), transactionId); 408 | 409 | if (retries.size() > 0) { 410 | log.debug("In multi-range query, retries size: {}, thread id: {}, tx id: {}, start tx id: {}, txCtr id: {}", 411 | retries.size(), Thread.currentThread().getId(), transactionId, startTxId, txCtr.get()); 412 | 413 | if (startTxId == txCtr.get()) { 414 | log.debug("In multi-range query, to restart with thread id: {}, tx id: {}", 415 | Thread.currentThread().getId(), transactionId); 416 | 417 | if (i + 1 != maxRuns) { 418 | this.restart(); 419 | } 420 | } 421 | } 422 | } else { 423 | log.debug("Finish multi-range query's all of future-based invocations with size: {}, thread id: {}, tx id: {}, number of retries:{}", 424 | queries.size(), Thread.currentThread().getId(), transactionId, (counter - 1)); 425 | break; 426 | } 427 | 428 | } 429 | 430 | if (retries.size() > 0) { 431 | log.error("After max number of retries: {}, some range queries still failed and forced with empty returns with transaction id: {}", 432 | maxRuns, transactionId); 433 | throw new PermanentBackendException("Encounter exceptions when invoking getRange(.) calls in getMultiRange(.)"); 434 | } 435 | 436 | return resultMap; 437 | 438 | } 439 | 440 | public void set(final byte[] key, final byte[] value) { 441 | inserts.add(new Insert(key, value)); 442 | tx.set(key, value); 443 | } 444 | 445 | public void clear(final byte[] key) { 446 | deletions.add(key); 447 | tx.clear(key); 448 | } 449 | 450 | 451 | private class Insert { 452 | private final byte[] key; 453 | private final byte[] value; 454 | 455 | public Insert(final byte[] key, final byte[] value) { 456 | this.key = key; 457 | this.value = value; 458 | } 459 | 460 | public byte[] getKey() { 461 | return this.key; 462 | } 463 | 464 | public byte[] getValue() { 465 | return this.value; 466 | } 467 | } 468 | } 469 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/FoundationDBContainer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph; 16 | 17 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.CLUSTER_FILE_PATH; 18 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.DIRECTORY; 19 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.ISOLATION_LEVEL; 20 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.GET_RANGE_MODE; 21 | import static org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions.VERSION; 22 | import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.DROP_ON_CLEAR; 23 | import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.STORAGE_BACKEND; 24 | import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.buildGraphConfiguration; 25 | 26 | import java.io.IOException; 27 | import java.net.ServerSocket; 28 | 29 | import org.janusgraph.diskstorage.configuration.ModifiableConfiguration; 30 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 31 | import org.testcontainers.containers.BindMode; 32 | import org.testcontainers.containers.Container; 33 | import org.testcontainers.containers.ContainerLaunchException; 34 | import org.testcontainers.containers.FixedHostPortGenericContainer; 35 | 36 | import org.slf4j.Logger; 37 | import org.slf4j.LoggerFactory; 38 | 39 | public class FoundationDBContainer extends FixedHostPortGenericContainer { 40 | 41 | private final Logger log = LoggerFactory.getLogger(FoundationDBContainer.class); 42 | 43 | public static final String DEFAULT_IMAGE_AND_TAG = "foundationdb/foundationdb:6.2.30"; 44 | private static final Integer DEFAULT_PORT = 4500; 45 | private static final String FDB_CLUSTER_FILE_ENV_KEY = "FDB_CLUSTER_FILE"; 46 | private static final String FDB_NETWORKING_MODE_ENV_KEY = "FDB_NETWORKING_MODE"; 47 | private static final String FDB_PORT_ENV_KEY = "FDB_PORT"; 48 | private static final String DEFAULT_NETWORKING_MODE = "host"; 49 | private static final String DEFAULT_CLUSTER_FILE_PARENT_DIR = "/etc/foundationdb"; 50 | private static final String DEFAULT_CLUSTER_FILE_PATH = DEFAULT_CLUSTER_FILE_PARENT_DIR + "/" + "fdb.cluster"; 51 | private static final String DEFAULT_VOLUME_SOURCE_PATH = "./fdb"; 52 | 53 | 54 | public FoundationDBContainer(String dockerImageName) { 55 | super(dockerImageName); 56 | Integer port = findRandomOpenPortOnAllLocalInterfaces(); 57 | this.addFixedExposedPort(port, port); 58 | this.addExposedPorts(port); 59 | this.addEnv(FDB_CLUSTER_FILE_ENV_KEY, DEFAULT_CLUSTER_FILE_PATH); 60 | this.addEnv(FDB_PORT_ENV_KEY, port.toString()); 61 | this.addEnv(FDB_NETWORKING_MODE_ENV_KEY, DEFAULT_NETWORKING_MODE); 62 | this.withClasspathResourceMapping(DEFAULT_VOLUME_SOURCE_PATH, DEFAULT_CLUSTER_FILE_PARENT_DIR, BindMode.READ_WRITE); 63 | } 64 | 65 | public FoundationDBContainer(){ 66 | this(DEFAULT_IMAGE_AND_TAG); 67 | } 68 | 69 | private Integer findRandomOpenPortOnAllLocalInterfaces() { 70 | try (ServerSocket socket = new ServerSocket(0)) { 71 | return socket.getLocalPort(); 72 | } catch (Exception e) { 73 | log.error("Couldn't open random port, using default port '%d'.", DEFAULT_PORT); 74 | return DEFAULT_PORT; 75 | } 76 | } 77 | 78 | @Override 79 | public void start() { 80 | if (this.getContainerId() != null) { 81 | // Already started this container. 82 | return; 83 | } 84 | super.start(); 85 | // initialize the database 86 | Container.ExecResult execResult; 87 | try { 88 | execResult = this.execInContainer("fdbcli", "--exec", "configure new single ssd"); 89 | } catch (UnsupportedOperationException | IOException | InterruptedException e) { 90 | throw new ContainerLaunchException("Container startup failed. Failed to initialize the database.", e); 91 | } 92 | if (execResult.getExitCode() != 0) { 93 | throw new ContainerLaunchException("Container startup failed. Failed to initialize the database. Received non zero exit code from fdbcli command. Response code was: " + execResult.getExitCode() + "."); 94 | } 95 | } 96 | 97 | public ModifiableConfiguration getFoundationDBConfiguration() { 98 | return getFoundationDBConfiguration("janusgraph-test-fdb"); 99 | } 100 | 101 | private String getAndCheckRangeModeFromTestEnvironment() { 102 | String mode = System.getProperty("getrangemode"); 103 | if (mode == null) { 104 | log.warn("No getrangemode property is chosen, use default value: list to proceed"); 105 | return "list"; 106 | } 107 | else if (mode.equalsIgnoreCase("iterator")){ 108 | log.info("getrangemode property is chosen as: iterator"); 109 | return "iterator"; 110 | } 111 | else if (mode.equalsIgnoreCase("list")){ 112 | log.info("getrangemode property is chosen as: list"); 113 | return "list"; 114 | } 115 | else { 116 | log.warn("getrange mode property chosen: " + mode + " does not match supported modes: iterator or list, choose default value: list to proceed"); 117 | return "list"; 118 | } 119 | } 120 | 121 | public ModifiableConfiguration getFoundationDBConfiguration(final String graphName) { 122 | ModifiableConfiguration config = buildGraphConfiguration() 123 | .set(STORAGE_BACKEND,"org.janusgraph.diskstorage.foundationdb.FoundationDBStoreManager") 124 | .set(DIRECTORY, graphName) 125 | .set(DROP_ON_CLEAR, false) 126 | .set(CLUSTER_FILE_PATH, "target/test-classes/fdb/fdb.cluster") 127 | .set(ISOLATION_LEVEL, "read_committed_with_write") 128 | .set(GET_RANGE_MODE, getAndCheckRangeModeFromTestEnvironment()) 129 | .set(VERSION, 620); 130 | 131 | return config; 132 | } 133 | 134 | public WriteConfiguration getFoundationDBGraphConfiguration() { 135 | return getFoundationDBConfiguration().getConfiguration(); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/FoundationDBGraphComputerProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints; 16 | 17 | import org.janusgraph.FoundationDBContainer; 18 | import org.janusgraph.diskstorage.foundationdb.FoundationDBTx; 19 | import org.janusgraph.diskstorage.configuration.ModifiableConfiguration; 20 | import org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration; 21 | import org.janusgraph.graphdb.olap.computer.FulgoraGraphComputer; 22 | import org.apache.tinkerpop.gremlin.GraphProvider; 23 | 24 | import java.time.Duration; 25 | import java.util.Set; 26 | 27 | /** 28 | * @author Ted Wilmes (twilmes@gmail.com) 29 | */ 30 | @GraphProvider.Descriptor(computer = FulgoraGraphComputer.class) 31 | public class FoundationDBGraphComputerProvider extends AbstractJanusGraphComputerProvider { 32 | 33 | private final static FoundationDBContainer container = new FoundationDBContainer(); 34 | 35 | @Override 36 | public ModifiableConfiguration getJanusGraphConfiguration(String graphName, Class test, String testMethodName) { 37 | container.start(); 38 | ModifiableConfiguration config = super.getJanusGraphConfiguration(graphName, test, testMethodName); 39 | config.setAll(container.getFoundationDBConfiguration().getAll()); 40 | config.set(GraphDatabaseConfiguration.IDAUTHORITY_WAIT, Duration.ofMillis(20)); 41 | config.set(GraphDatabaseConfiguration.STORAGE_TRANSACTIONAL,false); 42 | return config; 43 | } 44 | 45 | @Override 46 | public Set getImplementations() { 47 | final Set implementations = super.getImplementations(); 48 | implementations.add(FoundationDBTx.class); 49 | return implementations; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/FoundationDBGraphProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints; 16 | 17 | import org.janusgraph.FoundationDBContainer; 18 | import org.janusgraph.diskstorage.configuration.ModifiableConfiguration; 19 | 20 | /** 21 | * @author Ted Wilmes (twilmes@gmail.com) 22 | */ 23 | public class FoundationDBGraphProvider extends AbstractJanusGraphProvider { 24 | 25 | private final static FoundationDBContainer container = new FoundationDBContainer(); 26 | 27 | @Override 28 | public ModifiableConfiguration getJanusGraphConfiguration(String graphName, Class test, String testMethodName) { 29 | container.start(); 30 | if (graphName != null) return container.getFoundationDBConfiguration(graphName); 31 | else return container.getFoundationDBConfiguration(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/FoundationDBMultiQueryGraphProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints; 16 | 17 | import org.janusgraph.FoundationDBContainer; 18 | import org.janusgraph.diskstorage.configuration.ModifiableConfiguration; 19 | 20 | import static org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.USE_MULTIQUERY; 21 | 22 | /** 23 | * @author Ted Wilmes (twilmes@gmail.com) 24 | */ 25 | public class FoundationDBMultiQueryGraphProvider extends AbstractJanusGraphProvider { 26 | 27 | private final static FoundationDBContainer container = new FoundationDBContainer(); 28 | 29 | @Override 30 | public ModifiableConfiguration getJanusGraphConfiguration(String graphName, Class test, String testMethodName) { 31 | container.start(); 32 | return container.getFoundationDBConfiguration() 33 | .set(USE_MULTIQUERY, true); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/process/FoundationDBJanusGraphComputerTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints.process; 16 | 17 | import org.apache.tinkerpop.gremlin.GraphProviderClass; 18 | import org.apache.tinkerpop.gremlin.process.ProcessComputerSuite; 19 | import org.janusgraph.core.JanusGraph; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.janusgraph.FoundationDBContainer; 23 | import org.janusgraph.blueprints.FoundationDBGraphComputerProvider; 24 | 25 | /** 26 | * @author Ted Wilmes (twilmes@gmail.com) 27 | */ 28 | @RunWith(ProcessComputerSuite.class) 29 | @GraphProviderClass(provider = FoundationDBGraphComputerProvider.class, graph = JanusGraph.class) 30 | public class FoundationDBJanusGraphComputerTest { 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/process/FoundationDBJanusGraphMultiQueryProcessTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2020 JanusGraph Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints.process; 16 | 17 | import org.apache.tinkerpop.gremlin.GraphProviderClass; 18 | import org.janusgraph.core.JanusGraph; 19 | import org.junit.runner.RunWith; 20 | 21 | import org.janusgraph.FoundationDBContainer; 22 | import org.janusgraph.blueprints.FoundationDBMultiQueryGraphProvider; 23 | 24 | /** 25 | * @author Ted Wilmes (twilmes@gmail.com) 26 | */ 27 | @RunWith(FoundationDBProcessStandardSuite.class) 28 | @GraphProviderClass(provider = FoundationDBMultiQueryGraphProvider.class, graph = JanusGraph.class) 29 | public class FoundationDBJanusGraphMultiQueryProcessTest { 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/process/FoundationDBJanusGraphProcessTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints.process; 16 | 17 | import org.apache.tinkerpop.gremlin.GraphProviderClass; 18 | import org.janusgraph.core.JanusGraph; 19 | import org.junit.runner.RunWith; 20 | 21 | import org.janusgraph.blueprints.FoundationDBGraphProvider; 22 | 23 | /** 24 | * @author Ted Wilmes (twilmes@gmail.com) 25 | */ 26 | @RunWith(FoundationDBProcessStandardSuite.class) 27 | @GraphProviderClass(provider = FoundationDBGraphProvider.class, graph = JanusGraph.class) 28 | public class FoundationDBJanusGraphProcessTest { 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/process/FoundationDBProcessStandardSuite.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints.process; 16 | 17 | import org.apache.commons.lang.ArrayUtils; 18 | import org.apache.tinkerpop.gremlin.process.ProcessStandardSuite; 19 | import org.apache.tinkerpop.gremlin.process.traversal.TraversalInterruptionTest; 20 | import org.junit.runners.model.InitializationError; 21 | import org.junit.runners.model.RunnerBuilder; 22 | 23 | import java.lang.reflect.Field; 24 | 25 | /** 26 | * @todo see if the exclusion of the TraversalInterruptionTest is necessary 27 | */ 28 | public class FoundationDBProcessStandardSuite extends ProcessStandardSuite { 29 | 30 | public FoundationDBProcessStandardSuite(final Class classToTest, final RunnerBuilder builder) throws InitializationError { 31 | super(classToTest, builder, getTestList()); 32 | } 33 | 34 | private static Class[] getTestList() throws InitializationError { 35 | try { 36 | final Field field = ProcessStandardSuite.class.getDeclaredField("allTests"); 37 | field.setAccessible(true); 38 | return (Class[]) ArrayUtils.removeElement((Class[]) field.get(null), TraversalInterruptionTest.class); 39 | } catch (ReflectiveOperationException e) { 40 | throw new InitializationError("Unable to create test list"); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/blueprints/structure/FoundationDBJanusGraphStructureTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.blueprints.structure; 16 | 17 | import org.apache.tinkerpop.gremlin.GraphProviderClass; 18 | import org.apache.tinkerpop.gremlin.structure.StructureStandardSuite; 19 | import org.janusgraph.core.JanusGraph; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.janusgraph.blueprints.FoundationDBGraphProvider; 23 | 24 | /** 25 | * @author Ted Wilmes (twilmes@gmail.com) 26 | */ 27 | @RunWith(StructureStandardSuite.class) 28 | @GraphProviderClass(provider = FoundationDBGraphProvider.class, graph = JanusGraph.class) 29 | public class FoundationDBJanusGraphStructureTest { 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/diskstorage/foundationdb/FoundationDBFixedLengthKCVSTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.BackendException; 18 | import org.janusgraph.diskstorage.KeyColumnValueStoreTest; 19 | import org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStoreManager; 20 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStoreManagerAdapter; 21 | 22 | import org.janusgraph.FoundationDBContainer; 23 | import com.google.common.collect.ImmutableMap; 24 | import org.junit.jupiter.api.Test; 25 | import org.testcontainers.junit.jupiter.Container; 26 | import org.testcontainers.junit.jupiter.Testcontainers; 27 | 28 | /** 29 | * @author Ted Wilmes (twilmes@gmail.com) 30 | */ 31 | @Testcontainers 32 | public class FoundationDBFixedLengthKCVSTest extends KeyColumnValueStoreTest { 33 | 34 | @Container 35 | public static FoundationDBContainer container = new FoundationDBContainer(); 36 | 37 | public KeyColumnValueStoreManager openStorageManager() throws BackendException { 38 | FoundationDBStoreManager sm = new FoundationDBStoreManager(container.getFoundationDBConfiguration()); 39 | return new OrderedKeyValueStoreManagerAdapter(sm, ImmutableMap.of(storeName, 8)); 40 | } 41 | 42 | @Test 43 | @Override 44 | public void testConcurrentGetSlice() { 45 | 46 | } 47 | 48 | @Test @Override 49 | public void testConcurrentGetSliceAndMutate() { 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/diskstorage/foundationdb/FoundationDBKeyValueTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.BackendException; 18 | import org.janusgraph.diskstorage.KeyValueStoreTest; 19 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStoreManager; 20 | 21 | import org.janusgraph.FoundationDBContainer; 22 | import org.testcontainers.junit.jupiter.Container; 23 | import org.testcontainers.junit.jupiter.Testcontainers; 24 | 25 | /** 26 | * @author Ted Wilmes (twilmes@gmail.com) 27 | */ 28 | @Testcontainers 29 | public class FoundationDBKeyValueTest extends KeyValueStoreTest { 30 | 31 | @Container 32 | public static FoundationDBContainer container = new FoundationDBContainer(); 33 | 34 | 35 | @Override 36 | public OrderedKeyValueStoreManager openStorageManager() throws BackendException { 37 | return new FoundationDBStoreManager(container.getFoundationDBConfiguration()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/diskstorage/foundationdb/FoundationDBLogTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.BackendException; 18 | import org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStoreManager; 19 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStoreManagerAdapter; 20 | import org.janusgraph.diskstorage.log.KCVSLogTest; 21 | 22 | import org.janusgraph.FoundationDBContainer; 23 | import org.testcontainers.junit.jupiter.Container; 24 | import org.testcontainers.junit.jupiter.Testcontainers; 25 | 26 | /** 27 | * @author Ted Wilmes (twilmes@gmail.com) 28 | */ 29 | @Testcontainers 30 | public class FoundationDBLogTest extends KCVSLogTest { 31 | 32 | @Container 33 | public static FoundationDBContainer container = new FoundationDBContainer(); 34 | 35 | public KeyColumnValueStoreManager openStorageManager() throws BackendException { 36 | FoundationDBStoreManager sm = new FoundationDBStoreManager(container.getFoundationDBConfiguration()); 37 | return new OrderedKeyValueStoreManagerAdapter(sm); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/diskstorage/foundationdb/FoundationDBVariableLengthKCVSTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.diskstorage.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.BackendException; 18 | import org.janusgraph.diskstorage.KeyColumnValueStoreTest; 19 | import org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStoreManager; 20 | import org.janusgraph.diskstorage.keycolumnvalue.keyvalue.OrderedKeyValueStoreManagerAdapter; 21 | 22 | import org.janusgraph.FoundationDBContainer; 23 | import org.junit.jupiter.api.Test; 24 | import org.testcontainers.junit.jupiter.Container; 25 | import org.testcontainers.junit.jupiter.Testcontainers; 26 | 27 | /** 28 | * @author Ted Wilmes (twilmes@gmail.com) 29 | */ 30 | @Testcontainers 31 | public class FoundationDBVariableLengthKCVSTest extends KeyColumnValueStoreTest { 32 | 33 | @Container 34 | public static FoundationDBContainer container = new FoundationDBContainer(); 35 | 36 | public KeyColumnValueStoreManager openStorageManager() throws BackendException { 37 | FoundationDBStoreManager sm = new FoundationDBStoreManager(container.getFoundationDBConfiguration()); 38 | return new OrderedKeyValueStoreManagerAdapter(sm); 39 | } 40 | 41 | @Test 42 | @Override 43 | public void testConcurrentGetSlice() { 44 | 45 | } 46 | 47 | @Test @Override 48 | public void testConcurrentGetSliceAndMutate() { 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/database/management/FoundationDBManagementTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.database.management; 16 | 17 | import org.janusgraph.FoundationDBContainer; 18 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 19 | import org.testcontainers.junit.jupiter.Container; 20 | import org.testcontainers.junit.jupiter.Testcontainers; 21 | 22 | /** 23 | * @author Ted Wilmes (twilmes@gmail.com) 24 | */ 25 | @Testcontainers 26 | public class FoundationDBManagementTest extends ManagementTest { 27 | 28 | @Container 29 | public static FoundationDBContainer container = new FoundationDBContainer(); 30 | 31 | @Override 32 | public WriteConfiguration getConfiguration() { 33 | return container.getFoundationDBGraphConfiguration(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBGraphConcurrentTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 18 | import org.janusgraph.graphdb.JanusGraphConcurrentTest; 19 | 20 | import org.janusgraph.FoundationDBContainer; 21 | import org.junit.jupiter.api.Disabled; 22 | import org.testcontainers.junit.jupiter.Container; 23 | import org.testcontainers.junit.jupiter.Testcontainers; 24 | 25 | /** 26 | * @author Ted Wilmes (twilmes@gmail.com) 27 | */ 28 | @Testcontainers 29 | @Disabled 30 | public class FoundationDBGraphConcurrentTest extends JanusGraphConcurrentTest { 31 | 32 | @Container 33 | public static FoundationDBContainer container = new FoundationDBContainer(); 34 | 35 | @Override 36 | public WriteConfiguration getConfiguration() { 37 | return container.getFoundationDBGraphConfiguration(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBGraphPerformanceMemoryTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 18 | import org.janusgraph.graphdb.JanusGraphPerformanceMemoryTest; 19 | import org.janusgraph.FoundationDBContainer; 20 | import org.testcontainers.junit.jupiter.Container; 21 | import org.testcontainers.junit.jupiter.Testcontainers; 22 | 23 | /** 24 | * @author Ted Wilmes (twilmes@gmail.com) 25 | */ 26 | @Testcontainers 27 | public class FoundationDBGraphPerformanceMemoryTest extends JanusGraphPerformanceMemoryTest { 28 | 29 | @Container 30 | public static FoundationDBContainer container = new FoundationDBContainer(); 31 | 32 | @Override 33 | public WriteConfiguration getConfiguration() { 34 | return container.getFoundationDBGraphConfiguration(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBGraphTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import java.time.Duration; 18 | import java.time.temporal.ChronoUnit; 19 | 20 | import org.janusgraph.core.JanusGraphException; 21 | import org.janusgraph.core.JanusGraphFactory; 22 | import org.janusgraph.diskstorage.BackendException; 23 | import org.janusgraph.diskstorage.configuration.ConfigOption; 24 | import org.janusgraph.diskstorage.configuration.ModifiableConfiguration; 25 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 26 | import org.janusgraph.graphdb.JanusGraphTest; 27 | import org.junit.jupiter.api.Disabled; 28 | import org.junit.jupiter.api.Test; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | 32 | import org.janusgraph.FoundationDBContainer; 33 | import org.janusgraph.diskstorage.foundationdb.FoundationDBConfigOptions; 34 | import org.janusgraph.diskstorage.foundationdb.FoundationDBTx.IsolationLevel; 35 | import org.testcontainers.junit.jupiter.Container; 36 | import org.testcontainers.junit.jupiter.Testcontainers; 37 | 38 | import static org.junit.jupiter.api.Assertions.assertEquals; 39 | import static org.junit.jupiter.api.Assertions.assertThrows; 40 | import static org.junit.jupiter.api.Assertions.assertTrue; 41 | 42 | /** 43 | * @author Ted Wilmes (twilmes@gmail.com) 44 | */ 45 | @Testcontainers 46 | public class FoundationDBGraphTest extends JanusGraphTest { 47 | 48 | @Container 49 | public static FoundationDBContainer container = new FoundationDBContainer(); 50 | 51 | private static final Logger log = 52 | LoggerFactory.getLogger(FoundationDBGraphTest.class); 53 | 54 | @Override 55 | public WriteConfiguration getConfiguration() { 56 | ModifiableConfiguration modifiableConfiguration = container.getFoundationDBConfiguration(); 57 | String methodName = testInfo.getTestMethod().toString(); 58 | if (methodName.equals("testConsistencyEnforcement")) { 59 | IsolationLevel iso = IsolationLevel.SERIALIZABLE; 60 | log.debug("Forcing isolation level {} for test method {}", iso, methodName); 61 | modifiableConfiguration.set(FoundationDBConfigOptions.ISOLATION_LEVEL, iso.toString()); 62 | } else { 63 | IsolationLevel iso = null; 64 | if (modifiableConfiguration.has(FoundationDBConfigOptions.ISOLATION_LEVEL)) { 65 | iso = ConfigOption.getEnumValue(modifiableConfiguration.get(FoundationDBConfigOptions.ISOLATION_LEVEL),IsolationLevel.class); 66 | } 67 | log.debug("Using isolation level {} (null means adapter default) for test method {}", iso, methodName); 68 | } 69 | return modifiableConfiguration.getConfiguration(); 70 | } 71 | 72 | 73 | @Test 74 | public void testVertexCentricQuerySmall() { 75 | testVertexCentricQuery(1450 /*noVertices*/); 76 | } 77 | 78 | @Test 79 | @Disabled 80 | @Override 81 | public void testConsistencyEnforcement() { 82 | // Check that getConfiguration() explicitly set serializable isolation 83 | // This could be enforced with a JUnit assertion instead of a Precondition, 84 | // but a failure here indicates a problem in the test itself rather than the 85 | // system-under-test, so a Precondition seems more appropriate 86 | //IsolationLevel effective = ConfigOption.getEnumValue(config.get(ConfigElement.getPath(FoundationDBStoreManager.ISOLATION_LEVEL), String.class),IsolationLevel.class); 87 | //Preconditions.checkState(IsolationLevel.SERIALIZABLE.equals(effective)); 88 | super.testConsistencyEnforcement(); 89 | } 90 | 91 | @Test 92 | @Disabled 93 | @Override 94 | public void testConcurrentConsistencyEnforcement() {} 95 | 96 | @Test 97 | public void testIDBlockAllocationTimeout() throws BackendException { 98 | config.set("ids.authority.wait-time", Duration.of(0L, ChronoUnit.NANOS)); 99 | config.set("ids.renew-timeout", Duration.of(1L, ChronoUnit.MILLIS)); 100 | close(); 101 | JanusGraphFactory.drop(graph); 102 | open(config); 103 | assertThrows(JanusGraphException.class, () -> { 104 | graph.addVertex(); 105 | }); 106 | 107 | assertTrue(graph.isOpen()); 108 | 109 | close(); // must be able to close cleanly 110 | 111 | // Must be able to reopen 112 | open(config); 113 | 114 | assertEquals(0L, (long) graph.traversal().V().count().next()); 115 | } 116 | 117 | @Test 118 | @Disabled("disabled because exceeds FDB transaction commit limit") 119 | @Override 120 | public void testLargeJointIndexRetrieval() {} 121 | 122 | @Test 123 | @Disabled 124 | @Override 125 | public void testIndexShouldRegisterWhenWeRemoveAnInstance(){} 126 | 127 | @Test 128 | @Disabled 129 | @Override 130 | public void testIndexUpdateSyncWithMultipleInstances(){} 131 | 132 | @Test 133 | @Override 134 | public void testVertexCentricQuery() { 135 | // updated to not exceed FDB transaction commit limit 136 | testVertexCentricQuery(1000 /*noVertices*/); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBOLAPTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import org.janusgraph.FoundationDBContainer; 18 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 19 | import org.janusgraph.olap.OLAPTest; 20 | import org.testcontainers.junit.jupiter.Container; 21 | import org.testcontainers.junit.jupiter.Testcontainers; 22 | 23 | /** 24 | * @author Ted Wilmes (twilmes@gmail.com) 25 | */ 26 | @Testcontainers 27 | public class FoundationDBOLAPTest extends OLAPTest { 28 | 29 | @Container 30 | public static FoundationDBContainer container = new FoundationDBContainer(); 31 | 32 | @Override 33 | public WriteConfiguration getConfiguration() { 34 | return container.getFoundationDBGraphConfiguration(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBOperationCountingTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 18 | import org.janusgraph.graphdb.JanusGraphOperationCountingTest; 19 | 20 | import org.janusgraph.FoundationDBContainer; 21 | import org.junit.jupiter.api.Disabled; 22 | import org.junit.jupiter.api.Test; 23 | import org.testcontainers.junit.jupiter.Container; 24 | import org.testcontainers.junit.jupiter.Testcontainers; 25 | 26 | /** 27 | * @author Ted Wilmes (twilmes@gmail.com) 28 | */ 29 | @Testcontainers 30 | public class FoundationDBOperationCountingTest extends JanusGraphOperationCountingTest { 31 | 32 | @Container 33 | public static FoundationDBContainer container = new FoundationDBContainer(); 34 | 35 | @Override 36 | public WriteConfiguration getBaseConfiguration() { 37 | return container.getFoundationDBGraphConfiguration(); 38 | } 39 | 40 | @Test 41 | @Disabled 42 | @Override 43 | public void testCacheConcurrency(){} 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/org/janusgraph/graphdb/foundationdb/FoundationDBPartitionGraphTest.java: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Expero Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package org.janusgraph.graphdb.foundationdb; 16 | 17 | import org.janusgraph.diskstorage.configuration.WriteConfiguration; 18 | import org.janusgraph.graphdb.JanusGraphPartitionGraphTest; 19 | 20 | import org.janusgraph.FoundationDBContainer; 21 | import org.testcontainers.junit.jupiter.Container; 22 | import org.testcontainers.junit.jupiter.Testcontainers; 23 | 24 | /** 25 | * @author Ted Wilmes (twilmes@gmail.com) 26 | */ 27 | @Testcontainers 28 | public class FoundationDBPartitionGraphTest extends JanusGraphPartitionGraphTest { 29 | 30 | @Container 31 | public static FoundationDBContainer container = new FoundationDBContainer(); 32 | 33 | @Override 34 | public WriteConfiguration getBaseConfiguration() { 35 | return container.getFoundationDBGraphConfiguration(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/fdb/empty: -------------------------------------------------------------------------------- 1 | #this file intentionally left blank 2 | -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Copyright 2020 JanusGraph Authors 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | log4j.appender.A1=org.apache.log4j.FileAppender 17 | log4j.appender.A1.File=${project.build.directory}/test.log 18 | log4j.appender.A1.Threshold=ALL 19 | log4j.appender.A1.layout=org.apache.log4j.PatternLayout 20 | log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%20.20t] %-5p %30.30c: %m%n 21 | 22 | log4j.appender.A2=org.apache.log4j.ConsoleAppender 23 | log4j.appender.A2.Threshold=ALL 24 | log4j.appender.A2.layout=org.apache.log4j.PatternLayout 25 | log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%20.20t] %-5p %30.30c: %m%n 26 | 27 | log4j.rootLogger=INFO, A1, A2 28 | --------------------------------------------------------------------------------