opensearch-project / opensearch-java

Java Client for OpenSearch
Apache License 2.0
106 stars 169 forks source link

[BUG] Generic HTTP Actions in Java Client does not work with AwsSdk2Transport #978

Closed reta closed 1 month ago

reta commented 1 month ago

Description

Generic HTTP Actions in Java Client does not work with AwsSdk2Transport

Issues Resolved

Closes https://github.com/opensearch-project/opensearch-java/issues/969

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. For more information on following Developer Certificate of Origin and signing off your commits, please check here.

BrendonFaleiro commented 1 month ago

Hey @reta . I had something similar as well. But I am stuck on the request signing bit. With the standard client requests (SearchRequest and so on), the request parameter of prepareRequestBody is just the body of the request. However with generic requests, the request sent to prepareRequestBody has all the fields and the Body is an Optional.

With this difference, buffer.addContent(request) doesn't just get the body content, but gets what would otherwise be in the endpoint.

And then the request signing gets messed up resulting in:

ResponseCode: 403, ErrorType: security_exception, ErrorReason: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been
'GET
/index-name/_search
cancel_after_time_interval=30s
content-length:
content-type:application/json
host:search-ps-os-poc-rgs2zxfej6ggjpsc6fadtijgca.us-west-2.es.amazonaws.com
x-amz-content-sha256:{some-sha-256}
x-amz-date:20240510T014712Z
x-amz-security-token:{someToken}
content-length;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-security-token
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20240510T014712Z
20240510/us-west-2/es/aws4_request
eec266967bc7058668f377cceb217586b148bbfbd356ddeeb916657f05f3d2fd'

In the case of generic requests, we'd have to pull out the body and pass just the body to buffer.addContent(request).

I am not sure how to get that done in a way that it is de/serialized properly.

I thought I'd let you know in case you hit the same errors.

reta commented 1 month ago

Hey @reta . I had something similar as well. But I am stuck on the request signing bit.

Thanks a lot for heads up @BrendonFaleiro , one of the reasons I keep it as a draft is to verify e2e works (waiting for test AWS account to be provisioned), thanks again!

BrendonFaleiro commented 1 month ago

Oh.. and one more. Before passing the bodyStream to the responseDeserializer, you will have to make a copy of the bodyStream into a new InputStream. The stream is only read from when the user gets the result, but we close the stream in the finally block of executeSync. So when the user tries to access the body, they will get java.io.IOException: Attempted read on closed stream.

In the ApacheHttpClient5Transport and RestTransport, this is achieved by copying the Entity with the stream entity = new BufferedHttpEntity(entity).

reta commented 1 month ago

Oh.. and one more. Before passing the bodyStream to the responseDeserializer, you will have to make a copy of the bodyStream into a new InputStream.

That should fixed already, the stream is read fully now and kept as byte[] (for exactly the same reasons), thanks

dblock commented 1 month ago

Thanks a lot for heads up @BrendonFaleiro , one of the reasons I keep it as a draft is to verify e2e works (waiting for test AWS account to be provisioned), thanks again!

@VachaShah or I can test this quickly if you want, PR using this code into https://github.com/dblock/opensearch-java-client-demo (there are a few branches)

reta commented 1 month ago

@VachaShah or I can test this quickly if you want, PR using this code into https://github.com/dblock/opensearch-java-client-demo (there are a few branches)

That would be great @dblock , I very much stuck on the way to test it e2e due to complexity of crosssacounts, MFA and assumed roles combinations (this is the way I have access to it), not able to overcome HTTP/403 yet.

dblock commented 1 month ago

969

Worked like a charm, built with this change, then used code in https://github.com/dblock/opensearch-java-client-demo/tree/generic-next.

export AWS_...
export ENDPOINT=...
export AWS_REGION=us-west-2
$ mvn compile exec:java   -Dexec.mainClass="Generic"   -Dlog4j.configurationFile=target/log4j2.xml   -Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog   -Dorg.apache.commons.logging.simplelog.log.org.apache.http.wire=INFO
Picked up JAVA_TOOL_OPTIONS: -Dlog4j2.formatMsgNoLookups=true
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------------------< org.openearch:java-client >----------------------
[INFO] Building java-client 1.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- resources:3.3.1:resources (default-resources) @ java-client ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource from src/main/resources to target
[INFO] 
[INFO] --- compiler:3.10.1:compile (default-compile) @ java-client ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- exec:3.1.0:java (default-cli) @ java-client ---
{
  "name" : "fcecc570a4b1e0527475991424f81e8d",
  "cluster_name" : "013306242651:dblock-test-opensearch-27",
  "cluster_uuid" : "CDx1PKXnQnuym3oTrEPglA",
  "version" : {
    "distribution" : "opensearch",
    "number" : "2.7.0",
    "build_type" : "tar",
    "build_hash" : "unknown",
    "build_date" : "2023-06-28T07:07:20.444435752Z",
    "build_snapshot" : false,
    "lucene_version" : "9.5.0",
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

{"_index":"movies","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":0,"_primary_term":1}
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.221 s
[INFO] Finished at: 2024-05-14T08:01:24-04:00
[INFO] ------------------------------------------------------------------------
reta commented 1 month ago

Lint check fails, https://www.javadoc.io/doc/org.opensearch.client/opensearch-java/latest/index.html](https://www.javadoc.io/doc/org.opensearch.client/opensearch-java/latest/index.html is not available at the moment ...