Create index fails using 'PUT' over Java's HttpURLConnection

I'm using Java and send a 'PUT' request to create a new index over an HttpURLConnection.

The url is: http://localhost:9200/myIndexName

I've used 2 content-types: text/plain and application/json

I consistently get a 400 error. These 'GET' requests work fine:

  1. http://localhost:9200/_cat/indices?v
  2. http://localhost:9200/_count?pretty

Very frustrating :slight_smile:

Do you need help?

May be share your code and we can start from there?

Hi David!! Yes, thank you for asking if I need help. Here is the code (hope it is an acceptable format):

private String send(String httpVerb, String theurl, String contentType) {

URL url = null;
BufferedReader reader = null;
StringBuilder stringBuilder;
String result = "";

try {

// create the HttpURLConnection
url = new URL(theurl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", contentType);
connection.setDoOutput(true);
connection.setRequestMethod("PUT");

// read the output from the server
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
stringBuilder = new StringBuilder();

String line = null;
while ((line = reader.readLine()) != null) {
  stringBuilder.append(line + "\n");
}
result = stringBuilder.toString();

}
catch (Exception e) {
logger.error("**ERROR> " + e.toString());
}
return result;
}

@SuppressWarnings("unchecked")
private JSONObject createIndex(JSONObject jsonReqAsObject) {

String indexname = jsonReqAsObject.get("index").toString();
JSONObject json = new JSONObject();
String url = "http://localhost:9200/" + indexname;
logger.info("URL> " + url);
String result = this.send("PUT", url, "application/json");
json.put("message", result);
return json;
}

Please format your code, logs or configuration files using </> icon as explained in this guide and not the citation button. It will make your post more readable.

Or use markdown style like:

```
CODE
```

This is the icon to use if you are not using markdown format:

There's a live preview panel for exactly this reasons.

Lots of people read these forums, and many of them will simply skip over a post that is difficult to read, because it's just too large an investment of their time to try and follow a wall of badly formatted text.
If your goal is to get an answer to your questions, it's in your interest to make it as easy to read and understand as possible.
Please update your post.

Any reason for not using the low level rest client?

I hope this is better.

private String send(String httpVerb, String theurl, String contentType) {
	
	URL url = null;
	BufferedReader reader = null;
	StringBuilder stringBuilder;
	String result = "";

	try {
		
		// create the HttpURLConnection
		url = new URL(theurl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestProperty("Content-Type", contentType);
		connection.setDoOutput(true);
		connection.setRequestMethod("PUT");

		// read the output from the server
		reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		stringBuilder = new StringBuilder();

		String line = null;
		while ((line = reader.readLine()) != null) {
			stringBuilder.append(line + "\n");
		}
		result = stringBuilder.toString();
		
	}
	catch (Exception e) {
		logger.error("**ERROR> " + e.toString());
	}
	return result;
}

@SuppressWarnings("unchecked")
private JSONObject createIndex(JSONObject jsonReqAsObject) {

	String indexname = jsonReqAsObject.get("index").toString();
	JSONObject json = new JSONObject();
	String url = "http://localhost:9200/" + indexname;
	logger.info("URL> " + url);
	String result = this.send("PUT", url, "application/json");
	json.put("message", result);
	return json;
}



Any reason for not using the low level rest client?

I can't figure it out to be honest.

You can't figure out what?

How to set it up; how to use it in a Tomcat application.

What I'd expect to see would be a .jar file to import in Java.

Did you read the guide ? https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-low.html

David,

I have learned a lot from the documentation as you suggested. I was successful in setting up a Maven environment for Elasticsearch. I tried both the low-level and high-level poms, and successfully created a .jar file to use in my Tomcat application. I can call methods in this jar file to connect to Elastic, but once I get to the RestClient.builder() in either the low or high level client calls, the code simply hangs up.

pom file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
	<modelVersion>4.0.0</modelVersion>
	<artifactId>N2NElasticsearch</artifactId>
	<groupId>com.nodonomy.elasticsearch</groupId>
	<version>1.0.0</version>
	<build>
	    <plugins>
	        <plugin>
	            <groupId>org.apache.maven.plugins</groupId>
	            <artifactId>maven-compiler-plugin</artifactId>
	            <version>3.5.1</version>
	            <configuration>
	                <source>1.8</source>
	                <target>1.8</target>
	            </configuration>
	        </plugin>
	    </plugins>
	</build>
	<dependencies>
	<dependency>
	    <groupId>org.elasticsearch.client</groupId>
	    <artifactId>elasticsearch-rest-high-level-client</artifactId>
	    <version>7.1.0</version>
	</dependency>
	<dependency>
	    <groupId>org.eclipse.ecf</groupId>
	    <artifactId>org.apache.log4j</artifactId>
	    <version>1.2.15.v201012070815</version>
	</dependency>
	<dependency>
	    <groupId>org.apache.clerezza.ext</groupId>
	    <artifactId>org.json.simple</artifactId>
	    <version>0.4</version>
	</dependency>
	</dependencies>
</project>

And my Java class:

package com.mycompany.elasticsearch;

import org.apache.log4j.Logger;
import org.apache.http.HttpHost;
import org.elasticsearch.client.*;
import org.json.simple.JSONObject;

public class N2NESElastic {
	
	private Logger logger = null;
	
	public N2NESElastic() {
		logger = Logger.getLogger(com.mycompany.elasticsearch.N2NESElastic.class);
		logger.info("[SERVER] N2NESElastic(). Inside the constructor...");
	}
	
	private static final String HOST = "localhost"; //"127.0.0.1";
	private static final int PORT_ONE = 9200;
	private static final int PORT_TWO = 9201;
	private static final String SCHEME = "http";
	private RestClient restClient = null;
	private RestHighLevelClient client = null;

	@SuppressWarnings("unchecked")
	public synchronized JSONObject processRequest(JSONObject jsonReqAsObject, String command) {
		logger.info("[N2NESElastic] Command: " + command);
		JSONObject json = null;
		String message = "command: " + command;
		
		// - - - - - - - - - - - - - - - - - - - -
		// O P E N
		// - - - - - - - - - - - - - - - - - - - -
		logger.info("Calling makeConnection()...");
		this.makeConnection();
		logger.info("Connection established...");
		
		// - - - - - - - - - - - - - - - - - - - -
		// C L O S E
		// - - - - - - - - - - - - - - - - - - - -
		try {
			logger.info("Calling closeConnection()...");
			this.closeConnection();
			logger.info("Connection closed...");
		}
		catch (Exception e) {
			logger.error("**xERROR> " + e.toString());
		}
		
		json.put("message", message);
		
		return json;
	}
	
	private synchronized void makeConnection() {
		logger.info("Making connection...");
		
		logger.info("Creating hostPort1...");
		HttpHost hostPort1 = new HttpHost("localhost", 9200, "http");
		
		logger.info("Creating hostPort2...");
		HttpHost hostPort2 = new HttpHost("localhost", 9201, "http");
		
		//logger.info("Calling restClient builder...");
		//RestClient.builder(hostPort1, hostPort2).build();  // LOW LEVEL: HANGS
		
		logger.info("Calling high-level-rest builder...");  // HIGH LEVEL: ALSO HANGS
		client = new RestHighLevelClient(
				RestClient.builder(
				new HttpHost("localhost", 9200, "http"),
				new HttpHost("localhost", 9201, "http")));
		
		logger.info("Done building...");  // NEVER GET TO THIS LINE
	}

	private synchronized void closeConnection() {
		try {
			logger.info("Closing connection...");
			restClient.close();
		}
		catch (Exception e) {
			logger.error("**ERROR> " + e.toString());
		}
	}
	
}

Any help you can offer will be appreciated.

In my Eclipse project I have the following external .jar files from Elastic:
elasticsearch-7.1.0.jar
elasticsearch-core-7.1.0.jar
elasticsearch-rest-client-7.1.0.jar
elasticsearch-rest-high-level-client-7.1.0.jar

  • David

Where? Could you share your logs so we can see where it is hanging?

BTW, you should try may be to run a client.info(...) call after it gets created?

May be my "demo" repo could help?

David, I comment in the code I sent where it hangs.

Method: makeConnection()

David, In your example, you show what classes to import: thank you.

Last request: where to find and download the .jar files in which these classes are found.

I'm using maven so I don't have to worry. But everything is on maven central otherwise.

David,

I never used Maven before, but now I've learned, and I have a new java project in Eclipse that I converted to a Maven project. All dependencies in pom.xml are taken care of just as they should be. My java classes look great.

After all that, however, the code still hangs at the exact same point as before.

Here is what I do:

  1. I create a .jar file from my elasticsearch Maven project. I then add this .jar file to my Tomcat application.

  2. My Tomcat application then instantiates the my elasticsearch class, an I call RestClient and RestClient builder, just as in the documentation:

		restClient = RestClient.builder(
				new HttpHost(HOST, PORT_ONE, SCHEME),
				new HttpHost(HOST, PORT_TWO, SCHEME)).build();

I know that the HttpHost calls happen correctly, but the call to RestClient.builder() hangs.

MY QUESTION: do you think this is some timing (synchronous / asynchronous) issue between Tomcat (port 8080) and elastic search?

Really, I need your HELP!! Everything is in place, all the dependencies are good, the code looks like it will work, but it hangs, just like before.

No. I don't think so.

Could you create a main() method and just run it from Eclipse?
We would see how it works.

Next step is may be to share your project on Github so we can look.
But may be just run the example I shared first.

Hmm. RestClient.builder() running from main() does not hang.

I'm putting my thinking hat on, but I would also like to know what your thoughts are. My first thought is that I'm missing elasticsearch dependencies in my Tomcat application, and I'll be checking on this today.

Or you have a conflicting dependency coming from tomcat....

I have a Maven Java project calling the Elastic server on 9200 that works by itself when running in Eclipse.

If, however, I try to use this code in my Tomcat application, it hangs exactly as described earlier. I've unsuccessfully tried both of the following:

  1. Create a .jar file from the Maven project and use that in my Tomcat app
  2. Add the working code to my Tomcat app (including referencing all the .jar files that Elastic used in the Maven project).

QUESTION: is there example Tomcat application that uses Elastic, a "Hello World" type of application to use as a start?