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:

committed by
David Pursehouse

parent
91ff74efc8
commit
1d71d309a4
@@ -14,123 +14,60 @@
|
||||
|
||||
package com.google.gerrit.elasticsearch;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.gerrit.elasticsearch.ElasticChangeIndex.CHANGES_PREFIX;
|
||||
import static com.google.gerrit.elasticsearch.ElasticChangeIndex.CLOSED_CHANGES;
|
||||
import static com.google.gerrit.elasticsearch.ElasticChangeIndex.OPEN_CHANGES;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gerrit.elasticsearch.ElasticChangeIndex.ChangeMapping;
|
||||
import com.google.gerrit.server.index.IndexModule.IndexType;
|
||||
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
|
||||
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
|
||||
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
|
||||
import com.google.gerrit.testutil.InMemoryModule;
|
||||
import com.google.gerrit.testutil.InMemoryRepositoryManager.Repo;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
import org.eclipse.jgit.junit.TestRepository;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.NodeBuilder;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
||||
private static final Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
private static final String INDEX_NAME =
|
||||
String.format("%s%04d", CHANGES_PREFIX,
|
||||
ChangeSchemaDefinitions.INSTANCE.getLatest().getVersion());
|
||||
private static Node node;
|
||||
private static String port;
|
||||
private static File elasticDir;
|
||||
|
||||
static class NodeInfo {
|
||||
String httpAddress;
|
||||
}
|
||||
|
||||
static class Info {
|
||||
Map<String, NodeInfo> nodes;
|
||||
}
|
||||
private static ElasticNodeInfo nodeInfo;
|
||||
|
||||
@BeforeClass
|
||||
public static void startIndexService()
|
||||
throws InterruptedException, ExecutionException {
|
||||
if (node != null) {
|
||||
if (nodeInfo != null) {
|
||||
// do not start Elasticsearch twice
|
||||
return;
|
||||
}
|
||||
elasticDir = Files.createTempDir();
|
||||
Path elasticDirPath = elasticDir.toPath();
|
||||
Settings settings = Settings.settingsBuilder()
|
||||
.put("cluster.name", "gerrit")
|
||||
.put("node.name", "Gerrit Elasticsearch Test Node")
|
||||
.put("node.local", true)
|
||||
.put("discovery.zen.ping.multicast.enabled", false)
|
||||
.put("index.store.fs.memory.enabled", true)
|
||||
.put("index.gateway.type", "none")
|
||||
.put("index.max_result_window", Integer.MAX_VALUE)
|
||||
.put("gateway.type", "default")
|
||||
.put("http.port", 0)
|
||||
.put("discovery.zen.ping.unicast.hosts", "[\"localhost\"]")
|
||||
.put("path.home", elasticDirPath.toAbsolutePath())
|
||||
.put("path.data", elasticDirPath.resolve("data").toAbsolutePath())
|
||||
.put("path.work", elasticDirPath.resolve("work").toAbsolutePath())
|
||||
.put("path.logs", elasticDirPath.resolve("logs").toAbsolutePath())
|
||||
.put("transport.tcp.connect_timeout", "60s")
|
||||
.build();
|
||||
|
||||
// Start the node
|
||||
node = NodeBuilder.nodeBuilder()
|
||||
.settings(settings)
|
||||
.node();
|
||||
|
||||
// Wait for it to be ready
|
||||
node.client()
|
||||
.admin()
|
||||
.cluster()
|
||||
.prepareHealth()
|
||||
.setWaitForYellowStatus()
|
||||
.execute()
|
||||
.actionGet();
|
||||
nodeInfo = ElasticTestUtils.startElasticsearchNode();
|
||||
|
||||
createIndexes();
|
||||
|
||||
assertThat(node.isClosed()).isFalse();
|
||||
port = getHttpPort();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanupIndex() {
|
||||
node.client().admin().indices().prepareDelete(INDEX_NAME).execute();
|
||||
createIndexes();
|
||||
if (nodeInfo != null) {
|
||||
ElasticTestUtils.deleteIndexes(nodeInfo.node, INDEX_NAME);
|
||||
createIndexes();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stopElasticsearchServer() {
|
||||
if (node != null) {
|
||||
node.close();
|
||||
node = null;
|
||||
}
|
||||
if (elasticDir != null && elasticDir.delete()) {
|
||||
elasticDir = null;
|
||||
if (nodeInfo != null) {
|
||||
nodeInfo.node.close();
|
||||
nodeInfo.elasticDir.delete();
|
||||
nodeInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +75,7 @@ public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
||||
protected Injector createInjector() {
|
||||
Config elasticsearchConfig = new Config(config);
|
||||
InMemoryModule.setDefaults(elasticsearchConfig);
|
||||
elasticsearchConfig.setEnum("index", null, "type", IndexType.ELASTICSEARCH);
|
||||
elasticsearchConfig.setString("index", null, "protocol", "http");
|
||||
elasticsearchConfig.setString("index", null, "hostname", "localhost");
|
||||
elasticsearchConfig.setString("index", null, "port", port);
|
||||
elasticsearchConfig.setBoolean("index", "elasticsearch", "test", true);
|
||||
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port);
|
||||
return Guice.createInjector(
|
||||
new InMemoryModule(elasticsearchConfig, notesMigration));
|
||||
}
|
||||
@@ -154,35 +87,19 @@ public class ElasticQueryChangesTest extends AbstractQueryChangesTest {
|
||||
new ChangeMapping(ChangeSchemaDefinitions.INSTANCE.getLatest());
|
||||
openChangesMapping.closedChanges = null;
|
||||
closedChangesMapping.openChanges = null;
|
||||
node.client()
|
||||
nodeInfo.node
|
||||
.client()
|
||||
.admin()
|
||||
.indices()
|
||||
.prepareCreate(INDEX_NAME)
|
||||
.addMapping(OPEN_CHANGES, gson.toJson(openChangesMapping))
|
||||
.addMapping(CLOSED_CHANGES, gson.toJson(closedChangesMapping))
|
||||
.addMapping(OPEN_CHANGES,
|
||||
ElasticTestUtils.gson.toJson(openChangesMapping))
|
||||
.addMapping(CLOSED_CHANGES,
|
||||
ElasticTestUtils.gson.toJson(closedChangesMapping))
|
||||
.execute()
|
||||
.actionGet();
|
||||
}
|
||||
|
||||
private static String getHttpPort()
|
||||
throws InterruptedException, ExecutionException {
|
||||
String nodes = node.client().admin().cluster()
|
||||
.nodesInfo(new NodesInfoRequest("*")).get().toString();
|
||||
Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
Info info = gson.fromJson(nodes, Info.class);
|
||||
|
||||
checkState(info.nodes != null && info.nodes.size() == 1);
|
||||
Iterator<NodeInfo> values = info.nodes.values().iterator();
|
||||
String httpAddress = values.next().httpAddress;
|
||||
|
||||
checkState(
|
||||
!Strings.isNullOrEmpty(httpAddress) && httpAddress.indexOf(':') > 0);
|
||||
return httpAddress.substring(httpAddress.indexOf(':') + 1,
|
||||
httpAddress.length());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void byOwnerInvalidQuery() throws Exception {
|
||||
TestRepository<Repo> repo = createProject("repo");
|
||||
|
@@ -0,0 +1,144 @@
|
||||
// Copyright (C) 2016 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 com.google.common.base.Strings;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gerrit.server.index.IndexModule.IndexType;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.NodeBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
final class ElasticTestUtils {
|
||||
static final Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
|
||||
static class ElasticNodeInfo {
|
||||
final Node node;
|
||||
final String port;
|
||||
final File elasticDir;
|
||||
|
||||
private ElasticNodeInfo(Node node, File rootDir, String port) {
|
||||
this.node = node;
|
||||
this.port = port;
|
||||
this.elasticDir = rootDir;
|
||||
}
|
||||
}
|
||||
|
||||
static void configure(Config config, String port) {
|
||||
config.setEnum("index", null, "type", IndexType.ELASTICSEARCH);
|
||||
config.setString("index", null, "protocol", "http");
|
||||
config.setString("index", null, "hostname", "localhost");
|
||||
config.setString("index", null, "port", port);
|
||||
config.setBoolean("index", "elasticsearch", "test", true);
|
||||
}
|
||||
|
||||
static ElasticNodeInfo startElasticsearchNode()
|
||||
throws InterruptedException, ExecutionException {
|
||||
File elasticDir = Files.createTempDir();
|
||||
Path elasticDirPath = elasticDir.toPath();
|
||||
Settings settings = Settings.settingsBuilder()
|
||||
.put("cluster.name", "gerrit")
|
||||
.put("node.name", "Gerrit Elasticsearch Test Node")
|
||||
.put("node.local", true)
|
||||
.put("discovery.zen.ping.multicast.enabled", false)
|
||||
.put("index.store.fs.memory.enabled", true)
|
||||
.put("index.gateway.type", "none")
|
||||
.put("index.max_result_window", Integer.MAX_VALUE)
|
||||
.put("gateway.type", "default")
|
||||
.put("http.port", 0)
|
||||
.put("discovery.zen.ping.unicast.hosts", "[\"localhost\"]")
|
||||
.put("path.home", elasticDirPath.toAbsolutePath())
|
||||
.put("path.data", elasticDirPath.resolve("data").toAbsolutePath())
|
||||
.put("path.work", elasticDirPath.resolve("work").toAbsolutePath())
|
||||
.put("path.logs", elasticDirPath.resolve("logs").toAbsolutePath())
|
||||
.put("transport.tcp.connect_timeout", "60s")
|
||||
.build();
|
||||
|
||||
// Start the node
|
||||
Node node = NodeBuilder.nodeBuilder()
|
||||
.settings(settings)
|
||||
.node();
|
||||
|
||||
// Wait for it to be ready
|
||||
node.client()
|
||||
.admin()
|
||||
.cluster()
|
||||
.prepareHealth()
|
||||
.setWaitForYellowStatus()
|
||||
.execute()
|
||||
.actionGet();
|
||||
|
||||
assertThat(node.isClosed()).isFalse();
|
||||
return new ElasticNodeInfo(node, elasticDir, getHttpPort(node));
|
||||
}
|
||||
|
||||
static void deleteIndexes(Node node, String index) {
|
||||
node.client().admin().indices().prepareDelete(index).execute();
|
||||
}
|
||||
|
||||
static class NodeInfo {
|
||||
String httpAddress;
|
||||
}
|
||||
|
||||
static class Info {
|
||||
Map<String, NodeInfo> nodes;
|
||||
}
|
||||
|
||||
private static String getHttpPort(Node node)
|
||||
throws InterruptedException, ExecutionException {
|
||||
String nodes = node.client().admin().cluster()
|
||||
.nodesInfo(new NodesInfoRequest("*")).get().toString();
|
||||
Gson gson = new GsonBuilder()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
Info info = gson.fromJson(nodes, Info.class);
|
||||
if (info.nodes == null || info.nodes.size() != 1) {
|
||||
throw new RuntimeException(
|
||||
"Cannot extract local Elasticsearch http port");
|
||||
}
|
||||
Iterator<NodeInfo> values = info.nodes.values().iterator();
|
||||
String httpAddress = values.next().httpAddress;
|
||||
if (Strings.isNullOrEmpty(httpAddress)) {
|
||||
throw new RuntimeException(
|
||||
"Cannot extract local Elasticsearch http port");
|
||||
}
|
||||
if (httpAddress.indexOf(':') < 0) {
|
||||
throw new RuntimeException(
|
||||
"Seems that port is not included in Elasticsearch http_address");
|
||||
}
|
||||
return httpAddress.substring(httpAddress.indexOf(':') + 1,
|
||||
httpAddress.length());
|
||||
}
|
||||
|
||||
private ElasticTestUtils() {
|
||||
// hide default constructor
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user