简体   繁体   English

Amazon Redshift 数据 API REST HTTP 端点返回<unknownoperationexception />来自 Salesforce Apex 标注

[英]Amazon Redshift Data API REST HTTP endpoint returns <UnknownOperationException/> from Salesforce Apex callouts

I work for a consulting firm.我在一家咨询公司工作。 We are trying to authenticate outgoing Apex calls to the Amazon Redshift Data API from the Salesforce platform.我们正在尝试验证从 Salesforce 平台对 Amazon Redshift 数据 API 的传出 Apex 调用。 This will ultimately allow us to execute SQL calls and pull the results back through the Valence app in Salesforce.这最终将允许我们执行 SQL 调用并通过 Salesforce 中的 Valence 应用程序拉回结果。

I am looking for clarification and hopefully a basic example of the request I'm trying to construct, just so we can find a jumping off point.我正在寻求澄清,并希望有一个我正在尝试构建的请求的基本示例,这样我们就可以找到一个起点。

Specifically - we are trying to submit a basic POST request with the DescribeTable action to get some response back, but all we can get is an error in the response body saying "UnknownOperationException" in XML format.具体来说 - 我们正在尝试使用 DescribeTable 操作提交基本的 POST 请求以获取一些响应,但我们所能得到的只是响应正文中的一个错误,以 XML 格式显示“UnknownOperationException”。 We would be happy to get a different error at this point just so we can have some direction.我们很乐意在这一点上得到一个不同的错误,这样我们就可以有一些方向。

It's not clear as to what we need to include -目前尚不清楚我们需要包括什么 -

  • Are "Action" and "Version" supposed to be included in the query string instead of going into the body for a POST request? “Action”和“Version”是否应该包含在查询字符串中而不是进入 POST 请求的主体?
  • Are any additional parameters needed for the query string to properly route the request?查询字符串是否需要任何其他参数才能正确路由请求?
  • Should I be using a GET request even though there's a character limit on URLs that may be an issue?我是否应该使用 GET 请求,即使 URL 的字符数限制可能是个问题?
  • Does the Content-Type header need to be deliberately set and / or included in the canonical request? Content-Type 标头是否需要有意设置和/或包含在规范请求中? Some examples include it and others don't有些例子包括它,有些则没有

