Merge changes from topic "es5"
* changes:
Elasticsearch: Fix parsing of raw fields result for version 5
Elasticsearch: Add tests for project queries against version 5
Merge branch 'stable-2.15'
diff --git a/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch b/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch
new file mode 100644
index 0000000..3ccf5cd
--- /dev/null
+++ b/0001-Replace-native-http-git-_archive-with-Skylark-rules.patch
@@ -0,0 +1,133 @@
+Date: Wed, 30 May 2018 21:22:18 +0200
+Subject: [PATCH] Replace native {http,git}_archive with Skylark rules
+
+See [1] for more details.
+
+Test Plan:
+
+* Apply this CL on Bazel master: [2] and build bazel
+* Run with this custom built bazel version:
+
+ $ bazel test //javatests/...
+ $ bazel test //closure/...
+
+[1] https://groups.google.com/d/topic/bazel-discuss/dO2MHQLwJF0/discussion
+[2] https://bazel-review.googlesource.com/#/c/bazel/+/55932/
+---
+ closure/repositories.bzl | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/closure/repositories.bzl b/closure/repositories.bzl
+index 9b84a72..2816fb6 100644
+--- closure/repositories.bzl
++++ closure/repositories.bzl
+@@ -14,6 +14,7 @@
+
+ """External dependencies for Closure Rules."""
+
++load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
+ load("//closure/private:java_import_external.bzl", "java_import_external")
+ load("//closure/private:platform_http_file.bzl", "platform_http_file")
+ load("//closure:filegroup_external.bzl", "filegroup_external")
+@@ -405,7 +406,7 @@ def com_google_common_html_types():
+ )
+
+ def com_google_common_html_types_html_proto():
+- native.http_file(
++ http_file(
+ name = "com_google_common_html_types_html_proto",
+ sha256 = "6ece202f11574e37d0c31d9cf2e9e11a0dbc9218766d50d211059ebd495b49c3",
+ urls = [
+@@ -633,7 +634,7 @@ def com_google_javascript_closure_compiler():
+
+ def com_google_javascript_closure_library():
+ # After updating: bazel run //closure/library:regenerate -- "$PWD"
+- native.new_http_archive(
++ http_archive(
+ name = "com_google_javascript_closure_library",
+ urls = [
+ "https://mirror.bazel.build/github.com/google/closure-library/archive/v20180405.tar.gz",
+@@ -658,7 +659,7 @@ def com_google_jsinterop_annotations():
+
+ def com_google_protobuf():
+ # Note: Protobuf 3.6.0+ is going to use C++11
+- native.http_archive(
++ http_archive(
+ name = "com_google_protobuf",
+ strip_prefix = "protobuf-3.5.1",
+ sha256 = "826425182ee43990731217b917c5c3ea7190cfda141af4869e6d4ad9085a740f",
+@@ -669,7 +670,7 @@ def com_google_protobuf():
+ )
+
+ def com_google_protobuf_js():
+- native.new_http_archive(
++ http_archive(
+ name = "com_google_protobuf_js",
+ urls = [
+ "https://mirror.bazel.build/github.com/google/protobuf/archive/v3.5.1.tar.gz",
+@@ -722,7 +723,7 @@ def com_google_template_soy():
+ )
+
+ def com_google_template_soy_jssrc():
+- native.new_http_archive(
++ http_archive(
+ name = "com_google_template_soy_jssrc",
+ sha256 = "c76ab4cb6e46a7c76336640b3c40d6897b420209a6c0905cdcd32533dda8126a",
+ urls = [
+@@ -757,7 +758,7 @@ def com_squareup_javapoet():
+ )
+
+ def fonts_noto_hinted_deb():
+- native.http_file(
++ http_file(
+ name = "fonts_noto_hinted_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fonts-noto/fonts-noto-hinted_20161116-1_all.deb",
+@@ -767,7 +768,7 @@ def fonts_noto_hinted_deb():
+ )
+
+ def fonts_noto_mono_deb():
+- native.http_file(
++ http_file(
+ name = "fonts_noto_mono_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fonts-noto/fonts-noto-mono_20161116-1_all.deb",
+@@ -801,7 +802,7 @@ def javax_inject():
+ )
+
+ def libexpat_amd64_deb():
+- native.http_file(
++ http_file(
+ name = "libexpat_amd64_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/e/expat/libexpat1_2.1.0-6+deb8u3_amd64.deb",
+@@ -811,7 +812,7 @@ def libexpat_amd64_deb():
+ )
+
+ def libfontconfig_amd64_deb():
+- native.http_file(
++ http_file(
+ name = "libfontconfig_amd64_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/fontconfig/libfontconfig1_2.11.0-6.3+deb8u1_amd64.deb",
+@@ -821,7 +822,7 @@ def libfontconfig_amd64_deb():
+ )
+
+ def libfreetype_amd64_deb():
+- native.http_file(
++ http_file(
+ name = "libfreetype_amd64_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/f/freetype/libfreetype6_2.5.2-3+deb8u1_amd64.deb",
+@@ -831,7 +832,7 @@ def libfreetype_amd64_deb():
+ )
+
+ def libpng_amd64_deb():
+- native.http_file(
++ http_file(
+ name = "libpng_amd64_deb",
+ urls = [
+ "https://mirror.bazel.build/http.us.debian.org/debian/pool/main/libp/libpng/libpng12-0_1.2.50-2+deb8u2_amd64.deb",
+--
+2.16.3
+
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index d40e7d3..fea2f8c 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -369,36 +369,27 @@
`lib/jgit/jgit.bzl` setting LOCAL_JGIT_REPO to a directory holding a
JGit repository.
-[[local-action-cache]]
+[[bazel-local-caches]]
-To accelerate builds, local action cache can be activated.
-To activate the local action cache add these lines to your `~/.bazelrc` file:
+To accelerate builds, several caches are activated per default:
+
+* ~/.gerritcodereview/bazel-cache/downloaded-artifacts
+* ~/.gerritcodereview/bazel-cache/repository
+* ~/.gerritcodereview/bazel-cache/cas
+
+Currently none of these caches have a maximum size limit. See
+link:https://github.com/bazelbuild/bazel/issues/5139[this bazel issue] for
+details. Users should watch the cache sizes and clean them manually if
+necessary.
+
+Due to the `--experimental_strict_action_env` option used in `bazelrc`
+it is possible that some commands required by the build are not found
+on the PATH, causing the build to fail. In this case the PATH used in
+the build can be overridden with the `--action_env=PATH` directive in
+the user's `~/.bazelrc` file, for example:
----
-build --disk_cache=~/.gerritcodereview/bazel-cache/cas
-build --experimental_strict_action_env
-build --action_env=PATH
-----
-
-[[repository_cache]]
-
-To accelerate fetches, local repository cache is activated per default in Bazel.
-This cache is only used for rules_closure external repository and transitive
-dependendcies. That's because rules_closure uses standard Bazel download facility.
-For all other gerrit dependencies, the download_artifacts repository cache is used
-already.
-
-To change the default local repository cache directry, create accessible cache
-directory:
-
-----
- mkdir -p ~/.gerritcodereview/bazel-cache/repository
-----
-
-and add this line to your `~/.bazelrc` file:
-
-----
-build --repository_cache=/home/<user>/.gerritcodereview/bazel-cache/repository
+ build --action_env=PATH=/usr/local/opt/coreutils/libexec/gnubin/:/usr/local/bin/:/usr/bin/
----
GERRIT
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index c6cadbb..8acd663 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -165,7 +165,8 @@
To format Java source code, Gerrit uses the
link:https://github.com/google/google-java-format[`google-java-format`]
tool (version 1.5), and to format Bazel BUILD and WORKSPACE files the
-link:https://github.com/bazelbuild/buildifier[`buildifier`] tool (version 0.6.0).
+link:https://github.com/bazelbuild/buildtools/tree/master/buildifier[`buildifier`]
+tool (version 0.11.1).
These tools automatically apply format according to the style guides; this
streamlines code review by reducing the need for time-consuming, tedious,
and contentious discussions about trivial issues like whitespace.
diff --git a/WORKSPACE b/WORKSPACE
index 9420a74..bf207b5 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,5 +1,6 @@
workspace(name = "gerrit")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
load("//tools/bzl:maven_jar.bzl", "maven_jar", "GERRIT", "MAVEN_LOCAL")
load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION")
load("//plugins:external_plugin_deps.bzl", "external_plugin_deps")
@@ -13,6 +14,8 @@
http_archive(
name = "io_bazel_rules_closure",
+ build_file_content = "exports_files([\"0001-Replace-native-http-git-_archive-with-Skylark-rules.patch\"])",
+ patches = ["//:0001-Replace-native-http-git-_archive-with-Skylark-rules.patch"],
sha256 = "a80acb69c63d5f6437b099c111480a4493bad4592015af2127a2f49fb7512d8d",
strip_prefix = "rules_closure-0.7.0",
url = "https://github.com/bazelbuild/rules_closure/archive/0.7.0.tar.gz",
@@ -24,12 +27,12 @@
http_file(
name = "polymer_closure",
sha256 = "5a589bdba674e1fec7188e9251c8624ebf2d4d969beb6635f9148f420d1e08b1",
- url = "https://raw.githubusercontent.com/google/closure-compiler/775609aad61e14aef289ebec4bfc09ad88877f9e/contrib/externs/polymer-1.0.js",
+ urls = ["https://raw.githubusercontent.com/google/closure-compiler/775609aad61e14aef289ebec4bfc09ad88877f9e/contrib/externs/polymer-1.0.js"],
)
load("@bazel_skylib//:lib.bzl", "versions")
-versions.check(minimum_bazel_version = "0.7.0")
+versions.check(minimum_bazel_version = "0.14.0")
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
deleted file mode 100644
index 91f938c..0000000
--- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
+++ /dev/null
@@ -1,143 +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.extensions.events.LifecycleListener;
-import com.google.gerrit.lifecycle.LifecycleModule;
-import com.google.gson.JsonParser;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.Singleton;
-import java.io.IOException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpStatus;
-import org.apache.http.StatusLine;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
-import org.elasticsearch.client.Response;
-import org.elasticsearch.client.RestClient;
-import org.elasticsearch.client.RestClientBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListener {
- private static final Logger log = LoggerFactory.getLogger(ElasticRestClientProvider.class);
-
- private final HttpHost[] hosts;
- private final String username;
- private final String password;
-
- private RestClient client;
-
- @Inject
- ElasticRestClientProvider(ElasticConfiguration cfg) {
- hosts = cfg.urls.toArray(new HttpHost[cfg.urls.size()]);
- username = cfg.username;
- password = cfg.password;
- }
-
- public static LifecycleModule module() {
- return new LifecycleModule() {
- @Override
- protected void configure() {
- listener().to(ElasticRestClientProvider.class);
- }
- };
- }
-
- @Override
- public RestClient get() {
- if (client == null) {
- synchronized (this) {
- if (client == null) {
- client = build();
- ElasticVersion version = getVersion();
- log.info("Elasticsearch integration version {}", version);
- }
- }
- }
- return client;
- }
-
- @Override
- public void start() {}
-
- @Override
- public void stop() {
- if (client != null) {
- try {
- client.close();
- } catch (IOException e) {
- // Ignore. We can't do anything about it.
- }
- }
- }
-
- public static class FailedToGetVersion extends ElasticException {
- private static final long serialVersionUID = 1L;
- private static final String MESSAGE = "Failed to get Elasticsearch version";
-
- FailedToGetVersion(StatusLine status) {
- super(String.format("%s: %d %s", MESSAGE, status.getStatusCode(), status.getReasonPhrase()));
- }
-
- FailedToGetVersion(Throwable cause) {
- super(MESSAGE, cause);
- }
- }
-
- private ElasticVersion getVersion() throws ElasticException {
- try {
- Response response = client.performRequest("GET", "");
- StatusLine statusLine = response.getStatusLine();
- if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
- throw new FailedToGetVersion(statusLine);
- }
- String version =
- new JsonParser()
- .parse(AbstractElasticIndex.getContent(response))
- .getAsJsonObject()
- .get("version")
- .getAsJsonObject()
- .get("number")
- .getAsString();
- log.info("Connected to Elasticsearch version {}", version);
- return ElasticVersion.forVersion(version);
- } catch (IOException e) {
- throw new FailedToGetVersion(e);
- }
- }
-
- private RestClient build() {
- RestClientBuilder builder = RestClient.builder(hosts);
- setConfiguredCredentialsIfAny(builder);
- return builder.build();
- }
-
- private void setConfiguredCredentialsIfAny(RestClientBuilder builder) {
- if (username != null && password != null) {
- CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
- credentialsProvider.setCredentials(
- AuthScope.ANY, new UsernamePasswordCredentials(username, password));
- builder.setHttpClientConfigCallback(
- (HttpAsyncClientBuilder httpClientBuilder) ->
- httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
- }
- }
-}
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index ee4869b..b3a22bc 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -75,7 +75,6 @@
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
protected static final String BULK = "_bulk";
- protected static final String IGNORE_UNMAPPED = "ignore_unmapped";
protected static final String ORDER = "order";
protected static final String SEARCH = "_search";
@@ -105,8 +104,8 @@
private final Schema<V> schema;
private final SitePaths sitePaths;
private final String indexNameRaw;
- private final ElasticRestClientProvider client;
+ protected final ElasticRestClientProvider client;
protected final String indexName;
protected final Gson gson;
protected final ElasticQueryBuilder queryBuilder;
@@ -142,20 +141,21 @@
}
@Override
- public void delete(K c) throws IOException {
+ public void delete(K id) throws IOException {
String uri = getURI(indexNameRaw, BULK);
- Response response = postRequest(addActions(c), uri, getRefreshParam());
+ Response response = postRequest(getDeleteActions(id), uri, getRefreshParam());
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new IOException(
- String.format("Failed to delete %s from index %s: %s", c, indexName, statusCode));
+ String.format("Failed to delete %s from index %s: %s", id, indexName, statusCode));
}
}
@Override
public void deleteAll() throws IOException {
// Delete the index, if it exists.
- Response response = client.get().performRequest("HEAD", indexName);
+ String endpoint = indexName + client.adapter().indicesExistParam();
+ Response response = client.get().performRequest("HEAD", endpoint);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
response = client.get().performRequest("DELETE", indexName);
@@ -175,15 +175,14 @@
}
}
- protected abstract String addActions(K c);
+ protected abstract String getDeleteActions(K id);
protected abstract String getMappings();
protected abstract String getId(V v);
- protected String delete(String type, K c) {
- String id = c.toString();
- return new DeleteRequest(id, indexNameRaw, type).toString();
+ protected String delete(String type, K id) {
+ return new DeleteRequest(id.toString(), indexNameRaw, type).toString();
}
protected abstract V fromDocument(JsonObject doc, Set<String> fields);
@@ -191,7 +190,8 @@
protected FieldBundle toFieldBundle(JsonObject doc) {
Map<String, FieldDef<V, ?>> allFields = getSchema().getFields();
ListMultimap<String, Object> rawFields = ArrayListMultimap.create();
- for (Map.Entry<String, JsonElement> element : doc.get("fields").getAsJsonObject().entrySet()) {
+ for (Map.Entry<String, JsonElement> element :
+ doc.get(client.adapter().rawFieldsKey()).getAsJsonObject().entrySet()) {
checkArgument(
allFields.containsKey(element.getKey()), "Unrecognized field " + element.getKey());
FieldType<?> type = allFields.get(element.getKey()).getType();
@@ -250,7 +250,7 @@
protected JsonArray getSortArray(String idFieldName) {
JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "asc");
- properties.addProperty(IGNORE_UNMAPPED, true);
+ client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray();
addNamedElement(idFieldName, properties, sortArray);
@@ -286,7 +286,7 @@
this.index = index;
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
SearchSourceBuilder searchSource =
- new SearchSourceBuilder()
+ new SearchSourceBuilder(client.adapter())
.query(qb)
.from(opts.start())
.size(opts.limit())
diff --git a/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
index 1abdee9..c212a8b 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java
@@ -49,8 +49,8 @@
static class AccountMapping {
MappingProperties accounts;
- AccountMapping(Schema<AccountState> schema) {
- this.accounts = ElasticMapping.createMapping(schema);
+ AccountMapping(Schema<AccountState> schema, ElasticQueryAdapter adapter) {
+ this.accounts = ElasticMapping.createMapping(schema, adapter);
}
}
@@ -69,7 +69,7 @@
@Assisted Schema<AccountState> schema) {
super(cfg, sitePaths, schema, client, ACCOUNTS);
this.accountCache = accountCache;
- this.mapping = new AccountMapping(schema);
+ this.mapping = new AccountMapping(schema, client.adapter());
this.schema = schema;
}
@@ -98,8 +98,8 @@
}
@Override
- protected String addActions(Account.Id c) {
- return delete(ACCOUNTS, c);
+ protected String getDeleteActions(Account.Id a) {
+ return delete(ACCOUNTS, a);
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index c7b0fb5..ccf15d7 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -79,8 +79,8 @@
MappingProperties openChanges;
MappingProperties closedChanges;
- ChangeMapping(Schema<ChangeData> schema) {
- MappingProperties mapping = ElasticMapping.createMapping(schema);
+ ChangeMapping(Schema<ChangeData> schema, ElasticQueryAdapter adapter) {
+ MappingProperties mapping = ElasticMapping.createMapping(schema, adapter);
this.openChanges = mapping;
this.closedChanges = mapping;
}
@@ -107,7 +107,7 @@
this.db = db;
this.changeDataFactory = changeDataFactory;
this.schema = schema;
- mapping = new ChangeMapping(schema);
+ mapping = new ChangeMapping(schema, client.adapter());
}
@Override
@@ -161,7 +161,7 @@
private JsonArray getSortArray() {
JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "desc");
- properties.addProperty(IGNORE_UNMAPPED, true);
+ client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray();
addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray);
@@ -174,7 +174,7 @@
}
@Override
- protected String addActions(Id c) {
+ protected String getDeleteActions(Id c) {
return delete(OPEN_CHANGES, c) + delete(CLOSED_CHANGES, c);
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java b/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
index d1eab7c..d2de01e 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java
@@ -47,8 +47,8 @@
static class GroupMapping {
MappingProperties groups;
- GroupMapping(Schema<InternalGroup> schema) {
- this.groups = ElasticMapping.createMapping(schema);
+ GroupMapping(Schema<InternalGroup> schema, ElasticQueryAdapter adapter) {
+ this.groups = ElasticMapping.createMapping(schema, adapter);
}
}
@@ -67,7 +67,7 @@
@Assisted Schema<InternalGroup> schema) {
super(cfg, sitePaths, schema, client, GROUPS);
this.groupCache = groupCache;
- this.mapping = new GroupMapping(schema);
+ this.mapping = new GroupMapping(schema, client.adapter());
this.schema = schema;
}
@@ -95,8 +95,8 @@
}
@Override
- protected String addActions(AccountGroup.UUID c) {
- return delete(GROUPS, c);
+ protected String getDeleteActions(AccountGroup.UUID g) {
+ return delete(GROUPS, g);
}
@Override
diff --git a/java/com/google/gerrit/elasticsearch/ElasticMapping.java b/java/com/google/gerrit/elasticsearch/ElasticMapping.java
index bf6da5c..a30e546 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticMapping.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticMapping.java
@@ -21,12 +21,12 @@
import java.util.Map;
class ElasticMapping {
- static MappingProperties createMapping(Schema<?> schema) {
- ElasticMapping.Builder mapping = new ElasticMapping.Builder();
+ static MappingProperties createMapping(Schema<?> schema, ElasticQueryAdapter adapter) {
+ ElasticMapping.Builder mapping = new ElasticMapping.Builder(adapter);
for (FieldDef<?, ?> field : schema.getFields().values()) {
String name = field.getName();
FieldType<?> fieldType = field.getType();
- if (fieldType == FieldType.EXACT || fieldType == FieldType.KEYWORD) {
+ if (fieldType == FieldType.EXACT) {
mapping.addExactField(name);
} else if (fieldType == FieldType.TIMESTAMP) {
mapping.addTimestamp(name);
@@ -46,9 +46,14 @@
}
static class Builder {
+ private final ElasticQueryAdapter adapter;
private final ImmutableMap.Builder<String, FieldProperties> fields =
new ImmutableMap.Builder<>();
+ Builder(ElasticQueryAdapter adapter) {
+ this.adapter = adapter;
+ }
+
MappingProperties build() {
MappingProperties properties = new MappingProperties();
properties.properties = fields.build();
@@ -56,9 +61,10 @@
}
Builder addExactField(String name) {
- FieldProperties key = new FieldProperties("string");
- key.index = "not_analyzed";
- FieldProperties properties = new FieldProperties("string");
+ FieldProperties key = new FieldProperties(adapter.exactFieldType());
+ key.index = adapter.indexProperty();
+ FieldProperties properties;
+ properties = new FieldProperties(adapter.exactFieldType());
properties.fields = ImmutableMap.of("key", key);
fields.put(name, properties);
return this;
@@ -78,7 +84,7 @@
}
Builder addString(String name) {
- fields.put(name, new FieldProperties("string"));
+ fields.put(name, new FieldProperties(adapter.stringFieldType()));
return this;
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java b/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
index a536b41..dfb1c5d 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticProjectIndex.java
@@ -47,8 +47,8 @@
static class ProjectMapping {
MappingProperties projects;
- ProjectMapping(Schema<ProjectData> schema) {
- this.projects = ElasticMapping.createMapping(schema);
+ ProjectMapping(Schema<ProjectData> schema, ElasticQueryAdapter adapter) {
+ this.projects = ElasticMapping.createMapping(schema, adapter);
}
}
@@ -63,12 +63,12 @@
ElasticConfiguration cfg,
SitePaths sitePaths,
Provider<ProjectCache> projectCache,
- ElasticRestClientProvider clientBuilder,
+ ElasticRestClientProvider client,
@Assisted Schema<ProjectData> schema) {
- super(cfg, sitePaths, schema, clientBuilder, PROJECTS);
+ super(cfg, sitePaths, schema, client, PROJECTS);
this.projectCache = projectCache;
this.schema = schema;
- this.mapping = new ProjectMapping(schema);
+ this.mapping = new ProjectMapping(schema, client.adapter());
}
@Override
@@ -97,7 +97,7 @@
}
@Override
- protected String addActions(Project.NameKey nameKey) {
+ protected String getDeleteActions(Project.NameKey nameKey) {
return delete(PROJECTS, nameKey);
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
new file mode 100644
index 0000000..b6cbf2f
--- /dev/null
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
@@ -0,0 +1,81 @@
+// 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.gson.JsonObject;
+
+public class ElasticQueryAdapter {
+ private final boolean ignoreUnmapped;
+ private final String searchFilteringName;
+ private final String indicesExistParam;
+ private final String exactFieldType;
+ private final String stringFieldType;
+ private final String indexProperty;
+ private final String rawFieldsKey;
+
+ ElasticQueryAdapter(ElasticVersion version) {
+ this.ignoreUnmapped = version == ElasticVersion.V2_4;
+ switch (version) {
+ case V5_6:
+ case V6_2:
+ this.searchFilteringName = "_source";
+ this.indicesExistParam = "?allow_no_indices=false";
+ this.exactFieldType = "keyword";
+ this.stringFieldType = "text";
+ this.indexProperty = "true";
+ this.rawFieldsKey = "_source";
+ break;
+ case V2_4:
+ default:
+ this.searchFilteringName = "fields";
+ this.indicesExistParam = "";
+ this.exactFieldType = "string";
+ this.stringFieldType = "string";
+ this.indexProperty = "not_analyzed";
+ this.rawFieldsKey = "fields";
+ break;
+ }
+ }
+
+ void setIgnoreUnmapped(JsonObject properties) {
+ if (ignoreUnmapped) {
+ properties.addProperty("ignore_unmapped", true);
+ }
+ }
+
+ public String searchFilteringName() {
+ return searchFilteringName;
+ }
+
+ String indicesExistParam() {
+ return indicesExistParam;
+ }
+
+ String exactFieldType() {
+ return exactFieldType;
+ }
+
+ String stringFieldType() {
+ return stringFieldType;
+ }
+
+ String indexProperty() {
+ return indexProperty;
+ }
+
+ String rawFieldsKey() {
+ return rawFieldsKey;
+ }
+}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java b/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
index c8c6345..2a97e2e 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryBuilder.java
@@ -94,7 +94,7 @@
return intRangeQuery(p);
} else if (type == FieldType.TIMESTAMP) {
return timestampQuery(p);
- } else if (type == FieldType.EXACT || type == FieldType.KEYWORD) {
+ } else if (type == FieldType.EXACT) {
return exactQuery(p);
} else if (type == FieldType.PREFIX) {
return QueryBuilders.matchPhrasePrefixQuery(name, value);
diff --git a/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java b/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
index 102305b..c2c4548 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticRestClientProvider.java
@@ -43,6 +43,7 @@
private final String password;
private RestClient client;
+ private ElasticQueryAdapter adapter;
@Inject
ElasticRestClientProvider(ElasticConfiguration cfg) {
@@ -68,6 +69,7 @@
client = build();
ElasticVersion version = getVersion();
logger.atInfo().log("Elasticsearch integration version %s", version);
+ adapter = new ElasticQueryAdapter(version);
}
}
}
@@ -88,6 +90,11 @@
}
}
+ ElasticQueryAdapter adapter() {
+ get(); // Make sure we're connected
+ return adapter;
+ }
+
public static class FailedToGetVersion extends ElasticException {
private static final long serialVersionUID = 1L;
private static final String MESSAGE = "Failed to get Elasticsearch version";
diff --git a/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java b/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
index 7a12080..c0becd1 100644
--- a/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
+++ b/java/com/google/gerrit/elasticsearch/builders/MatchQueryBuilder.java
@@ -27,9 +27,14 @@
enum Type {
/** The text is analyzed and used as a phrase query. */
- PHRASE,
+ MATCH_PHRASE,
/** The text is analyzed and used in a phrase query, with the last term acting as a prefix. */
- PHRASE_PREFIX
+ MATCH_PHRASE_PREFIX;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase(Locale.US);
+ }
}
private final String name;
@@ -52,14 +57,6 @@
@Override
protected void doXContent(XContentBuilder builder) throws IOException {
- builder.startObject("match");
- builder.startObject(name);
-
- builder.field("query", text);
- if (type != null) {
- builder.field("type", type.toString().toLowerCase(Locale.ENGLISH));
- }
- builder.endObject();
- builder.endObject();
+ builder.startObject(type.toString()).field(name, text).endObject();
}
}
diff --git a/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java b/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
index 26fac4c..940146f 100644
--- a/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
+++ b/java/com/google/gerrit/elasticsearch/builders/QueryBuilders.java
@@ -33,7 +33,7 @@
* @param text The query text (to be analyzed).
*/
public static MatchQueryBuilder matchPhraseQuery(String name, Object text) {
- return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.PHRASE);
+ return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.MATCH_PHRASE);
}
/**
@@ -43,7 +43,7 @@
* @param text The query text (to be analyzed).
*/
public static MatchQueryBuilder matchPhrasePrefixQuery(String name, Object text) {
- return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.PHRASE_PREFIX);
+ return new MatchQueryBuilder(name, text).type(MatchQueryBuilder.Type.MATCH_PHRASE_PREFIX);
}
/**
diff --git a/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java b/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
index e72e9fa..35cbea9 100644
--- a/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
+++ b/java/com/google/gerrit/elasticsearch/builders/SearchSourceBuilder.java
@@ -14,6 +14,7 @@
package com.google.gerrit.elasticsearch.builders;
+import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
import java.io.IOException;
import java.util.List;
@@ -23,6 +24,7 @@
* <p>A trimmed down and modified version of org.elasticsearch.search.builder.SearchSourceBuilder.
*/
public class SearchSourceBuilder {
+ private final ElasticQueryAdapter adapter;
private QuerySourceBuilder querySourceBuilder;
@@ -33,7 +35,9 @@
private List<String> fieldNames;
/** Constructs a new search source builder. */
- public SearchSourceBuilder() {}
+ public SearchSourceBuilder(ElasticQueryAdapter adapter) {
+ this.adapter = adapter;
+ }
/** Constructs a new search source builder with a search query. */
public SearchSourceBuilder query(QueryBuilder query) {
@@ -95,9 +99,9 @@
if (fieldNames != null) {
if (fieldNames.size() == 1) {
- builder.field("fields", fieldNames.get(0));
+ builder.field(adapter.searchFilteringName(), fieldNames.get(0));
} else {
- builder.startArray("fields");
+ builder.startArray(adapter.searchFilteringName());
for (String fieldName : fieldNames) {
builder.value(fieldName);
}
diff --git a/java/com/google/gerrit/index/FieldDef.java b/java/com/google/gerrit/index/FieldDef.java
index 1d0a594..b1ffac1 100644
--- a/java/com/google/gerrit/index/FieldDef.java
+++ b/java/com/google/gerrit/index/FieldDef.java
@@ -34,10 +34,6 @@
return new FieldDef.Builder<>(FieldType.EXACT, name);
}
- public static FieldDef.Builder<String> keyword(String name) {
- return new FieldDef.Builder<>(FieldType.KEYWORD, name);
- }
-
public static FieldDef.Builder<String> fullText(String name) {
return new FieldDef.Builder<>(FieldType.FULL_TEXT, name);
}
diff --git a/java/com/google/gerrit/index/FieldType.java b/java/com/google/gerrit/index/FieldType.java
index 376c071..0db0284 100644
--- a/java/com/google/gerrit/index/FieldType.java
+++ b/java/com/google/gerrit/index/FieldType.java
@@ -33,9 +33,6 @@
/** A string field searched using exact-match semantics. */
public static final FieldType<String> EXACT = new FieldType<>("EXACT");
- /** A Keyword field searched using non-analyzed-match semantics. */
- public static final FieldType<String> KEYWORD = new FieldType<>("KEYWORD");
-
/** A string field searched using prefix. */
public static final FieldType<String> PREFIX = new FieldType<>("PREFIX");
diff --git a/java/com/google/gerrit/lucene/AbstractLuceneIndex.java b/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
index 57afffd..3871ced 100644
--- a/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
+++ b/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
@@ -330,7 +330,7 @@
for (Object value : values.getValues()) {
doc.add(new LongField(name, ((Timestamp) value).getTime(), store));
}
- } else if (type == FieldType.KEYWORD || type == FieldType.EXACT || type == FieldType.PREFIX) {
+ } else if (type == FieldType.EXACT || type == FieldType.PREFIX) {
for (Object value : values.getValues()) {
doc.add(new StringField(name, (String) value, store));
}
@@ -353,10 +353,7 @@
for (IndexableField field : doc.getFields()) {
checkArgument(allFields.containsKey(field.name()), "Unrecognized field " + field.name());
FieldType<?> type = allFields.get(field.name()).getType();
- if (type == FieldType.EXACT
- || type == FieldType.FULL_TEXT
- || type == FieldType.PREFIX
- || type == FieldType.KEYWORD) {
+ if (type == FieldType.EXACT || type == FieldType.FULL_TEXT || type == FieldType.PREFIX) {
rawFields.put(field.name(), field.stringValue());
} else if (type == FieldType.INTEGER || type == FieldType.INTEGER_RANGE) {
rawFields.put(field.name(), field.numericValue().intValue());
diff --git a/java/com/google/gerrit/lucene/QueryBuilder.java b/java/com/google/gerrit/lucene/QueryBuilder.java
index c7fc880..6aab7c7 100644
--- a/java/com/google/gerrit/lucene/QueryBuilder.java
+++ b/java/com/google/gerrit/lucene/QueryBuilder.java
@@ -148,7 +148,7 @@
return intRangeQuery(p);
} else if (type == FieldType.TIMESTAMP) {
return timestampQuery(p);
- } else if (type == FieldType.EXACT || type == FieldType.KEYWORD) {
+ } else if (type == FieldType.EXACT) {
return exactQuery(p);
} else if (type == FieldType.PREFIX) {
return prefixQuery(p);
diff --git a/java/com/google/gerrit/server/index/group/GroupField.java b/java/com/google/gerrit/server/index/group/GroupField.java
index 779dc6b..29e3867 100644
--- a/java/com/google/gerrit/server/index/group/GroupField.java
+++ b/java/com/google/gerrit/server/index/group/GroupField.java
@@ -18,7 +18,6 @@
import static com.google.gerrit.index.FieldDef.exact;
import static com.google.gerrit.index.FieldDef.fullText;
import static com.google.gerrit.index.FieldDef.integer;
-import static com.google.gerrit.index.FieldDef.keyword;
import static com.google.gerrit.index.FieldDef.prefix;
import static com.google.gerrit.index.FieldDef.storedOnly;
import static com.google.gerrit.index.FieldDef.timestamp;
@@ -41,11 +40,11 @@
/** Group UUID. */
public static final FieldDef<InternalGroup, String> UUID =
- keyword("uuid").stored().build(g -> g.getGroupUUID().get());
+ exact("uuid").stored().build(g -> g.getGroupUUID().get());
/** Group owner UUID. */
public static final FieldDef<InternalGroup, String> OWNER_UUID =
- keyword("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
+ exact("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
/** Timestamp indicating when this group was created. */
public static final FieldDef<InternalGroup, Timestamp> CREATED_ON =
diff --git a/javatests/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java b/javatests/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java
index ede0397..0d24a5d 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java
@@ -42,11 +42,9 @@
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
-import org.junit.Ignore;
import org.junit.Test;
@NoHttpd
-@Ignore
public abstract class AbstractReindexTests extends StandaloneSiteTest {
private static final String CHANGES = ChangeSchemaDefinitions.NAME;
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
index 49c34dd..1aa8d54 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
@@ -14,9 +14,7 @@
package com.google.gerrit.acceptance.pgm;
-import com.google.gerrit.acceptance.NoHttpd;
import org.junit.Ignore;
-@NoHttpd
@Ignore
public class ElasticReindexIT extends AbstractReindexTests {}
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ReindexIT.java
index e4a2805..18d2628 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ReindexIT.java
@@ -14,7 +14,4 @@
package com.google.gerrit.acceptance.pgm;
-import com.google.gerrit.acceptance.NoHttpd;
-
-@NoHttpd
public class ReindexIT extends AbstractReindexTests {}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java
index 2aef875..a02d691 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticQueryChangesTest.java
@@ -18,15 +18,12 @@
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.InMemoryModule;
-import com.google.gerrit.testing.InMemoryRepositoryManager.Repo;
import com.google.gerrit.testing.IndexConfig;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.junit.AfterClass;
import org.junit.BeforeClass;
-import org.junit.Test;
public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
@ConfigSuite.Default
@@ -73,12 +70,4 @@
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
}
-
- @Test
- public void byOwnerInvalidQuery() throws Exception {
- TestRepository<Repo> repo = createProject("repo");
- insert(repo, newChange(repo), userId);
- String nameEmail = user.asIdentifiedUser().getNameEmail();
- assertQuery("owner: \"" + nameEmail + "\"\\");
- }
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
new file mode 100644
index 0000000..649fc6f
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
@@ -0,0 +1,73 @@
+// 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.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+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 ElasticV5QueryAccountsTest extends AbstractQueryAccountsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V5_6);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @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();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
new file mode 100644
index 0000000..4aa08fa
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
@@ -0,0 +1,73 @@
+// 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.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
+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 ElasticV5QueryChangesTest extends AbstractQueryChangesTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V5_6);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @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();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
new file mode 100644
index 0000000..72f8b49
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
@@ -0,0 +1,73 @@
+// 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.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+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 ElasticV5QueryGroupsTest extends AbstractQueryGroupsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V5_6);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @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();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
new file mode 100644
index 0000000..7b49e1d
--- /dev/null
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
@@ -0,0 +1,73 @@
+// 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.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
+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 ElasticV5QueryProjectsTest extends AbstractQueryProjectsTest {
+ @ConfigSuite.Default
+ public static Config defaultConfig() {
+ return IndexConfig.createForElasticsearch();
+ }
+
+ private static ElasticNodeInfo nodeInfo;
+ private static ElasticContainer<?> container;
+
+ @BeforeClass
+ public static void startIndexService() {
+ if (nodeInfo != null) {
+ // do not start Elasticsearch twice
+ return;
+ }
+
+ container = ElasticContainer.createAndStart(ElasticVersion.V5_6);
+ nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
+ }
+
+ @AfterClass
+ public static void stopElasticsearchServer() {
+ if (container != null) {
+ container.stop();
+ }
+ }
+
+ private String testName() {
+ return testName.getMethodName().toLowerCase() + "_";
+ }
+
+ @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();
+ ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
+ return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
+ }
+}
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index db71a63..bd70884 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -2901,6 +2901,14 @@
assertQuery("query:query4");
}
+ @Test
+ public void byOwnerInvalidQuery() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ insert(repo, newChange(repo), userId);
+ String nameEmail = user.asIdentifiedUser().getNameEmail();
+ assertQuery("owner: \"" + nameEmail + "\"\\");
+ }
+
protected ChangeInserter newChange(TestRepository<Repo> repo) throws Exception {
return newChange(repo, null, null, null, null, false);
}
diff --git a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
index 5ee3aa4..1dfe7df 100644
--- a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
@@ -70,6 +70,7 @@
}
@Test
+ @Override
public void byOwnerInvalidQuery() throws Exception {
TestRepository<Repo> repo = createProject("repo");
Change change1 = insert(repo, newChange(repo), userId);
diff --git a/lib/polymer_externs/BUILD b/lib/polymer_externs/BUILD
index 2f1bdbd..ae8f9c0 100644
--- a/lib/polymer_externs/BUILD
+++ b/lib/polymer_externs/BUILD
@@ -18,9 +18,16 @@
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
+genrule(
+ name = "polymer_closure_renamed",
+ srcs = ["@polymer_closure//file"],
+ outs = ["polymer_closure_renamed.js"],
+ cmd = "cp $< $@",
+)
+
closure_js_library(
name = "polymer_closure",
- srcs = ["@polymer_closure//file"],
+ srcs = [":polymer_closure_renamed"],
data = ["//lib:LICENSE-Apache2.0"],
no_closure_library = True,
)
diff --git a/tools/bazel.rc b/tools/bazel.rc
index ab974d9..8f158e9 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -1,2 +1,5 @@
build --workspace_status_command=./tools/workspace-status.sh --strategy=Closure=worker
+build --disk_cache=~/.gerritcodereview/bazel-cache/cas
+build --repository_cache=~/.gerritcodereview/bazel-cache/repository
+build --experimental_strict_action_env
test --build_tests_only