S3 Batch Operations examples using the AWS SDK for Java - Amazon Simple Storage Service

S3 Batch Operations examples using the AWS SDK for Java

This section provides examples of how to create and manage S3 Batch Operations jobs using the AWS SDK for Java. For instructions on creating and testing a working sample, see Testing the Amazon S3 Java Code Examples.

Creating a Batch Operations job

The following example creates an S3 Batch Operations job using the AWS SDK for Java.

For more information about creating a job, see Creating an S3 Batch Operations job.

For information about setting up the permissions that you need to create a job, see Granting permissions for Amazon S3 Batch Operations.

package aws.example.s3control; import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3control.AWSS3Control; import com.amazonaws.services.s3control.AWSS3ControlClient; import com.amazonaws.services.s3control.model.*; import java.util.UUID; import java.util.ArrayList; import static com.amazonaws.regions.Regions.US_WEST_2; public class CreateJob { public static void main(String[] args) { String accountId = "Account ID"; String iamRoleArn = "IAM Role ARN"; String reportBucketName = "arn:aws:s3:::bucket-where-completion-report-goes"; String uuid = UUID.randomUUID().toString(); ArrayList tagSet = new ArrayList<S3Tag>(); tagSet.add(new S3Tag().withKey("keyOne").withValue("ValueOne")); try { JobOperation jobOperation = new JobOperation() .withS3PutObjectTagging(new S3SetObjectTaggingOperation() .withTagSet(tagSet) ); JobManifest manifest = new JobManifest() .withSpec(new JobManifestSpec() .withFormat("S3BatchOperations_CSV_20180820") .withFields(new String[]{ "Bucket", "Key" })) .withLocation(new JobManifestLocation() .withObjectArn("arn:aws:s3:::my_manifests/manifest.csv") .withETag("60e460c9d1046e73f7dde5043ac3ae85")); JobReport jobReport = new JobReport() .withBucket(reportBucketName) .withPrefix("reports") .withFormat("Report_CSV_20180820") .withEnabled(true) .withReportScope("AllTasks"); AWSS3Control s3ControlClient = AWSS3ControlClient.builder() .withCredentials(new ProfileCredentialsProvider()) .withRegion(US_WEST_2) .build(); s3ControlClient.createJob(new CreateJobRequest() .withAccountId(accountId) .withOperation(jobOperation) .withManifest(manifest) .withReport(jobReport) .withPriority(42) .withRoleArn(iamRoleArn) .withClientRequestToken(uuid) .withDescription("job description") .withConfirmationRequired(false) ); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it and returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }

Canceling a Batch Operations job

The following example cancels an S3 Batch Operations job using the AWS SDK for Java.

package aws.example.s3control; import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3control.AWSS3Control; import com.amazonaws.services.s3control.AWSS3ControlClient; import com.amazonaws.services.s3control.model.UpdateJobStatusRequest; import static com.amazonaws.regions.Regions.US_WEST_2; public class CancelJob { public static void main(String[] args) { String accountId = "Account ID"; String jobId = "00e123a4-c0d8-41f4-a0eb-b46f9ba5b07c"; try { AWSS3Control s3ControlClient = AWSS3ControlClient.builder() .withCredentials(new ProfileCredentialsProvider()) .withRegion(US_WEST_2) .build(); s3ControlClient.updateJobStatus(new UpdateJobStatusRequest() .withAccountId(accountId) .withJobId(jobId) .withStatusUpdateReason("No longer needed") .withRequestedJobStatus("Cancelled")); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it and returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }

Updating the status of a Batch Operations job

The following example updates the status of an S3 Batch Operations job using the AWS SDK for Java.

For more information about job status, see Job status.

package aws.example.s3control; import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3control.AWSS3Control; import com.amazonaws.services.s3control.AWSS3ControlClient; import com.amazonaws.services.s3control.model.UpdateJobStatusRequest; import static com.amazonaws.regions.Regions.US_WEST_2; public class UpdateJobStatus { public static void main(String[] args) { String accountId = "Account ID"; String jobId = "00e123a4-c0d8-41f4-a0eb-b46f9ba5b07c"; try { AWSS3Control s3ControlClient = AWSS3ControlClient.builder() .withCredentials(new ProfileCredentialsProvider()) .withRegion(US_WEST_2) .build(); s3ControlClient.updateJobStatus(new UpdateJobStatusRequest() .withAccountId(accountId) .withJobId(jobId) .withRequestedJobStatus("Ready")); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it and returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }

Updating the priority of a Batch Operations job

The following example updates the priority of an S3 Batch Operations job using the AWS SDK for Java.

For more information about job priority, see Assigning job priority.

package aws.example.s3control; import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.s3control.AWSS3Control; import com.amazonaws.services.s3control.AWSS3ControlClient; import com.amazonaws.services.s3control.model.UpdateJobPriorityRequest; import static com.amazonaws.regions.Regions.US_WEST_2; public class UpdateJobPriority { public static void main(String[] args) { String accountId = "Account ID"; String jobId = "00e123a4-c0d8-41f4-a0eb-b46f9ba5b07c"; try { AWSS3Control s3ControlClient = AWSS3ControlClient.builder() .withCredentials(new ProfileCredentialsProvider()) .withRegion(US_WEST_2) .build(); s3ControlClient.updateJobPriority(new UpdateJobPriorityRequest() .withAccountId(accountId) .withJobId(jobId) .withPriority(98)); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it and returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }

Using Batch Operations with tags

You can label and control access to your S3 Batch Operations jobs by adding tags. Tags can be used to identify who is responsible for a Batch Operations job. You can create jobs with tags attached to them, and you can add tags to jobs after they are created. For more information, see Controlling access and labeling jobs using tags.

Create a Batch Operations job with job tags used for labeling

The following example creates an S3 Batch Operations job with tags using the AWS SDK for Java.

public String createJob(final AWSS3ControlClient awss3ControlClient) { final String manifestObjectArn = "arn:aws:s3:::example-manifest-bucket/manifests/10_manifest.csv"; final String manifestObjectVersionId = "example-5dc7a8bfb90808fc5d546218"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec().withFormat(JobManifestFormat.S3InventoryReport_CSV_20161130); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::example-report-bucket"; final String jobReportPrefix = "example-job-reports"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final String lambdaFunctionArn = "arn:aws:lambda:us-west-2:123456789012:function:example-function"; final JobOperation jobOperation = new JobOperation() .withLambdaInvoke(new LambdaInvokeOperation().withFunctionArn(lambdaFunctionArn)); final S3Tag departmentTag = new S3Tag().withKey("department").withValue("Marketing"); final S3Tag fiscalYearTag = new S3Tag().withKey("FiscalYear").withValue("2020"); final String roleArn = "arn:aws:iam::123456789012:role/example-batch-operations-role"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Test lambda job") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withTags(departmentTag, fiscalYearTag) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }

Delete the job tags of a Batch Operations job

The following example deletes the tags of an S3 Batch Operations job using the AWS SDK for Java.

public void deleteJobTagging(final AWSS3ControlClient awss3ControlClient, final String jobId) { final DeleteJobTaggingRequest deleteJobTaggingRequest = new DeleteJobTaggingRequest() .withJobId(jobId); final DeleteJobTaggingResult deleteJobTaggingResult = awss3ControlClient.deleteJobTagging(deleteJobTaggingRequest); }

Get the job tags of a Batch Operations job

The following example gets the tags of an S3 Batch Operations job using the AWS SDK for Java.

public List<S3Tag> getJobTagging(final AWSS3ControlClient awss3ControlClient, final String jobId) { final GetJobTaggingRequest getJobTaggingRequest = new GetJobTaggingRequest() .withJobId(jobId); final GetJobTaggingResult getJobTaggingResult = awss3ControlClient.getJobTagging(getJobTaggingRequest); final List<S3Tag> tags = getJobTaggingResult.getTags(); return tags; }

Put job tags in a Batch Operations job

The following example puts the tags of an S3 Batch Operations job using the AWS SDK for Java.

public void putJobTagging(final AWSS3ControlClient awss3ControlClient, final String jobId) { final S3Tag departmentTag = new S3Tag().withKey("department").withValue("Marketing"); final S3Tag fiscalYearTag = new S3Tag().withKey("FiscalYear").withValue("2020"); final PutJobTaggingRequest putJobTaggingRequest = new PutJobTaggingRequest() .withJobId(jobId) .withTags(departmentTag, fiscalYearTag); final PutJobTaggingResult putJobTaggingResult = awss3ControlClient.putJobTagging(putJobTaggingRequest); }

Using S3 Batch Operations with S3 Object Lock

You can use S3 Batch Operations with S3 Object Lock to manage retention or to enable a legal hold for many Amazon S3 objects at once. You specify the list of target objects in your manifest and submit it to Batch Operations for completion. For more information, see Managing S3 Object Lock retention dates and Managing S3 Object Lock legal hold.

The following examples show how to create an IAM role with S3 Batch Operations permissions, and update the role permissions to create jobs that enable object lock using the AWS SDK for Java. In the code, replace any variable values with those that suit your needs. You must also have a CSV manifest identifying the objects for your S3 Batch Operations job. For more information, see Specifying a manifest.

You perform the following steps:

  1. Create an IAM role and assign S3 Batch Operations permissions to run. This step is required for all S3 Batch Operations jobs.

  2. Set up S3 Batch Operations with S3 Object Lock to run.

    You allow the role to do the following:

    1. Run Object Lock on the S3 bucket that contains the target objects that you want Batch Operations to run on.

    2. Read the S3 bucket where the manifest CSV file and the objects are located.

    3. Write the results of the S3 Batch Operations job to the reporting bucket.

public void createObjectLockRole() { final String roleName = "bops-object-lock"; final String trustPolicy = "{" + " \"Version\": \"2012-10-17\", " + " \"Statement\": [ " + " { " + " \"Effect\": \"Allow\", " + " \"Principal\": { " + " \"Service\": [" + " \"batchoperations.s3.amazonaws.com\"" + " ]" + " }, " + " \"Action\": \"sts:AssumeRole\" " + " } " + " ]" + "}"; final String bopsPermissions = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": \"s3:GetBucketObjectLockConfiguration\"," + " \"Resource\": [" + " \"arn:aws:s3:::ManifestBucket\"" + " ]" + " }," + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:GetObject\"," + " \"s3:GetObjectVersion\"," + " \"s3:GetBucketLocation\"" + " ]," + " \"Resource\": [" + " \"arn:aws:s3:::ManifestBucket/*\"" + " ]" + " }," + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:PutObject\"," + " \"s3:GetBucketLocation\"" + " ]," + " \"Resource\": [" + " \"arn:aws:s3:::ReportBucket/*\"" + " ]" + " }" + " ]" + "}"; final AmazonIdentityManagement iam = AmazonIdentityManagementClientBuilder.defaultClient(); final CreateRoleRequest createRoleRequest = new CreateRoleRequest() .withAssumeRolePolicyDocument(bopsPermissions) .withRoleName(roleName); final CreateRoleResult createRoleResult = iam.createRole(createRoleRequest); final PutRolePolicyRequest putRolePolicyRequest = new PutRolePolicyRequest() .withPolicyDocument(bopsPermissions) .withPolicyName("bops-permissions") .withRoleName(roleName); final PutRolePolicyResult putRolePolicyResult = iam.putRolePolicy(putRolePolicyRequest); }

Use S3 Batch Operations with S3 Object Lock retention

The following example allows the rule to set S3 Object Lock retention for your objects in the manifest bucket.

You update the role to include s3:PutObjectRetention permissions so you can run Object Lock retention on the objects in your bucket.

public void allowPutObjectRetention() { final String roleName = "bops-object-lock"; final String retentionPermissions = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:PutObjectRetention\"" + " ]," + " \"Resource\": [" + " \"arn:aws:s3:::ManifestBucket*\"" + " ]" + " }" + " ]" + "}"; final AmazonIdentityManagement iam = AmazonIdentityManagementClientBuilder.defaultClient(); final PutRolePolicyRequest putRolePolicyRequest = new PutRolePolicyRequest() .withPolicyDocument(retentionPermissions) .withPolicyName("retention-permissions") .withRoleName(roleName); final PutRolePolicyResult putRolePolicyResult = iam.putRolePolicy(putRolePolicyRequest); }

Use S3 Batch Operations with S3 Object Lock retention compliance mode

The following example builds on the previous examples of creating a trust policy, and setting S3 Batch Operations and S3 Object Lock configuration permissions on your objects. This example sets the retention mode to COMPLIANCE and the retain until date to January 1, 2020, and creates a job to target objects in the manifest bucket and report the results in the reports bucket that you identified.

public String createComplianceRetentionJob(final AWSS3ControlClient awss3ControlClient) throws ParseException { final String manifestObjectArn = "arn:aws:s3:::ManifestBucket/complaince-objects-manifest.csv"; final String manifestObjectVersionId = "your-object-version-Id"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec() .withFormat(JobManifestFormat.S3BatchOperations_CSV_20180820) .withFields("Bucket", "Key"); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::ReportBucket"; final String jobReportPrefix = "reports/compliance-objects-bops"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); final Date janFirst = format.parse("01/01/2020"); final JobOperation jobOperation = new JobOperation() .withS3PutObjectRetention(new S3SetObjectRetentionOperation() .withRetention(new S3Retention() .withMode(S3ObjectLockRetentionMode.COMPLIANCE) .withRetainUntilDate(janFirst))); final String roleArn = "arn:aws:iam::123456789012:role/bops-object-lock"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Set compliance retain-until to 1 Jan 2020") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }

The following example extends the COMPLIANCE mode's retain until date to January 15, 2020.

public String createExtendComplianceRetentionJob(final AWSS3ControlClient awss3ControlClient) throws ParseException { final String manifestObjectArn = "arn:aws:s3:::ManifestBucket/complaince-objects-manifest.csv"; final String manifestObjectVersionId = "15ad5ba069e6bbc465c77bf83d541385"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec() .withFormat(JobManifestFormat.S3BatchOperations_CSV_20180820) .withFields("Bucket", "Key"); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::ReportBucket"; final String jobReportPrefix = "reports/compliance-objects-bops"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); final Date jan15th = format.parse("15/01/2020"); final JobOperation jobOperation = new JobOperation() .withS3PutObjectRetention(new S3SetObjectRetentionOperation() .withRetention(new S3Retention() .withMode(S3ObjectLockRetentionMode.COMPLIANCE) .withRetainUntilDate(jan15th))); final String roleArn = "arn:aws:iam::123456789012:role/bops-object-lock"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Extend compliance retention to 15 Jan 2020") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }

Use S3 Batch Operations with S3 Object Lock retention governance mode

The following example builds on the previous example of creating a trust policy, and setting S3 Batch Operations and S3 Object Lock configuration permissions. It shows how to apply S3 Object Lock retention governance with the retain until date set to January 30, 2020 across multiple objects. It creates a Batch Operations job that uses the manifest bucket and reports the results in the reports bucket.

public String createGovernanceRetentionJob(final AWSS3ControlClient awss3ControlClient) throws ParseException { final String manifestObjectArn = "arn:aws:s3:::ManifestBucket/governance-objects-manifest.csv"; final String manifestObjectVersionId = "15ad5ba069e6bbc465c77bf83d541385"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec() .withFormat(JobManifestFormat.S3BatchOperations_CSV_20180820) .withFields("Bucket", "Key"); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::ReportBucket"; final String jobReportPrefix = "reports/governance-objects"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); final Date jan30th = format.parse("30/01/2020"); final JobOperation jobOperation = new JobOperation() .withS3PutObjectRetention(new S3SetObjectRetentionOperation() .withRetention(new S3Retention() .withMode(S3ObjectLockRetentionMode.GOVERNANCE) .withRetainUntilDate(jan30th))); final String roleArn = "arn:aws:iam::123456789012:role/bops-object-lock"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Put governance retention") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }

The following example builds on the previous example of creating a trust policy, and setting S3 Batch Operations and S3 Object Lock configuration permissions. It shows how to bypass retention governance across multiple objects and creates a Batch Operations job that uses the manifest bucket and reports the results in the reports bucket.

public void allowBypassGovernance() { final String roleName = "bops-object-lock"; final String bypassGovernancePermissions = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:BypassGovernanceRetention\"" + " ]," + " \"Resource\": [" + " \"arn:aws:s3:::ManifestBucket/*\"" + " ]" + " }" + " ]" + "}"; final AmazonIdentityManagement iam = AmazonIdentityManagementClientBuilder.defaultClient(); final PutRolePolicyRequest putRolePolicyRequest = new PutRolePolicyRequest() .withPolicyDocument(bypassGovernancePermissions) .withPolicyName("bypass-governance-permissions") .withRoleName(roleName); final PutRolePolicyResult putRolePolicyResult = iam.putRolePolicy(putRolePolicyRequest); } public String createRemoveGovernanceRetentionJob(final AWSS3ControlClient awss3ControlClient) { final String manifestObjectArn = "arn:aws:s3:::ManifestBucket/governance-objects-manifest.csv"; final String manifestObjectVersionId = "15ad5ba069e6bbc465c77bf83d541385"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec() .withFormat(JobManifestFormat.S3BatchOperations_CSV_20180820) .withFields("Bucket", "Key"); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::ReportBucket"; final String jobReportPrefix = "reports/bops-governance"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final JobOperation jobOperation = new JobOperation() .withS3PutObjectRetention(new S3SetObjectRetentionOperation() .withRetention(new S3Retention())); final String roleArn = "arn:aws:iam::123456789012:role/bops-object-lock"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Remove governance retention") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }

Use S3 Batch Operations with S3 Object Lock legal hold

The following example builds on the previous examples of creating a trust policy, and setting S3 Batch Operations and S3 Object Lock configuration permissions. It shows how to disable Object Lock legal hold on objects using Batch Operations.

This example first updates the role allow s3:PutObjectLegalHold permissions and then creates a Batch Operations job that turns off (removes) legal hold from the objects identified in the manifest and reports on it.

public void allowPutObjectLegalHold() { final String roleName = "bops-object-lock"; final String legalHoldPermissions = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:PutObjectLegalHold\"" + " ]," + " \"Resource\": [" + " \"arn:aws:s3:::ManifestBucket/*\"" + " ]" + " }" + " ]" + "}"; final AmazonIdentityManagement iam = AmazonIdentityManagementClientBuilder.defaultClient(); final PutRolePolicyRequest putRolePolicyRequest = new PutRolePolicyRequest() .withPolicyDocument(legalHoldPermissions) .withPolicyName("legal-hold-permissions") .withRoleName(roleName); final PutRolePolicyResult putRolePolicyResult = iam.putRolePolicy(putRolePolicyRequest); }

Use the example below if you want to turn off legal hold.

public String createLegalHoldOffJob(final AWSS3ControlClient awss3ControlClient) { final String manifestObjectArn = "arn:aws:s3:::ManifestBucket/legalhold-object-manifest.csv"; final String manifestObjectVersionId = "15ad5ba069e6bbc465c77bf83d541385"; final JobManifestLocation manifestLocation = new JobManifestLocation() .withObjectArn(manifestObjectArn) .withETag(manifestObjectVersionId); final JobManifestSpec manifestSpec = new JobManifestSpec() .withFormat(JobManifestFormat.S3BatchOperations_CSV_20180820) .withFields("Bucket", "Key"); final JobManifest manifestToPublicApi = new JobManifest() .withLocation(manifestLocation) .withSpec(manifestSpec); final String jobReportBucketArn = "arn:aws:s3:::ReportBucket"; final String jobReportPrefix = "reports/legalhold-objects-bops"; final JobReport jobReport = new JobReport() .withEnabled(true) .withReportScope(JobReportScope.AllTasks) .withBucket(jobReportBucketArn) .withPrefix(jobReportPrefix) .withFormat(JobReportFormat.Report_CSV_20180820); final JobOperation jobOperation = new JobOperation() .withS3PutObjectLegalHold(new S3SetObjectLegalHoldOperation() .withLegalHold(new S3ObjectLockLegalHold() .withStatus(S3ObjectLockLegalHoldStatus.OFF))); final String roleArn = "arn:aws:iam::123456789012:role/bops-object-lock"; final Boolean requiresConfirmation = true; final int priority = 10; final CreateJobRequest request = new CreateJobRequest() .withAccountId("123456789012") .withDescription("Turn off legal hold") .withManifest(manifestToPublicApi) .withOperation(jobOperation) .withPriority(priority) .withRoleArn(roleArn) .withReport(jobReport) .withConfirmationRequired(requiresConfirmation); final CreateJobResult result = awss3ControlClient.createJob(request); return result.getJobId(); }