405 Errors from Java HighLevel Rest Client

I am relegated to using 1.2.4 since that is the latest version available at the company I work for (AWS OS version stuck at 1.2). I was able to ultimately get AWS OS working by manually constructing my HTTP requests and the corresponding JSON bodies (can provide examples if needed). Unfortunately I am unable to use the Java HLRC methods to make the same requests successfully (create index/mapping, add document, search created document). I cannot use the sample code from the Opensearch docs site copy and pasted almost 1 to 1 (changes only to auth for AWS and Spring Boot beans).

My question is, is there some issue with 1.2 or with AWS OS that specifically prevents this functionality? I am copy pasting the example code, only changing the basic auth credentials provider with the AWS4Signer interceptor as required by my using AWS.

Here is the stack trace I get from using the corresponding code snippet.

Stack trace:

2022-09-14 20:12:51.313 ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is OpenSearchStatusException[OpenSearch exception [type=exception, reason=Incorrect HTTP method for uri [/sample-elasticsearch/custom-index?master_timeout=30s&timeout=30s] and method [PUT], allowed: [POST]]]] with root cause
org.opensearch.OpenSearchStatusException: OpenSearch exception [type=exception, reason=Incorrect HTTP method for uri [/sample-elasticsearch/custom-index?master_timeout=30s&timeout=30s] and method [PUT], allowed: [POST]]
    at org.opensearch.rest.BytesRestResponse.errorFromXContent(BytesRestResponse.java:202) ~[opensearch-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.RestHighLevelClient.parseEntity(RestHighLevelClient.java:2075) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.RestHighLevelClient.parseResponseException(RestHighLevelClient.java:2052) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.RestHighLevelClient.internalPerformRequest(RestHighLevelClient.java:1775) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.RestHighLevelClient.performRequest(RestHighLevelClient.java:1745) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.RestHighLevelClient.performRequestAndParseEntity(RestHighLevelClient.java:1709) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at org.opensearch.client.IndicesClient.create(IndicesClient.java:160) ~[opensearch-rest-high-level-client-1.2.4.jar!/:1.2.4]
    at
............. 

Code snippet used:

CreateIndexRequest createIndexRequest = new CreateIndexRequest("custom-index");

        createIndexRequest.settings(Settings.builder() //Specify in the settings how many shards you want in the index.
                .put("index.number_of_shards", 4)
                .put("index.number_of_replicas", 3)
        );
        //Create a set of maps for the index's mappings.
        HashMap<String, String> typeMapping = new HashMap<String, String>();
        typeMapping.put("type", "integer");
        HashMap<String, Object> ageMapping = new HashMap<String, Object>();
        ageMapping.put("age", typeMapping);
        HashMap<String, Object> mapping = new HashMap<String, Object>();
        mapping.put("properties", ageMapping);
        createIndexRequest.mapping(mapping);
        try {
            CreateIndexResponse createIndexResponse = openSearchClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            log.info("Created index {}", createIndexResponse.index());
        } catch (IOException e) {
            log.error("Issue with create index request for index named \"custom-index\"", e);
        }

and “openSearchClient” is a Spring bean

private final RestHighLevelClient openSearchClient;

from

@Bean
public RestHighLevelClient elasticsearchClient() {
        // https://github.com/acm19/aws-request-signing-apache-interceptor
        HttpRequestInterceptor interceptor = new AwsRequestSigningApacheInterceptor(
                "es",
                Aws4Signer.create(),
                awsClientConfiguration.awsCredentialsProvider(),
                awsClientConfiguration.region()
        );

        RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostname, port, HTTPS_SCHEME))
                .setPathPrefix("sample-elasticsearch")
                .setHttpClientConfigCallback(e -> e.addInterceptorLast(interceptor));

        return new RestHighLevelClient(restClientBuilder);
    }

Any help would be greatly appreciated. I can technically work around this with manual JSON. But after having to abandon spring-data due to the Opensearch fork and compatibility issues, I really would prefer to use a proper Java API and method calls as opposed to making manual JSON in Java.

bump.

Worth noting, I have tried both HLRC and java-rest-client with the same result.

If a opensearch-spring-data client were released, would you be able to use it? Have you looked at the opensearch-java client?

Presuming compatibility with 1.2 OpenSearch then yes, absolutely I could use an openserach-spring-data client. In fact, it would be preferable for little boilerplate code for basic functionality.

I have tried both opensearch-java-client and opensearch-java-high-level-rest-client and both result in the same odd “PUT not allowed, must use POST method” error. Genuinely cannot tell if I have an AWS configuration issue or if the api is bugged for 1.2.4

Final bump. Need to have 20 characters to post though.

Keep an eye out for a spring data client. The planned release date hasn’t been set, but it should be weeks rather than months.

That is fantastic news @wbeckler! Thank you for the update. I will migrate as soon as possible and hope it resolves the issue! :slight_smile: