I need to upload an ndjson dashboard file to the kibana endpoint in Java. The below command is successful with the ndjson files:
curl -X POST api/saved_objects/_import?overwrite=true -H "kbn-xsrf: true" --form file=@file.ndjson
When calling the curl command from Java with the ndjson files it runs successfully, however we would prefer to use Java connections. When attempting to do the same thing with an HttpsURLConnection we receive the 415 error (Unsupported media type) with the same files.
Any ideas why this continues to return 415 error? We are using kibana 8.4.2
I believe the problem is that the /api/saved_objects/_import endpoint expects the request to be of type multipart/form-data.
Please note that this affects the way your NDJSON is appended to the request. The Java API provides the necessary tools for that approach, and there are some examples of usage on the internet. Please let us know if you have any trouble attaching your NDJSON that way.
I modified the code to handle the ndjson files as multipart files (using the HttpPostMultipart class) but the connection is returning 400 errors. The error is being returned from the line:
throw new IOException("Server returned non-OK status: " + status);
I added some logging to the HttpPostMultipart class and found that the Content-Type is set to null:
I am not familiar with the HttpPostMultipart class, is it part of the standard Java API?
When using multipart POST, the Content-Type header should have the multipart/form-data value.
If the library you are using is not setting it for you, then you might have to hardcode it.
I truly appreciate your responses! Any response is better than none
The HttpPostMultipart class is the code from the example you linked to. The first part shows how to write the HttpPostMultipart class.
In the HttpPostMultipart class example the Content-Type header is hardcoded to multipart/form-data, this is the header on the multipart/form-data message:
Each form or message in the multipart message should have a header indicating the contents. The kibana endpoint is returning 400 for messages at this point.
Sorry I just posted the link as an illustrative example, did not pay too much attention to the class names.
Comparing your requests against the ones performed by Kibana UI when using the Import feature, there's a couple differences:
The name of the form field is simply "file" instead of the "updateFile" you are currently using. I believe that should make a difference (considering this validation).
The Content-Transfer-Encoding header is not sent by the UI, so we can get rid of it probably.
@gsoldevila THANK YOU! That was the secret sauce to getting this working. Changing the form field to "file" and getting rid of the Content-Transfer-Encoding header were the missing pieces.
Just to document what worked in Java to upload the ndjson files to Kibana. Our server is https and we used a username and password for authentication.
Use the link referenced in first response then made the following changes
Implementing the HttpPostMultipart in the application:
URL url = new URL("https://" + host + "/api/saved_objects/_import?overwrite=true");
Map<String, String> headers = new HashMap<>();
headers.put(HttpHeaders.AUTHORIZATION, getBasicAuthenticationHeader(user, password));
headers.put("kbn-xsrf", "true");
HttpPostMultipart multipart = new HttpPostMultipart(url.toString(), "utf-8", headers);
// has to be named file to work with Kibana - the file value is a File object
multipart.addFilePart("file", file);
String response = multipart.finish();
Modified the addFilePart method in the HttpPostMultipart class to work for Kibana POST.
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.