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
+ 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