Merge branch 'stable-2.14' into stable-2.15
* stable-2.14: GroupField: Change UUID fields' type to KEYWORD Add keyword type to index type system Elasticsearch: Encapsulate supported versions in an enum Change-Id: Ic30a5bc0c69623a22f1305c96bfa70e3daeed054
This commit is contained in:
commit
199a33168a
@ -63,6 +63,7 @@ junit_tests(
|
|||||||
"//gerrit-server:query_tests_code",
|
"//gerrit-server:query_tests_code",
|
||||||
"//gerrit-server:server",
|
"//gerrit-server:server",
|
||||||
"//gerrit-server:testutil",
|
"//gerrit-server:testutil",
|
||||||
|
"//lib:truth",
|
||||||
"//lib/guice",
|
"//lib/guice",
|
||||||
"//lib/httpcomponents:httpcore",
|
"//lib/httpcomponents:httpcore",
|
||||||
"//lib/jgit/org.eclipse.jgit:jgit",
|
"//lib/jgit/org.eclipse.jgit:jgit",
|
||||||
|
@ -64,6 +64,6 @@ public class ElasticIndexModule extends AbstractIndexModule {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<? extends VersionManager> getVersionManager() {
|
protected Class<? extends VersionManager> getVersionManager() {
|
||||||
return ElasticVersionManager.class;
|
return ElasticIndexVersionManager.class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,14 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ElasticVersionManager extends VersionManager {
|
public class ElasticIndexVersionManager extends VersionManager {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ElasticVersionManager.class);
|
private static final Logger log = LoggerFactory.getLogger(ElasticIndexVersionManager.class);
|
||||||
|
|
||||||
private final String prefix;
|
private final String prefix;
|
||||||
private final ElasticIndexVersionDiscovery versionDiscovery;
|
private final ElasticIndexVersionDiscovery versionDiscovery;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ElasticVersionManager(
|
ElasticIndexVersionManager(
|
||||||
ElasticConfiguration cfg,
|
ElasticConfiguration cfg,
|
||||||
SitePaths sitePaths,
|
SitePaths sitePaths,
|
||||||
DynamicSet<OnlineUpgradeListener> listeners,
|
DynamicSet<OnlineUpgradeListener> listeners,
|
@ -26,7 +26,7 @@ class ElasticMapping {
|
|||||||
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) {
|
if (fieldType == FieldType.EXACT || fieldType == FieldType.KEYWORD) {
|
||||||
mapping.addExactField(name);
|
mapping.addExactField(name);
|
||||||
} else if (fieldType == FieldType.TIMESTAMP) {
|
} else if (fieldType == FieldType.TIMESTAMP) {
|
||||||
mapping.addTimestamp(name);
|
mapping.addTimestamp(name);
|
||||||
|
@ -94,7 +94,7 @@ public class ElasticQueryBuilder {
|
|||||||
return intRangeQuery(p);
|
return intRangeQuery(p);
|
||||||
} else if (type == FieldType.TIMESTAMP) {
|
} else if (type == FieldType.TIMESTAMP) {
|
||||||
return timestampQuery(p);
|
return timestampQuery(p);
|
||||||
} else if (type == FieldType.EXACT) {
|
} else if (type == FieldType.EXACT || type == FieldType.KEYWORD) {
|
||||||
return exactQuery(p);
|
return exactQuery(p);
|
||||||
} else if (type == FieldType.PREFIX) {
|
} else if (type == FieldType.PREFIX) {
|
||||||
return QueryBuilders.matchPhrasePrefixQuery(name, value);
|
return QueryBuilders.matchPhrasePrefixQuery(name, value);
|
||||||
|
@ -67,8 +67,8 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
client = build();
|
client = build();
|
||||||
String version = getVersion();
|
ElasticVersion version = getVersion();
|
||||||
log.info("Connected to Elasticsearch version {}", version);
|
log.info("Elasticsearch integration version {}", version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,20 +102,23 @@ class ElasticRestClientProvider implements Provider<RestClient>, LifecycleListen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getVersion() throws ElasticException {
|
private ElasticVersion getVersion() throws ElasticException {
|
||||||
try {
|
try {
|
||||||
Response response = client.performRequest("GET", "");
|
Response response = client.performRequest("GET", "");
|
||||||
StatusLine statusLine = response.getStatusLine();
|
StatusLine statusLine = response.getStatusLine();
|
||||||
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
|
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
|
||||||
throw new FailedToGetVersion(statusLine);
|
throw new FailedToGetVersion(statusLine);
|
||||||
}
|
}
|
||||||
return new JsonParser()
|
String version =
|
||||||
|
new JsonParser()
|
||||||
.parse(AbstractElasticIndex.getContent(response))
|
.parse(AbstractElasticIndex.getContent(response))
|
||||||
.getAsJsonObject()
|
.getAsJsonObject()
|
||||||
.get("version")
|
.get("version")
|
||||||
.getAsJsonObject()
|
.getAsJsonObject()
|
||||||
.get("number")
|
.get("number")
|
||||||
.getAsString();
|
.getAsString();
|
||||||
|
log.info("Connected to Elasticsearch version {}", version);
|
||||||
|
return ElasticVersion.forVersion(version);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new FailedToGetVersion(e);
|
throw new FailedToGetVersion(e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
// 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.common.base.Joiner;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public enum ElasticVersion {
|
||||||
|
V2_4("2.4.*"),
|
||||||
|
V5_6("5.6.*"),
|
||||||
|
V6_2("6.2.*");
|
||||||
|
|
||||||
|
private final String version;
|
||||||
|
private final Pattern pattern;
|
||||||
|
|
||||||
|
private ElasticVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
this.pattern = Pattern.compile(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidVersion extends ElasticException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
InvalidVersion(String version) {
|
||||||
|
super(
|
||||||
|
String.format(
|
||||||
|
"Invalid version: [%s]. Supported versions: %s", version, supportedVersions()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ElasticVersion forVersion(String version) throws InvalidVersion {
|
||||||
|
for (ElasticVersion value : ElasticVersion.values()) {
|
||||||
|
if (value.pattern.matcher(version).matches()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new InvalidVersion(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String supportedVersions() {
|
||||||
|
return Joiner.on(", ").join(ElasticVersion.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
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;
|
||||||
@ -24,13 +25,7 @@ import org.testcontainers.containers.GenericContainer;
|
|||||||
public class ElasticContainer<SELF extends ElasticContainer<SELF>> extends GenericContainer<SELF> {
|
public class ElasticContainer<SELF extends ElasticContainer<SELF>> extends GenericContainer<SELF> {
|
||||||
private static final int ELASTICSEARCH_DEFAULT_PORT = 9200;
|
private static final int ELASTICSEARCH_DEFAULT_PORT = 9200;
|
||||||
|
|
||||||
public enum Version {
|
public static ElasticContainer<?> createAndStart(ElasticVersion version) {
|
||||||
V2,
|
|
||||||
V5,
|
|
||||||
V6
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ElasticContainer<?> createAndStart(Version version) {
|
|
||||||
// Assumption violation is not natively supported by Testcontainers.
|
// Assumption violation is not natively supported by Testcontainers.
|
||||||
// See https://github.com/testcontainers/testcontainers-java/issues/343
|
// See https://github.com/testcontainers/testcontainers-java/issues/343
|
||||||
try {
|
try {
|
||||||
@ -43,22 +38,22 @@ public class ElasticContainer<SELF extends ElasticContainer<SELF>> extends Gener
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ElasticContainer<?> createAndStart() {
|
public static ElasticContainer<?> createAndStart() {
|
||||||
return createAndStart(Version.V2);
|
return createAndStart(ElasticVersion.V2_4);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getImageName(Version version) {
|
private static String getImageName(ElasticVersion version) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case V2:
|
case V2_4:
|
||||||
return "elasticsearch:2.4.6-alpine";
|
return "elasticsearch:2.4.6-alpine";
|
||||||
case V5:
|
case V5_6:
|
||||||
return "elasticsearch:5.6.9-alpine";
|
return "elasticsearch:5.6.9-alpine";
|
||||||
case V6:
|
case V6_2:
|
||||||
return "docker.elastic.co/elasticsearch/elasticsearch:6.2.4";
|
return "docker.elastic.co/elasticsearch/elasticsearch:6.2.4";
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Unsupported version: " + version.name());
|
throw new IllegalStateException("No tests for version: " + version.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ElasticContainer(Version version) {
|
private ElasticContainer(ElasticVersion version) {
|
||||||
super(getImageName(version));
|
super(getImageName(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
// 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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
public class ElasticVersionTest {
|
||||||
|
@Rule public ExpectedException exception = ExpectedException.none();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void supportedVersion() throws Exception {
|
||||||
|
assertThat(ElasticVersion.forVersion("2.4.0")).isEqualTo(ElasticVersion.V2_4);
|
||||||
|
assertThat(ElasticVersion.forVersion("2.4.6")).isEqualTo(ElasticVersion.V2_4);
|
||||||
|
|
||||||
|
assertThat(ElasticVersion.forVersion("5.6.0")).isEqualTo(ElasticVersion.V5_6);
|
||||||
|
assertThat(ElasticVersion.forVersion("5.6.9")).isEqualTo(ElasticVersion.V5_6);
|
||||||
|
|
||||||
|
assertThat(ElasticVersion.forVersion("6.2.0")).isEqualTo(ElasticVersion.V6_2);
|
||||||
|
assertThat(ElasticVersion.forVersion("6.2.4")).isEqualTo(ElasticVersion.V6_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void unsupportedVersion() throws Exception {
|
||||||
|
exception.expect(ElasticVersion.InvalidVersion.class);
|
||||||
|
exception.expectMessage(
|
||||||
|
"Invalid version: [4.0.0]. Supported versions: " + ElasticVersion.supportedVersions());
|
||||||
|
ElasticVersion.forVersion("4.0.0");
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,10 @@ public final class FieldDef<I, T> {
|
|||||||
return new FieldDef.Builder<>(FieldType.EXACT, name);
|
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) {
|
public static FieldDef.Builder<String> fullText(String name) {
|
||||||
return new FieldDef.Builder<>(FieldType.FULL_TEXT, name);
|
return new FieldDef.Builder<>(FieldType.FULL_TEXT, name);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ public class FieldType<T> {
|
|||||||
/** A string field searched using exact-match semantics. */
|
/** A string field searched using exact-match semantics. */
|
||||||
public static final FieldType<String> EXACT = new FieldType<>("EXACT");
|
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. */
|
/** A string field searched using prefix. */
|
||||||
public static final FieldType<String> PREFIX = new FieldType<>("PREFIX");
|
public static final FieldType<String> PREFIX = new FieldType<>("PREFIX");
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ public abstract class AbstractLuceneIndex<K, V> implements Index<K, V> {
|
|||||||
for (Object value : values.getValues()) {
|
for (Object value : values.getValues()) {
|
||||||
doc.add(new LongField(name, ((Timestamp) value).getTime(), store));
|
doc.add(new LongField(name, ((Timestamp) value).getTime(), store));
|
||||||
}
|
}
|
||||||
} else if (type == FieldType.EXACT || type == FieldType.PREFIX) {
|
} else if (type == FieldType.KEYWORD || type == FieldType.EXACT || type == FieldType.PREFIX) {
|
||||||
for (Object value : values.getValues()) {
|
for (Object value : values.getValues()) {
|
||||||
doc.add(new StringField(name, (String) value, store));
|
doc.add(new StringField(name, (String) value, store));
|
||||||
}
|
}
|
||||||
|
@ -141,20 +141,21 @@ public class QueryBuilder<V> {
|
|||||||
"field not in schema v%s: %s",
|
"field not in schema v%s: %s",
|
||||||
schema.getVersion(),
|
schema.getVersion(),
|
||||||
p.getField().getName());
|
p.getField().getName());
|
||||||
if (p.getType() == FieldType.INTEGER) {
|
FieldType<?> type = p.getType();
|
||||||
|
if (type == FieldType.INTEGER) {
|
||||||
return intQuery(p);
|
return intQuery(p);
|
||||||
} else if (p.getType() == FieldType.INTEGER_RANGE) {
|
} else if (type == FieldType.INTEGER_RANGE) {
|
||||||
return intRangeQuery(p);
|
return intRangeQuery(p);
|
||||||
} else if (p.getType() == FieldType.TIMESTAMP) {
|
} else if (type == FieldType.TIMESTAMP) {
|
||||||
return timestampQuery(p);
|
return timestampQuery(p);
|
||||||
} else if (p.getType() == FieldType.EXACT) {
|
} else if (type == FieldType.EXACT || type == FieldType.KEYWORD) {
|
||||||
return exactQuery(p);
|
return exactQuery(p);
|
||||||
} else if (p.getType() == FieldType.PREFIX) {
|
} else if (type == FieldType.PREFIX) {
|
||||||
return prefixQuery(p);
|
return prefixQuery(p);
|
||||||
} else if (p.getType() == FieldType.FULL_TEXT) {
|
} else if (type == FieldType.FULL_TEXT) {
|
||||||
return fullTextQuery(p);
|
return fullTextQuery(p);
|
||||||
} else {
|
} else {
|
||||||
throw FieldType.badFieldType(p.getType());
|
throw FieldType.badFieldType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
|
|||||||
import static com.google.gerrit.index.FieldDef.exact;
|
import static com.google.gerrit.index.FieldDef.exact;
|
||||||
import static com.google.gerrit.index.FieldDef.fullText;
|
import static com.google.gerrit.index.FieldDef.fullText;
|
||||||
import static com.google.gerrit.index.FieldDef.integer;
|
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.prefix;
|
||||||
import static com.google.gerrit.index.FieldDef.timestamp;
|
import static com.google.gerrit.index.FieldDef.timestamp;
|
||||||
|
|
||||||
@ -36,11 +37,11 @@ public class GroupField {
|
|||||||
|
|
||||||
/** Group UUID. */
|
/** Group UUID. */
|
||||||
public static final FieldDef<InternalGroup, String> UUID =
|
public static final FieldDef<InternalGroup, String> UUID =
|
||||||
exact("uuid").stored().build(g -> g.getGroupUUID().get());
|
keyword("uuid").stored().build(g -> g.getGroupUUID().get());
|
||||||
|
|
||||||
/** Group owner UUID. */
|
/** Group owner UUID. */
|
||||||
public static final FieldDef<InternalGroup, String> OWNER_UUID =
|
public static final FieldDef<InternalGroup, String> OWNER_UUID =
|
||||||
exact("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
|
keyword("owner_uuid").build(g -> g.getOwnerGroupUUID().get());
|
||||||
|
|
||||||
/** Timestamp indicating when this group was created. */
|
/** Timestamp indicating when this group was created. */
|
||||||
public static final FieldDef<InternalGroup, Timestamp> CREATED_ON =
|
public static final FieldDef<InternalGroup, Timestamp> CREATED_ON =
|
||||||
|
Loading…
Reference in New Issue
Block a user