Initial implementation extracted from Gerrit stable-3.5
Files removed from Gerrit core in Change Ib7b5167ce2
and added to a separate project, packaged as libModule.
Having an external libModule allows Gerrit core to be
independent from ElasticSearch and, at the same time,
allow existing users to keep their setup without having
to migrate their indexes.
Original-Author: Alice Kober-Sotzek <aliceks@google.com>
Original-Author: Dave Borowitz <dborowitz@google.com>
Original-Author: David Ostrovsky <david@ostrovsky.org>
Original-Author: David Pursehouse <dpursehouse@collab.net>
Original-Author: David Pursehouse <dpursehouse@digital.ai>
Original-Author: Dmitrii Filippov <dmfilippov@google.com>
Original-Author: Dyrone Teng <dyroneteng@gmail.com>
Original-Author: Edwin Kempin <ekempin@google.com>
Original-Author: Gal Paikin <paiking@google.com>
Original-Author: Han-Wen Nienhuys <hanwen@google.com>
Original-Author: Hugo Arès <hugo.ares@ericsson.com>
Original-Author: Jacek Centkowski <jcentkowski@collab.net>
Original-Author: Joerg Zieren <zieren@google.com>
Original-Author: Marco Miller <marco.miller@ericsson.com>
Original-Author: Marija Savtchouk <mariasavtchouk@google.com>
Original-Author: Maxime Guerreiro <maximeg@google.com>
Original-Author: Paladox <thomasmulhall410@yahoo.com>
Original-Author: Pat Long <pllong@arista.com>
Original-Author: Patrick Hiesel <hiesel@google.com>
Original-Author: Sven Selberg <svense@axis.com>
Change-Id: I25586488ff7044ab4f05e2357cd272e9fb661a69
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..06352ab
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,110 @@
+load("@rules_java//java:defs.bzl", "java_library")
+load("//tools/bzl:junit.bzl", "junit_tests")
+load("//javatests/com/google/gerrit/acceptance:tests.bzl", "acceptance_tests")
+load(
+ "//tools/bzl:plugin.bzl",
+ "PLUGIN_DEPS",
+ "PLUGIN_TEST_DEPS",
+ "gerrit_plugin",
+)
+
+gerrit_plugin (
+ name = "index-elasticsearch",
+ srcs = glob(["src/main/java/**/*.java"]),
+ deps = [
+ "//java/com/google/gerrit/common:annotations",
+ "//java/com/google/gerrit/entities",
+ "//java/com/google/gerrit/exceptions",
+ "//java/com/google/gerrit/extensions:api",
+ "//java/com/google/gerrit/index",
+ "//java/com/google/gerrit/index:query_exception",
+ "//java/com/google/gerrit/index/project",
+ "//java/com/google/gerrit/lifecycle",
+ "//java/com/google/gerrit/proto",
+ "//java/com/google/gerrit/server",
+ "//lib:gson",
+ "//lib:guava",
+ "//lib:jgit",
+ "//lib:protobuf",
+ "//lib/commons:lang",
+ "@elasticsearch-rest-client//jar",
+ "//lib/flogger:api",
+ "//lib/guice",
+ "//lib/guice:guice-assistedinject",
+ "@httpasyncclient//jar",
+ "//lib/httpcomponents:httpclient",
+ "//lib/httpcomponents:httpcore",
+ "@httpcore-nio//jar",
+ "@jackson-core//jar",
+ ],
+)
+
+java_library(
+ name = "elasticsearch_test_utils",
+ testonly = True,
+ srcs = [],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//java/com/google/gerrit/index",
+ "//lib:guava",
+ "//lib:jgit",
+ "//lib:junit",
+ "//lib/guice",
+ "//lib/httpcomponents:httpcore",
+ "//lib/jackson:jackson-annotations",
+ "//lib/testcontainers",
+ "//lib/testcontainers:docker-java-api",
+ "//lib/testcontainers:docker-java-transport",
+ "@testcontainers-elasticsearch//jar",
+ ":index-elasticsearch__plugin",
+ ],
+)
+
+ELASTICSEARCH_DEPS = [
+ ":elasticsearch_test_utils",
+ "//java/com/google/gerrit/testing:gerrit-test-util",
+ "//lib/guice",
+ "//lib:jgit",
+]
+
+HTTP_TEST_DEPS = [
+ "@httpasyncclient//jar",
+ "//lib/httpcomponents:httpclient",
+]
+
+QUERY_TESTS_DEP = "//javatests/com/google/gerrit/server/query/%s:abstract_query_tests"
+
+TYPES = [
+ "account",
+ "change",
+ "group",
+ "project",
+]
+
+SUFFIX = "sTest.java"
+
+ELASTICSEARCH_TESTS_V7 = {i: "ElasticV7Query" + i.capitalize() + SUFFIX for i in TYPES}
+
+ELASTICSEARCH_TAGS = [
+ "docker",
+ "elastic",
+]
+
+junit_tests(
+ name = "index-elasticsearch_tests",
+ size = "small",
+ srcs = glob(
+ ["src/test/java/**/*Test.java"],
+ exclude = ["Elastic*Query*" + SUFFIX],
+ ),
+ tags = ["elastic"],
+ deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+ "//java/com/google/gerrit/testing:gerrit-test-util",
+ "//lib:guava",
+ "//lib:jgit",
+ "//lib/guice",
+ "//lib/httpcomponents:httpcore",
+ "//lib/truth",
+ ":elasticsearch_test_utils",
+ ],
+)
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..a8708e7
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,2 @@
+pluginPipeline(formatCheckId: 'gerritforge:index-elasticsearch-code-style',
+ buildCheckId: 'gerritforge:index-elasticsearch-build-test')
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6565f33
--- /dev/null
+++ b/README.md
@@ -0,0 +1,44 @@
+# Index backend for Gerrit, based on ElasticSearch
+
+Indexing backend libModule for [Gerrit Code Review](https://gerritcodereview.com)
+based on [ElasticSearch](https://www.elastic.co/elasticsearch/).
+
+This module was original part of Gerrit core and then extracted into a separate
+component from v3.5.0-rc3 as part of [Change-Id: Ib7b5167ce](https://gerrit-review.googlesource.com/c/gerrit/+/323676).
+
+## How to build
+
+This libModule is built like a Gerrit in-tree plugin, using Bazelisk. See the
+[build instructions](src/main/resources/Documentation/build.md) for more details.
+
+## Setup
+
+* Install index-elasticsearch module
+
+Install the index-elasticsearch.jar into the `$GERRIT_SITE/lib` directory.
+
+Add the index-elasticsearch module to `$GERRIT_SITE/etc/gerrit.config` as follows:
+
+```ini
+[gerrit]
+ installIndexModule = com.google.gerrit.elasticsearch.ElasticIndexModule
+```
+
+When installing the module on Gerrit replicas, use following example:
+
+```ini
+[gerrit]
+ installIndexModule = com.google.gerrit.elasticsearch.ReplicaElasticIndexModule
+```
+
+For further information and supported options, refer to [config](src/main/resources/Documentation/config.md)
+documentation.
+
+## Integration test
+
+Gerrit acceptance tests allow the execution with an alternate implementation of
+the indexing backend using the `GERRIT_INDEX_MODULE` environment variable.
+
+```sh
+bazel test --test_env=GERRIT_INDEX_MODULE=com.google.gerrit.elasticsearch.ElasticIndexModule //...
+```
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
new file mode 100644
index 0000000..b863175
--- /dev/null
+++ b/external_plugin_deps.bzl
@@ -0,0 +1,49 @@
+load("//tools/bzl:maven_jar.bzl", "maven_jar")
+
+TESTCONTAINERS_VERSION = "1.15.3"
+
+# Ensure artifacts compatibility by selecting them from the Bill Of Materials
+# https://search.maven.org/artifact/net.openhft/chronicle-bom/2.20.191/pom
+def external_plugin_deps():
+ # When upgrading elasticsearch-rest-client, also upgrade httpcore-nio
+ # and httpasyncclient as necessary in tools/nongoogle.bzl. Consider
+ # also the other org.apache.httpcomponents dependencies in
+ # WORKSPACE.
+ maven_jar(
+ name = "elasticsearch-rest-client",
+ artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.8.1",
+ sha1 = "59feefe006a96a39f83b0dfb6780847e06c1d0a8",
+ )
+
+ maven_jar(
+ name = "testcontainers-elasticsearch",
+ artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
+ sha1 = "595e3a50f59cd3c1d281ca6c1bc4037e277a1353",
+ )
+
+ # elasticsearch-rest-client explicitly depends on this version
+ maven_jar(
+ name = "httpasyncclient",
+ artifact = "org.apache.httpcomponents:httpasyncclient:4.1.4",
+ sha1 = "f3a3240681faae3fa46b573a4c7e50cec9db0d86",
+ )
+
+ # elasticsearch-rest-client explicitly depends on this version
+ maven_jar(
+ name = "httpcore-nio",
+ artifact = "org.apache.httpcomponents:httpcore-nio:4.4.12",
+ sha1 = "84cd29eca842f31db02987cfedea245af020198b",
+ )
+
+ maven_jar(
+ name = "jackson-core",
+ artifact = "com.fasterxml.jackson.core:jackson-core:2.11.3",
+ sha1 = "c2351800432bdbdd8284c3f5a7f0782a352aa84a",
+ )
+
+ maven_jar(
+ name = "httpasyncclient",
+ artifact = "org.apache.httpcomponents:httpasyncclient:4.1.4",
+ sha1 = "f3a3240681faae3fa46b573a4c7e50cec9db0d86",
+ )
+
diff --git a/java/com/google/gerrit/elasticsearch/BUILD b/java/com/google/gerrit/elasticsearch/BUILD
deleted file mode 100644
index 8bab80b..0000000
--- a/java/com/google/gerrit/elasticsearch/BUILD
+++ /dev/null
@@ -1,33 +0,0 @@
-load("@rules_java//java:defs.bzl", "java_library")
-
-java_library(
- name = "elasticsearch",
- srcs = glob(["**/*.java"]),
- visibility = ["//visibility:public"],
- deps = [
- "//java/com/google/gerrit/common:annotations",
- "//java/com/google/gerrit/entities",
- "//java/com/google/gerrit/exceptions",
- "//java/com/google/gerrit/extensions:api",
- "//java/com/google/gerrit/index",
- "//java/com/google/gerrit/index:query_exception",
- "//java/com/google/gerrit/index/project",
- "//java/com/google/gerrit/lifecycle",
- "//java/com/google/gerrit/proto",
- "//java/com/google/gerrit/server",
- "//lib:gson",
- "//lib:guava",
- "//lib:jgit",
- "//lib:protobuf",
- "//lib/commons:lang",
- "//lib/elasticsearch-rest-client",
- "//lib/flogger:api",
- "//lib/guice",
- "//lib/guice:guice-assistedinject",
- "//lib/httpcomponents:httpasyncclient",
- "//lib/httpcomponents:httpclient",
- "//lib/httpcomponents:httpcore",
- "//lib/httpcomponents:httpcore-nio",
- "//lib/jackson:jackson-core",
- ],
-)
diff --git a/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java b/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java
deleted file mode 100644
index f086ab1..0000000
--- a/java/com/google/gerrit/pgm/init/index/elasticsearch/ElasticIndexModuleOnInit.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.pgm.init.index.elasticsearch;
-
-import com.google.gerrit.elasticsearch.ElasticAccountIndex;
-import com.google.gerrit.elasticsearch.ElasticGroupIndex;
-import com.google.gerrit.pgm.init.index.IndexModuleOnInit;
-import com.google.gerrit.server.index.account.AccountIndex;
-import com.google.gerrit.server.index.group.GroupIndex;
-import com.google.inject.AbstractModule;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-public class ElasticIndexModuleOnInit extends AbstractModule {
-
- @Override
- protected void configure() {
- install(
- new FactoryModuleBuilder()
- .implement(AccountIndex.class, ElasticAccountIndex.class)
- .build(AccountIndex.Factory.class));
-
- install(
- new FactoryModuleBuilder()
- .implement(GroupIndex.class, ElasticGroupIndex.class)
- .build(GroupIndex.Factory.class));
-
- install(new IndexModuleOnInit());
- }
-}
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
deleted file mode 100644
index 0632241..0000000
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.acceptance.pgm;
-
-import static com.google.gerrit.elasticsearch.ElasticTestUtils.getConfig;
-
-import com.google.gerrit.elasticsearch.ElasticVersion;
-import com.google.gerrit.testing.ConfigSuite;
-import org.eclipse.jgit.lib.Config;
-
-public class ElasticReindexIT extends AbstractReindexTests {
- @ConfigSuite.Default
- public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_8);
- }
-}
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
deleted file mode 100644
index f35bcb7..0000000
--- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.acceptance.ssh;
-
-import static com.google.gerrit.elasticsearch.ElasticTestUtils.createAllIndexes;
-import static com.google.gerrit.elasticsearch.ElasticTestUtils.getConfig;
-
-import com.google.gerrit.elasticsearch.ElasticVersion;
-import com.google.gerrit.index.IndexType;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.inject.Injector;
-import org.eclipse.jgit.lib.Config;
-
-/** Tests for every supported {@link IndexType#isElasticsearch()} most recent index version. */
-public class ElasticIndexIT extends AbstractIndexTests {
-
- @ConfigSuite.Default
- public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_8);
- }
-
- @Override
- public void configureIndex(Injector injector) {
- createAllIndexes(injector);
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/BUILD b/javatests/com/google/gerrit/elasticsearch/BUILD
deleted file mode 100644
index 3036811..0000000
--- a/javatests/com/google/gerrit/elasticsearch/BUILD
+++ /dev/null
@@ -1,85 +0,0 @@
-load("@rules_java//java:defs.bzl", "java_library")
-load("//tools/bzl:junit.bzl", "junit_tests")
-
-java_library(
- name = "elasticsearch_test_utils",
- testonly = True,
- srcs = [
- "ElasticContainer.java",
- "ElasticTestUtils.java",
- ],
- visibility = ["//visibility:public"],
- deps = [
- "//java/com/google/gerrit/elasticsearch",
- "//java/com/google/gerrit/index",
- "//lib:guava",
- "//lib:jgit",
- "//lib:junit",
- "//lib/guice",
- "//lib/httpcomponents:httpcore",
- "//lib/jackson:jackson-annotations",
- "//lib/log:api",
- "//lib/testcontainers",
- "//lib/testcontainers:docker-java-api",
- "//lib/testcontainers:docker-java-transport",
- "//lib/testcontainers:testcontainers-elasticsearch",
- ],
-)
-
-ELASTICSEARCH_DEPS = [
- ":elasticsearch_test_utils",
- "//java/com/google/gerrit/elasticsearch",
- "//java/com/google/gerrit/testing:gerrit-test-util",
- "//lib/guice",
- "//lib:jgit",
-]
-
-HTTP_TEST_DEPS = [
- "//lib/httpcomponents:httpasyncclient",
- "//lib/httpcomponents:httpclient",
-]
-
-QUERY_TESTS_DEP = "//javatests/com/google/gerrit/server/query/%s:abstract_query_tests"
-
-TYPES = [
- "account",
- "change",
- "group",
- "project",
-]
-
-SUFFIX = "sTest.java"
-
-ELASTICSEARCH_TESTS_V7 = {i: "ElasticV7Query" + i.capitalize() + SUFFIX for i in TYPES}
-
-ELASTICSEARCH_TAGS = [
- "docker",
- "elastic",
-]
-
-[junit_tests(
- name = "elasticsearch_query_%ss_test_V7" % name,
- size = "large",
- srcs = [src],
- tags = ELASTICSEARCH_TAGS,
- deps = ELASTICSEARCH_DEPS + [QUERY_TESTS_DEP % name] + HTTP_TEST_DEPS,
-) for name, src in ELASTICSEARCH_TESTS_V7.items()]
-
-junit_tests(
- name = "elasticsearch_tests",
- size = "small",
- srcs = glob(
- ["*Test.java"],
- exclude = ["Elastic*Query*" + SUFFIX],
- ),
- tags = ["elastic"],
- deps = [
- "//java/com/google/gerrit/elasticsearch",
- "//java/com/google/gerrit/testing:gerrit-test-util",
- "//lib:guava",
- "//lib:jgit",
- "//lib/guice",
- "//lib/httpcomponents:httpcore",
- "//lib/truth",
- ],
-)
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
deleted file mode 100644
index c330961..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import org.apache.http.HttpHost;
-import org.junit.AssumptionViolatedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testcontainers.elasticsearch.ElasticsearchContainer;
-import org.testcontainers.utility.DockerImageName;
-
-/* Helper class for running ES integration tests in docker container */
-public class ElasticContainer extends ElasticsearchContainer {
- private static final int ELASTICSEARCH_DEFAULT_PORT = 9200;
-
- public static ElasticContainer createAndStart(ElasticVersion version) {
- // Assumption violation is not natively supported by Testcontainers.
- // See https://github.com/testcontainers/testcontainers-java/issues/343
- try {
- ElasticContainer container = new ElasticContainer(version);
- container.start();
- return container;
- } catch (Throwable t) {
- throw new AssumptionViolatedException("Unable to start container", t);
- }
- }
-
- private static String getImageName(ElasticVersion version) {
- switch (version) {
- case V7_6:
- return "blacktop/elasticsearch:7.6.2";
- case V7_7:
- return "blacktop/elasticsearch:7.7.1";
- case V7_8:
- return "blacktop/elasticsearch:7.8.1";
- }
- throw new IllegalStateException("No tests for version: " + version.name());
- }
-
- private ElasticContainer(ElasticVersion version) {
- super(
- DockerImageName.parse(getImageName(version))
- .asCompatibleSubstituteFor("docker.elastic.co/elasticsearch/elasticsearch"));
- }
-
- @Override
- protected Logger logger() {
- return LoggerFactory.getLogger("org.testcontainers");
- }
-
- public HttpHost getHttpHost() {
- return new HttpHost(getContainerIpAddress(), getMappedPort(ELASTICSEARCH_DEFAULT_PORT));
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java b/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
deleted file mode 100644
index dcc6880..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import com.google.gerrit.index.IndexDefinition;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.TypeLiteral;
-import java.util.Collection;
-import java.util.UUID;
-import org.eclipse.jgit.lib.Config;
-
-public final class ElasticTestUtils {
- public static void configure(Config config, ElasticContainer container, String prefix) {
- String hostname = container.getHttpHost().getHostName();
- int port = container.getHttpHost().getPort();
- config.setString("index", null, "type", "elasticsearch");
- config.setString("elasticsearch", null, "server", "http://" + hostname + ":" + port);
- config.setString("elasticsearch", null, "prefix", prefix);
- config.setInt("index", null, "maxLimit", 10000);
- }
-
- public static void createAllIndexes(Injector injector) {
- Collection<IndexDefinition<?, ?, ?>> indexDefs =
- injector.getInstance(Key.get(new TypeLiteral<Collection<IndexDefinition<?, ?, ?>>>() {}));
- for (IndexDefinition<?, ?, ?> indexDef : indexDefs) {
- indexDef.getIndexCollection().getSearchIndex().deleteAll();
- }
- }
-
- public static Config getConfig(ElasticVersion version) {
- ElasticContainer container = ElasticContainer.createAndStart(version);
- String indicesPrefix = UUID.randomUUID().toString();
- Config cfg = new Config();
- configure(cfg, container, indicesPrefix);
- return cfg;
- }
-
- private ElasticTestUtils() {
- // hide default constructor
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
deleted file mode 100644
index 4826490..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import com.google.gerrit.server.query.account.AbstractQueryAccountsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.gerrit.testing.InMemoryModule;
-import com.google.gerrit.testing.IndexConfig;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class ElasticV7QueryAccountsTest extends AbstractQueryAccountsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return IndexConfig.createForElasticsearch();
- }
-
- private static ElasticContainer container;
-
- @BeforeClass
- public static void startIndexService() {
- if (container == null) {
- // Only start Elasticsearch once
- container = ElasticContainer.createAndStart(ElasticVersion.V7_8);
- }
- }
-
- @AfterClass
- public static void stopElasticsearchServer() {
- if (container != null) {
- container.stop();
- }
- }
-
- @Override
- protected void initAfterLifecycleStart() throws Exception {
- super.initAfterLifecycleStart();
- ElasticTestUtils.createAllIndexes(injector);
- }
-
- @Override
- protected Injector createInjector() {
- Config elasticsearchConfig = new Config(config);
- InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName.getSanitizedMethodName();
- ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix);
- return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
deleted file mode 100644
index d9a4d2e..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import static java.util.concurrent.TimeUnit.MINUTES;
-
-import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.gerrit.testing.GerritTestName;
-import com.google.gerrit.testing.InMemoryModule;
-import com.google.gerrit.testing.IndexConfig;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClients;
-import org.eclipse.jgit.lib.Config;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-
-public class ElasticV7QueryChangesTest extends AbstractQueryChangesTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return IndexConfig.createForElasticsearch();
- }
-
- private static ElasticContainer container;
- private static CloseableHttpAsyncClient client;
-
- @BeforeClass
- public static void startIndexService() {
- if (container == null) {
- // Only start Elasticsearch once
- container = ElasticContainer.createAndStart(ElasticVersion.V7_8);
- client = HttpAsyncClients.createDefault();
- client.start();
- }
- }
-
- @AfterClass
- public static void stopElasticsearchServer() {
- if (container != null) {
- container.stop();
- }
- }
-
- @Rule public final GerritTestName testName = new GerritTestName();
-
- @After
- public void closeIndex() throws Exception {
- // Close the index after each test to prevent exceeding Elasticsearch's
- // shard limit (see Issue 10120).
- client
- .execute(
- new HttpPost(
- String.format(
- "http://%s:%d/%s*/_close",
- container.getHttpHost().getHostName(),
- container.getHttpHost().getPort(),
- testName.getSanitizedMethodName())),
- HttpClientContext.create(),
- null)
- .get(5, MINUTES);
- }
-
- @Override
- protected void initAfterLifecycleStart() throws Exception {
- super.initAfterLifecycleStart();
- ElasticTestUtils.createAllIndexes(injector);
- }
-
- @Override
- protected Injector createInjector() {
- Config elasticsearchConfig = new Config(config);
- InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName.getSanitizedMethodName();
- ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix);
- return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
deleted file mode 100644
index 0fc96f8..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import com.google.gerrit.server.query.group.AbstractQueryGroupsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.gerrit.testing.InMemoryModule;
-import com.google.gerrit.testing.IndexConfig;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class ElasticV7QueryGroupsTest extends AbstractQueryGroupsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return IndexConfig.createForElasticsearch();
- }
-
- private static ElasticContainer container;
-
- @BeforeClass
- public static void startIndexService() {
- if (container == null) {
- // Only start Elasticsearch once
- container = ElasticContainer.createAndStart(ElasticVersion.V7_8);
- }
- }
-
- @AfterClass
- public static void stopElasticsearchServer() {
- if (container != null) {
- container.stop();
- }
- }
-
- @Override
- protected void initAfterLifecycleStart() throws Exception {
- super.initAfterLifecycleStart();
- ElasticTestUtils.createAllIndexes(injector);
- }
-
- @Override
- protected Injector createInjector() {
- Config elasticsearchConfig = new Config(config);
- InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName.getSanitizedMethodName();
- ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix);
- return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
- }
-}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
deleted file mode 100644
index 1e56af9..0000000
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.elasticsearch;
-
-import com.google.gerrit.server.query.project.AbstractQueryProjectsTest;
-import com.google.gerrit.testing.ConfigSuite;
-import com.google.gerrit.testing.InMemoryModule;
-import com.google.gerrit.testing.IndexConfig;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import org.eclipse.jgit.lib.Config;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class ElasticV7QueryProjectsTest extends AbstractQueryProjectsTest {
- @ConfigSuite.Default
- public static Config defaultConfig() {
- return IndexConfig.createForElasticsearch();
- }
-
- private static ElasticContainer container;
-
- @BeforeClass
- public static void startIndexService() {
- if (container == null) {
- // Only start Elasticsearch once
- container = ElasticContainer.createAndStart(ElasticVersion.V7_8);
- }
- }
-
- @AfterClass
- public static void stopElasticsearchServer() {
- if (container != null) {
- container.stop();
- }
- }
-
- @Override
- protected void initAfterLifecycleStart() throws Exception {
- super.initAfterLifecycleStart();
- ElasticTestUtils.createAllIndexes(injector);
- }
-
- @Override
- protected Injector createInjector() {
- Config elasticsearchConfig = new Config(config);
- InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = testName.getSanitizedMethodName();
- ElasticTestUtils.configure(elasticsearchConfig, container, indicesPrefix);
- return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
- }
-}
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
rename to src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
similarity index 97%
rename from java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
index c443529..e544d9f 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticConfiguration.java
@@ -32,7 +32,7 @@
import org.elasticsearch.client.RestClientBuilder;
@Singleton
-class ElasticConfiguration {
+public class ElasticConfiguration {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
static final String SECTION_ELASTICSEARCH = "elasticsearch";
@@ -50,7 +50,7 @@
static final String DEFAULT_USERNAME = "elastic";
static final int DEFAULT_NUMBER_OF_SHARDS = 1;
static final int DEFAULT_NUMBER_OF_REPLICAS = 1;
- static final int DEFAULT_MAX_RESULT_WINDOW = 10000;
+ static final int DEFAULT_MAX_RESULT_WINDOW = Integer.MAX_VALUE;
static final int DEFAULT_CONNECT_TIMEOUT = RestClientBuilder.DEFAULT_CONNECT_TIMEOUT_MILLIS;
static final int DEFAULT_SOCKET_TIMEOUT = RestClientBuilder.DEFAULT_SOCKET_TIMEOUT_MILLIS;
diff --git a/java/com/google/gerrit/elasticsearch/ElasticException.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticException.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticException.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticException.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticIndexModule.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexModule.java
similarity index 81%
rename from java/com/google/gerrit/elasticsearch/ElasticIndexModule.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticIndexModule.java
index 15d6126..671e9f4 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticIndexModule.java
+++ b/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexModule.java
@@ -14,15 +14,21 @@
package com.google.gerrit.elasticsearch;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.index.project.ProjectIndex;
+import com.google.gerrit.server.ModuleImpl;
import com.google.gerrit.server.index.AbstractIndexModule;
import com.google.gerrit.server.index.VersionManager;
import com.google.gerrit.server.index.account.AccountIndex;
import com.google.gerrit.server.index.change.ChangeIndex;
import com.google.gerrit.server.index.group.GroupIndex;
+import com.google.inject.Inject;
import java.util.Map;
+@ModuleImpl(name = AbstractIndexModule.INDEX_MODULE)
public class ElasticIndexModule extends AbstractIndexModule {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
public static ElasticIndexModule singleVersionWithExplicitVersions(
Map<String, Integer> versions, int threads, boolean slave) {
return new ElasticIndexModule(versions, threads, slave);
@@ -32,12 +38,18 @@
return new ElasticIndexModule(null, 0, slave);
}
- private ElasticIndexModule(Map<String, Integer> singleVersions, int threads, boolean slave) {
+ protected ElasticIndexModule(Map<String, Integer> singleVersions, int threads, boolean slave) {
super(singleVersions, threads, slave);
}
+ @Inject
+ public ElasticIndexModule() {
+ this(null, 0, false);
+ }
+
@Override
public void configure() {
+ logger.atInfo().log("Gerrit index backend set to ElasticSearch");
super.configure();
install(ElasticRestClientProvider.module());
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticIndexVersionManager.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionManager.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticIndexVersionManager.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionManager.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticMapping.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticMapping.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticMapping.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticMapping.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticSetting.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticSetting.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticSetting.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticSetting.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticStoredValue.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticStoredValue.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticStoredValue.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticStoredValue.java
diff --git a/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/ElasticVersion.java
rename to src/main/java/com/google/gerrit/elasticsearch/ElasticVersion.java
diff --git a/src/main/java/com/google/gerrit/elasticsearch/PrimaryElasticIndexModule.java b/src/main/java/com/google/gerrit/elasticsearch/PrimaryElasticIndexModule.java
new file mode 100644
index 0000000..8500844
--- /dev/null
+++ b/src/main/java/com/google/gerrit/elasticsearch/PrimaryElasticIndexModule.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.server.ModuleImpl;
+import com.google.gerrit.server.index.AbstractIndexModule;
+
+@ModuleImpl(name = AbstractIndexModule.INDEX_MODULE)
+public class PrimaryElasticIndexModule extends ElasticIndexModule {
+
+ public PrimaryElasticIndexModule() {
+ super(null, 0, false);
+ }
+}
diff --git a/src/main/java/com/google/gerrit/elasticsearch/ReplicaElasticIndexModule.java b/src/main/java/com/google/gerrit/elasticsearch/ReplicaElasticIndexModule.java
new file mode 100644
index 0000000..8845cbe
--- /dev/null
+++ b/src/main/java/com/google/gerrit/elasticsearch/ReplicaElasticIndexModule.java
@@ -0,0 +1,26 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.elasticsearch;
+
+import com.google.gerrit.server.ModuleImpl;
+import com.google.gerrit.server.index.AbstractIndexModule;
+
+@ModuleImpl(name = AbstractIndexModule.INDEX_MODULE)
+public class ReplicaElasticIndexModule extends ElasticIndexModule {
+
+ public ReplicaElasticIndexModule() {
+ super(null, 0, true);
+ }
+}
diff --git a/java/com/google/gerrit/elasticsearch/builders/BoolQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/BoolQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/BoolQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/BoolQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/ExistsQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/ExistsQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/ExistsQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/ExistsQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/MatchAllQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/MatchAllQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/MatchAllQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/MatchAllQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/QueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/QueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/QueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/QueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java b/src/main/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/QuerySourceBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/QuerySourceBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/QuerySourceBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/QuerySourceBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/RangeQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/RangeQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/RangeQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/RangeQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/RegexpQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/RegexpQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/RegexpQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/RegexpQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/TermQueryBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/TermQueryBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/TermQueryBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/TermQueryBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/builders/XContentBuilder.java b/src/main/java/com/google/gerrit/elasticsearch/builders/XContentBuilder.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/builders/XContentBuilder.java
rename to src/main/java/com/google/gerrit/elasticsearch/builders/XContentBuilder.java
diff --git a/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java b/src/main/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
rename to src/main/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java
diff --git a/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java b/src/main/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java
rename to src/main/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java
diff --git a/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java b/src/main/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
rename to src/main/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java
diff --git a/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java b/src/main/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
rename to src/main/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java
diff --git a/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java b/src/main/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java
similarity index 100%
rename from java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java
rename to src/main/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java
diff --git a/src/main/java/com/google/gerrit/elasticsearch/init/InitElasticSearchIndex.java b/src/main/java/com/google/gerrit/elasticsearch/init/InitElasticSearchIndex.java
new file mode 100644
index 0000000..76b2d3b
--- /dev/null
+++ b/src/main/java/com/google/gerrit/elasticsearch/init/InitElasticSearchIndex.java
@@ -0,0 +1,73 @@
+package com.google.gerrit.elasticsearch.init;
+
+import com.google.common.collect.Iterables;
+import com.google.gerrit.index.IndexType;
+import com.google.gerrit.index.SchemaDefinitions;
+import com.google.gerrit.pgm.init.api.ConsoleUI;
+import com.google.gerrit.pgm.init.api.InitFlags;
+import com.google.gerrit.pgm.init.api.InitStep;
+import com.google.gerrit.pgm.init.api.Section;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.index.IndexModule;
+import com.google.gerrit.server.index.IndexUtils;
+import com.google.inject.Inject;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class InitElasticSearchIndex implements InitStep {
+ private final ConsoleUI ui;
+ private final Section index;
+ private final SitePaths site;
+ private final InitFlags initFlags;
+ private final Section gerrit;
+ private final Section.Factory sections;
+
+ @Inject
+ InitElasticSearchIndex(
+ ConsoleUI ui, Section.Factory sections, SitePaths site, InitFlags initFlags) {
+ this.ui = ui;
+ this.index = sections.get("index", null);
+ this.gerrit = sections.get("gerrit", null);
+ this.site = site;
+ this.initFlags = initFlags;
+ this.sections = sections;
+ }
+
+ @Override
+ public void run() throws IOException {
+ ui.header("Index");
+ IndexType type =
+ new IndexType(
+ index.select("Type", "type", IndexType.getDefault(), IndexType.getKnownTypes()));
+
+ Section elasticsearch = sections.get("elasticsearch", null);
+ elasticsearch.string("Index Prefix", "prefix", "gerrit_");
+ elasticsearch.string("Server", "server", "http://localhost:9200");
+ index.string("Result window size", "maxLimit", "10000");
+
+ if ((site.isNew || isEmptySite()) && type.isLucene()) {
+ for (SchemaDefinitions<?> def : IndexModule.ALL_SCHEMA_DEFS) {
+ IndexUtils.setReady(site, def.getName(), def.getLatest().getVersion(), true);
+ }
+ } else {
+ String message =
+ String.format(
+ "\nThe index must be %sbuilt before starting Gerrit:\n"
+ + " java -jar gerrit.war reindex -d site_path\n",
+ site.isNew ? "" : "re");
+ ui.message(message);
+ initFlags.autoStart = false;
+ }
+ }
+
+ private boolean isEmptySite() {
+ try (DirectoryStream<Path> files =
+ Files.newDirectoryStream(site.resolve(gerrit.get("basePath")))) {
+ return Iterables.isEmpty(files);
+ } catch (IOException e) {
+ return true;
+ }
+ }
+}
diff --git a/src/main/main.iml b/src/main/main.iml
new file mode 100644
index 0000000..908ad4f
--- /dev/null
+++ b/src/main/main.iml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
\ No newline at end of file
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
new file mode 100644
index 0000000..b6f6e51
--- /dev/null
+++ b/src/main/resources/Documentation/build.md
@@ -0,0 +1,37 @@
+# Build
+
+This plugin is built with Bazel in-tree build.
+
+## Build in Gerrit tree
+
+Create a symbolic link of the repsotiory source to the Gerrit source
+tree /plugins/index-elasticsearch directory, and the external_plugin_deps.bzl
+dependencies linked to /plugins/external_plugin_deps.bzl.
+
+Example:
+
+```sh
+git clone https://gerrit.googlesource.com/gerrit
+git clone https://gerrit.googlesource.com/modules/index-elasticsearch
+cd gerrit/plugins
+ln -s ../../index-elasticsearch index-elasticsearch
+ln -sf ../../external_plugin_deps.bzl .
+```
+
+From the Gerrit source tree issue the command `bazelsk build plugins/index-elasticsearch`.
+
+Example:
+
+```sh
+bazelisk build plugins/index-elasticsearch
+```
+
+The libModule jar file is created under `basel-bin/plugins/index-elasticsearch/index-elasticsearch.jar`
+
+To execute the tests run `bazelisk test plugins/index-elasticsearch/...` from the Gerrit source tree.
+
+Example:
+
+```sh
+bazelisk test plugins/index-elasticsearch/...
+```
\ No newline at end of file
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..2164d22
--- /dev/null
+++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,104 @@
+Configuration
+=============
+
+[[index]]
+=== Section index
+
+[[index.maxLimit]]index.maxLimit::
++
+Maximum limit to allow for search queries. Requesting results above this
+limit will truncate the list (but will still set `_more_changes` on
+result lists). Set to 0 for no limit.
+This value should not exceed the `index.max_result_window` value configured
+on the Elasticsearch server.
+If a value is not configured during site initialization, defaults to
+10000, which is the default value of `index.max_result_window` in Elasticsearch.
+
+[[elasticsearch]]
+=== Section elasticsearch
+
+WARNING: Support for Elasticsearch is still experimental and is not recommended
+for production use. For compatibility information, please refer to the
+link:https://www.gerritcodereview.com/elasticsearch.html[project homepage,role=external,window=_blank].
+
+Note that when Gerrit is configured to use Elasticsearch, the Elasticsearch
+server(s) must be reachable during the site initialization.
+
+[[elasticsearch.prefix]]elasticsearch.prefix::
++
+This setting can be used to prefix index names to allow multiple Gerrit
+instances in a single Elasticsearch cluster. Prefix `gerrit1_` would result in a
+change index named `gerrit1_changes_0001`.
++
+Not set by default.
+
+[[elasticsearch.server]]elasticsearch.server::
++
+Elasticsearch server URI in the form `http[s]://hostname:port`. The `port` is
+optional and defaults to `9200` if not specified.
++
+At least one server must be specified. May be specified multiple times to
+configure multiple Elasticsearch servers.
++
+Note that the site initialization program only allows to configure a single
+server. To configure multiple servers the `gerrit.config` file must be edited
+manually.
+
+[[elasticsearch.numberOfShards]]elasticsearch.numberOfShards::
++
+Sets the number of shards to use per index. Refer to the
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#_static_index_settings[
+Elasticsearch documentation,role=external,window=_blank] for details.
++
+Defaults to 1.
+
+[[elasticsearch.numberOfReplicas]]elasticsearch.numberOfReplicas::
++
+Sets the number of replicas to use per index. Refer to the
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#dynamic-index-settings[
+Elasticsearch documentation,role=external,window=_blank] for details.
++
+Defaults to 1.
+
+[[elasticsearch.maxResultWindow]]elasticsearch.maxResultWindow::
++
+Sets the maximum value of `from + size` for searches to use per index. Refer to the
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#dynamic-index-settings[
+Elasticsearch documentation,role=external,window=_blank] for details.
++
+Defaults to 10000.
+
+[[elasticsearch.connectTimeout]]elasticsearch.connectTimeout::
++
+Sets the timeout for connecting to elasticsearch.
++
+Defaults to `1 second`.
+
+[[elasticsearch.socketTimeout]]elasticsearch.socketTimeout::
++
+Sets the timeout for the underlying connection. For more information, refer to
+link:#httpd.idleTimeout[`httpd.idleTimeout`].
++
+Defaults to `30 seconds`.
+
+==== Elasticsearch Security
+
+When security is enabled in Elasticsearch, the username and password must be provided.
+Note that the same username and password are used for all servers.
+
+For further information about Elasticsearch security, please refer to
+link:https://www.elastic.co/guide/en/elasticsearch/reference/current/security-getting-started.html[the documentation,role=external,window=_blank].
+This is the current documentation link. Select another Elasticsearch version
+from the dropdown menu available on that page if need be.
+
+[[elasticsearch.username]]elasticsearch.username::
++
+Username used to connect to Elasticsearch.
++
+If a password is set, defaults to `elastic`, otherwise not set by default.
+
+[[elasticsearch.password]]elasticsearch.password::
++
+Password used to connect to Elasticsearch.
++
+Not set by default.
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
similarity index 100%
rename from javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
rename to src/test/java/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java
similarity index 100%
rename from javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
rename to src/test/java/com/google/gerrit/elasticsearch/ElasticVersionTest.java
diff --git a/src/test/test.iml b/src/test/test.iml
new file mode 100644
index 0000000..a0e49a3
--- /dev/null
+++ b/src/test/test.iml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/java" isTestSource="true" />
+ </content>
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
\ No newline at end of file