Throw StorageException instead of IOException from Index
Change-Id: I6b2c4442afbdbb678b5a8f1bc00f83b99f759734
This commit is contained in:
		@@ -22,7 +22,6 @@ import com.google.gerrit.index.query.QueryParseException;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.server.index.change.ChangeIndex;
 | 
			
		||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -53,17 +52,17 @@ public class DisabledChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData obj) throws IOException {
 | 
			
		||||
  public void replace(ChangeData obj) {
 | 
			
		||||
    throw new UnsupportedOperationException("ChangeIndex is disabled");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Change.Id key) throws IOException {
 | 
			
		||||
  public void delete(Change.Id key) {
 | 
			
		||||
    throw new UnsupportedOperationException("ChangeIndex is disabled");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {
 | 
			
		||||
  public void deleteAll() {
 | 
			
		||||
    throw new UnsupportedOperationException("ChangeIndex is disabled");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -74,12 +73,12 @@ public class DisabledChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {
 | 
			
		||||
  public void markReady(boolean ready) {
 | 
			
		||||
    throw new UnsupportedOperationException("ChangeIndex is disabled");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Optional<ChangeData> get(Change.Id key, QueryOptions opts) throws IOException {
 | 
			
		||||
  public Optional<ChangeData> get(Change.Id key, QueryOptions opts) {
 | 
			
		||||
    throw new UnsupportedOperationException("ChangeIndex is disabled");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ import com.google.gerrit.index.query.QueryParseException;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.server.index.change.ChangeIndex;
 | 
			
		||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
class ReadOnlyChangeIndex implements ChangeIndex {
 | 
			
		||||
  private final ChangeIndex index;
 | 
			
		||||
@@ -46,17 +45,17 @@ class ReadOnlyChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData obj) throws IOException {
 | 
			
		||||
  public void replace(ChangeData obj) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Change.Id key) throws IOException {
 | 
			
		||||
  public void delete(Change.Id key) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {
 | 
			
		||||
  public void deleteAll() {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +66,7 @@ class ReadOnlyChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {
 | 
			
		||||
  public void markReady(boolean ready) {
 | 
			
		||||
    // do nothing
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -167,23 +167,23 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {
 | 
			
		||||
  public void markReady(boolean ready) {
 | 
			
		||||
    IndexUtils.setReady(sitePaths, indexNameRaw, schema.getVersion(), ready);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(K id) throws IOException {
 | 
			
		||||
  public void delete(K id) {
 | 
			
		||||
    String uri = getURI(type, BULK);
 | 
			
		||||
    Response response = postRequest(uri, getDeleteActions(id), getRefreshParam());
 | 
			
		||||
    int statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      throw new IOException(
 | 
			
		||||
      throw new StorageException(
 | 
			
		||||
          String.format("Failed to delete %s from index %s: %s", id, indexName, statusCode));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {
 | 
			
		||||
  public void deleteAll() {
 | 
			
		||||
    // Delete the index, if it exists.
 | 
			
		||||
    String endpoint = indexName + client.adapter().indicesExistParam();
 | 
			
		||||
    Response response = performRequest("HEAD", endpoint);
 | 
			
		||||
@@ -192,7 +192,7 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
      response = performRequest("DELETE", indexName);
 | 
			
		||||
      statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
      if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
        throw new IOException(
 | 
			
		||||
        throw new StorageException(
 | 
			
		||||
            String.format("Failed to delete index %s: %s", indexName, statusCode));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -205,7 +205,7 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
    statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      String error = String.format("Failed to create index %s: %s", indexName, statusCode);
 | 
			
		||||
      throw new IOException(error);
 | 
			
		||||
      throw new StorageException(error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -307,21 +307,24 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
    return sortArray;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected String getURI(String type, String request) throws UnsupportedEncodingException {
 | 
			
		||||
    String encodedIndexName = URLEncoder.encode(indexName, UTF_8.toString());
 | 
			
		||||
    if (SEARCH.equals(request) && client.adapter().omitTypeFromSearch()) {
 | 
			
		||||
      return encodedIndexName + "/" + request;
 | 
			
		||||
  protected String getURI(String type, String request) {
 | 
			
		||||
    try {
 | 
			
		||||
      String encodedIndexName = URLEncoder.encode(indexName, UTF_8.toString());
 | 
			
		||||
      if (SEARCH.equals(request) && client.adapter().omitTypeFromSearch()) {
 | 
			
		||||
        return encodedIndexName + "/" + request;
 | 
			
		||||
      }
 | 
			
		||||
      String encodedType = URLEncoder.encode(type, UTF_8.toString());
 | 
			
		||||
      return encodedIndexName + "/" + encodedType + "/" + request;
 | 
			
		||||
    } catch (UnsupportedEncodingException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
    String encodedType = URLEncoder.encode(type, UTF_8.toString());
 | 
			
		||||
    return encodedIndexName + "/" + encodedType + "/" + request;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected Response postRequest(String uri, Object payload) throws IOException {
 | 
			
		||||
  protected Response postRequest(String uri, Object payload) {
 | 
			
		||||
    return performRequest("POST", uri, payload);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected Response postRequest(String uri, Object payload, Map<String, String> params)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
  protected Response postRequest(String uri, Object payload, Map<String, String> params) {
 | 
			
		||||
    return performRequest("POST", uri, payload, params);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -329,18 +332,16 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
    return target.substring(0, target.length() - 1) + "," + addition.substring(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Response performRequest(String method, String uri) throws IOException {
 | 
			
		||||
  private Response performRequest(String method, String uri) {
 | 
			
		||||
    return performRequest(method, uri, null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Response performRequest(String method, String uri, @Nullable Object payload)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
  private Response performRequest(String method, String uri, @Nullable Object payload) {
 | 
			
		||||
    return performRequest(method, uri, payload, Collections.emptyMap());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Response performRequest(
 | 
			
		||||
      String method, String uri, @Nullable Object payload, Map<String, String> params)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
      String method, String uri, @Nullable Object payload, Map<String, String> params) {
 | 
			
		||||
    Request request = new Request(method, uri.startsWith("/") ? uri : "/" + uri);
 | 
			
		||||
    if (payload != null) {
 | 
			
		||||
      String payloadStr = payload instanceof String ? (String) payload : payload.toString();
 | 
			
		||||
@@ -349,7 +350,11 @@ abstract class AbstractElasticIndex<K, V> implements Index<K, V> {
 | 
			
		||||
    for (Map.Entry<String, String> entry : params.entrySet()) {
 | 
			
		||||
      request.addParameter(entry.getKey(), entry.getValue());
 | 
			
		||||
    }
 | 
			
		||||
    return client.get().performRequest(request);
 | 
			
		||||
    try {
 | 
			
		||||
      return client.get().performRequest(request);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected class ElasticQuerySource implements DataSource<V> {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
 | 
			
		||||
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.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
import com.google.gerrit.index.query.DataSource;
 | 
			
		||||
@@ -38,7 +39,6 @@ import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import org.apache.http.HttpStatus;
 | 
			
		||||
import org.elasticsearch.client.Response;
 | 
			
		||||
@@ -73,7 +73,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(AccountState as) throws IOException {
 | 
			
		||||
  public void replace(AccountState as) {
 | 
			
		||||
    BulkRequest bulk =
 | 
			
		||||
        new IndexRequest(getId(as), indexName, type, client.adapter())
 | 
			
		||||
            .add(new UpdateRequest<>(schema, as));
 | 
			
		||||
@@ -82,7 +82,7 @@ public class ElasticAccountIndex extends AbstractElasticIndex<Account.Id, Accoun
 | 
			
		||||
    Response response = postRequest(uri, bulk, getRefreshParam());
 | 
			
		||||
    int statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      throw new IOException(
 | 
			
		||||
      throw new StorageException(
 | 
			
		||||
          String.format(
 | 
			
		||||
              "Failed to replace account %s in index %s: %s",
 | 
			
		||||
              as.getAccount().getId(), indexName, statusCode));
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@ 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.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
import com.google.gerrit.index.query.DataSource;
 | 
			
		||||
@@ -59,7 +60,6 @@ import com.google.gson.JsonElement;
 | 
			
		||||
import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@@ -106,7 +106,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData cd) throws IOException {
 | 
			
		||||
  public void replace(ChangeData cd) {
 | 
			
		||||
    String deleteIndex;
 | 
			
		||||
    String insertIndex;
 | 
			
		||||
 | 
			
		||||
@@ -130,7 +130,7 @@ class ElasticChangeIndex extends AbstractElasticIndex<Change.Id, ChangeData>
 | 
			
		||||
    Response response = postRequest(uri, bulk, getRefreshParam());
 | 
			
		||||
    int statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      throw new IOException(
 | 
			
		||||
      throw new StorageException(
 | 
			
		||||
          String.format(
 | 
			
		||||
              "Failed to replace change %s in index %s: %s", cd.getId(), indexName, statusCode));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
 | 
			
		||||
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.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
import com.google.gerrit.index.query.DataSource;
 | 
			
		||||
@@ -36,7 +37,6 @@ import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import org.apache.http.HttpStatus;
 | 
			
		||||
import org.elasticsearch.client.Response;
 | 
			
		||||
@@ -71,7 +71,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(InternalGroup group) throws IOException {
 | 
			
		||||
  public void replace(InternalGroup group) {
 | 
			
		||||
    BulkRequest bulk =
 | 
			
		||||
        new IndexRequest(getId(group), indexName, type, client.adapter())
 | 
			
		||||
            .add(new UpdateRequest<>(schema, group));
 | 
			
		||||
@@ -80,7 +80,7 @@ public class ElasticGroupIndex extends AbstractElasticIndex<AccountGroup.UUID, I
 | 
			
		||||
    Response response = postRequest(uri, bulk, getRefreshParam());
 | 
			
		||||
    int statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      throw new IOException(
 | 
			
		||||
      throw new StorageException(
 | 
			
		||||
          String.format(
 | 
			
		||||
              "Failed to replace group %s in index %s: %s",
 | 
			
		||||
              group.getGroupUUID().get(), indexName, statusCode));
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ import com.google.gerrit.elasticsearch.ElasticMapping.MappingProperties;
 | 
			
		||||
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.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
import com.google.gerrit.index.project.ProjectData;
 | 
			
		||||
@@ -36,7 +37,6 @@ import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Provider;
 | 
			
		||||
import com.google.inject.assistedinject.Assisted;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import org.apache.http.HttpStatus;
 | 
			
		||||
import org.elasticsearch.client.Response;
 | 
			
		||||
@@ -71,7 +71,7 @@ public class ElasticProjectIndex extends AbstractElasticIndex<Project.NameKey, P
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ProjectData projectState) throws IOException {
 | 
			
		||||
  public void replace(ProjectData projectState) {
 | 
			
		||||
    BulkRequest bulk =
 | 
			
		||||
        new IndexRequest(projectState.getProject().getName(), indexName, type, client.adapter())
 | 
			
		||||
            .add(new UpdateRequest<>(schema, projectState));
 | 
			
		||||
@@ -80,7 +80,7 @@ public class ElasticProjectIndex extends AbstractElasticIndex<Project.NameKey, P
 | 
			
		||||
    Response response = postRequest(uri, bulk, getRefreshParam());
 | 
			
		||||
    int statusCode = response.getStatusLine().getStatusCode();
 | 
			
		||||
    if (statusCode != HttpStatus.SC_OK) {
 | 
			
		||||
      throw new IOException(
 | 
			
		||||
      throw new StorageException(
 | 
			
		||||
          String.format(
 | 
			
		||||
              "Failed to replace project %s in index %s: %s",
 | 
			
		||||
              projectState.getProject().getName(), indexName, statusCode));
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@ import com.google.gerrit.index.query.FieldBundle;
 | 
			
		||||
import com.google.gerrit.index.query.IndexPredicate;
 | 
			
		||||
import com.google.gerrit.index.query.Predicate;
 | 
			
		||||
import com.google.gerrit.index.query.QueryParseException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -48,24 +47,18 @@ public interface Index<K, V> {
 | 
			
		||||
   * searchers, but should be visible within a reasonable amount of time.
 | 
			
		||||
   *
 | 
			
		||||
   * @param obj document object
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  void replace(V obj) throws IOException;
 | 
			
		||||
  void replace(V obj);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delete a document from the index by key.
 | 
			
		||||
   *
 | 
			
		||||
   * @param key document key
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  void delete(K key) throws IOException;
 | 
			
		||||
  void delete(K key);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delete all documents from the index.
 | 
			
		||||
   *
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  void deleteAll() throws IOException;
 | 
			
		||||
  /** Delete all documents from the index. */
 | 
			
		||||
  void deleteAll();
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Convert the given operator predicate into a source searching the index and returning only the
 | 
			
		||||
@@ -91,20 +84,17 @@ public interface Index<K, V> {
 | 
			
		||||
   * @param opts query options. Options that do not make sense in the context of a single document,
 | 
			
		||||
   *     such as start, will be ignored.
 | 
			
		||||
   * @return a single document if present.
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  default Optional<V> get(K key, QueryOptions opts) throws IOException {
 | 
			
		||||
  default Optional<V> get(K key, QueryOptions opts) {
 | 
			
		||||
    opts = opts.withStart(0).withLimit(2);
 | 
			
		||||
    ImmutableList<V> results;
 | 
			
		||||
    try {
 | 
			
		||||
      results = getSource(keyPredicate(key), opts).read().toList();
 | 
			
		||||
    } catch (QueryParseException e) {
 | 
			
		||||
      throw new IOException("Unexpected QueryParseException during get()", e);
 | 
			
		||||
    } catch (StorageException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException("Unexpected QueryParseException during get()", e);
 | 
			
		||||
    }
 | 
			
		||||
    if (results.size() > 1) {
 | 
			
		||||
      throw new IOException("Multiple results found in index for key " + key + ": " + results);
 | 
			
		||||
      throw new StorageException("Multiple results found in index for key " + key + ": " + results);
 | 
			
		||||
    }
 | 
			
		||||
    return results.stream().findFirst();
 | 
			
		||||
  }
 | 
			
		||||
@@ -116,20 +106,17 @@ public interface Index<K, V> {
 | 
			
		||||
   * @param opts query options. Options that do not make sense in the context of a single document,
 | 
			
		||||
   *     such as start, will be ignored.
 | 
			
		||||
   * @return an abstraction of a raw index document to retrieve fields from.
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  default Optional<FieldBundle> getRaw(K key, QueryOptions opts) throws IOException {
 | 
			
		||||
  default Optional<FieldBundle> getRaw(K key, QueryOptions opts) {
 | 
			
		||||
    opts = opts.withStart(0).withLimit(2);
 | 
			
		||||
    ImmutableList<FieldBundle> results;
 | 
			
		||||
    try {
 | 
			
		||||
      results = getSource(keyPredicate(key), opts).readRaw().toList();
 | 
			
		||||
    } catch (QueryParseException e) {
 | 
			
		||||
      throw new IOException("Unexpected QueryParseException during get()", e);
 | 
			
		||||
    } catch (StorageException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException("Unexpected QueryParseException during get()", e);
 | 
			
		||||
    }
 | 
			
		||||
    if (results.size() > 1) {
 | 
			
		||||
      throw new IOException("Multiple results found in index for key " + key + ": " + results);
 | 
			
		||||
      throw new StorageException("Multiple results found in index for key " + key + ": " + results);
 | 
			
		||||
    }
 | 
			
		||||
    return results.stream().findFirst();
 | 
			
		||||
  }
 | 
			
		||||
@@ -146,7 +133,6 @@ public interface Index<K, V> {
 | 
			
		||||
   * Mark whether this index is up-to-date and ready to serve reads.
 | 
			
		||||
   *
 | 
			
		||||
   * @param ready whether the index is ready
 | 
			
		||||
   * @throws IOException
 | 
			
		||||
   */
 | 
			
		||||
  void markReady(boolean ready) throws IOException;
 | 
			
		||||
  void markReady(boolean ready);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ import com.google.common.collect.FluentIterable;
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.google.common.flogger.FluentLogger;
 | 
			
		||||
import com.google.gerrit.exceptions.StorageException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -179,7 +178,7 @@ public class Schema<T> {
 | 
			
		||||
              Object v;
 | 
			
		||||
              try {
 | 
			
		||||
                v = f.get(obj);
 | 
			
		||||
              } catch (StorageException e) {
 | 
			
		||||
              } catch (RuntimeException e) {
 | 
			
		||||
                logger.atSevere().withCause(e).log(
 | 
			
		||||
                    "error getting field %s of %s", f.getName(), obj);
 | 
			
		||||
                return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -213,7 +213,7 @@ public abstract class AbstractLuceneIndex<K, V> implements Index<K, V> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {
 | 
			
		||||
  public void markReady(boolean ready) {
 | 
			
		||||
    IndexUtils.setReady(sitePaths, name, schema.getVersion(), ready);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -287,8 +287,12 @@ public abstract class AbstractLuceneIndex<K, V> implements Index<K, V> {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {
 | 
			
		||||
    writer.deleteAll();
 | 
			
		||||
  public void deleteAll() {
 | 
			
		||||
    try {
 | 
			
		||||
      writer.deleteAll();
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public IndexWriter getWriter() {
 | 
			
		||||
 
 | 
			
		||||
@@ -71,12 +71,12 @@ public class ChangeSubIndex extends AbstractLuceneIndex<Change.Id, ChangeData>
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData obj) throws IOException {
 | 
			
		||||
  public void replace(ChangeData obj) {
 | 
			
		||||
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Change.Id key) throws IOException {
 | 
			
		||||
  public void delete(Change.Id key) {
 | 
			
		||||
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ import static com.google.gerrit.server.index.account.AccountField.FULL_NAME;
 | 
			
		||||
import static com.google.gerrit.server.index.account.AccountField.ID;
 | 
			
		||||
import static com.google.gerrit.server.index.account.AccountField.PREFERRED_EMAIL_EXACT;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.FieldDef;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
@@ -120,20 +121,20 @@ public class LuceneAccountIndex extends AbstractLuceneIndex<Account.Id, AccountS
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(AccountState as) throws IOException {
 | 
			
		||||
  public void replace(AccountState as) {
 | 
			
		||||
    try {
 | 
			
		||||
      replace(idTerm(as), toDocument(as)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Account.Id key) throws IOException {
 | 
			
		||||
  public void delete(Account.Id key) {
 | 
			
		||||
    try {
 | 
			
		||||
      delete(idTerm(key)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -200,7 +200,7 @@ public class LuceneChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData cd) throws IOException {
 | 
			
		||||
  public void replace(ChangeData cd) {
 | 
			
		||||
    Term id = LuceneChangeIndex.idTerm(cd);
 | 
			
		||||
    // toDocument is essentially static and doesn't depend on the specific
 | 
			
		||||
    // sub-index, so just pick one.
 | 
			
		||||
@@ -211,23 +211,23 @@ public class LuceneChangeIndex implements ChangeIndex {
 | 
			
		||||
      } else {
 | 
			
		||||
        Futures.allAsList(openIndex.delete(id), closedIndex.replace(id, doc)).get();
 | 
			
		||||
      }
 | 
			
		||||
    } catch (StorageException | ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Change.Id id) throws IOException {
 | 
			
		||||
  public void delete(Change.Id id) {
 | 
			
		||||
    Term idTerm = LuceneChangeIndex.idTerm(id);
 | 
			
		||||
    try {
 | 
			
		||||
      Futures.allAsList(openIndex.delete(idTerm), closedIndex.delete(idTerm)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {
 | 
			
		||||
  public void deleteAll() {
 | 
			
		||||
    openIndex.deleteAll();
 | 
			
		||||
    closedIndex.deleteAll();
 | 
			
		||||
  }
 | 
			
		||||
@@ -247,7 +247,7 @@ public class LuceneChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {
 | 
			
		||||
  public void markReady(boolean ready) {
 | 
			
		||||
    // Arbitrary done on open index, as ready bit is set
 | 
			
		||||
    // per index and not sub index
 | 
			
		||||
    openIndex.markReady(ready);
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ package com.google.gerrit.lucene;
 | 
			
		||||
import static com.google.common.collect.Iterables.getOnlyElement;
 | 
			
		||||
import static com.google.gerrit.server.index.group.GroupField.UUID;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.FieldDef;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
@@ -110,20 +111,20 @@ public class LuceneGroupIndex extends AbstractLuceneIndex<AccountGroup.UUID, Int
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(InternalGroup group) throws IOException {
 | 
			
		||||
  public void replace(InternalGroup group) {
 | 
			
		||||
    try {
 | 
			
		||||
      replace(idTerm(group), toDocument(group)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(AccountGroup.UUID key) throws IOException {
 | 
			
		||||
  public void delete(AccountGroup.UUID key) {
 | 
			
		||||
    try {
 | 
			
		||||
      delete(idTerm(key)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ package com.google.gerrit.lucene;
 | 
			
		||||
import static com.google.common.collect.Iterables.getOnlyElement;
 | 
			
		||||
import static com.google.gerrit.index.project.ProjectField.NAME;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.FieldDef;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.Schema;
 | 
			
		||||
@@ -110,20 +111,20 @@ public class LuceneProjectIndex extends AbstractLuceneIndex<Project.NameKey, Pro
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ProjectData projectState) throws IOException {
 | 
			
		||||
  public void replace(ProjectData projectState) {
 | 
			
		||||
    try {
 | 
			
		||||
      replace(idTerm(projectState), toDocument(projectState)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Project.NameKey nameKey) throws IOException {
 | 
			
		||||
  public void delete(Project.NameKey nameKey) {
 | 
			
		||||
    try {
 | 
			
		||||
      delete(idTerm(nameKey)).get();
 | 
			
		||||
    } catch (ExecutionException | InterruptedException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ import com.google.common.base.Function;
 | 
			
		||||
import com.google.common.collect.ImmutableMap;
 | 
			
		||||
import com.google.common.collect.ImmutableSet;
 | 
			
		||||
import com.google.common.collect.Sets;
 | 
			
		||||
import com.google.gerrit.exceptions.StorageException;
 | 
			
		||||
import com.google.gerrit.index.QueryOptions;
 | 
			
		||||
import com.google.gerrit.index.project.ProjectField;
 | 
			
		||||
import com.google.gerrit.server.CurrentUser;
 | 
			
		||||
@@ -49,23 +50,22 @@ public final class IndexUtils {
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
  public static void setReady(SitePaths sitePaths, String name, int version, boolean ready)
 | 
			
		||||
      throws IOException {
 | 
			
		||||
  public static void setReady(SitePaths sitePaths, String name, int version, boolean ready) {
 | 
			
		||||
    try {
 | 
			
		||||
      GerritIndexStatus cfg = new GerritIndexStatus(sitePaths);
 | 
			
		||||
      cfg.setReady(name, version, ready);
 | 
			
		||||
      cfg.save();
 | 
			
		||||
    } catch (ConfigInvalidException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
    } catch (ConfigInvalidException | IOException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public static boolean getReady(SitePaths sitePaths, String name, int version) throws IOException {
 | 
			
		||||
  public static boolean getReady(SitePaths sitePaths, String name, int version) {
 | 
			
		||||
    try {
 | 
			
		||||
      GerritIndexStatus cfg = new GerritIndexStatus(sitePaths);
 | 
			
		||||
      return cfg.getReady(name, version);
 | 
			
		||||
    } catch (ConfigInvalidException e) {
 | 
			
		||||
      throw new IOException(e);
 | 
			
		||||
    } catch (ConfigInvalidException | IOException e) {
 | 
			
		||||
      throw new StorageException(e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -120,11 +120,7 @@ public class OnlineReindexer<K, V, I extends Index<K, V>> {
 | 
			
		||||
  public void activateIndex() {
 | 
			
		||||
    indexes.setSearchIndex(index);
 | 
			
		||||
    logger.atInfo().log("Using %s schema version %s", name, version(index));
 | 
			
		||||
    try {
 | 
			
		||||
      index.markReady(true);
 | 
			
		||||
    } catch (IOException e) {
 | 
			
		||||
      logger.atWarning().log("Error activating new %s schema version %s", name, version(index));
 | 
			
		||||
    }
 | 
			
		||||
    index.markReady(true);
 | 
			
		||||
 | 
			
		||||
    List<I> toRemove = Lists.newArrayListWithExpectedSize(1);
 | 
			
		||||
    for (I i : indexes.getWriteIndexes()) {
 | 
			
		||||
@@ -133,12 +129,8 @@ public class OnlineReindexer<K, V, I extends Index<K, V>> {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    for (I i : toRemove) {
 | 
			
		||||
      try {
 | 
			
		||||
        i.markReady(false);
 | 
			
		||||
        indexes.removeWriteIndex(version(i));
 | 
			
		||||
      } catch (IOException e) {
 | 
			
		||||
        logger.atWarning().log("Error deactivating old %s schema version %s", name, version(i));
 | 
			
		||||
      }
 | 
			
		||||
      i.markReady(false);
 | 
			
		||||
      indexes.removeWriteIndex(version(i));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ import com.google.gerrit.index.query.Predicate;
 | 
			
		||||
import com.google.gerrit.reviewdb.client.Change;
 | 
			
		||||
import com.google.gerrit.server.query.change.ChangeData;
 | 
			
		||||
import com.google.gerrit.server.query.change.ChangeDataSource;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class DummyChangeIndex implements ChangeIndex {
 | 
			
		||||
  @Override
 | 
			
		||||
@@ -32,13 +31,13 @@ public class DummyChangeIndex implements ChangeIndex {
 | 
			
		||||
  public void close() {}
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void replace(ChangeData cd) throws IOException {}
 | 
			
		||||
  public void replace(ChangeData cd) {}
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void delete(Change.Id id) throws IOException {}
 | 
			
		||||
  public void delete(Change.Id id) {}
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void deleteAll() throws IOException {}
 | 
			
		||||
  public void deleteAll() {}
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public ChangeDataSource getSource(Predicate<ChangeData> p, QueryOptions opts) {
 | 
			
		||||
@@ -46,7 +45,7 @@ public class DummyChangeIndex implements ChangeIndex {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void markReady(boolean ready) throws IOException {}
 | 
			
		||||
  public void markReady(boolean ready) {}
 | 
			
		||||
 | 
			
		||||
  public int getMaxLimit() {
 | 
			
		||||
    return Integer.MAX_VALUE;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user