Merge branch 'stable-2.14' into stable-2.15
* stable-2.14: ElasticReindexIT: Add tests against Elasticsearch version 5 Elasticsearch: Add tests for queries against version 5 MatchQueryBuilder: Don't use deprecated "match" query Elasticsearch: Add an adapter to support V5 Add Bazel version check Change-Id: I72f7ce2f87061f1799abc1a73f57b93a2859b6b6
This commit is contained in:
11
WORKSPACE
11
WORKSPACE
@@ -4,6 +4,13 @@ load("//tools/bzl:maven_jar.bzl", "maven_jar", "GERRIT", "MAVEN_LOCAL")
|
|||||||
load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION")
|
load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION")
|
||||||
load("//plugins:external_plugin_deps.bzl", "external_plugin_deps")
|
load("//plugins:external_plugin_deps.bzl", "external_plugin_deps")
|
||||||
|
|
||||||
|
http_archive(
|
||||||
|
name = "bazel_skylib",
|
||||||
|
sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d",
|
||||||
|
strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
|
||||||
|
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"],
|
||||||
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "io_bazel_rules_closure",
|
name = "io_bazel_rules_closure",
|
||||||
sha256 = "6691c58a2cd30a86776dd9bb34898b041e37136f2dc7e24cadaeaf599c95c657",
|
sha256 = "6691c58a2cd30a86776dd9bb34898b041e37136f2dc7e24cadaeaf599c95c657",
|
||||||
@@ -20,6 +27,10 @@ http_file(
|
|||||||
url = "https://raw.githubusercontent.com/google/closure-compiler/775609aad61e14aef289ebec4bfc09ad88877f9e/contrib/externs/polymer-1.0.js",
|
url = "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")
|
||||||
|
|
||||||
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
|
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
|
||||||
|
|
||||||
# Prevent redundant loading of dependencies.
|
# Prevent redundant loading of dependencies.
|
||||||
|
@@ -50,7 +50,6 @@ import org.elasticsearch.client.Response;
|
|||||||
|
|
||||||
abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
|
abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
|
||||||
protected static final String BULK = "_bulk";
|
protected static final String BULK = "_bulk";
|
||||||
protected static final String IGNORE_UNMAPPED = "ignore_unmapped";
|
|
||||||
protected static final String ORDER = "order";
|
protected static final String ORDER = "order";
|
||||||
protected static final String SEARCH = "_search";
|
protected static final String SEARCH = "_search";
|
||||||
|
|
||||||
@@ -80,8 +79,8 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
|
|||||||
private final Schema<V> schema;
|
private final Schema<V> schema;
|
||||||
private final SitePaths sitePaths;
|
private final SitePaths sitePaths;
|
||||||
private final String indexNameRaw;
|
private final String indexNameRaw;
|
||||||
private final ElasticRestClientProvider client;
|
|
||||||
|
|
||||||
|
protected final ElasticRestClientProvider client;
|
||||||
protected final String indexName;
|
protected final String indexName;
|
||||||
protected final Gson gson;
|
protected final Gson gson;
|
||||||
protected final ElasticQueryBuilder queryBuilder;
|
protected final ElasticQueryBuilder queryBuilder;
|
||||||
@@ -130,7 +129,8 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
|
|||||||
@Override
|
@Override
|
||||||
public void deleteAll() throws IOException {
|
public void deleteAll() throws IOException {
|
||||||
// Delete the index, if it exists.
|
// 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();
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
if (statusCode == HttpStatus.SC_OK) {
|
if (statusCode == HttpStatus.SC_OK) {
|
||||||
response = client.get().performRequest("DELETE", indexName);
|
response = client.get().performRequest("DELETE", indexName);
|
||||||
@@ -182,7 +182,7 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
|
|||||||
protected JsonArray getSortArray(String idFieldName) {
|
protected JsonArray getSortArray(String idFieldName) {
|
||||||
JsonObject properties = new JsonObject();
|
JsonObject properties = new JsonObject();
|
||||||
properties.addProperty(ORDER, "asc");
|
properties.addProperty(ORDER, "asc");
|
||||||
properties.addProperty(IGNORE_UNMAPPED, true);
|
client.adapter().setIgnoreUnmapped(properties);
|
||||||
|
|
||||||
JsonArray sortArray = new JsonArray();
|
JsonArray sortArray = new JsonArray();
|
||||||
addNamedElement(idFieldName, properties, sortArray);
|
addNamedElement(idFieldName, properties, sortArray);
|
||||||
|
@@ -61,8 +61,8 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
|
|||||||
public static class AccountMapping {
|
public static class AccountMapping {
|
||||||
MappingProperties accounts;
|
MappingProperties accounts;
|
||||||
|
|
||||||
public AccountMapping(Schema<AccountState> schema) {
|
public AccountMapping(Schema<AccountState> schema, ElasticQueryAdapter adapter) {
|
||||||
this.accounts = ElasticMapping.createMapping(schema);
|
this.accounts = ElasticMapping.createMapping(schema, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
|
|||||||
@Assisted Schema<AccountState> schema) {
|
@Assisted Schema<AccountState> schema) {
|
||||||
super(cfg, sitePaths, schema, client, ACCOUNTS);
|
super(cfg, sitePaths, schema, client, ACCOUNTS);
|
||||||
this.accountCache = accountCache;
|
this.accountCache = accountCache;
|
||||||
this.mapping = new AccountMapping(schema);
|
this.mapping = new AccountMapping(schema, client.adapter());
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
|
|||||||
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
||||||
fields = IndexUtils.accountFields(opts);
|
fields = IndexUtils.accountFields(opts);
|
||||||
SearchSourceBuilder searchSource =
|
SearchSourceBuilder searchSource =
|
||||||
new SearchSourceBuilder()
|
new SearchSourceBuilder(client.adapter())
|
||||||
.query(qb)
|
.query(qb)
|
||||||
.from(opts.start())
|
.from(opts.start())
|
||||||
.size(opts.limit())
|
.size(opts.limit())
|
||||||
|
@@ -87,8 +87,8 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
|
|||||||
MappingProperties openChanges;
|
MappingProperties openChanges;
|
||||||
MappingProperties closedChanges;
|
MappingProperties closedChanges;
|
||||||
|
|
||||||
ChangeMapping(Schema<ChangeData> schema) {
|
ChangeMapping(Schema<ChangeData> schema, ElasticQueryAdapter adapter) {
|
||||||
MappingProperties mapping = ElasticMapping.createMapping(schema);
|
MappingProperties mapping = ElasticMapping.createMapping(schema, adapter);
|
||||||
this.openChanges = mapping;
|
this.openChanges = mapping;
|
||||||
this.closedChanges = mapping;
|
this.closedChanges = mapping;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
|
|||||||
this.db = db;
|
this.db = db;
|
||||||
this.changeDataFactory = changeDataFactory;
|
this.changeDataFactory = changeDataFactory;
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
mapping = new ChangeMapping(schema);
|
this.mapping = new ChangeMapping(schema, client.adapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -189,7 +189,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
|
|||||||
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
||||||
fields = IndexUtils.changeFields(opts);
|
fields = IndexUtils.changeFields(opts);
|
||||||
SearchSourceBuilder searchSource =
|
SearchSourceBuilder searchSource =
|
||||||
new SearchSourceBuilder()
|
new SearchSourceBuilder(client.adapter())
|
||||||
.query(qb)
|
.query(qb)
|
||||||
.from(opts.start())
|
.from(opts.start())
|
||||||
.size(opts.limit())
|
.size(opts.limit())
|
||||||
@@ -431,7 +431,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
|
|||||||
private JsonArray getSortArray() {
|
private JsonArray getSortArray() {
|
||||||
JsonObject properties = new JsonObject();
|
JsonObject properties = new JsonObject();
|
||||||
properties.addProperty(ORDER, "desc");
|
properties.addProperty(ORDER, "desc");
|
||||||
properties.addProperty(IGNORE_UNMAPPED, true);
|
client.adapter().setIgnoreUnmapped(properties);
|
||||||
|
|
||||||
JsonArray sortArray = new JsonArray();
|
JsonArray sortArray = new JsonArray();
|
||||||
addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray);
|
addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray);
|
||||||
|
@@ -60,8 +60,8 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
|
|||||||
static class GroupMapping {
|
static class GroupMapping {
|
||||||
MappingProperties groups;
|
MappingProperties groups;
|
||||||
|
|
||||||
GroupMapping(Schema<InternalGroup> schema) {
|
GroupMapping(Schema<InternalGroup> schema, ElasticQueryAdapter adapter) {
|
||||||
this.groups = ElasticMapping.createMapping(schema);
|
this.groups = ElasticMapping.createMapping(schema, adapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
|
|||||||
@Assisted Schema<InternalGroup> schema) {
|
@Assisted Schema<InternalGroup> schema) {
|
||||||
super(cfg, sitePaths, schema, client, GROUPS);
|
super(cfg, sitePaths, schema, client, GROUPS);
|
||||||
this.groupCache = groupCache;
|
this.groupCache = groupCache;
|
||||||
this.mapping = new GroupMapping(schema);
|
this.mapping = new GroupMapping(schema, client.adapter());
|
||||||
this.schema = schema;
|
this.schema = schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
|
|||||||
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
|
||||||
fields = IndexUtils.groupFields(opts);
|
fields = IndexUtils.groupFields(opts);
|
||||||
SearchSourceBuilder searchSource =
|
SearchSourceBuilder searchSource =
|
||||||
new SearchSourceBuilder()
|
new SearchSourceBuilder(client.adapter())
|
||||||
.query(qb)
|
.query(qb)
|
||||||
.from(opts.start())
|
.from(opts.start())
|
||||||
.size(opts.limit())
|
.size(opts.limit())
|
||||||
|
@@ -21,13 +21,15 @@ import com.google.gerrit.index.Schema;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
class ElasticMapping {
|
class ElasticMapping {
|
||||||
static MappingProperties createMapping(Schema<?> schema) {
|
static MappingProperties createMapping(Schema<?> schema, ElasticQueryAdapter adapter) {
|
||||||
ElasticMapping.Builder mapping = new ElasticMapping.Builder();
|
ElasticMapping.Builder mapping = new ElasticMapping.Builder(adapter);
|
||||||
for (FieldDef<?, ?> field : schema.getFields().values()) {
|
for (FieldDef<?, ?> field : schema.getFields().values()) {
|
||||||
String name = field.getName();
|
String name = field.getName();
|
||||||
FieldType<?> fieldType = field.getType();
|
FieldType<?> fieldType = field.getType();
|
||||||
if (fieldType == FieldType.EXACT || fieldType == FieldType.KEYWORD) {
|
if (fieldType == FieldType.EXACT) {
|
||||||
mapping.addExactField(name);
|
mapping.addExactField(name);
|
||||||
|
} else if (fieldType == FieldType.KEYWORD) {
|
||||||
|
mapping.addKeywordField(name);
|
||||||
} else if (fieldType == FieldType.TIMESTAMP) {
|
} else if (fieldType == FieldType.TIMESTAMP) {
|
||||||
mapping.addTimestamp(name);
|
mapping.addTimestamp(name);
|
||||||
} else if (fieldType == FieldType.INTEGER
|
} else if (fieldType == FieldType.INTEGER
|
||||||
@@ -46,9 +48,14 @@ class ElasticMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class Builder {
|
static class Builder {
|
||||||
|
private final ElasticQueryAdapter adapter;
|
||||||
private final ImmutableMap.Builder<String, FieldProperties> fields =
|
private final ImmutableMap.Builder<String, FieldProperties> fields =
|
||||||
new ImmutableMap.Builder<>();
|
new ImmutableMap.Builder<>();
|
||||||
|
|
||||||
|
Builder(ElasticQueryAdapter adapter) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
}
|
||||||
|
|
||||||
MappingProperties build() {
|
MappingProperties build() {
|
||||||
MappingProperties properties = new MappingProperties();
|
MappingProperties properties = new MappingProperties();
|
||||||
properties.properties = fields.build();
|
properties.properties = fields.build();
|
||||||
@@ -56,9 +63,20 @@ class ElasticMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Builder addExactField(String name) {
|
Builder addExactField(String name) {
|
||||||
FieldProperties key = new FieldProperties("string");
|
FieldProperties key = new FieldProperties(adapter.keywordFieldType());
|
||||||
key.index = "not_analyzed";
|
key.index = adapter.indexProperty();
|
||||||
FieldProperties properties = new FieldProperties("string");
|
FieldProperties properties;
|
||||||
|
properties = new FieldProperties(adapter.stringFieldType());
|
||||||
|
properties.fields = ImmutableMap.of("key", key);
|
||||||
|
fields.put(name, properties);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder addKeywordField(String name) {
|
||||||
|
FieldProperties key = new FieldProperties(adapter.keywordFieldType());
|
||||||
|
key.index = adapter.indexProperty();
|
||||||
|
FieldProperties properties;
|
||||||
|
properties = new FieldProperties(adapter.keywordFieldType());
|
||||||
properties.fields = ImmutableMap.of("key", key);
|
properties.fields = ImmutableMap.of("key", key);
|
||||||
fields.put(name, properties);
|
fields.put(name, properties);
|
||||||
return this;
|
return this;
|
||||||
@@ -78,7 +96,7 @@ class ElasticMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Builder addString(String name) {
|
Builder addString(String name) {
|
||||||
fields.put(name, new FieldProperties("string"));
|
fields.put(name, new FieldProperties(adapter.stringFieldType()));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,74 @@
|
|||||||
|
// 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 keywordFieldType;
|
||||||
|
private final String stringFieldType;
|
||||||
|
private final String indexProperty;
|
||||||
|
|
||||||
|
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.keywordFieldType = "keyword";
|
||||||
|
this.stringFieldType = "text";
|
||||||
|
this.indexProperty = "true";
|
||||||
|
break;
|
||||||
|
case V2_4:
|
||||||
|
default:
|
||||||
|
this.searchFilteringName = "fields";
|
||||||
|
this.indicesExistParam = "";
|
||||||
|
this.keywordFieldType = "string";
|
||||||
|
this.stringFieldType = "string";
|
||||||
|
this.indexProperty = "not_analyzed";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIgnoreUnmapped(JsonObject properties) {
|
||||||
|
if (ignoreUnmapped) {
|
||||||
|
properties.addProperty("ignore_unmapped", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String searchFilteringName() {
|
||||||
|
return searchFilteringName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String indicesExistParam() {
|
||||||
|
return indicesExistParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
String keywordFieldType() {
|
||||||
|
return keywordFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
String stringFieldType() {
|
||||||
|
return stringFieldType;
|
||||||
|
}
|
||||||
|
|
||||||
|
String indexProperty() {
|
||||||
|
return indexProperty;
|
||||||
|
}
|
||||||
|
}
|
@@ -44,6 +44,7 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
|
|||||||
private final String password;
|
private final String password;
|
||||||
|
|
||||||
private RestClient client;
|
private RestClient client;
|
||||||
|
private ElasticQueryAdapter adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ElasticRestClientProvider(ElasticConfiguration cfg) {
|
ElasticRestClientProvider(ElasticConfiguration cfg) {
|
||||||
@@ -69,6 +70,7 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
|
|||||||
client = build();
|
client = build();
|
||||||
ElasticVersion version = getVersion();
|
ElasticVersion version = getVersion();
|
||||||
log.info("Elasticsearch integration version {}", version);
|
log.info("Elasticsearch integration version {}", version);
|
||||||
|
adapter = new ElasticQueryAdapter(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -89,6 +91,11 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ElasticQueryAdapter adapter() {
|
||||||
|
get(); // Make sure we're connected
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
public static class FailedToGetVersion extends ElasticException {
|
public static class FailedToGetVersion extends ElasticException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final String MESSAGE = "Failed to get Elasticsearch version";
|
private static final String MESSAGE = "Failed to get Elasticsearch version";
|
||||||
|
@@ -27,9 +27,14 @@ class MatchQueryBuilder extends QueryBuilder {
|
|||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
/** The text is analyzed and used as a phrase query. */
|
/** 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. */
|
/** 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;
|
private final String name;
|
||||||
@@ -52,14 +57,6 @@ class MatchQueryBuilder extends QueryBuilder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doXContent(XContentBuilder builder) throws IOException {
|
protected void doXContent(XContentBuilder builder) throws IOException {
|
||||||
builder.startObject("match");
|
builder.startObject(type.toString()).field(name, text).endObject();
|
||||||
builder.startObject(name);
|
|
||||||
|
|
||||||
builder.field("query", text);
|
|
||||||
if (type != null) {
|
|
||||||
builder.field("type", type.toString().toLowerCase(Locale.ENGLISH));
|
|
||||||
}
|
|
||||||
builder.endObject();
|
|
||||||
builder.endObject();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,7 @@ public abstract class QueryBuilders {
|
|||||||
* @param text The query text (to be analyzed).
|
* @param text The query text (to be analyzed).
|
||||||
*/
|
*/
|
||||||
public static MatchQueryBuilder matchPhraseQuery(String name, Object text) {
|
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 @@ public abstract class QueryBuilders {
|
|||||||
* @param text The query text (to be analyzed).
|
* @param text The query text (to be analyzed).
|
||||||
*/
|
*/
|
||||||
public static MatchQueryBuilder matchPhrasePrefixQuery(String name, Object text) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.elasticsearch.builders;
|
package com.google.gerrit.elasticsearch.builders;
|
||||||
|
|
||||||
|
import com.google.gerrit.elasticsearch.ElasticQueryAdapter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ import java.util.List;
|
|||||||
* <p>A trimmed down and modified version of org.elasticsearch.search.builder.SearchSourceBuilder.
|
* <p>A trimmed down and modified version of org.elasticsearch.search.builder.SearchSourceBuilder.
|
||||||
*/
|
*/
|
||||||
public class SearchSourceBuilder {
|
public class SearchSourceBuilder {
|
||||||
|
private final ElasticQueryAdapter adapter;
|
||||||
|
|
||||||
private QuerySourceBuilder querySourceBuilder;
|
private QuerySourceBuilder querySourceBuilder;
|
||||||
|
|
||||||
@@ -33,7 +35,9 @@ public class SearchSourceBuilder {
|
|||||||
private List<String> fieldNames;
|
private List<String> fieldNames;
|
||||||
|
|
||||||
/** Constructs a new search source builder. */
|
/** 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. */
|
/** Constructs a new search source builder with a search query. */
|
||||||
public SearchSourceBuilder query(QueryBuilder query) {
|
public SearchSourceBuilder query(QueryBuilder query) {
|
||||||
@@ -95,9 +99,9 @@ public class SearchSourceBuilder {
|
|||||||
|
|
||||||
if (fieldNames != null) {
|
if (fieldNames != null) {
|
||||||
if (fieldNames.size() == 1) {
|
if (fieldNames.size() == 1) {
|
||||||
builder.field("fields", fieldNames.get(0));
|
builder.field(adapter.searchFilteringName(), fieldNames.get(0));
|
||||||
} else {
|
} else {
|
||||||
builder.startArray("fields");
|
builder.startArray(adapter.searchFilteringName());
|
||||||
for (String fieldName : fieldNames) {
|
for (String fieldName : fieldNames) {
|
||||||
builder.value(fieldName);
|
builder.value(fieldName);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
package com.google.gerrit.elasticsearch;
|
package com.google.gerrit.elasticsearch;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.gerrit.elasticsearch.ElasticVersion;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.apache.http.HttpHost;
|
import org.apache.http.HttpHost;
|
||||||
import org.junit.internal.AssumptionViolatedException;
|
import org.junit.internal.AssumptionViolatedException;
|
||||||
|
@@ -17,14 +17,11 @@ package com.google.gerrit.elasticsearch;
|
|||||||
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
|
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
|
||||||
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
|
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
|
||||||
import com.google.gerrit.testutil.InMemoryModule;
|
import com.google.gerrit.testutil.InMemoryModule;
|
||||||
import com.google.gerrit.testutil.InMemoryRepositoryManager.Repo;
|
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import org.eclipse.jgit.junit.TestRepository;
|
|
||||||
import org.eclipse.jgit.lib.Config;
|
import org.eclipse.jgit.lib.Config;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
||||||
private static ElasticNodeInfo nodeInfo;
|
private static ElasticNodeInfo nodeInfo;
|
||||||
@@ -66,12 +63,4 @@ public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
|||||||
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
|
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
|
||||||
return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration));
|
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 + "\"\\");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,66 @@
|
|||||||
|
// 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.testutil.InMemoryModule;
|
||||||
|
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 {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,66 @@
|
|||||||
|
// 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.testutil.InMemoryModule;
|
||||||
|
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 {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,66 @@
|
|||||||
|
// 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.testutil.InMemoryModule;
|
||||||
|
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 {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
@@ -2593,6 +2593,14 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
|
|||||||
assertQuery("query:query4");
|
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 {
|
protected ChangeInserter newChange(TestRepository<Repo> repo) throws Exception {
|
||||||
return newChange(repo, null, null, null, null, false);
|
return newChange(repo, null, null, null, null, false);
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,7 @@ public class LuceneQueryChangesTest extends AbstractQueryChangesTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Override
|
||||||
public void byOwnerInvalidQuery() throws Exception {
|
public void byOwnerInvalidQuery() throws Exception {
|
||||||
TestRepository<Repo> repo = createProject("repo");
|
TestRepository<Repo> repo = createProject("repo");
|
||||||
Change change1 = insert(repo, newChange(repo), userId);
|
Change change1 = insert(repo, newChange(repo), userId);
|
||||||
|
Reference in New Issue
Block a user