Elastic Search: Split reusable code to utility classes

As a preparatory step before adding the implementation of the account
index in Elastic Search, split out code that can be reused into utility
classes.

Change-Id: I46e0fe4e4e2ef969565cd2f481ab45c46397016e
Signed-off-by: Dariusz Luksza <dluksza@collab.net>
Signed-off-by: David Pursehouse <dpursehouse@collab.net>
This commit is contained in:
Dariusz Luksza
2016-09-22 14:44:40 +02:00
committed by David Pursehouse
parent 91ff74efc8
commit 1d71d309a4
8 changed files with 233 additions and 152 deletions

View File

@@ -15,9 +15,11 @@
package com.google.gerrit.elasticsearch;
import static com.google.common.base.Preconditions.checkState;
import static org.apache.commons.codec.binary.Base64.decodeBase64;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import com.google.common.base.Strings;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
@@ -26,6 +28,9 @@ import com.google.gerrit.server.index.Index;
import com.google.gerrit.server.index.IndexUtils;
import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.index.Schema.Values;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gwtorm.protobuf.ProtobufCodec;
import org.eclipse.jgit.lib.Config;
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -33,6 +38,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.searchbox.client.JestClientFactory;
@@ -46,6 +52,16 @@ import io.searchbox.indices.DeleteIndex;
import io.searchbox.indices.IndicesExists;
abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
protected static <T> List<T> decodeProtos(JsonObject doc, String fieldName,
ProtobufCodec<T> codec) {
JsonArray field = doc.getAsJsonArray(fieldName);
if (field == null) {
return null;
}
return FluentIterable.from(field)
.transform(i -> codec.decode(decodeBase64(i.toString())))
.toList();
}
private final Schema<V> schema;
private final FillArgs fillArgs;
@@ -55,7 +71,6 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
protected final String indexName;
protected final JestHttpClient client;
AbstractElasticIndex(@GerritServerConfig Config cfg,
FillArgs fillArgs,
SitePaths sitePaths,

View File

@@ -34,9 +34,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.index.FieldDef;
import com.google.gerrit.server.index.FieldDef.FillArgs;
import com.google.gerrit.server.index.FieldType;
import com.google.gerrit.server.index.IndexUtils;
import com.google.gerrit.server.index.QueryOptions;
import com.google.gerrit.server.index.Schema;
@@ -56,7 +54,6 @@ import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gwtorm.protobuf.ProtobufCodec;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Provider;
@@ -94,30 +91,9 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
MappingProperties closedChanges;
ChangeMapping(Schema<ChangeData> schema) {
ElasticMapping.Builder mappingBuilder = new ElasticMapping.Builder();
for (FieldDef<?, ?> field : schema.getFields().values()) {
String name = field.getName();
FieldType<?> fieldType = field.getType();
if (fieldType == FieldType.EXACT) {
mappingBuilder.addExactField(name);
} else if (fieldType == FieldType.TIMESTAMP) {
mappingBuilder.addTimestamp(name);
} else if (fieldType == FieldType.INTEGER
|| fieldType == FieldType.INTEGER_RANGE
|| fieldType == FieldType.LONG) {
mappingBuilder.addNumber(name);
} else if (fieldType == FieldType.PREFIX
|| fieldType == FieldType.FULL_TEXT
|| fieldType == FieldType.STORED_ONLY) {
mappingBuilder.addString(name);
} else {
throw new IllegalArgumentException(
"Unsupported field type " + fieldType.getName());
}
}
MappingProperties mapping = mappingBuilder.build();
openChanges = mapping;
closedChanges = mapping;
MappingProperties mapping = ElasticMapping.createMapping(schema);
this.openChanges = mapping;
this.closedChanges = mapping;
}
}
@@ -149,17 +125,6 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
.setFieldNamingPolicy(LOWER_CASE_WITH_UNDERSCORES).create();
}
private static <T> List<T> decodeProtos(JsonObject doc, String fieldName,
ProtobufCodec<T> codec) {
JsonArray field = doc.getAsJsonArray(fieldName);
if (field == null) {
return null;
}
return FluentIterable.from(field)
.transform(i -> codec.decode(decodeBase64(i.toString())))
.toList();
}
@Override
public void replace(ChangeData cd) throws IOException {
String deleteIndex;
@@ -236,7 +201,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
sort.setIgnoreUnmapped();
}
QueryBuilder qb = queryBuilder.toQueryBuilder(p);
fields = IndexUtils.fields(opts);
fields = IndexUtils.changeFields(opts);
SearchSourceBuilder searchSource = new SearchSourceBuilder()
.query(qb)
.from(opts.start())

View File

@@ -15,10 +15,38 @@
package com.google.gerrit.elasticsearch;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.server.index.FieldDef;
import com.google.gerrit.server.index.FieldType;
import com.google.gerrit.server.index.Schema;
import java.util.Map;
class ElasticMapping {
static MappingProperties createMapping(Schema<?> schema) {
ElasticMapping.Builder mapping = new ElasticMapping.Builder();
for (FieldDef<?, ?> field : schema.getFields().values()) {
String name = field.getName();
FieldType<?> fieldType = field.getType();
if (fieldType == FieldType.EXACT) {
mapping.addExactField(name);
} else if (fieldType == FieldType.TIMESTAMP) {
mapping.addTimestamp(name);
} else if (fieldType == FieldType.INTEGER
|| fieldType == FieldType.INTEGER_RANGE
|| fieldType == FieldType.LONG) {
mapping.addNumber(name);
} else if (fieldType == FieldType.PREFIX
|| fieldType == FieldType.FULL_TEXT
|| fieldType == FieldType.STORED_ONLY) {
mapping.addString(name);
} else {
throw new IllegalStateException(
"Unsupported field type: " + fieldType.getName());
}
}
return mapping.build();
}
static class Builder {
private final ImmutableMap.Builder<String, FieldProperties> fields =
new ImmutableMap.Builder<>();