Knowledge Management

How to write to kvstore with java sdk?

organus
Explorer

We are trying to inject JSON directly into our KV Store instance while using a defined _key inside the JSON object.

We are not able to connect because of the following error:

2016-09-23 10:25:01 ERROR stderr:71 - com.splunk.HttpException: HTTP 400 -- <?xml version="1.0" encoding="UTF-8"?>
2016-09-23 10:25:01 ERROR stderr:71 - <response>
2016-09-23 10:25:01 ERROR stderr:71 -   <messages>
2016-09-23 10:25:01 ERROR stderr:71 -     <msg type="ERROR">Must supply 'Content-Type' header set to 'application/json'</msg>
2016-09-23 10:25:01 ERROR stderr:71 -   </messages>
2016-09-23 10:25:01 ERROR stderr:71 - </response>

We have looked for a way to add message headers to the RequestMessage object but we do not see a method in the source. Where do we inject message headers?

The method breaks on the following line:

response = service.send(kvStorePath, requestMessage);

Below is our method:

    private void writeToKVStore(File uglyJsonFile) throws IOException {
        String nextJSON = "";
        ResponseMessage response = null;
        BufferedReader br = null;
        ServiceArgs serviceArgs = null;
        Service service = null;
        RequestMessage requestMessage = null;
        int port = params.getKvStorePort();
        String kvStorePath = params.getKvStorePath();
        String kvStoreScheme = params.getKvStoreScheme();
        String kvStoreUsername = params.getkvStoreUsername();
        String kvStorePassword = params.getkvStorePassword();
        String kvStoreHost = params.getKvStoreHost();
        String kvStoreApp = params.getKvStoreApp();

        try {
            HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);

            serviceArgs = new ServiceArgs();
            serviceArgs.setScheme(kvStoreScheme);
            serviceArgs.setUsername(kvStoreUsername);
            serviceArgs.setPassword(kvStorePassword);
            serviceArgs.setHost(kvStoreHost);
            serviceArgs.setPort(port);
            serviceArgs.setApp(kvStoreApp); // kvStoreApp = "kvstore"


            service = Service.connect(serviceArgs);

            // TODO set up requestMessage
            // Must supply 'Content-Type' header set to 'application/json'
            requestMessage = new RequestMessage("POST");

//          service.send(params.getKvStorePath(), requestMessage);

            br = new BufferedReader(new FileReader(uglyJsonFile));

            while ((nextJSON = br.readLine()) != null) {
                requestMessage.setContent(nextJSON);
                response = service.send(kvStorePath, requestMessage);

            }

        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
            ex.printStackTrace();
            if (response != null) {
                String nextLine = "";
                LOGGER.error("Status: " + response.getStatus());
                BufferedReader responseContent = new BufferedReader(new InputStreamReader(response.getContent(), "UTF-8"));
                while((nextLine = responseContent.readLine()) != null) {
                    LOGGER.error(nextLine);
                }
            }
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                LOGGER.error(e.getMessage());
                e.printStackTrace();
                throw e;
            } 
        }

    }
0 Karma
1 Solution

organus
Explorer

We solved this problem by replicating code in the Service class. The Map returned by the RequestMessage.getHeader() method can be modified directly, without using methods in the class:

requestMessage.getHeader().put("Content-Type", "application/json");

The writeToKVStore(File) method now returns without errors. We got it all to work. This should be a fairly pluggable solution. See the working code below:

    private void writeToKVStore(File uglyJsonFile) throws IOException, Exception {
        String nextJSON = "";
        ResponseMessage response = null;
        BufferedReader br = null;
        ServiceArgs serviceArgs = null;
        Service service = null;
        RequestMessage requestMessage = null;
        int port = params.getKvStorePort();
        String kvStorePath = params.getKvStorePath();
        String kvStoreScheme = params.getKvStoreScheme();
        String kvStoreUsername = params.getkvStoreUsername();
        String kvStorePassword = params.getkvStorePassword();
        String kvStoreHost = params.getKvStoreHost();
        String kvStoreApp = params.getKvStoreApp();

        try {
            // Set up service and connect
            // This fixes an issue with conflicting security protocols in v. 1.4
            HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);

            serviceArgs = new ServiceArgs();
            serviceArgs.setScheme(kvStoreScheme);
            serviceArgs.setUsername(kvStoreUsername);
            serviceArgs.setPassword(kvStorePassword);
            serviceArgs.setHost(kvStoreHost);
            serviceArgs.setPort(port);
            serviceArgs.setApp(kvStoreApp); // kvStoreApp = "kvstore"

            service = Service.connect(serviceArgs);

            // Set up RequestMessage
            requestMessage = new RequestMessage("POST");
            requestMessage.getHeader().put("Content-Type", "application/json");

            // Set up stream input from file
            br = new BufferedReader(new FileReader(uglyJsonFile));

            // Loop through file and commit data to KV Store
            while ((nextJSON = br.readLine()) != null) {
                // batch_save requires an array of JSON objects.  We submit a single record at a time so we need to wrap in brackets.
                requestMessage.setContent("[" + nextJSON + "]");
                // kvStorePath = /servicesNS/nobody/kvstore/storage/collections/data/{your_collection_here}/batch_save
                response = service.send(kvStorePath, requestMessage);

            }

        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
            ex.printStackTrace();
            if (response != null) {
                String nextLine = "";
                LOGGER.error("Status: " + response.getStatus());
                BufferedReader responseContent = new BufferedReader(new InputStreamReader(response.getContent(), "UTF-8"));
                while((nextLine = responseContent.readLine()) != null) {
                    LOGGER.error(nextLine);
                }
            }
            throw ex;
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                LOGGER.error(e.getMessage());
                e.printStackTrace();
                throw e;
            } 
        }

    }

