diff --git a/.gitignore b/.gitignore index a1c2a23..d4c93d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,6 @@ # Log file *.log -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - # Package Files # *.jar *.war @@ -21,3 +15,14 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +#Intellij IDEA +.idea/ +*.iml + +#VSCode project files +.vscode +**/.factorypath + +# Maven target directory +target/ diff --git a/README.md b/README.md index 374b6c4..420c0b4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,47 @@ -# elasticsearch-rule +# Elasticsearch Rule A JUnit rule for starting an elasticsearch server on the local machine. + +## Sample Usage + +```java +private static final String ELASTICSEARCH_CLUSTER_NAME = "elasticsearch"; + +@ClassRule +public static final ElasticsearchRule elasticsearchRule = new ElasticsearchRule(ELASTICSEARCH_CLUSTER_NAME); + +private static TransportClient transportClient; + +@BeforeClass +public static void setUpClass() { + transportClient = elasticsearchRule.getTransportClient(); +} + +@Test +public void testClient() { + String indexName = "twitter"; + CreateIndexResponse createIndexResponse = transportClient.admin().indices().prepareCreate(indexName).get(); + Assert.assertTrue(createIndexResponse.isAcknowledged()); +} +``` +It is also possible to get the network address of the Elasticsearch server and construct the TransportClient: +```java +@BeforeClass +public static void setUpClass() { + String address = elasticsearchRule.getAddress(); + String elasticsearchHost = address.split(":")[0]; + int elasticsearchPort = Integer.parseInt(address.split(":")[1]); + InetAddress elasticsearchInetAddress; + try { + elasticsearchInetAddress = InetAddress.getByName(elasticsearchHost); + } catch (UnknownHostException e) { + throw new AssertionError("Cannot get the elasticsearch server address " + elasticsearchHost + ".", e); + } + Settings settings = Settings.builder().put("cluster.name", ELASTICSEARCH_CLUSTER_NAME).build(); + transportClient = new PreBuiltTransportClient(settings); + transportClient.addTransportAddress(new TransportAddress(elasticsearchInetAddress, elasticsearchPort)); +} +``` + +## Add it to your project +You can refer to this library by either of java build systems (Maven, Gradle, SBT or Leiningen) using snippets from this jitpack link: +[![](https://jitpack.io/v/sahabpardaz/elasticsearch-rule.svg)](https://jitpack.io/#sahabpardaz/elasticsearch-rule) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e305be1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + + ir.sahab + elasticsearch-rule + 1.0.0 + + + UTF-8 + 6.2.4 + + + + + junit + junit + 4.12 + + + org.elasticsearch + elasticsearch + ${elasticsearch.version} + + + org.elasticsearch + elasticsearch-cli + ${elasticsearch.version} + + + org.elasticsearch.client + transport + ${elasticsearch.version} + + + org.elasticsearch.plugin + transport-netty4-client + ${elasticsearch.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + compile + true + true + + -Xlint:all + -proc:none + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + verify + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.1.0 + + + + test-jar + + + + + + + \ No newline at end of file diff --git a/src/main/java/ir/sahab/elasticsearchrule/ElasticsearchRule.java b/src/main/java/ir/sahab/elasticsearchrule/ElasticsearchRule.java new file mode 100644 index 0000000..6b93b59 --- /dev/null +++ b/src/main/java/ir/sahab/elasticsearchrule/ElasticsearchRule.java @@ -0,0 +1,94 @@ +package ir.sahab.elasticsearchrule; + +import java.io.IOException; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Random; +import java.util.concurrent.ExecutionException; +import org.elasticsearch.cli.Terminal; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.common.network.NetworkModule; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.env.Environment; +import org.elasticsearch.index.reindex.ReindexPlugin; +import org.elasticsearch.node.InternalSettingsPreparer; +import org.elasticsearch.node.Node; +import org.elasticsearch.node.NodeValidationException; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.transport.Netty4Plugin; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.junit.rules.ExternalResource; + +/** + * A JUnit rule for starting an elasticsearch server on the local machine. + */ +public class ElasticsearchRule extends ExternalResource { + + private TransportClient transportClient; + private TransportAddress transportAddress; + private String clusterName; + private Node server; + + public ElasticsearchRule(String clusterName) { + this.clusterName = clusterName; + } + + @Override + protected void before() throws IOException, NodeValidationException, ExecutionException, InterruptedException { + // Set up a setting for Elasticsearch server node. + Settings.Builder builder = Settings.builder(); + builder.put(NetworkModule.TRANSPORT_TYPE_KEY, Netty4Plugin.NETTY_TRANSPORT_NAME); + builder.put("node.id.seed", 0L); + builder.put("node.name", "node" + new Random().nextInt(10000)); + builder.put(Environment.PATH_DATA_SETTING.getKey(), Files.createTempDirectory("elastic.data")); + builder.put(Environment.PATH_HOME_SETTING.getKey(), Files.createTempDirectory("elastic.home")); + builder.put(ClusterName.CLUSTER_NAME_SETTING.getKey(), clusterName); + builder.put("discovery.type", "single-node"); + Settings settings = builder.build(); + + // Create the Elasticsearch server node and running it. + // Netty4Plugin is necessary for making a TransportClient. + // ReindexPlugin is necessary for making "delete by query" available. + server = new TestNode(settings, Arrays.asList(Netty4Plugin.class, ReindexPlugin.class)); + server.start(); + server.client().admin().cluster().prepareHealth().setWaitForYellowStatus().execute().get(); + + // Create a transport client ready to be used in tests. + transportAddress = server.injector().getInstance(TransportService.class).boundAddress().publishAddress(); + transportClient = new PreBuiltTransportClient(server.settings()); + transportClient.addTransportAddress(transportAddress); + } + + @Override + protected void after() { + transportClient.close(); + try { + server.close(); + } catch (IOException e) { + throw new AssertionError("Cannot close the server."); + } + } + + /** + * A wrapper class for class org.elasticsearch.node.Node to make its constructor public. + */ + public static class TestNode extends Node { + public TestNode(Settings preparedSettings, Collection> classpathPlugins) { + super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, Terminal.DEFAULT, + Collections.emptyMap(), null), classpathPlugins); + } + } + + public TransportClient getTransportClient() { + return transportClient; + } + + public String getAddress() { + return transportAddress.toString(); + } +} \ No newline at end of file diff --git a/src/test/java/ir/sahab/elasticsearchrule/ElasticsearchRuleTest.java b/src/test/java/ir/sahab/elasticsearchrule/ElasticsearchRuleTest.java new file mode 100644 index 0000000..76de34e --- /dev/null +++ b/src/test/java/ir/sahab/elasticsearchrule/ElasticsearchRuleTest.java @@ -0,0 +1,79 @@ +package ir.sahab.elasticsearchrule; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +public class ElasticsearchRuleTest { + + private static final String ELASTICSEARCH_CLUSTER_NAME = "elasticsearch"; + + @ClassRule + public static final ElasticsearchRule elasticsearchRule = new ElasticsearchRule(ELASTICSEARCH_CLUSTER_NAME); + + private static TransportClient transportClient; + + @BeforeClass + public static void setUpClass() { + transportClient = elasticsearchRule.getTransportClient(); + } + + @Test + public void testClient() { + String indexName = "twitter"; + CreateIndexResponse createIndexResponse = transportClient.admin().indices().prepareCreate(indexName).get(); + Assert.assertTrue(createIndexResponse.isAcknowledged()); + transportClient.admin().cluster().prepareHealth().setWaitForYellowStatus().get(); + String json = "{" + + " \"user\":\"kimchy\"," + + " \"postDate\":\"2013-01-30\"," + + " \"message\":\"trying out Elasticsearch\"" + + "}"; + IndexResponse response = transportClient.prepareIndex("twitter", "tweet") + .setSource(json, XContentType.JSON) + .get(); + Assert.assertEquals(RestStatus.CREATED, response.status()); + transportClient.admin().indices().prepareRefresh(indexName).get(); + + SearchResponse searchResponse = transportClient.prepareSearch(indexName) + .setQuery(QueryBuilders.matchQuery("user", "kimchy")) + .get(); + Assert.assertEquals(1, searchResponse.getHits().getHits().length); + String postDate = (String) searchResponse.getHits().getAt(0).getSourceAsMap().get("message"); + Assert.assertEquals("trying out Elasticsearch", postDate); + } + + @Test + public void testAddress() { + String address = elasticsearchRule.getAddress(); + String elasticsearchHost = address.split(":")[0]; + int elasticsearchPort = Integer.parseInt(address.split(":")[1]); + InetAddress elasticsearchInetAddress; + try { + elasticsearchInetAddress = InetAddress.getByName(elasticsearchHost); + } catch (UnknownHostException e) { + throw new AssertionError("Cannot get the elasticsearch server address " + elasticsearchHost + ".", e); + } + Settings settings = Settings.builder().put("cluster.name", ELASTICSEARCH_CLUSTER_NAME).build(); + TransportClient internalTransportClient = new PreBuiltTransportClient(settings); + internalTransportClient.addTransportAddress(new TransportAddress(elasticsearchInetAddress, elasticsearchPort)); + String indexName = "twitter2"; + CreateIndexResponse createIndexResponse = internalTransportClient.admin().indices().prepareCreate(indexName).get(); + Assert.assertTrue(createIndexResponse.isAcknowledged()); + internalTransportClient.close(); + } +} \ No newline at end of file diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml new file mode 100644 index 0000000..9a4f4bb --- /dev/null +++ b/src/test/resources/log4j2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file