Amazon web services 如何与AWS SDK2一起使用AWS请求签名PACHEINTERCEPTOR
我试图在已经使用ApacheHTTP客户端的现有Java代码上使用对Neptune SPARQL的REST调用。我不想混合和匹配AWS SDK1和SDK2(我用于将owl加载到Neptune的S3部分) 我看到这些解决方案:Amazon web services 如何与AWS SDK2一起使用AWS请求签名PACHEINTERCEPTOR,amazon-web-services,rest,sparql,apache-httpclient-4.x,amazon-neptune,Amazon Web Services,Rest,Sparql,Apache Httpclient 4.x,Amazon Neptune,我试图在已经使用ApacheHTTP客户端的现有Java代码上使用对Neptune SPARQL的REST调用。我不想混合和匹配AWS SDK1和SDK2(我用于将owl加载到Neptune的S3部分) 我看到这些解决方案: AWSRequestSigningApacheInterceptor与SDK1一起工作,但在SDK2中找不到等效项 在github上构建适配器类,以便在SDK 2中使用混合匹配SDK 1和2 其中Vicky Thakor变得更加通用,只是为任何Java REST实现实现了
- AWSRequestSigningApacheInterceptor与SDK1一起工作,但在SDK2中找不到等效项
- 在github上构建适配器类,以便在SDK 2中使用混合匹配SDK 1和2
- 其中Vicky Thakor变得更加通用,只是为任何Java REST实现实现了V4签名
有这样的事吗?或者上述解决方案之一是目前可用的最佳解决方案吗?因此,我决定使用第二个选项,但有一个重要的警告:它不处理AWS\u会话\u令牌。这是一个简单的解决方案。我将其与原始答案一起发布在这里有一些最简单的代码,可以向ElasticSearchAPI(不是Neptune SPARQL,而是REST)发出一些不同的经过身份验证的REST请求 pom.xml:
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<!-- version number is not needed due to the BOM below -->
</dependency>
<!-- below is needed for this issue: https://github.com/aws/aws-sdk-java-v2/issues/652 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.11</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>apache-client</artifactId>
<!-- version number is not needed due to the BOM below -->
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bom</artifactId>
<version>2.7.36</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
您的问题是在Github项目中直接提出的:-粗略的回答是,使用适配器类,但您仍然需要依赖SDK 1Thanks。我希望有一个新的答案,但到目前为止,似乎仍然是最新的。
import org.json.JSONObject;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.params.Aws4SignerParams;
import software.amazon.awssdk.http.*;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.utils.StringInputStream;
import java.io.*;
public class ElasticSearch implements Closeable {
private static final String HOST = "my-elasticsearch-3490jvoi2je3o.us-east-2.es.amazonaws.com";
private Aws4SignerParams params = Aws4SignerParams.builder()
.awsCredentials(DefaultCredentialsProvider.create().resolveCredentials())
.signingName("es") // "es" stands for elastic search. Change this to match your service!
.signingRegion(Region.US_EAST_2)
.build();
private Aws4Signer signer = Aws4Signer.create();
SdkHttpClient httpClient = ApacheHttpClient.builder().build();
/** @param path should not have a leading "/" */
private HttpExecuteResponse restRequest(SdkHttpMethod method, String path) throws IOException {
return restRequest(method, path, null);
}
private HttpExecuteResponse restRequest(SdkHttpMethod method, String path, JSONObject body)
throws IOException {
SdkHttpFullRequest.Builder b = SdkHttpFullRequest.builder()
.encodedPath(path)
.host(HOST)
.method(method)
.protocol("https");
if (body != null) {
b.putHeader("Content-Type", "application/json; charset=utf-8");
b.contentStreamProvider(() -> new StringInputStream(body.toString()));
}
SdkHttpFullRequest request = b.build();
// now sign it
SdkHttpFullRequest signedRequest = signer.sign(request, params);
HttpExecuteRequest.Builder rb = HttpExecuteRequest.builder().request(signedRequest);
// !!!: line below is necessary even though the contentStreamProvider is in the request.
// Otherwise the body will be missing from the request and auth signature will fail.
request.contentStreamProvider().ifPresent(c -> rb.contentStreamProvider(c));
return httpClient.prepareRequest(rb.build()).call();
}
public void search(String indexName, String searchString) throws IOException {
HttpExecuteResponse result = restRequest(SdkHttpMethod.GET, indexName+"/_search",
new JSONObject().put("query",
new JSONObject().put("match",
new JSONObject().put("txt",
new JSONObject().put("query", searchString)))));
System.out.println("Search results:");
System.out.println(new JSONObject(result.responseBody()));
}
/** @return success status */
public boolean createIndex(String indexName) throws IOException {
if (indexName.contains("/")) {
throw new RuntimeException("indexName cannot contain '/' character");
}
HttpExecuteResponse r = restRequest(SdkHttpMethod.PUT, indexName);
System.out.println("PUT /"+indexName + " response code: " + r.httpResponse().statusCode());
printInputStream(r.responseBody().get());
return r.httpResponse().isSuccessful();
}
private void printInputStream(InputStream is) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
String readLine;
while (((readLine = br.readLine()) != null)) System.out.println(readLine);
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean postDoc(String indexName, String docId, JSONObject docBody) throws IOException {
HttpExecuteResponse response = restRequest(
SdkHttpMethod.PUT,
String.format("%s/_doc/%s", indexName, docId),
docBody
);
System.out.println("Index operation response:");
printInputStream(response.responseBody().get());
return response.httpResponse().isSuccessful();
}
@Override
public void close() throws IOException {
httpClient.close();
}
}