View solution in original post

organus
Explorer

We solved this problem by replicating code in the Service class. The Map returned by the RequestMessage.getHeader() method can be modified directly, without using methods in the class:

requestMessage.getHeader().put("Content-Type", "application/json");

The writeToKVStore(File) method now returns without errors. We got it all to work. This should be a fairly pluggable solution. See the working code below:

    private void writeToKVStore(File uglyJsonFile) throws IOException, Exception {
        String nextJSON = "";
        ResponseMessage response = null;
        BufferedReader br = null;
        ServiceArgs serviceArgs = null;
        Service service = null;
        RequestMessage requestMessage = null;
        int port = params.getKvStorePort();
        String kvStorePath = params.getKvStorePath();
        String kvStoreScheme = params.getKvStoreScheme();
        String kvStoreUsername = params.getkvStoreUsername();
        String kvStorePassword = params.getkvStorePassword();
        String kvStoreHost = params.getKvStoreHost();
        String kvStoreApp = params.getKvStoreApp();

        try {
            // Set up service and connect
            // This fixes an issue with conflicting security protocols in v. 1.4
            HttpService.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);

            serviceArgs = new ServiceArgs();
            serviceArgs.setScheme(kvStoreScheme);
            serviceArgs.setUsername(kvStoreUsername);
            serviceArgs.setPassword(kvStorePassword);
            serviceArgs.setHost(kvStoreHost);
            serviceArgs.setPort(port);
            serviceArgs.setApp(kvStoreApp); // kvStoreApp = "kvstore"

            service = Service.connect(serviceArgs);

            // Set up RequestMessage
            requestMessage = new RequestMessage("POST");
            requestMessage.getHeader().put("Content-Type", "application/json");

            // Set up stream input from file
            br = new BufferedReader(new FileReader(uglyJsonFile));

            // Loop through file and commit data to KV Store
            while ((nextJSON = br.readLine()) != null) {
                // batch_save requires an array of JSON objects.  We submit a single record at a time so we need to wrap in brackets.
                requestMessage.setContent("[" + nextJSON + "]");
                // kvStorePath = /servicesNS/nobody/kvstore/storage/collections/data/{your_collection_here}/batch_save
                response = service.send(kvStorePath, requestMessage);

            }

        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        } catch (Exception ex) {
            LOGGER.error(ex.getMessage());
            ex.printStackTrace();
            if (response != null) {
                String nextLine = "";
                LOGGER.error("Status: " + response.getStatus());
                BufferedReader responseContent = new BufferedReader(new InputStreamReader(response.getContent(), "UTF-8"));
                while((nextLine = responseContent.readLine()) != null) {
                    LOGGER.error(nextLine);
                }
            }
            throw ex;
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
            } catch (IOException e) {
                LOGGER.error(e.getMessage());
                e.printStackTrace();
                throw e;
            } 
        }

    }
Got questions? Get answers!

Join the Splunk Community Slack to learn, troubleshoot, and make connections with fellow Splunk practitioners in real time!

Meet up IRL or virtually!

Join Splunk User Groups to connect and learn in-person by region or remotely by topic or industry.

Get Updates on the Splunk Community!

Why Splunk Customers Should Attend Cisco Live 2026 Las Vegas

Why Splunk Customers Should Attend Cisco Live 2026 Las Vegas     Cisco Live 2026 is almost here, and this ...

What Is the Name of the USB Key Inserted by Bob Smith? (BOTS Hint, Not the Answer)

Hello Splunkers,   So you searched, “what is the name of the usb key inserted by bob smith?”  Not gonna lie… ...

Automating Threat Operations and Threat Hunting with Recorded Future

    Automating Threat Operations and Threat Hunting with Recorded Future June 29, 2026 | Register   Is your ...