diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java similarity index 99% rename from gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexIT.java rename to gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java index f55c68b807..1cedb91307 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/AbstractReindexTests.java @@ -44,7 +44,7 @@ import org.junit.Test; @NoHttpd @Ignore -public abstract class AbstractReindexIT extends StandaloneSiteTest { +public abstract class AbstractReindexTests extends StandaloneSiteTest { /** @param injector injector */ public abstract void configureIndex(Injector injector) throws Exception; diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/BUILD b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/BUILD index 8f9cf350e2..a5f0d4e9f9 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/BUILD +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/BUILD @@ -11,16 +11,8 @@ acceptance_tests( deps = [":util"], ) -java_library( - name = "util", - testonly = 1, - srcs = ["IndexUpgradeController.java"], - deps = ["//gerrit-acceptance-tests:lib"], -) - acceptance_tests( srcs = [ - "AbstractReindexIT.java", "ElasticReindexIT.java", ], group = "elastic", @@ -34,3 +26,13 @@ acceptance_tests( "//gerrit-elasticsearch:elasticsearch_test_utils", ], ) + +java_library( + name = "util", + testonly = 1, + srcs = [ + "AbstractReindexTests.java", + "IndexUpgradeController.java", + ], + deps = ["//gerrit-acceptance-tests:lib"], +) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java index 0d6581cf8b..37207ff3ab 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java @@ -27,7 +27,7 @@ import org.junit.Ignore; @NoHttpd @Ignore -public class ElasticReindexIT extends AbstractReindexIT { +public class ElasticReindexIT extends AbstractReindexTests { private static ElasticContainer container; @ConfigSuite.Default diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java index c9808eab81..743ccc3dad 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/pgm/ReindexIT.java @@ -18,7 +18,7 @@ import com.google.gerrit.acceptance.NoHttpd; import com.google.inject.Injector; @NoHttpd -public class ReindexIT extends AbstractReindexIT { +public class ReindexIT extends AbstractReindexTests { @Override public void configureIndex(Injector injector) throws Exception {} diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java index 58613e7a71..d314997420 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java @@ -16,19 +16,15 @@ package com.google.gerrit.elasticsearch; import static com.google.gson.FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES; import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.stream.Collectors.toList; import static org.apache.commons.codec.binary.Base64.decodeBase64; import com.google.common.base.Strings; import com.google.common.collect.FluentIterable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Streams; import com.google.common.io.CharStreams; import com.google.gerrit.elasticsearch.builders.SearchSourceBuilder; -import com.google.gerrit.elasticsearch.builders.XContentBuilder; +import com.google.gerrit.elasticsearch.bulk.DeleteRequest; import com.google.gerrit.index.Index; import com.google.gerrit.index.Schema; -import com.google.gerrit.index.Schema.Values; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.index.IndexUtils; @@ -50,10 +46,6 @@ import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpHead; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ContentType; import org.apache.http.nio.entity.NStringEntity; import org.eclipse.jgit.lib.Config; @@ -61,11 +53,8 @@ import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; abstract class AbstractElasticIndex implements Index { - protected static final String BULK = "_bulk"; - protected static final String DELETE = "delete"; protected static final String IGNORE_UNMAPPED = "ignore_unmapped"; - protected static final String INDEX = "index"; protected static final String ORDER = "order"; protected static final String SEARCH = "_search"; @@ -143,7 +132,7 @@ abstract class AbstractElasticIndex implements Index { @Override public void delete(K c) throws IOException { String uri = getURI(indexNameRaw, BULK); - Response response = performRequest(HttpPost.METHOD_NAME, addActions(c), uri, getRefreshParam()); + Response response = postRequest(addActions(c), uri, getRefreshParam()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { throw new IOException( @@ -154,10 +143,10 @@ abstract class AbstractElasticIndex implements Index { @Override public void deleteAll() throws IOException { // Delete the index, if it exists. - Response response = client.performRequest(HttpHead.METHOD_NAME, indexName); + Response response = client.performRequest("HEAD", indexName); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { - response = client.performRequest(HttpDelete.METHOD_NAME, indexName); + response = client.performRequest("DELETE", indexName); statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { throw new IOException( @@ -166,8 +155,7 @@ abstract class AbstractElasticIndex implements Index { } // Recreate the index. - response = - performRequest(HttpPut.METHOD_NAME, getMappings(), indexName, Collections.emptyMap()); + response = performRequest("PUT", getMappings(), indexName, Collections.emptyMap()); statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { String error = String.format("Failed to create index %s: %s", indexName, statusCode); @@ -183,44 +171,7 @@ abstract class AbstractElasticIndex implements Index { protected String delete(String type, K c) { String id = c.toString(); - return toAction(type, id, DELETE); - } - - private static boolean shouldAddElement(Object element) { - return !(element instanceof String) || !((String) element).isEmpty(); - } - - protected String toDoc(V v) throws IOException { - try (XContentBuilder closeable = new XContentBuilder()) { - XContentBuilder builder = closeable.startObject(); - for (Values values : schema.buildFields(v)) { - String name = values.getField().getName(); - if (values.getField().isRepeatable()) { - builder.field( - name, - Streams.stream(values.getValues()) - .filter(e -> shouldAddElement(e)) - .collect(toList())); - } else { - Object element = Iterables.getOnlyElement(values.getValues(), ""); - if (shouldAddElement(element)) { - builder.field(name, element); - } - } - } - return builder.endObject().string() + System.lineSeparator(); - } - } - - protected String toAction(String type, String id, String action) { - JsonObject properties = new JsonObject(); - properties.addProperty("_id", id); - properties.addProperty("_index", indexName); - properties.addProperty("_type", type); - - JsonObject jsonAction = new JsonObject(); - jsonAction.add(action, properties); - return jsonAction.toString() + System.lineSeparator(); + return new DeleteRequest(id, indexNameRaw, type).toString(); } protected void addNamedElement(String name, JsonObject element, JsonArray array) { @@ -257,9 +208,15 @@ abstract class AbstractElasticIndex implements Index { return encodedIndexName + "/" + encodedType + "/" + request; } - protected Response performRequest( - String method, String payload, String uri, Map params) throws IOException { - HttpEntity entity = new NStringEntity(payload, ContentType.APPLICATION_JSON); + protected Response postRequest(Object payload, String uri, Map params) + throws IOException { + return performRequest("POST", payload, uri, params); + } + + private Response performRequest( + String method, Object payload, String uri, Map params) throws IOException { + String payloadStr = payload instanceof String ? (String) payload : payload.toString(); + HttpEntity entity = new NStringEntity(payloadStr, ContentType.APPLICATION_JSON); return client.performRequest(method, uri, params, entity); } } diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java index 36988dd1a4..570c9ef18e 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticAccountIndex.java @@ -21,6 +21,9 @@ import com.google.common.collect.Lists; import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties; import com.google.gerrit.elasticsearch.builders.QueryBuilder; import com.google.gerrit.elasticsearch.builders.SearchSourceBuilder; +import com.google.gerrit.elasticsearch.bulk.BulkRequest; +import com.google.gerrit.elasticsearch.bulk.IndexRequest; +import com.google.gerrit.elasticsearch.bulk.UpdateRequest; import com.google.gerrit.index.QueryOptions; import com.google.gerrit.index.Schema; import com.google.gerrit.index.query.DataSource; @@ -50,7 +53,6 @@ import java.util.List; import java.util.Set; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; -import org.apache.http.client.methods.HttpPost; import org.eclipse.jgit.lib.Config; import org.elasticsearch.client.Response; import org.slf4j.Logger; @@ -72,6 +74,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex accountCache; + private final Schema schema; @AssistedInject ElasticAccountIndex( @@ -83,15 +86,16 @@ public class ElasticAccountIndex extends AbstractElasticIndex(schema, as)); String uri = getURI(ACCOUNTS, BULK); - Response response = performRequest(HttpPost.METHOD_NAME, bulk, uri, getRefreshParam()); + Response response = postRequest(bulk, uri, getRefreshParam()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { throw new IOException( @@ -151,8 +155,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex results = Collections.emptyList(); String uri = getURI(ACCOUNTS, SEARCH); - Response response = - performRequest(HttpPost.METHOD_NAME, search, uri, Collections.emptyMap()); + Response response = postRequest(search, uri, Collections.emptyMap()); StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK) { String content = getContent(response); diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java index 7799936326..49a807faf1 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java @@ -33,6 +33,10 @@ import com.google.common.collect.Sets; import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties; import com.google.gerrit.elasticsearch.builders.QueryBuilder; import com.google.gerrit.elasticsearch.builders.SearchSourceBuilder; +import com.google.gerrit.elasticsearch.bulk.BulkRequest; +import com.google.gerrit.elasticsearch.bulk.DeleteRequest; +import com.google.gerrit.elasticsearch.bulk.IndexRequest; +import com.google.gerrit.elasticsearch.bulk.UpdateRequest; import com.google.gerrit.index.QueryOptions; import com.google.gerrit.index.Schema; import com.google.gerrit.index.query.Predicate; @@ -71,7 +75,6 @@ import java.util.Set; import org.apache.commons.codec.binary.Base64; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; -import org.apache.http.client.methods.HttpPost; import org.eclipse.jgit.lib.Config; import org.elasticsearch.client.Response; import org.slf4j.Logger; @@ -100,6 +103,7 @@ class ElasticChangeIndex extends AbstractElasticIndex private final ChangeMapping mapping; private final Provider db; private final ChangeData.Factory changeDataFactory; + private final Schema schema; @Inject ElasticChangeIndex( @@ -112,6 +116,7 @@ class ElasticChangeIndex extends AbstractElasticIndex super(cfg, sitePaths, schema, clientBuilder, CHANGES); this.db = db; this.changeDataFactory = changeDataFactory; + this.schema = schema; mapping = new ChangeMapping(schema); } @@ -132,12 +137,13 @@ class ElasticChangeIndex extends AbstractElasticIndex throw new IOException(e); } - String bulk = toAction(insertIndex, getId(cd), INDEX); - bulk += toDoc(cd); - bulk += toAction(deleteIndex, cd.getId().toString(), DELETE); + BulkRequest bulk = + new IndexRequest(getId(cd), indexName, insertIndex) + .add(new UpdateRequest<>(schema, cd)) + .add(new DeleteRequest(cd.getId().toString(), indexName, deleteIndex)); String uri = getURI(CHANGES, BULK); - Response response = performRequest(HttpPost.METHOD_NAME, bulk, uri, getRefreshParam()); + Response response = postRequest(bulk, uri, getRefreshParam()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { throw new IOException( @@ -205,8 +211,7 @@ class ElasticChangeIndex extends AbstractElasticIndex try { List results = Collections.emptyList(); String uri = getURI(types); - Response response = - performRequest(HttpPost.METHOD_NAME, search, uri, Collections.emptyMap()); + Response response = postRequest(search, uri, Collections.emptyMap()); StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK) { String content = getContent(response); diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java index 4ed6a901f0..f1f87cd0e8 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticGroupIndex.java @@ -19,6 +19,9 @@ import com.google.common.collect.Lists; import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties; import com.google.gerrit.elasticsearch.builders.QueryBuilder; import com.google.gerrit.elasticsearch.builders.SearchSourceBuilder; +import com.google.gerrit.elasticsearch.bulk.BulkRequest; +import com.google.gerrit.elasticsearch.bulk.IndexRequest; +import com.google.gerrit.elasticsearch.bulk.UpdateRequest; import com.google.gerrit.index.QueryOptions; import com.google.gerrit.index.Schema; import com.google.gerrit.index.query.DataSource; @@ -49,7 +52,6 @@ import java.util.Optional; import java.util.Set; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; -import org.apache.http.client.methods.HttpPost; import org.eclipse.jgit.lib.Config; import org.elasticsearch.client.Response; import org.slf4j.Logger; @@ -71,6 +73,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex groupCache; + private final Schema schema; @AssistedInject ElasticGroupIndex( @@ -82,15 +85,16 @@ public class ElasticGroupIndex extends AbstractElasticIndex(schema, group)); String uri = getURI(GROUPS, BULK); - Response response = performRequest(HttpPost.METHOD_NAME, bulk, uri, getRefreshParam()); + Response response = postRequest(bulk, uri, getRefreshParam()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { throw new IOException( @@ -150,8 +154,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex results = Collections.emptyList(); String uri = getURI(GROUPS, SEARCH); - Response response = - performRequest(HttpPost.METHOD_NAME, search, uri, Collections.emptyMap()); + Response response = postRequest(search, uri, Collections.emptyMap()); StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK) { String content = getContent(response); diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java index 61d59adbd2..85fa2c1a82 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticIndexVersionDiscovery.java @@ -14,16 +14,14 @@ package com.google.gerrit.elasticsearch; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import static java.util.stream.Collectors.toList; + import com.google.gson.JsonParser; import com.google.inject.Inject; import com.google.inject.Singleton; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map.Entry; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import org.elasticsearch.client.Response; @@ -42,16 +40,14 @@ class ElasticIndexVersionDiscovery { String name = prefix + indexName + "_"; Response response = client.performRequest(HttpGet.METHOD_NAME, name + "*/_aliases"); - int statusCode = response.getStatusLine().getStatusCode(); - if (statusCode == HttpStatus.SC_OK) { - String content = AbstractElasticIndex.getContent(response); - JsonObject object = new JsonParser().parse(content).getAsJsonObject(); - - List versions = new ArrayList<>(object.size()); - for (Entry entry : object.entrySet()) { - versions.add(entry.getKey().replace(name, "")); - } - return versions; + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + return new JsonParser() + .parse(AbstractElasticIndex.getContent(response)) + .getAsJsonObject() + .entrySet() + .stream() + .map(e -> e.getKey().replace(name, "")) + .collect(toList()); } return Collections.emptyList(); } diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticVersionManager.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticVersionManager.java index dce8fac2e8..36d40f5a7d 100644 --- a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticVersionManager.java +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/ElasticVersionManager.java @@ -14,7 +14,7 @@ package com.google.gerrit.elasticsearch; -import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; import com.google.common.primitives.Ints; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.gerrit.index.Index; @@ -50,7 +50,7 @@ public class ElasticVersionManager extends VersionManager { ElasticIndexVersionDiscovery versionDiscovery) { super(sitePaths, listeners, defs, VersionManager.getOnlineUpgrade(cfg)); this.versionDiscovery = versionDiscovery; - prefix = MoreObjects.firstNonNull(cfg.getString("index", null, "prefix"), "gerrit"); + prefix = Strings.nullToEmpty(cfg.getString("elasticsearch", null, "prefix")); } @Override diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java new file mode 100644 index 0000000000..c7757b2f63 --- /dev/null +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/ActionRequest.java @@ -0,0 +1,44 @@ +// 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.bulk; + +import com.google.gson.JsonObject; + +abstract class ActionRequest extends BulkRequest { + + private final String action; + private final String id; + private final String index; + private final String type; + + protected ActionRequest(String action, String id, String index, String type) { + this.action = action; + this.id = id; + this.index = index; + this.type = type; + } + + @Override + protected String getRequest() { + JsonObject properties = new JsonObject(); + properties.addProperty("_id", id); + properties.addProperty("_index", index); + properties.addProperty("_type", type); + + JsonObject jsonAction = new JsonObject(); + jsonAction.add(action, properties); + return jsonAction.toString() + System.lineSeparator(); + } +} diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java new file mode 100644 index 0000000000..be5ad8d25a --- /dev/null +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/BulkRequest.java @@ -0,0 +1,43 @@ +// 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.bulk; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BulkRequest { + + private final List requests = new ArrayList<>(); + + protected BulkRequest() { + add(this); + } + + public BulkRequest add(BulkRequest request) { + requests.add(request); + return this; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (BulkRequest request : requests) { + builder.append(request.getRequest()); + } + return builder.toString(); + } + + protected abstract String getRequest(); +} diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java new file mode 100644 index 0000000000..7d549ca453 --- /dev/null +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/DeleteRequest.java @@ -0,0 +1,22 @@ +// 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.bulk; + +public class DeleteRequest extends ActionRequest { + + public DeleteRequest(String id, String index, String type) { + super("delete", id, index, type); + } +} diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java new file mode 100644 index 0000000000..b131501635 --- /dev/null +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/IndexRequest.java @@ -0,0 +1,22 @@ +// 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.bulk; + +public class IndexRequest extends ActionRequest { + + public IndexRequest(String id, String index, String type) { + super("index", id, index, type); + } +} diff --git a/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java new file mode 100644 index 0000000000..a693f6db4c --- /dev/null +++ b/gerrit-elasticsearch/src/main/java/com/google/gerrit/elasticsearch/bulk/UpdateRequest.java @@ -0,0 +1,64 @@ +// 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.bulk; + +import static java.util.stream.Collectors.toList; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Streams; +import com.google.gerrit.elasticsearch.builders.XContentBuilder; +import com.google.gerrit.index.Schema; +import com.google.gerrit.index.Schema.Values; +import java.io.IOException; + +public class UpdateRequest extends BulkRequest { + + private final Schema schema; + private final V v; + + public UpdateRequest(Schema schema, V v) { + this.schema = schema; + this.v = v; + } + + @Override + protected String getRequest() { + try (XContentBuilder closeable = new XContentBuilder()) { + XContentBuilder builder = closeable.startObject(); + for (Values values : schema.buildFields(v)) { + String name = values.getField().getName(); + if (values.getField().isRepeatable()) { + builder.field( + name, + Streams.stream(values.getValues()) + .filter(e -> shouldAddElement(e)) + .collect(toList())); + } else { + Object element = Iterables.getOnlyElement(values.getValues(), ""); + if (shouldAddElement(element)) { + builder.field(name, element); + } + } + } + return builder.endObject().string() + System.lineSeparator(); + } catch (IOException e) { + return e.toString(); + } + } + + private boolean shouldAddElement(Object element) { + return !(element instanceof String) || !((String) element).isEmpty(); + } +}