Java 无法创建具有传递状态属性的SNS平台应用程序

Java 无法创建具有传递状态属性的SNS平台应用程序,java,amazon-web-services,aws-sdk,amazon-sns,Java,Amazon Web Services,Aws Sdk,Amazon Sns,我正在尝试创建SNS平台应用程序,并使用AWS SDK(Java)为其启用交付状态功能。作为第一步,我创建了必要的角色“SNSSuccessFeedback”和“SNSFailureFeedback”。示例代码(Groovy): 但由于某种原因,我得到了一个错误: 无效参数:属性原因:属性值无效:FailureFeedbackRoleArn:arn:aws:iam::1234567890:角色/SNS失败反馈不是允许SNS写入Cloudwatch日志的有效角色(服务:AmazonS;状态代码:4

我正在尝试创建SNS平台应用程序,并使用AWS SDK(Java)为其启用交付状态功能。作为第一步,我创建了必要的角色“SNSSuccessFeedback”和“SNSFailureFeedback”。示例代码(Groovy):

但由于某种原因,我得到了一个错误:

无效参数:属性原因:属性值无效:FailureFeedbackRoleArn:arn:aws:iam::1234567890:角色/SNS失败反馈不是允许SNS写入Cloudwatch日志的有效角色(服务:AmazonS;状态代码:400;错误代码:InvalidParameter;请求ID:c1dbd591-f044-584a-bbac-85fa9a0cbe8d)

如果我只是在角色创建之后和平台应用程序创建之前添加延迟(例如Thread.sleep(5000)),那么平台应用程序将成功创建,不会出现错误


那么,创建角色和启用交付状态的平台应用程序的正确方法是什么呢?

在创建角色时,您将体验到最终的一致性。时间延迟允许角色对下一个API请求“可见”。您可以枚举IAM角色以查看所需的角色是否“可见”,而不是任意的时间延迟。

如果角色不“可见”,该怎么办?最好检查该角色是否在
listRoles()请求中返回。如果未返回角色,请稍等片刻,然后再次检查。这样,您就可以保证在调用
createPlatformApplication()
时该角色可用。由于
listRoles()需要的时间可能比
listRoles()
返回该角色所需的时间多一点
正在通过公开的API直接与IAM对话,而另一个请求正在通过可能存在额外传播延迟的不同(AWS/内部)接口与IAM对话的不同服务对话。可能有用:这个问题是关于用户策略+S3,而不是角色+SNS,但答案应该同样适用+1@Michael-sqlbot这很有趣——我还没有考虑过。感谢您注意到这一点。我在AWS控制台(SNS控制台)中体验到了这一点,当我第二次尝试时,它起了作用。
AmazonIdentityManagementClient aimClient = getAimClient(/*credentials*/)

// create "SNSSuccessFeedback" role:
aimClient.createRole(new CreateRoleRequest().withRoleName("SNSSuccessFeedback")
        .withAssumeRolePolicyDocument('{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"sts:AssumeRole"}]}'))
aimClient.putRolePolicy(new PutRolePolicyRequest().withRoleName("SNSSuccessFeedback")
        .withPolicyName("oneClick_SNSSuccessFeedback_1234567890")
        .withPolicyDocument('{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents","logs:PutMetricFilter","logs:PutRetentionPolicy"],"Resource":["*"]}]}'))
// the same code for "SNSFailureFeedback" role

// get ARN for both "SNSSuccessFeedback" and "SNSFailureFeedback"

// create platform application:
AmazonSNSClient snsClient = getSnsClient(/*credentials*/)
snsClient.createPlatformApplication(new CreatePlatformApplicationRequest()
        .withName("myapp")
        .withPlatform("APNS")
        .withAttributes([PlatformPrincipal: "certificate", PlatformCredential: "key",
                SuccessFeedbackRoleArn: successRoleArn, FailureFeedbackRoleArn: failureRoleArn,
                SuccessFeedbackSampleRate: "100"]))