如何将 AWSRequestSigningApacheInterceptor 与 AWS SDK2 结合使用 [英] How to use AWSRequestSigningApacheInterceptor with AWS SDK2

查看:32
本文介绍了如何将 AWSRequestSigningApacheInterceptor 与 AWS SDK2 结合使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在已经使用 Apache HTTP 客户端的现有 Java 代码上使用对 Neptune SPARQL 的 REST 调用.我不想混合搭配 AWS SDK1 和 SDK2(我用于将 owl 加载到 Neptune 的 S3 部分).

I am trying to use REST calls to Neptune SPARQL on existing Java code which already uses Apache HTTP clients. I'd like to not mix and match AWS SDK1 and SDK2 (which I use for the S3 portion of loading owl to Neptune).

我看到了这些解决方案:

I see these solutions:

  • AWSRequestSigningApacheInterceptor 适用于 SDK1,但在 SDK2 中找不到等效项.

  • AWSRequestSigningApacheInterceptor that works with SDK1, but can't find the equivalent in SDK2.

aws-request-signing-apache-github 上的拦截器 用于构建适配器类,以便它可以在 SDK 2 中与混合匹配 SDK 1 & 一起使用.2

aws-request-signing-apache-interceptor on github for building an adaptor class so it can be used in SDK 2 with mix-and-match SDK 1 & 2

javaquery/Examples 其中 Vicky Thakor 变得更加通用并且刚刚实现了 V4签署任何 Java REST 实现

javaquery/Examples where Vicky Thakor has gone even more generic and just implemented the V4 signing for any Java REST implementation

但这些都不是我所期望的:AWS SDK 2 的 Apache 拦截器的 AWS 或 Apache 实现.

But none of these is what I expected: an AWS or Apache implmentation of an Apache Interceptor for AWS SDK 2.

有这种事吗?或者上述解决方案之一是目前最好的解决方案吗?

Is there such a thing? or is one of the above solutions the best available at the moment?

推荐答案

这里有一些最少的代码,用于向 ElasticSearch API(不是 Neptune SPARQL,但都是 REST)发出一些不同的经过身份验证的 REST 请求.

Here is some minimal code to make a few different authenticated REST requests to the ElasticSearch API (not Neptune SPARQL, but it's all 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>

这是Java:

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();
    }
}

这篇关于如何将 AWSRequestSigningApacheInterceptor 与 AWS SDK2 结合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