package org.vertexium.elasticsearch; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; import org.apache.commons.io.FileUtils; import org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.junit.rules.ExternalResource; import org.vertexium.Graph; import org.vertexium.GraphConfiguration; import org.vertexium.GraphWithSearchIndex; import org.vertexium.VertexiumException; import org.vertexium.util.VertexiumLogger; import org.vertexium.util.VertexiumLoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.UUID; import static org.codelibs.elasticsearch.runner.ElasticsearchClusterRunner.newConfigs; import static org.vertexium.GraphConfiguration.AUTO_FLUSH; import static org.vertexium.GraphConfiguration.SEARCH_INDEX_PROP_PREFIX; import static org.vertexium.elasticsearch.DefaultIndexSelectionStrategy.CONFIG_EXTENDED_DATA_INDEX_NAME_PREFIX; import static org.vertexium.elasticsearch.DefaultIndexSelectionStrategy.CONFIG_INDEX_NAME; import static org.vertexium.elasticsearch.ElasticSearchSearchIndexConfiguration.*; public class ElasticsearchResource extends ExternalResource { private static final VertexiumLogger LOGGER = VertexiumLoggerFactory.getLogger(ElasticsearchResource.class); private static final String ES_INDEX_NAME = "vertexium-test"; private static final String ES_CLUSTER_NAME = "vertexium-test-cluster"; private static final String ES_EXTENDED_DATA_INDEX_NAME_PREFIX = "vertexium-test-"; private static final String PLUGIN_CLASS_PATH = "/vertexium-elasticsearch-singledocument-plugin.zip"; private ElasticsearchClusterRunner runner; private Map extraConfig = null; public ElasticsearchResource() { } public ElasticsearchResource(Map extraConfig) { this.extraConfig = extraConfig; } @Override protected void before() throws Throwable { File tempDir = new File(System.getProperty("java.io.tmpdir")); File basePath = new File(tempDir, "vertexium-test-" + UUID.randomUUID().toString()); installPlugin(basePath); runner = new ElasticsearchClusterRunner(); runner.onBuild((i, builder) -> builder.put("script.disable_dynamic", "false") .put("gateway.type", "local") .put("index.number_of_shards", "1") .put("cluster.name", ES_CLUSTER_NAME) .put("index.number_of_replicas", "0") ).build(newConfigs().basePath(basePath.getAbsolutePath()).ramIndexStore().numOfNode(1)); runner.ensureGreen(); super.before(); } @Override protected void after() { if (runner != null) { runner.close(); runner.clean(); } super.after(); } public void dropIndices() throws Exception { String[] indices = runner.admin().indices().prepareGetIndex().execute().get().indices(); for (String index : indices) { if (index.equals(ES_INDEX_NAME) || index.startsWith(ES_EXTENDED_DATA_INDEX_NAME_PREFIX)) { LOGGER.info("deleting test index: %s", index); runner.admin().indices().prepareDelete(index).execute().actionGet(); } } } @SuppressWarnings("unchecked") public Map createConfig() { Map configMap = new HashMap(); configMap.put(AUTO_FLUSH, true); configMap.put(SEARCH_INDEX_PROP_PREFIX, ElasticsearchSingleDocumentSearchIndex.class.getName()); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + CONFIG_INDEX_NAME, ES_INDEX_NAME); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + CONFIG_EXTENDED_DATA_INDEX_NAME_PREFIX, ES_EXTENDED_DATA_INDEX_NAME_PREFIX); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + STORE_SOURCE_DATA, "true"); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + CLUSTER_NAME, ES_CLUSTER_NAME); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + ES_LOCATIONS, getLocation()); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + NUMBER_OF_SHARDS, 1); configMap.put(SEARCH_INDEX_PROP_PREFIX + "." + NUMBER_OF_REPLICAS, 0); if (extraConfig != null) { configMap.putAll(extraConfig); } return configMap; } private String getLocation() { ClusterStateResponse responsee = runner.node().client().admin().cluster().prepareState().execute().actionGet(); InetSocketTransportAddress address = (InetSocketTransportAddress) responsee.getState().getNodes().getNodes().values().iterator().next().value.getAddress(); return "localhost:" + address.address().getPort(); } private void installPlugin(File basePath) throws IOException, ZipException { File pluginsPath = new File(basePath, "plugins"); File vertexiumZipFile = new File(basePath, "vertexium.zip"); File vertexiumPluginPath = new File(pluginsPath, "vertexium-elasticsearch"); if (!vertexiumPluginPath.mkdirs()) { System.out.println("Could not create directories"); } InputStream in = ElasticsearchSingleDocumentSearchIndexTestBase.class.getResourceAsStream(PLUGIN_CLASS_PATH); if (in == null) { throw new VertexiumException("Could not find: " + PLUGIN_CLASS_PATH); } FileUtils.copyInputStreamToFile(in, vertexiumZipFile); ZipFile zipFile = new ZipFile(vertexiumZipFile); zipFile.extractAll(vertexiumPluginPath.getAbsolutePath()); } public boolean disableEdgeIndexing(Graph graph) { ElasticsearchSingleDocumentSearchIndex searchIndex = (ElasticsearchSingleDocumentSearchIndex) ((GraphWithSearchIndex) graph).getSearchIndex(); searchIndex.getConfig().getGraphConfiguration().set(GraphConfiguration.SEARCH_INDEX_PROP_PREFIX + "." + ElasticSearchSearchIndexConfiguration.INDEX_EDGES, "false"); return true; } }