The sprawling Amazon docs recommend repeatedly that you either use their CLI tool to access the Redshift data (which isn't applicable here), OR to use their numerous SDKs to code authentication into your app... but because we are using Salesforce Apex, we are not able to take advantage of either of those.庞大的 Amazon 文档反复建议您使用他们的 CLI 工具访问 Redshift 数据(此处不适用),或者使用他们众多的 SDK 将身份验证编码到您的应用程序中……但是因为我们使用的是 Salesforce Apex,我们无法利用其中任何一个。

So, we have 2 options -所以,我们有 2 个选择 -

  1. Use the Named / External Credentials in Salesforce to authenticate for us, using the AWS Signature Version 4 protocol.使用 AWS 签名版本 4 协议,使用 Salesforce 中的命名/外部凭证为我们进行身份验证。 Our company doesn't have experience with this and it's not clear as to how this interacts with additional query (URL), body, or header parameters included in the request.我们公司没有这方面的经验,也不清楚这如何与请求中包含的其他查询 (URL)、正文或标头参数交互。

OR要么

  1. Code the authentication protocol ourselves, which we have done, but we're getting the same issue using both our code and the Named Credential callout, so it's not clear what the connection issue is.我们自己对身份验证协议进行编码,我们已经这样做了,但是我们在使用我们的代码和命名凭证标注时遇到了同样的问题,因此不清楚连接问题是什么。

For the sake of brevity, here are some links to documentation I've reviewed.为简洁起见,这里有一些指向我查看过的文档的链接。 I'm HOPING I missed a small detail somewhere.我希望我在某处遗漏了一个小细节。 Basic request code is at the bottom and is what returns the error for the Redshift callout request -基本请求代码位于底部,它返回 Redshift 标注请求的错误 -

Description of the action and parameters to include in the body - this is from the Redshift Data API docs specifically要包含在正文中的操作和参数的描述 - 这具体来自 Redshift Data API 文档

https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_DescribeTable.html https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_DescribeTable.html

"You can use a GET or POST request to send requests to Amazon Redshift. The difference between the two is that for the GET request your parameters are sent as query string parameters. For the POST request they are included in the body of the request. " - Redshift management guide “您可以使用 GET 或 POST 请求向 Amazon Redshift 发送请求。两者之间的区别在于,对于 GET 请求,您的参数作为查询字符串参数发送。对于 POST 请求,它们包含在请求正文中。 ” - Redshift 管理指南

https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-signing-requests.html https://docs.aws.amazon.com/redshift/latest/mgmt/amazon-redshift-signing-requests.html

Example of the signing process which involves constructing a canonical request.涉及构建规范请求的签名过程示例。 From the AWS general reference.来自 AWS 一般参考。 The named credential / signing would need to carry out this same process命名凭证/签名将需要执行相同的过程

https://docs.aws.amazon.com/general/latest/gr/create-signed-request.html https://docs.aws.amazon.com/general/latest/gr/create-signed-request.html

I've tried following the documentation examples as closely as possible, but I'm not getting an error related to the specifics of the request, so it's hard to understand where the issue is.我已尝试尽可能严格地遵循文档示例,但我没有收到与请求细节相关的错误,因此很难理解问题出在哪里。

I've tried both basic GET and POST requests for the DescribeTable action, to no avail.我已经尝试了 DescribeTable 操作的基本 GET 和 POST 请求,但无济于事。 I've wanted to stick with POST if possible because body JSON is preferred over query parameters IMO.如果可能的话,我想坚持使用 POST,因为主体 JSON 优于查询参数 IMO。

In the common parameters section of the docs, it indicates the Action and Version params are necessary for each call, but the rest depend on the context and only seem necessary for GET requests.在文档的公共参数部分,它表示每次调用都需要 Action 和 Version 参数,但其余参数取决于上下文,并且似乎只对 GET 请求是必需的。

https://docs.aws.amazon.com/redshift-data/latest/APIReference/CommonParameters.html https://docs.aws.amazon.com/redshift-data/latest/APIReference/CommonParameters.html

The list of common errors does not describe UnknownOperationException.常见错误列表没有描述 UnknownOperationException。

https://docs.aws.amazon.com/redshift-data/latest/APIReference/CommonErrors.html https://docs.aws.amazon.com/redshift-data/latest/APIReference/CommonErrors.html

Identifying info is dummied in for this post.这篇文章的识别信息是虚拟的。

global class JPTestClass {
    public static void jpTestMethod(){
        String POSTMAN_CALLOUT = 'callout:Testing_Postman_API';
        // This points to https://redshift-data.us-east-1.amazonaws.com
        String REDSHIFT_CALLOUT = 'callout:Redshift_Data_API';
        
        send(POSTMAN_CALLOUT);
        send(REDSHIFT_CALLOUT);
    }
    
    public static void send(String callout){
        HttpRequest request = new HttpRequest();

        // parameters in the POST request body
        String payloadString = JSON.serialize(new Map<String, Object>{
                    'Action' => 'DescribeTable',
                    'Version' => '2010-05-08',
                    'ClusterIdentifier' => '<<<XXX>>>', 
                    'ConnectedDatabase' => '<<<XXX>>>',
                    'Database' => '<<<XXX>>>',
                    'MaxResults' => 1000,
                    'NextToken' => '',
                    'Schema' => '<<<XXX>>>',
                    'SecretArn' => '<<<XXX>>>',
                    'Table' => 'salesforce_contacts',
                    'WorkgroupName' => ''
                });
        
        System.debug(payloadString);
        
        request.setEndpoint(callout + '?Action=DescribeTable&Version=2010-05-08');
        request.setMethod('POST');
        
        request.setBody(payloadString);
        
        HttpResponse response = new Http().send(request);
        
        System.debug(response.getBody());
    }
}

These are the headers received in the request by Postman.这些是 Postman 在请求中收到的标头。 Authorization header generated by Salesforce. Salesforce 生成的授权标头。

x-forwarded-for: "xxxxxxxxx"
x-forwarded-proto: "xxxxxxxxx"
x-forwarded-port: "xxxxxxxxx"
host: "36b0a2b5-79a5-471e-ac92-06122c76dad2.mock.pstmn.io"
x-amzn-trace-id: "Root=1-639b9d8c-64700ff707de06582eafc6ce"
content-length: "263"
user-agent: "SFDC-Callout/56.0"
sfdc_stack_depth: "1"
accept: "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
authorization: "AWS4-HMAC-SHA256 Credential=<<<ACCESS KEY>>>/20221215/us-east-1/redshift-data/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=0be75a778aa72003cd29140ea52b3db74b6d559078efa382697f8d78b5460b7f"
x-amz-date: "20221215T221956Z"
x-amz-content-sha256: "ec4ae9564eca8bf406807d8ec6305ddbf8435095b269db6f3162b5cfcac4cad8"
accept-encoding: "gzip,deflate"

To anyone curious - the requests succeeded after including these headers, which are NOT included with either 1) Salesforce AWS Signature 4 named credentials, or 2) generated Postman authorization headers.对于任何好奇的人 - 在包含这些标头后请求成功,这些标头不包含在 1) Salesforce AWS Signature 4 命名凭证或 2) 生成的 Postman 授权标头中。

I also could not locate these via the Redshift Data API docs, but they are described in other API docs.我也无法通过 Redshift 数据 API 文档找到它们,但它们在其他 API 文档中有描述。

'X-Amz-Target' => 'RedshiftData.' + action, e.g. 'RedshiftData.DescribeTable'
'X-Requested-With' => 'XMLHttpRequest'
'Content-Type' => 'application/x-amz-json-1.1'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM