@SdkInternalApi
    final PutBucketPolicyResult executePutBucketPolicy(PutBucketPolicyRequest putBucketPolicyRequest) {

        ExecutionContext executionContext = createExecutionContext(putBucketPolicyRequest);
        AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics();
        awsRequestMetrics.startEvent(Field.ClientExecuteTime);
        Request<PutBucketPolicyRequest> request = null;
        Response<PutBucketPolicyResult> response = null;

        try {
            awsRequestMetrics.startEvent(Field.RequestMarshallTime);
            try {
                String bucket = putBucketPolicyRequest.getBucket();
                Arn arn = null;
                if (bucket != null && bucket.startsWith("arn:")) {
                    arn = Arn.fromString(bucket);
                    AwsResource awsResource = com.amazonaws.services.s3control.internal.S3ControlArnConverter.getInstance().convertArn(arn);

                    if (!(awsResource instanceof com.amazonaws.services.s3control.internal.S3ControlBucketResource)) {
                        throw new IllegalArgumentException("Unsupported ARN type: " + awsResource.getClass()
                                + ". Expected com.amazonaws.services.s3control.internal.S3ControlBucketResource.");
                    }

                    com.amazonaws.services.s3control.internal.S3ControlBucketResource resource = (com.amazonaws.services.s3control.internal.S3ControlBucketResource) awsResource;

                    putBucketPolicyRequest = putBucketPolicyRequest.clone();
                    putBucketPolicyRequest.setBucket(resource.getBucketName());

                    String accountId = putBucketPolicyRequest.getAccountId();
                    String accountIdInArn = resource.getAccountId();
                    if (accountId != null && !accountId.equals(accountIdInArn)) {
                        throw new IllegalArgumentException(String.format("%s field provided from the request (%s) is different from the one in the ARN (%s)",
                                "accountId", accountId, accountIdInArn));
                    }
                    putBucketPolicyRequest.setAccountId(accountIdInArn);
                }
                request = new PutBucketPolicyRequestMarshaller().marshall(super.beforeMarshalling(putBucketPolicyRequest));
                // Binds the request metrics to the current request.
                request.setAWSRequestMetrics(awsRequestMetrics);
                request.addHandlerContext(HandlerContextKey.CLIENT_ENDPOINT, endpoint);
                request.addHandlerContext(HandlerContextKey.ENDPOINT_OVERRIDDEN, isEndpointOverridden());
                request.addHandlerContext(HandlerContextKey.SIGNING_REGION, getSigningRegion());
                request.addHandlerContext(HandlerContextKey.SERVICE_ID, "S3 Control");
                request.addHandlerContext(HandlerContextKey.OPERATION_NAME, "PutBucketPolicy");
                request.addHandlerContext(HandlerContextKey.ADVANCED_CONFIG, advancedConfig);
                request.addHandlerContext(S3ControlHandlerContextKey.S3_ARNABLE_FIELD, new S3ArnableField().withArn(arn));

            } finally {
                awsRequestMetrics.endEvent(Field.RequestMarshallTime);
            }

            URI endpointTraitHost = null;
            if (!clientConfiguration.isDisableHostPrefixInjection()) {
                ValidationUtils.assertStringNotEmpty(putBucketPolicyRequest.getAccountId(), "AccountId");
                HostnameValidator.validateHostnameCompliant(putBucketPolicyRequest.getAccountId(), "AccountId", "putBucketPolicyRequest");

                String hostPrefix = "{AccountId}.";
                String resolvedHostPrefix = String.format("%s.", putBucketPolicyRequest.getAccountId());

                endpointTraitHost = UriResourcePathUtils.updateUriHost(endpoint, resolvedHostPrefix);
            }

            StaxResponseHandler<PutBucketPolicyResult> responseHandler = new com.amazonaws.services.s3control.internal.S3ControlStaxResponseHandler<PutBucketPolicyResult>(
                    new PutBucketPolicyResultStaxUnmarshaller());

            response = invoke(request, responseHandler, executionContext, null, endpointTraitHost);

            return response.getAwsResponse();

        } finally {

            endClientExecution(awsRequestMetrics, request, response);
        }
    }
<note>
<p>
This action puts a bucket policy to an Amazon S3 on Outposts bucket. To put a policy on an S3 bucket, see <a
href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketPolicy.html">PutBucketPolicy</a> in the
<i>Amazon S3 API Reference</i>.
</p>
</note>
<p>
Applies an Amazon S3 bucket policy to an Outposts bucket. For more information, see <a
href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/S3onOutposts.html">Using Amazon S3 on Outposts</a> in
the <i>Amazon S3 User Guide</i>.
</p>
<p>
If you are using an identity other than the root user of the Amazon Web Services account that owns the Outposts
bucket, the calling identity must have the <code>PutBucketPolicy</code> permissions on the specified Outposts
bucket and belong to the bucket owner's account in order to use this action.
</p>
<p>
If you don't have <code>PutBucketPolicy</code> permissions, Amazon S3 returns a <code>403 Access Denied</code>
error. If you have the correct permissions, but you're not using an identity that belongs to the bucket owner's
account, Amazon S3 returns a <code>405 Method Not Allowed</code> error.
</p>
<important>
<p>
As a security precaution, the root user of the Amazon Web Services account that owns a bucket can always use this
action, even if the policy explicitly denies the root user the ability to perform this action.
</p>
</important>
<p>
For more information about bucket policies, see <a
href="https://docs.aws.amazon.com/AmazonS3/latest/dev/using-iam-policies.html">Using Bucket Policies and User
Policies</a>.
</p>
<p>
All Amazon S3 on Outposts REST API requests for this action require an additional parameter of
<code>x-amz-outpost-id</code> to be passed with the request. In addition, you must use an S3 on Outposts endpoint
hostname prefix instead of <code>s3-control</code>. For an example of the request syntax for Amazon S3 on
Outposts that uses the S3 on Outposts endpoint hostname prefix and the <code>x-amz-outpost-id</code> derived by
using the access point ARN, see the <a href=
"https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_PutBucketPolicy.html#API_control_PutBucketPolicy_Examples"
>Examples</a> section.
</p>
<p>
The following actions are related to <code>PutBucketPolicy</code>:
</p>
<ul>
<li>
<p>
<a href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_GetBucketPolicy.html">GetBucketPolicy</a>
</p>
</li>
<li>
<p>
<a
href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_DeleteBucketPolicy.html">DeleteBucketPolicy</a>
</p>
</li>
</ul>

@param putBucketPolicyRequest
@return Result of the PutBucketPolicy operation returned by the service.
@sample AWSS3Control.PutBucketPolicy
@see <a href="http://docs.aws.amazon.com/goto/WebAPI/s3control-2018-08-20/PutBucketPolicy" target="_top">AWS API
     Documentation</a>
aws-java-sdk-s3control/src/main/java/com/amazonaws/services/s3control/AWSS3ControlClient.java