

The AWS SDK for Java 1.x reached end-of-support on December 31, 2025. We recommend that you migrate to the [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) to continue receiving new features, availability improvements, and security updates.

# AWS SDK for Java Code Examples
<a name="prog-services"></a>

This section provides tutorials and examples of using the AWS SDK for Java v1 to program AWS services.

Find the source code for these examples and others in the AWS documentation [code examples repository on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples).

To propose a new code example for the AWS documentation team to consider producing, create a new request. The team is looking to produce code examples that cover broader scenarios and use cases, versus simple code snippets that cover only individual API calls. For instructions, see the [Contributing guidelines](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/CONTRIBUTING.md) in the code examples respository on GitHub..

## AWS SDK for Java 2.x
<a name="aws-sdk-for-java-2-x"></a>

In 2018, AWS released the [AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html). This guide contains instructions on using the latest Java SDK along with example code.

**Note**  
See [Additional Documentation and Resources](welcome.md#additional-resources) for more examples and additional resources available for AWS SDK for Java developers\$1

**Topics**

# CloudWatch Examples Using the AWS SDK for Java
<a name="examples-cloudwatch"></a>

This section provides examples of programming [CloudWatch](https://aws.amazon.com/cloudwatch/) using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

Amazon CloudWatch monitors your Amazon Web Services (AWS) resources and the applications you run on AWS in real time. You can use CloudWatch to collect and track metrics, which are variables you can measure for your resources and applications. CloudWatch alarms send notifications or automatically make changes to the resources you are monitoring based on rules that you define.

For more information about CloudWatch, see the [Amazon CloudWatch User Guide](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Getting Metrics from CloudWatch](examples-cloudwatch-get-metrics.md)
+ [Publishing Custom Metric Data](examples-cloudwatch-publish-custom-metrics.md)
+ [Working with CloudWatch Alarms](examples-cloudwatch-create-alarms.md)
+ [Using Alarm Actions in CloudWatch](examples-cloudwatch-use-alarm-actions.md)
+ [Sending Events to CloudWatch](examples-cloudwatch-send-events.md)

# Getting Metrics from CloudWatch
<a name="examples-cloudwatch-get-metrics"></a>

## Listing Metrics
<a name="listing-metrics"></a>

To list CloudWatch metrics, create a [ListMetricsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/ListMetricsRequest.html) and call the AmazonCloudWatchClient’s `listMetrics` method. You can use the `ListMetricsRequest` to filter the returned metrics by namespace, metric name, or dimensions.

**Note**  
A list of metrics and dimensions that are posted by AWS services can be found within the \$1https---docs-aws-amazon-com-AmazonCloudWatch-latest-monitoring-CW-Support-For-AWS-html\$1[Amazon CloudWatch Metrics and Dimensions Reference] in the Amazon CloudWatch User Guide.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.ListMetricsRequest;
import com.amazonaws.services.cloudwatch.model.ListMetricsResult;
import com.amazonaws.services.cloudwatch.model.Metric;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

ListMetricsRequest request = new ListMetricsRequest()
        .withMetricName(name)
        .withNamespace(namespace);

boolean done = false;

while(!done) {
    ListMetricsResult response = cw.listMetrics(request);

    for(Metric metric : response.getMetrics()) {
        System.out.printf(
            "Retrieved metric %s", metric.getMetricName());
    }

    request.setNextToken(response.getNextToken());

    if(response.getNextToken() == null) {
        done = true;
    }
}
```

The metrics are returned in a [ListMetricsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/ListMetricsResult.html) by calling its `getMetrics` method. The results may be *paged*. To retrieve the next batch of results, call `setNextToken` on the original request object with the return value of the `ListMetricsResult` object’s `getNextToken` method, and pass the modified request object back to another call to `listMetrics`.

## More Information
<a name="more-information"></a>
+  [ListMetrics](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html) in the Amazon CloudWatch API Reference.

# Publishing Custom Metric Data
<a name="examples-cloudwatch-publish-custom-metrics"></a>

A number of AWS services publish [their own metrics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/aws-namespaces.html) in namespaces beginning with " `AWS` " You can also publish custom metric data using your own namespace (as long as it doesn’t begin with " `AWS` ").

## Publish Custom Metric Data
<a name="publish-custom-metric-data"></a>

To publish your own metric data, call the AmazonCloudWatchClient’s `putMetricData` method with a [PutMetricDataRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/PutMetricDataRequest.html). The `PutMetricDataRequest` must include the custom namespace to use for the data, and information about the data point itself in a [MetricDatum](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/MetricDatum.html) object.

**Note**  
You cannot specify a namespace that begins with " `AWS` ". Namespaces that begin with " `AWS` " are reserved for use by Amazon Web Services products.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.MetricDatum;
import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest;
import com.amazonaws.services.cloudwatch.model.PutMetricDataResult;
import com.amazonaws.services.cloudwatch.model.StandardUnit;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

Dimension dimension = new Dimension()
    .withName("UNIQUE_PAGES")
    .withValue("URLS");

MetricDatum datum = new MetricDatum()
    .withMetricName("PAGES_VISITED")
    .withUnit(StandardUnit.None)
    .withValue(data_point)
    .withDimensions(dimension);

PutMetricDataRequest request = new PutMetricDataRequest()
    .withNamespace("SITE/TRAFFIC")
    .withMetricData(datum);

PutMetricDataResult response = cw.putMetricData(request);
```

## More Information
<a name="more-information"></a>
+  [Using Amazon CloudWatch Metrics](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/working_with_metrics.html) in the Amazon CloudWatch User Guide.
+  [AWS Namespaces](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/aws-namespaces.html) in the Amazon CloudWatch User Guide.
+  [PutMetricData](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricData.html) in the Amazon CloudWatch API Reference.

# Working with CloudWatch Alarms
<a name="examples-cloudwatch-create-alarms"></a>

## Create an Alarm
<a name="create-an-alarm"></a>

To create an alarm based on a CloudWatch metric, call the AmazonCloudWatchClient’s `putMetricAlarm` method with a [PutMetricAlarmRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/PutMetricAlarmRequest.html) filled with the alarm conditions.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.ComparisonOperator;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmResult;
import com.amazonaws.services.cloudwatch.model.StandardUnit;
import com.amazonaws.services.cloudwatch.model.Statistic;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

Dimension dimension = new Dimension()
    .withName("InstanceId")
    .withValue(instanceId);

PutMetricAlarmRequest request = new PutMetricAlarmRequest()
    .withAlarmName(alarmName)
    .withComparisonOperator(
        ComparisonOperator.GreaterThanThreshold)
    .withEvaluationPeriods(1)
    .withMetricName("CPUUtilization")
    .withNamespace("{AWS}/EC2")
    .withPeriod(60)
    .withStatistic(Statistic.Average)
    .withThreshold(70.0)
    .withActionsEnabled(false)
    .withAlarmDescription(
        "Alarm when server CPU utilization exceeds 70%")
    .withUnit(StandardUnit.Seconds)
    .withDimensions(dimension);

PutMetricAlarmResult response = cw.putMetricAlarm(request);
```

## List Alarms
<a name="list-alarms"></a>

To list the CloudWatch alarms that you have created, call the AmazonCloudWatchClient’s `describeAlarms` method with a [DescribeAlarmsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/DescribeAlarmsRequest.html) that you can use to set options for the result.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.DescribeAlarmsResult;
import com.amazonaws.services.cloudwatch.model.MetricAlarm;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

boolean done = false;
DescribeAlarmsRequest request = new DescribeAlarmsRequest();

while(!done) {

    DescribeAlarmsResult response = cw.describeAlarms(request);

    for(MetricAlarm alarm : response.getMetricAlarms()) {
        System.out.printf("Retrieved alarm %s", alarm.getAlarmName());
    }

    request.setNextToken(response.getNextToken());

    if(response.getNextToken() == null) {
        done = true;
    }
}
```

The list of alarms can be obtained by calling `getMetricAlarms` on the [DescribeAlarmsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/DescribeAlarmsResult.html) that is returned by `describeAlarms`.

The results may be *paged*. To retrieve the next batch of results, call `setNextToken` on the original request object with the return value of the `DescribeAlarmsResult` object’s `getNextToken` method, and pass the modified request object back to another call to `describeAlarms`.

**Note**  
You can also retrieve alarms for a specific metric by using the AmazonCloudWatchClient’s `describeAlarmsForMetric` method. Its use is similar to `describeAlarms`.

## Delete Alarms
<a name="delete-alarms"></a>

To delete CloudWatch alarms, call the AmazonCloudWatchClient’s `deleteAlarms` method with a [DeleteAlarmsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/DeleteAlarmsRequest.html) containing one or more names of alarms that you want to delete.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsResult;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

DeleteAlarmsRequest request = new DeleteAlarmsRequest()
    .withAlarmNames(alarm_name);

DeleteAlarmsResult response = cw.deleteAlarms(request);
```

## More Information
<a name="more-information"></a>
+  [Creating Amazon CloudWatch Alarms](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) in the Amazon CloudWatch User Guide
+  [PutMetricAlarm](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricAlarm.html) in the Amazon CloudWatch API Reference
+  [DescribeAlarms](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DescribeAlarms.html) in the Amazon CloudWatch API Reference
+  [DeleteAlarms](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DeleteAlarms.html) in the Amazon CloudWatch API Reference

# Using Alarm Actions in CloudWatch
<a name="examples-cloudwatch-use-alarm-actions"></a>

Using CloudWatch alarm actions, you can create alarms that perform actions such as automatically stopping, terminating, rebooting, or recovering Amazon EC2 instances.

**Note**  
Alarm actions can be added to an alarm by using the [PutMetricAlarmRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/PutMetricAlarmRequest.html)'s `setAlarmActions` method when [creating an alarm](examples-cloudwatch-create-alarms.md).

## Enable Alarm Actions
<a name="enable-alarm-actions"></a>

To enable alarm actions for a CloudWatch alarm, call the AmazonCloudWatchClient’s `enableAlarmActions` with a [EnableAlarmActionsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/EnableAlarmActionsRequest.html) containing one or more names of alarms whose actions you want to enable.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.EnableAlarmActionsRequest;
import com.amazonaws.services.cloudwatch.model.EnableAlarmActionsResult;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

EnableAlarmActionsRequest request = new EnableAlarmActionsRequest()
    .withAlarmNames(alarm);

EnableAlarmActionsResult response = cw.enableAlarmActions(request);
```

## Disable Alarm Actions
<a name="disable-alarm-actions"></a>

To disable alarm actions for a CloudWatch alarm, call the AmazonCloudWatchClient’s `disableAlarmActions` with a [DisableAlarmActionsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatch/model/DisableAlarmActionsRequest.html) containing one or more names of alarms whose actions you want to disable.

 **Imports** 

```
import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.DisableAlarmActionsRequest;
import com.amazonaws.services.cloudwatch.model.DisableAlarmActionsResult;
```

 **Code** 

```
final AmazonCloudWatch cw =
    AmazonCloudWatchClientBuilder.defaultClient();

DisableAlarmActionsRequest request = new DisableAlarmActionsRequest()
    .withAlarmNames(alarmName);

DisableAlarmActionsResult response = cw.disableAlarmActions(request);
```

## More Information
<a name="more-information"></a>
+  [Create Alarms to Stop, Terminate, Reboot, or Recover an Instance](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/UsingAlarmActions.html) in the Amazon CloudWatch User Guide
+  [PutMetricAlarm](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_PutMetricAlarm.html) in the Amazon CloudWatch API Reference
+  [EnableAlarmActions](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_EnableAlarmActions.html) in the Amazon CloudWatch API Reference
+  [DisableAlarmActions](http://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_DisableAlarmActions.html) in the Amazon CloudWatch API Reference

# Sending Events to CloudWatch
<a name="examples-cloudwatch-send-events"></a>

 CloudWatch Events delivers a near real-time stream of system events that describe changes in AWS resources to Amazon EC2 instances, Lambda functions, Kinesis streams, Amazon ECS tasks, Step Functions state machines, Amazon SNS topics, Amazon SQS queues, or built-in targets. You can match events and route them to one or more target functions or streams by using simple rules.

## Add Events
<a name="add-events"></a>

To add custom CloudWatch events, call the AmazonCloudWatchEventsClient’s `putEvents` method with a [PutEventsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatchevents/model/PutEventsRequest.html) object that contains one or more [PutEventsRequestEntry](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatchevents/model/PutEventsRequestEntry.html) objects that provide details about each event. You can specify several parameters for the entry such as the source and type of the event, resources associated with the event, and so on.

**Note**  
You can specify a maximum of 10 events per call to `putEvents`.

 **Imports** 

```
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutEventsRequest;
import com.amazonaws.services.cloudwatchevents.model.PutEventsRequestEntry;
import com.amazonaws.services.cloudwatchevents.model.PutEventsResult;
```

 **Code** 

```
final AmazonCloudWatchEvents cwe =
    AmazonCloudWatchEventsClientBuilder.defaultClient();

final String EVENT_DETAILS =
    "{ \"key1\": \"value1\", \"key2\": \"value2\" }";

PutEventsRequestEntry request_entry = new PutEventsRequestEntry()
    .withDetail(EVENT_DETAILS)
    .withDetailType("sampleSubmitted")
    .withResources(resource_arn)
    .withSource("aws-sdk-java-cloudwatch-example");

PutEventsRequest request = new PutEventsRequest()
    .withEntries(request_entry);

PutEventsResult response = cwe.putEvents(request);
```

## Add Rules
<a name="add-rules"></a>

To create or update a rule, call the AmazonCloudWatchEventsClient’s `putRule` method with a [PutRuleRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatchevents/model/PutRuleRequest.html) with the name of the rule and optional parameters such as the [event pattern](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html), IAM role to associate with the rule, and a [scheduling expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html) that describes how often the rule is run.

 **Imports** 

```
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutRuleRequest;
import com.amazonaws.services.cloudwatchevents.model.PutRuleResult;
import com.amazonaws.services.cloudwatchevents.model.RuleState;
```

 **Code** 

```
final AmazonCloudWatchEvents cwe =
    AmazonCloudWatchEventsClientBuilder.defaultClient();

PutRuleRequest request = new PutRuleRequest()
    .withName(rule_name)
    .withRoleArn(role_arn)
    .withScheduleExpression("rate(5 minutes)")
    .withState(RuleState.ENABLED);

PutRuleResult response = cwe.putRule(request);
```

## Add Targets
<a name="add-targets"></a>

Targets are the resources that are invoked when a rule is triggered. Example targets include Amazon EC2 instances, Lambda functions, Kinesis streams, Amazon ECS tasks, Step Functions state machines, and built-in targets.

To add a target to a rule, call the AmazonCloudWatchEventsClient’s `putTargets` method with a [PutTargetsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/cloudwatchevents/model/PutTargetsRequest.html) containing the rule to update and a list of targets to add to the rule.

 **Imports** 

```
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEvents;
import com.amazonaws.services.cloudwatchevents.AmazonCloudWatchEventsClientBuilder;
import com.amazonaws.services.cloudwatchevents.model.PutTargetsRequest;
import com.amazonaws.services.cloudwatchevents.model.PutTargetsResult;
import com.amazonaws.services.cloudwatchevents.model.Target;
```

 **Code** 

```
final AmazonCloudWatchEvents cwe =
    AmazonCloudWatchEventsClientBuilder.defaultClient();

Target target = new Target()
    .withArn(function_arn)
    .withId(target_id);

PutTargetsRequest request = new PutTargetsRequest()
    .withTargets(target)
    .withRule(rule_name);

PutTargetsResult response = cwe.putTargets(request);
```

## More Information
<a name="more-information"></a>
+  [Adding Events with PutEvents](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/AddEventsPutEvents.html) in the Amazon CloudWatch Events User Guide
+  [Schedule Expressions for Rules](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html) in the Amazon CloudWatch Events User Guide
+  [Event Types for CloudWatch Events](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/EventTypes.html) in the Amazon CloudWatch Events User Guide
+  [Events and Event Patterns](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html) in the Amazon CloudWatch Events User Guide
+  [PutEvents](http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutEvents.html) in the Amazon CloudWatch Events API Reference
+  [PutTargets](http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutTargets.html) in the Amazon CloudWatch Events API Reference
+  [PutRule](http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutRule.html) in the Amazon CloudWatch Events API Reference

# DynamoDB Examples Using the AWS SDK for Java
<a name="examples-dynamodb"></a>

This section provides examples of programming [DynamoDB](https://aws.amazon.com/dynamodb/) using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Use AWS account-based endpoints](#account-based-endpoint-routing)
+ [Working with Tables in DynamoDB](examples-dynamodb-tables.md)
+ [Working with Items in DynamoDB](examples-dynamodb-items.md)

## Use AWS account-based endpoints
<a name="account-based-endpoint-routing"></a>

DynamoDB offers [AWS account-based endpoints](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.SDKOverview.html#Programming.SDKs.endpoints) that can improve performance by using your AWS account ID to streamline request routing. 

To take advantage of this feature, you need to use version 1.12.771 or greater of version 1 of AWS SDK for Java. You can find the latest version of the SDK listed in the [Maven central repository](https://central.sonatype.com/artifact/com.amazonaws/aws-java-sdk-bom). After a supported version of SDK is active, it automatically uses the new endpoints.

If you want to opt out of the account-based routing, you have four options:
+ Configure a DynamoDB service client with the `AccountIdEndpointMode` set to `DISABLED`.
+ Set an environment variable.
+ Set a JVM system property.
+ Update the shared AWS config file setting.

The following snippet is an example of how to disable account-based routing by configuring a DynamoDB service client:

```
ClientConfiguration config = new ClientConfiguration()
    .withAccountIdEndpointMode(AccountIdEndpointMode.DISABLED);
AWSCredentialsProvider credentialsProvider = new EnvironmentVariableCredentialsProvider();

AmazonDynamoDB dynamodb = AmazonDynamoDBClientBuilder.standard()
    .withClientConfiguration(config)
    .withCredentials(credentialsProvider)
    .withRegion(Regions.US_WEST_2)
    .build();
```

The AWS SDKs and Tools Reference Guide provides more information on the last [three configuration options](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html).

# Working with Tables in DynamoDB
<a name="examples-dynamodb-tables"></a>

Tables are the containers for all items in a DynamoDB database. Before you can add or remove data from DynamoDB, you must create a table.

For each table, you must define:
+ A table *name* that is unique for your account and region.
+ A *primary key* for which every value must be unique; no two items in your table can have the same primary key value.

  A primary key can be *simple*, consisting of a single partition (HASH) key, or *composite*, consisting of a partition and a sort (RANGE) key.

  Each key value has an associated *data type*, enumerated by the [ScalarAttributeType](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ScalarAttributeType.html) class. The key value can be binary (B), numeric (N), or a string (S). For more information, see [Naming Rules and Data Types](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) in the Amazon DynamoDB Developer Guide.
+  *Provisioned throughput* values that define the number of reserved read/write capacity units for the table.
**Note**  
 [Amazon DynamoDB pricing](https://aws.amazon.com/dynamodb/pricing/) is based on the provisioned throughput values that you set on your tables, so reserve only as much capacity as you think you’ll need for your table.

Provisioned throughput for a table can be modified at any time, so you can adjust capacity if your needs change.

## Create a Table
<a name="dynamodb-create-table"></a>

Use the [DynamoDB client](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html)'s `createTable` method to create a new DynamoDB table. You need to construct table attributes and a table schema, both of which are used to identify the primary key of your table. You must also supply initial provisioned throughput values and a table name. Only define key table attributes when creating your DynamoDB table.

**Note**  
If a table with the name you chose already exists, an [AmazonServiceException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/AmazonServiceException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
```

### Create a Table with a Simple Primary Key
<a name="dynamodb-create-table-simple"></a>

This code creates a table with a simple primary key ("Name").

 **Code** 

```
CreateTableRequest request = new CreateTableRequest()
    .withAttributeDefinitions(new AttributeDefinition(
             "Name", ScalarAttributeType.S))
    .withKeySchema(new KeySchemaElement("Name", KeyType.HASH))
    .withProvisionedThroughput(new ProvisionedThroughput(
             new Long(10), new Long(10)))
    .withTableName(table_name);

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    CreateTableResult result = ddb.createTable(request);
    System.out.println(result.getTableDescription().getTableName());
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/CreateTable.java) on GitHub.

### Create a Table with a Composite Primary Key
<a name="dynamodb-create-table-composite"></a>

Add another [AttributeDefinition](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/AttributeDefinition.html) and [KeySchemaElement](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/KeySchemaElement.html) to [CreateTableRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/CreateTableRequest.html).

 **Code** 

```
CreateTableRequest request = new CreateTableRequest()
    .withAttributeDefinitions(
          new AttributeDefinition("Language", ScalarAttributeType.S),
          new AttributeDefinition("Greeting", ScalarAttributeType.S))
    .withKeySchema(
          new KeySchemaElement("Language", KeyType.HASH),
          new KeySchemaElement("Greeting", KeyType.RANGE))
    .withProvisionedThroughput(
          new ProvisionedThroughput(new Long(10), new Long(10)))
    .withTableName(table_name);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/CreateTableCompositeKey.java) on GitHub.

## List Tables
<a name="dynamodb-list-tables"></a>

You can list the tables in a particular region by calling the [DynamoDB client](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html)'s `listTables` method.

**Note**  
If the named table doesn’t exist for your account and region, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.ListTablesRequest;
import com.amazonaws.services.dynamodbv2.model.ListTablesResult;
```

 **Code** 

```
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

ListTablesRequest request;

boolean more_tables = true;
String last_name = null;

while(more_tables) {
    try {
        if (last_name == null) {
        	request = new ListTablesRequest().withLimit(10);
        }
        else {
        	request = new ListTablesRequest()
        			.withLimit(10)
        			.withExclusiveStartTableName(last_name);
        }

        ListTablesResult table_list = ddb.listTables(request);
        List<String> table_names = table_list.getTableNames();

        if (table_names.size() > 0) {
            for (String cur_name : table_names) {
                System.out.format("* %s\n", cur_name);
            }
        } else {
            System.out.println("No tables found!");
            System.exit(0);
        }

        last_name = table_list.getLastEvaluatedTableName();
        if (last_name == null) {
            more_tables = false;
        }
```

By default, up to 100 tables are returned per call—​use `getLastEvaluatedTableName` on the returned [ListTablesResult](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/ListTablesResult.html) object to get the last table that was evaluated. You can use this value to start the listing after the last returned value of the previous listing.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/ListTables.java) on GitHub.

## Describe (Get Information about) a Table
<a name="dynamodb-describe-table"></a>

Call the [DynamoDB client](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html)'s `describeTable` method.

**Note**  
If the named table doesn’t exist for your account and region, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputDescription;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
```

 **Code** 

```
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    TableDescription table_info =
       ddb.describeTable(table_name).getTable();

    if (table_info != null) {
        System.out.format("Table name  : %s\n",
              table_info.getTableName());
        System.out.format("Table ARN   : %s\n",
              table_info.getTableArn());
        System.out.format("Status      : %s\n",
              table_info.getTableStatus());
        System.out.format("Item count  : %d\n",
              table_info.getItemCount().longValue());
        System.out.format("Size (bytes): %d\n",
              table_info.getTableSizeBytes().longValue());

        ProvisionedThroughputDescription throughput_info =
           table_info.getProvisionedThroughput();
        System.out.println("Throughput");
        System.out.format("  Read Capacity : %d\n",
              throughput_info.getReadCapacityUnits().longValue());
        System.out.format("  Write Capacity: %d\n",
              throughput_info.getWriteCapacityUnits().longValue());

        List<AttributeDefinition> attributes =
           table_info.getAttributeDefinitions();
        System.out.println("Attributes");
        for (AttributeDefinition a : attributes) {
            System.out.format("  %s (%s)\n",
                  a.getAttributeName(), a.getAttributeType());
        }
    }
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/DescribeTable.java) on GitHub.

## Modify (Update) a Table
<a name="dynamodb-update-table"></a>

You can modify your table’s provisioned throughput values at any time by calling the [DynamoDB client](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html)'s `updateTable` method.

**Note**  
If the named table doesn’t exist for your account and region, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.AmazonServiceException;
```

 **Code** 

```
ProvisionedThroughput table_throughput = new ProvisionedThroughput(
      read_capacity, write_capacity);

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    ddb.updateTable(table_name, table_throughput);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/UpdateTable.java) on GitHub.

## Delete a Table
<a name="dynamodb-delete-table"></a>

Call the [DynamoDB client](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/AmazonDynamoDB.html)'s `deleteTable` method and pass it the table’s name.

**Note**  
If the named table doesn’t exist for your account and region, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
```

 **Code** 

```
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    ddb.deleteTable(table_name);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/DeleteTable.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Guidelines for Working with Tables](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html) in the Amazon DynamoDB Developer Guide
+  [Working with Tables in DynamoDB](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html) in the Amazon DynamoDB Developer Guide

# Working with Items in DynamoDB
<a name="examples-dynamodb-items"></a>

In DynamoDB, an item is a collection of *attributes*, each of which has a *name* and a *value*. An attribute value can be a scalar, set, or document type. For more information, see [Naming Rules and Data Types](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) in the Amazon DynamoDB Developer Guide.

## Retrieve (Get) an Item from a Table
<a name="dynamodb-get-item"></a>

Call the AmazonDynamoDB’s `getItem` method and pass it a [GetItemRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/GetItemRequest.html) object with the table name and primary key value of the item you want. It returns a [GetItemResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/GetItemResult.html) object.

You can use the returned `GetItemResult` object’s `getItem()` method to retrieve a [Map](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) of key (String) and value ([AttributeValue](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/AttributeValue.html)) pairs that are associated with the item.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
```

 **Code** 

```
HashMap<String,AttributeValue> key_to_get =
    new HashMap<String,AttributeValue>();

key_to_get.put("DATABASE_NAME", new AttributeValue(name));

GetItemRequest request = null;
if (projection_expression != null) {
    request = new GetItemRequest()
        .withKey(key_to_get)
        .withTableName(table_name)
        .withProjectionExpression(projection_expression);
} else {
    request = new GetItemRequest()
        .withKey(key_to_get)
        .withTableName(table_name);
}

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    Map<String,AttributeValue> returned_item =
       ddb.getItem(request).getItem();
    if (returned_item != null) {
        Set<String> keys = returned_item.keySet();
        for (String key : keys) {
            System.out.format("%s: %s\n",
                    key, returned_item.get(key).toString());
        }
    } else {
        System.out.format("No item found with the key %s!\n", name);
    }
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/GetItem.java) on GitHub.

## Add a New Item to a Table
<a name="dynamodb-add-item"></a>

Create a [Map](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) of key-value pairs that represent the item’s attributes. These must include values for the table’s primary key fields. If the item identified by the primary key already exists, its fields are *updated* by the request.

**Note**  
If the named table doesn’t exist for your account and region, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import java.util.ArrayList;
```

 **Code** 

```
HashMap<String,AttributeValue> item_values =
    new HashMap<String,AttributeValue>();

item_values.put("Name", new AttributeValue(name));

for (String[] field : extra_fields) {
    item_values.put(field[0], new AttributeValue(field[1]));
}

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    ddb.putItem(table_name, item_values);
} catch (ResourceNotFoundException e) {
    System.err.format("Error: The table \"%s\" can't be found.\n", table_name);
    System.err.println("Be sure that it exists and that you've typed its name correctly!");
    System.exit(1);
} catch (AmazonServiceException e) {
    System.err.println(e.getMessage());
    System.exit(1);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/PutItem.java) on GitHub.

## Update an Existing Item in a Table
<a name="dynamodb-update-item"></a>

You can update an attribute for an item that already exists in a table by using the AmazonDynamoDB’s `updateItem` method, providing a table name, primary key value, and a map of fields to update.

**Note**  
If the named table doesn’t exist for your account and region, or if the item identified by the primary key you passed in doesn’t exist, a [ResourceNotFoundException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/model/ResourceNotFoundException.html) is thrown.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.model.AttributeAction;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import java.util.ArrayList;
```

 **Code** 

```
HashMap<String,AttributeValue> item_key =
   new HashMap<String,AttributeValue>();

item_key.put("Name", new AttributeValue(name));

HashMap<String,AttributeValueUpdate> updated_values =
    new HashMap<String,AttributeValueUpdate>();

for (String[] field : extra_fields) {
    updated_values.put(field[0], new AttributeValueUpdate(
                new AttributeValue(field[1]), AttributeAction.PUT));
}

final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();

try {
    ddb.updateItem(table_name, item_key, updated_values);
} catch (ResourceNotFoundException e) {
    System.err.println(e.getMessage());
    System.exit(1);
} catch (AmazonServiceException e) {
    System.err.println(e.getMessage());
    System.exit(1);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/UpdateItem.java) on GitHub.

## Use the DynamoDBMapper class
<a name="use-the-dynamodbmapper-class"></a>

The [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/) provides a [DynamoDBMapper](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) class, allowing you to map your client-side classes to Amazon DynamoDB tables. To use the [DynamoDBMapper](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) class, you define the relationship between items in a DynamoDB table and their corresponding object instances in your code by using annotations (as shown in the following code example). The [DynamoDBMapper](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) class enables you to access your tables; perform various create, read, update, and delete (CRUD) operations; and execute queries.

**Note**  
The [DynamoDBMapper](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) class does not allow you to create, update, or delete tables.

 **Imports** 

```
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException;
```

 **Code** 

The following Java code example shows you how to add content to the *Music* table by using the [DynamoDBMapper](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapper.html) class. After the content is added to the table, notice that an item is loaded by using the *Partition* and *Sort* keys. Then the *Awards* item is updated. For information on creating the *Music* table, see [Create a Table](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html) in the Amazon DynamoDB Developer Guide.

```
       AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
       MusicItems items = new MusicItems();

       try{
           // Add new content to the Music table
           items.setArtist(artist);
           items.setSongTitle(songTitle);
           items.setAlbumTitle(albumTitle);
           items.setAwards(Integer.parseInt(awards)); //convert to an int

           // Save the item
           DynamoDBMapper mapper = new DynamoDBMapper(client);
           mapper.save(items);

           // Load an item based on the Partition Key and Sort Key
           // Both values need to be passed to the mapper.load method
           String artistName = artist;
           String songQueryTitle = songTitle;

           // Retrieve the item
           MusicItems itemRetrieved = mapper.load(MusicItems.class, artistName, songQueryTitle);
           System.out.println("Item retrieved:");
           System.out.println(itemRetrieved);

           // Modify the Award value
           itemRetrieved.setAwards(2);
           mapper.save(itemRetrieved);
           System.out.println("Item updated:");
           System.out.println(itemRetrieved);

           System.out.print("Done");
       } catch (AmazonDynamoDBException e) {
           e.getStackTrace();
       }
   }

   @DynamoDBTable(tableName="Music")
   public static class MusicItems {

       //Set up Data Members that correspond to columns in the Music table
       private String artist;
       private String songTitle;
       private String albumTitle;
       private int awards;

       @DynamoDBHashKey(attributeName="Artist")
       public String getArtist() {
           return this.artist;
       }

       public void setArtist(String artist) {
           this.artist = artist;
       }

       @DynamoDBRangeKey(attributeName="SongTitle")
       public String getSongTitle() {
           return this.songTitle;
       }

       public void setSongTitle(String title) {
           this.songTitle = title;
       }

       @DynamoDBAttribute(attributeName="AlbumTitle")
       public String getAlbumTitle() {
           return this.albumTitle;
       }

       public void setAlbumTitle(String title) {
           this.albumTitle = title;
       }

       @DynamoDBAttribute(attributeName="Awards")
       public int getAwards() {
           return this.awards;
       }

       public void setAwards(int awards) {
           this.awards = awards;
       }
   }
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/dynamodb/src/main/java/aws/example/dynamodb/UseDynamoMapping.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Guidelines for Working with Items](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForItems.html) in the Amazon DynamoDB Developer Guide
+  [Working with Items in DynamoDB](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html) in the Amazon DynamoDB Developer Guide

# Amazon EC2 Examples Using the AWS SDK for Java
<a name="prog-services-ec2"></a>

This section provides examples of programming [Amazon EC2](https://aws.amazon.com/ec2/) with the AWS SDK for Java.

**Topics**
+ [Tutorial: Starting an EC2 Instance](how-to-ec2.md)
+ [Using IAM Roles to Grant Access to AWS Resources on Amazon EC2](java-dg-roles.md)
+ [Tutorial: Amazon EC2 Spot Instances](tutorial-spot-instances-java.md)
+ [Tutorial: Advanced Amazon EC2 Spot Request Management](tutorial-spot-adv-java.md)
+ [Managing Amazon EC2 Instances](examples-ec2-instances.md)
+ [Using Elastic IP Addresses in Amazon EC2](examples-ec2-elastic-ip.md)
+ [Use regions and availability zones](examples-ec2-regions-zones.md)
+ [Working with Amazon EC2 Key Pairs](examples-ec2-key-pairs.md)
+ [Working with Security Groups in Amazon EC2](examples-ec2-security-groups.md)

# Tutorial: Starting an EC2 Instance
<a name="how-to-ec2"></a>

This tutorial demonstrates how to use the AWS SDK for Java to start an EC2 instance.

**Topics**
+ [Prerequisites](#prerequisitesec2)
+ [Create an Amazon EC2 Security Group](create-security-group.md)
+ [Create a Key Pair](create-key-pair.md)
+ [Run an Amazon EC2 Instance](run-instance.md)

## Prerequisites
<a name="prerequisitesec2"></a>

Before you begin, be sure that you have created an AWS account and that you have set up your AWS credentials. For more information, see [Getting Started](getting-started.md).

# Create an Amazon EC2 Security Group
<a name="create-security-group"></a>

## EC2-Classic is retiring
<a name="retiringEC2Classic"></a>

**Warning**  
We are retiring EC2-Classic on August 15, 2022. We recommend that you migrate from EC2-Classic to a VPC. For more information, see the blog post [EC2-Classic-Classic Networking is Retiring – Here's How to Prepare](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

Create a *security group*, which acts as a virtual firewall that controls the network traffic for one or more EC2 instances. By default, Amazon EC2 associates your instances with a security group that allows no inbound traffic. You can create a security group that allows your EC2 instances to accept certain traffic. For example, if you need to connect to a Linux instance, you must configure the security group to allow SSH traffic. You can create a security group using the Amazon EC2 console or the AWS SDK for Java.

You create a security group for use in either EC2-Classic or EC2-VPC. For more information about EC2-Classic and EC2-VPC, see [Supported Platforms](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-supported-platforms.html) in the Amazon EC2 User Guide for Linux Instances.

For more information about creating a security group using the Amazon EC2 console, see [Amazon EC2 Security Groups](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html) in the Amazon EC2 User Guide for Linux Instances.

1. Create and initialize a [CreateSecurityGroupRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateSecurityGroupRequest.html) instance. Use the [withGroupName](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateSecurityGroupRequest.html#withGroupName-java.lang.String-) method to set the security group name, and the [withDescription](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateSecurityGroupRequest.html#withDescription-java.lang.String-) method to set the security group description, as follows:

   ```
   CreateSecurityGroupRequest csgr = new CreateSecurityGroupRequest();
   csgr.withGroupName("JavaSecurityGroup").withDescription("My security group");
   ```

   The security group name must be unique within the AWS region in which you initialize your Amazon EC2 client. You must use US-ASCII characters for the security group name and description.

1. Pass the request object as a parameter to the [createSecurityGroup](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2.html#createSecurityGroup-com.amazonaws.services.ec2.model.CreateSecurityGroupRequest-) method. The method returns a [CreateSecurityGroupResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateSecurityGroupResult.html) object, as follows:

   ```
   CreateSecurityGroupResult createSecurityGroupResult =
       amazonEC2Client.createSecurityGroup(csgr);
   ```

   If you attempt to create a security group with the same name as an existing security group, `createSecurityGroup` throws an exception.

By default, a new security group does not allow any inbound traffic to your Amazon EC2 instance. To allow inbound traffic, you must explicitly authorize security group ingress. You can authorize ingress for individual IP addresses, for a range of IP addresses, for a specific protocol, and for TCP/UDP ports.

1. Create and initialize an [IpPermission](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html) instance. Use the [withIpv4Ranges](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html#withIpv4Ranges-java.util.Collection-) method to set the range of IP addresses to authorize ingress for, and use the [withIpProtocol](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html#withIpProtocol-java.lang.String-) method to set the IP protocol. Use the [withFromPort](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html#withFromPort-java.lang.Integer-) and [withToPort](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html#withToPort-java.lang.Integer-) methods to specify range of ports to authorize ingress for, as follows:

   ```
   IpPermission ipPermission =
       new IpPermission();
   
   IpRange ipRange1 = new IpRange().withCidrIp("111.111.111.111/32");
   IpRange ipRange2 = new IpRange().withCidrIp("150.150.150.150/32");
   
   ipPermission.withIpv4Ranges(Arrays.asList(new IpRange[] {ipRange1, ipRange2}))
               .withIpProtocol("tcp")
               .withFromPort(22)
               .withToPort(22);
   ```

   All the conditions that you specify in the `IpPermission` object must be met in order for ingress to be allowed.

   Specify the IP address using CIDR notation. If you specify the protocol as TCP/UDP, you must provide a source port and a destination port. You can authorize ports only if you specify TCP or UDP.

1. Create and initialize an [AuthorizeSecurityGroupIngressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AuthorizeSecurityGroupEgressRequest.html) instance. Use the `withGroupName` method to specify the security group name, and pass the `IpPermission` object you initialized earlier to the [withIpPermissions](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AuthorizeSecurityGroupEgressRequest.html#withIpPermissions-com.amazonaws.services.ec2.model.IpPermission…​-) method, as follows:

   ```
   AuthorizeSecurityGroupIngressRequest authorizeSecurityGroupIngressRequest =
       new AuthorizeSecurityGroupIngressRequest();
   
   authorizeSecurityGroupIngressRequest.withGroupName("JavaSecurityGroup")
                                       .withIpPermissions(ipPermission);
   ```

1. Pass the request object into the [authorizeSecurityGroupIngress](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2Client.html#authorizeSecurityGroupIngress-com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest-) method, as follows:

   ```
   amazonEC2Client.authorizeSecurityGroupIngress(authorizeSecurityGroupIngressRequest);
   ```

   If you call `authorizeSecurityGroupIngress` with IP addresses for which ingress is already authorized, the method throws an exception. Create and initialize a new `IpPermission` object to authorize ingress for different IPs, ports, and protocols before calling `AuthorizeSecurityGroupIngress`.

Whenever you call the [authorizeSecurityGroupIngress](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2Client.html#authorizeSecurityGroupIngress-com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest-) or [authorizeSecurityGroupEgress](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2Client.html#authorizeSecurityGroupEgress-com.amazonaws.services.ec2.model.AuthorizeSecurityGroupEgressRequest-) methods, a rule is added to your security group.

# Create a Key Pair
<a name="create-key-pair"></a>

You must specify a key pair when you launch an EC2 instance and then specify the private key of the key pair when you connect to the instance. You can create a key pair or use an existing key pair that you’ve used when launching other instances. For more information, see [Amazon EC2 Key Pairs](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide for Linux Instances.

1. Create and initialize a [CreateKeyPairRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateKeyPairRequest.html) instance. Use the [withKeyName](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateKeyPairRequest.html#withKeyName-java.lang.String-) method to set the key pair name, as follows:

   ```
   CreateKeyPairRequest createKeyPairRequest = new CreateKeyPairRequest();
   
   createKeyPairRequest.withKeyName(keyName);
   ```
**Important**  
Key pair names must be unique. If you attempt to create a key pair with the same key name as an existing key pair, you’ll get an exception.

1. Pass the request object to the [createKeyPair](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2.html#createKeyPair-com.amazonaws.services.ec2.model.CreateKeyPairRequest--) method. The method returns a [CreateKeyPairResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateKeyPairResult.html) instance, as follows:

   ```
   CreateKeyPairResult createKeyPairResult =
     amazonEC2Client.createKeyPair(createKeyPairRequest);
   ```

1. Call the result object’s [getKeyPair](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateKeyPairResult.html#getKeyPair--) method to obtain a [KeyPair](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/KeyPair.html) object. Call the `KeyPair` object’s [getKeyMaterial](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/KeyPair.html#getKeyMaterial--) method to obtain the unencrypted PEM-encoded private key, as follows:

   ```
   KeyPair keyPair = new KeyPair();
   
   keyPair = createKeyPairResult.getKeyPair();
   
   String privateKey = keyPair.getKeyMaterial();
   ```

# Run an Amazon EC2 Instance
<a name="run-instance"></a>

Use the following procedure to launch one or more identically configured EC2 instances from the same Amazon Machine Image (AMI). After you create your EC2 instances, you can check their status. After your EC2 instances are running, you can connect to them.

1. Create and initialize a [RunInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html) instance. Make sure that the AMI, key pair, and security group that you specify exist in the region that you specified when you created the client object.

   ```
   RunInstancesRequest runInstancesRequest =
      new RunInstancesRequest();
   
   runInstancesRequest.withImageId("ami-a9d09ed1")
                      .withInstanceType(InstanceType.T1Micro)
                      .withMinCount(1)
                      .withMaxCount(1)
                      .withKeyName("my-key-pair")
                      .withSecurityGroups("my-security-group");
   ```  
 [withImageId](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withImageId-java.lang.String-)   
   + The ID of the AMI. To learn how to find public AMIs provided by Amazon or create your own, see [Amazon Machine Image (AMI)](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html).  
 [withInstanceType](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withInstanceType-java.lang.String-)   
   + An instance type that is compatible with the specified AMI. For more information, see [Instance Types](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html) in the Amazon EC2 User Guide for Linux Instances.  
 [withMinCount](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withMinCount-java.lang.Integer-)   
   + The minimum number of EC2 instances to launch. If this is more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches no instances.  
 [withMaxCount](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withMaxCount-java.lang.Integer-)   
   + The maximum number of EC2 instances to launch. If this is more instances than Amazon EC2 can launch in the target Availability Zone, Amazon EC2 launches the largest possible number of instances above `MinCount`. You can launch between 1 and the maximum number of instances you’re allowed for the instance type. For more information, see How many instances can I run in Amazon EC2 in the Amazon EC2 General FAQ.  
 [withKeyName](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withKeyName-java.lang.String-)   
   + The name of the EC2 key pair. If you launch an instance without specifying a key pair, you can’t connect to it. For more information, see [Create a Key Pair](create-key-pair.md).  
 [withSecurityGroups](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html#withSecurityGroups-java.util.Collection-)   
   + One or more security groups. For more information, see [Create an Amazon EC2 Security Group](create-security-group.md).

1. Launch the instances by passing the request object to the [runInstances](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2Client.html#runInstances-com.amazonaws.services.ec2.model.RunInstancesRequest-) method. The method returns a [RunInstancesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesResult.html) object, as follows:

   ```
   RunInstancesResult result = amazonEC2Client.runInstances(
                                 runInstancesRequest);
   ```

After your instance is running, you can connect to it using your key pair. For more information, see [Connect to Your Linux Instance](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html). in the Amazon EC2 User Guide for Linux Instances.

# Using IAM Roles to Grant Access to AWS Resources on Amazon EC2
<a name="java-dg-roles"></a>

All requests to Amazon Web Services (AWS) must be cryptographically signed using credentials issued by AWS. You can use *IAM roles* to conveniently grant secure access to AWS resources from your Amazon EC2 instances.

This topic provides information about how to use IAM roles with Java SDK applications running on Amazon EC2. For more information about IAM instances, see [IAM Roles for Amazon EC2](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) in the Amazon EC2 User Guide for Linux Instances.

## The default provider chain and EC2 instance profiles
<a name="default-provider-chain"></a>

If your application creates an AWS client using the default constructor, then the client will search for credentials using the *default credentials provider chain*, in the following order:

1. In the Java system properties: `aws.accessKeyId` and `aws.secretKey`.

1. In system environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.

1. In the default credentials file (the location of this file varies by platform).

1. Credentials delivered through the Amazon EC2 container service if the `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` environment variable is set and security manager has permission to access the variable.

1. In the *instance profile credentials*, which exist within the instance metadata associated with the IAM role for the EC2 instance.

1. Web Identity Token credentials from the environment or container.

The *instance profile credentials* step in the default provider chain is available only when running your application on an Amazon EC2 instance, but provides the greatest ease of use and best security when working with Amazon EC2 instances. You can also pass an [InstanceProfileCredentialsProvider](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/auth/InstanceProfileCredentialsProvider.html) instance directly to the client constructor to get instance profile credentials without proceeding through the entire default provider chain.

For example:

```
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
              .withCredentials(new InstanceProfileCredentialsProvider(false))
              .build();
```

When using this approach, the SDK retrieves temporary AWS credentials that have the same permissions as those associated with the IAM role associated with the Amazon EC2 instance in its instance profile. Although these credentials are temporary and would eventually expire, `InstanceProfileCredentialsProvider` periodically refreshes them for you so that the obtained credentials continue to allow access to AWS.

**Important**  
The automatic credentials refresh happens *only* when you use the default client constructor, which creates its own `InstanceProfileCredentialsProvider` as part of the default provider chain, or when you pass an `InstanceProfileCredentialsProvider` instance directly to the client constructor. If you use another method to obtain or pass instance profile credentials, you are responsible for checking for and refreshing expired credentials.

If the client constructor can’t find credentials using the credentials provider chain, it will throw an [AmazonClientException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/AmazonClientException.html).

## Walkthrough: Using IAM roles for EC2 instances
<a name="roles-walkthrough"></a>

The following walkthrough shows you how to retrieve an object from Amazon S3 using an IAM role to manage access.

### Create an IAM Role
<a name="java-dg-create-the-role"></a>

Create an IAM role that grants read-only access to Amazon S3.

1. Open the [IAM console](https://console.aws.amazon.com/iam/home).

1. In the navigation pane, select **Roles**, then **Create New Role**.

1. Enter a name for the role, then select **Next Step**. Remember this name, since you’ll need it when you launch your Amazon EC2 instance.

1. On the **Select Role Type** page, under ** AWS service Roles**, select ** Amazon EC2 **.

1. On the **Set Permissions** page, under **Select Policy Template**, select ** Amazon S3 Read Only Access**, then **Next Step**.

1. On the **Review** page, select **Create Role**.

### Launch an EC2 Instance and Specify Your IAM Role
<a name="java-dg-launch-ec2-instance-with-instance-profile"></a>

You can launch an Amazon EC2 instance with an IAM role using the Amazon EC2 console or the AWS SDK for Java.
+ To launch an Amazon EC2 instance using the console, follow the directions in [Getting Started with Amazon EC2 Linux Instances](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html) in the Amazon EC2 User Guide for Linux Instances.

  When you reach the **Review Instance Launch** page, select **Edit instance details**. In **IAM role**, choose the IAM role that you created previously. Complete the procedure as directed.
**Note**  
You’ll need to create or use an existing security group and key pair to connect to the instance.
+ To launch an Amazon EC2 instance with an IAM role using the AWS SDK for Java, see [Run an Amazon EC2 Instance](run-instance.md).

### Create your Application
<a name="java-dg-remove-the-credentials"></a>

Let’s build the sample application to run on the EC2 instance. First, create a directory that you can use to hold your tutorial files (for example, `GetS3ObjectApp`).

Next, copy the AWS SDK for Java libraries into your newly-created directory. If you downloaded the AWS SDK for Java to your `~/Downloads` directory, you can copy them using the following commands:

```
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/lib .
cp -r ~/Downloads/aws-java-sdk-{1.7.5}/third-party .
```

Open a new file, call it `GetS3Object.java`, and add the following code:

```
import java.io.*;

import com.amazonaws.auth.*;
import com.amazonaws.services.s3.*;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;

public class GetS3Object {
  private static final String bucketName = "text-content";
  private static final String key = "text-object.txt";

  public static void main(String[] args) throws IOException
  {
    AmazonS3 s3Client = AmazonS3ClientBuilder.defaultClient();

    try {
      System.out.println("Downloading an object");
      S3Object s3object = s3Client.getObject(
          new GetObjectRequest(bucketName, key));
      displayTextInputStream(s3object.getObjectContent());
    }
    catch(AmazonServiceException ase) {
      System.err.println("Exception was thrown by the service");
    }
    catch(AmazonClientException ace) {
      System.err.println("Exception was thrown by the client");
    }
  }

  private static void displayTextInputStream(InputStream input) throws IOException
  {
    // Read one text line at a time and display.
    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    while(true)
    {
      String line = reader.readLine();
      if(line == null) break;
      System.out.println( "    " + line );
    }
    System.out.println();
  }
}
```

Open a new file, call it `build.xml`, and add the following lines:

```
<project name="Get {S3} Object" default="run" basedir=".">
  <path id="aws.java.sdk.classpath">
    <fileset dir="./lib" includes="**/*.jar"/>
    <fileset dir="./third-party" includes="**/*.jar"/>
    <pathelement location="lib"/>
    <pathelement location="."/>
  </path>

  <target name="build">
  <javac debug="true"
    includeantruntime="false"
    srcdir="."
    destdir="."
    classpathref="aws.java.sdk.classpath"/>
  </target>

  <target name="run" depends="build">
    <java classname="GetS3Object" classpathref="aws.java.sdk.classpath" fork="true"/>
  </target>
</project>
```

Build and run the modified program. Note that there are no credentials are stored in the program. Therefore, unless you have your AWS credentials specified already, the code will throw `AmazonServiceException`. For example:

```
$ ant
Buildfile: /path/to/my/GetS3ObjectApp/build.xml

build:
  [javac] Compiling 1 source file to /path/to/my/GetS3ObjectApp

run:
   [java] Downloading an object
   [java] AmazonServiceException

BUILD SUCCESSFUL
```

### Transfer the Compiled Program to Your EC2 Instance
<a name="java-dg-transfer-compiled-program-to-ec2-instance"></a>

Transfer the program to your Amazon EC2 instance using secure copy (** `` **), along with the AWS SDK for Java libraries. The sequence of commands looks something like the following.

```
scp -p -i {my-key-pair}.pem GetS3Object.class ec2-user@{public_dns}:GetS3Object.class
scp -p -i {my-key-pair}.pem build.xml ec2-user@{public_dns}:build.xml
scp -r -p -i {my-key-pair}.pem lib ec2-user@{public_dns}:lib
scp -r -p -i {my-key-pair}.pem third-party ec2-user@{public_dns}:third-party
```

**Note**  
Depending on the Linux distribution that you used, the *user name* might be "ec2-user", "root", or "ubuntu". To get the public DNS name of your instance, open the [EC2 console](https://console.aws.amazon.com/ec2/home) and look for the **Public DNS** value in the **Description** tab (for example, `ec2-198-51-100-1.compute-1.amazonaws.com`).

In the preceding commands:
+  `GetS3Object.class` is your compiled program
+  `build.xml` is the ant file used to build and run your program
+ the `lib` and `third-party` directories are the corresponding library folders from the AWS SDK for Java.
+ The `-r` switch indicates that `scp` should do a recursive copy of all of the contents of the `library` and `third-party` directories in the AWS SDK for Java distribution.
+ The `-p` switch indicates that `scp` should preserve the permissions of the source files when it copies them to the destination.
**Note**  
The `-p` switch works only on Linux, macOS, or Unix. If you are copying files from Windows, you may need to fix the file permissions on your instance using the following command:

```
chmod -R u+rwx GetS3Object.class build.xml lib third-party
```

### Run the Sample Program on the EC2 Instance
<a name="java-dg-run-the-program"></a>

To run the program, connect to your Amazon EC2 instance. For more information, see [Connect to Your Linux Instance](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstances.html) in the Amazon EC2 User Guide for Linux Instances.

If ** ` ant ` ** is not available on your instance, install it using the following command:

```
sudo yum install ant
```

Then, run the program using `ant` as follows:

```
ant run
```

The program will write the contents of your Amazon S3 object to your command window.

# Tutorial: Amazon EC2 Spot Instances
<a name="tutorial-spot-instances-java"></a>

## Overview
<a name="tutor-spot-java-overview"></a>

Spot Instances enable you to bid on unused Amazon Elastic Compute Cloud (Amazon EC2) capacity t up to 90% versus the On-Demand Instance price and run the acquired instances for as long as your bid exceeds the current *Spot Price*. Amazon EC2 changes the Spot Price periodically based on supply and demand, and customers whose bids meet or exceed it gain access to the available Spot Instances. Like On-Demand Instances and Reserved Instances, Spot Instances provide you another option for obtaining more compute capacity.

Spot Instances can significantly lower your Amazon EC2 costs for batch processing, scientific research, image processing, video encoding, data and web crawling, financial analysis, and testing. Additionally, Spot Instances give you access to large amounts of additional capacity in situations where the need for that capacity is not urgent.

To use Spot Instances, place a Spot Instance request specifying the maximum price you are willing to pay per instance hour; this is your bid. If your bid exceeds the current Spot Price, your request is fulfilled and your instances will run until either you choose to terminate them or the Spot Price increases above your bid (whichever is sooner).

It’s important to note:
+ You will often pay less per hour than your bid. Amazon EC2 adjusts the Spot Price periodically as requests come in and available supply changes. Everyone pays the same Spot Price for that period regardless of whether their bid was higher. Therefore, you might pay less than your bid, but you will never pay more than your bid.
+ If you’re running Spot Instances and your bid no longer meets or exceeds the current Spot Price, your instances will be terminated. This means that you will want to make sure that your workloads and applications are flexible enough to take advantage of this opportunistic capacity.

Spot Instances perform exactly like other Amazon EC2 instances while running, and like other Amazon EC2 instances, Spot Instances can be terminated when you no longer need them. If you terminate your instance, you pay for any partial hour used (as you would for On-Demand or Reserved Instances). However, if the Spot Price goes above your bid and your instance is terminated by Amazon EC2, you will not be charged for any partial hour of usage.

This tutorial shows how to use AWS SDK for Java to do the following.
+ Submit a Spot Request
+ Determine when the Spot Request becomes fulfilled
+ Cancel the Spot Request
+ Terminate associated instances

## Prerequisites
<a name="tutor-spot-java-prereq"></a>

To use this tutorial you must have the AWS SDK for Java installed, as well as having met its basic installation prerequisites. See [Set up the AWS SDK for Java](setup-install.md) for more information.

## Step 1: Setting Up Your Credentials
<a name="tutor-spot-java-credentials"></a>

To begin using this code sample, you need to set up AWS credentials. See [Set up AWS Credentials and Region for Development](setup-credentials.md) for instructions on how to do that.

**Note**  
We recommend that you use the credentials of an IAM user to provide these values. For more information, see [Sign Up for AWS and Create an IAM User](signup-create-iam-user.md).

Now that you have configured your settings, you can get started using the code in the example.

## Step 2: Setting Up a Security Group
<a name="tutor-spot-java-sg"></a>

A *security group* acts as a firewall that controls the traffic allowed in and out of a group of instances. By default, an instance is started without any security group, which means that all incoming IP traffic, on any TCP port will be denied. So, before submitting our Spot Request, we will set up a security group that allows the necessary network traffic. For the purposes of this tutorial, we will create a new security group called "GettingStarted" that allows Secure Shell (SSH) traffic from the IP address where you are running your application from. To set up a new security group, you need to include or run the following code sample that sets up the security group programmatically.

After we create an `AmazonEC2` client object, we create a `CreateSecurityGroupRequest` object with the name, "GettingStarted" and a description for the security group. Then we call the `ec2.createSecurityGroup` API to create the group.

To enable access to the group, we create an `ipPermission` object with the IP address range set to the CIDR representation of the subnet for the local computer; the "/10" suffix on the IP address indicates the subnet for the specified IP address. We also configure the `ipPermission` object with the TCP protocol and port 22 (SSH). The final step is to call `ec2.authorizeSecurityGroupIngress` with the name of our security group and the `ipPermission` object.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Create a new security group.
try {
    CreateSecurityGroupRequest securityGroupRequest = new CreateSecurityGroupRequest("GettingStartedGroup", "Getting Started Security Group");
    ec2.createSecurityGroup(securityGroupRequest);
} catch (AmazonServiceException ase) {
    // Likely this means that the group is already created, so ignore.
    System.out.println(ase.getMessage());
}

String ipAddr = "0.0.0.0/0";

// Get the IP of the current host, so that we can limit the Security
// Group by default to the ip range associated with your subnet.
try {
    InetAddress addr = InetAddress.getLocalHost();

    // Get IP Address
    ipAddr = addr.getHostAddress()+"/10";
} catch (UnknownHostException e) {
}

// Create a range that you would like to populate.
ArrayList<String> ipRanges = new ArrayList<String>();
ipRanges.add(ipAddr);

// Open up port 22 for TCP traffic to the associated IP
// from above (e.g. ssh traffic).
ArrayList<IpPermission> ipPermissions = new ArrayList<IpPermission> ();
IpPermission ipPermission = new IpPermission();
ipPermission.setIpProtocol("tcp");
ipPermission.setFromPort(new Integer(22));
ipPermission.setToPort(new Integer(22));
ipPermission.setIpRanges(ipRanges);
ipPermissions.add(ipPermission);

try {
    // Authorize the ports to the used.
    AuthorizeSecurityGroupIngressRequest ingressRequest =
        new AuthorizeSecurityGroupIngressRequest("GettingStartedGroup",ipPermissions);
    ec2.authorizeSecurityGroupIngress(ingressRequest);
} catch (AmazonServiceException ase) {
    // Ignore because this likely means the zone has
    // already been authorized.
    System.out.println(ase.getMessage());
}
```

Note you only need to run this application once to create a new security group.

You can also create the security group using the AWS Toolkit for Eclipse. See [Managing Security Groups from AWS Cost Explorer](https://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/tke-sg.html) for more information.

## Step 3: Submitting Your Spot Request
<a name="tutor-spot-java-submit"></a>

To submit a Spot request, you first need to determine the instance type, Amazon Machine Image (AMI), and maximum bid price you want to use. You must also include the security group we configured previously, so that you can log into the instance if desired.

There are several instance types to choose from; go to Amazon EC2 Instance Types for a complete list. For this tutorial, we will use t1.micro, the cheapest instance type available. Next, we will determine the type of AMI we would like to use. We’ll use ami-a9d09ed1, the most up-to-date Amazon Linux AMI available when we wrote this tutorial. The latest AMI may change over time, but you can always determine the latest version AMI by following these steps:

1. Open the [Amazon EC2 console](https://console.aws.amazon.com/ec2/home).

1. Choose the **Launch Instance** button.

1. The first window displays the AMIs available. The AMI ID is listed next to each AMI title. Alternatively, you can use the `DescribeImages` API, but leveraging that command is outside the scope of this tutorial.

There are many ways to approach bidding for Spot Instances; to get a broad overview of the various approaches you should view the [Bidding for Spot Instances](https://www.youtube.com/watch?v=WD9N73F3Fao&feature=player_embedded) video. However, to get started, we’ll describe three common strategies: bid to ensure cost is less than on-demand pricing; bid based on the value of the resulting computation; bid so as to acquire computing capacity as quickly as possible.
+  *Reduce Cost below On-Demand* You have a batch processing job that will take a number of hours or days to run. However, you are flexible with respect to when it starts and when it completes. You want to see if you can complete it for less cost than with On-Demand Instances. You examine the Spot Price history for instance types using either the AWS Management Console or the Amazon EC2 API. For more information, go to [Viewing Spot Price History](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances-history.html). After you’ve analyzed the price history for your desired instance type in a given Availability Zone, you have two alternative approaches for your bid:
  + You could bid at the upper end of the range of Spot Prices (which are still below the On-Demand price), anticipating that your one-time Spot request would most likely be fulfilled and run for enough consecutive compute time to complete the job.
  + Or, you could specify the amount you are willing to pay for Spot Instances as a % of the On-Demand Instance price , and plan to combine many instances launched over time through a persistent request. If the specified price is exceeded, then the Spot Instance will terminate. (We will explain how to automate this task later in this tutorial.)
+  *Pay No More than the Value of the Result* You have a data processing job to run. You understand the value of the job’s results well enough to know how much they are worth in terms of computing costs. After you’ve analyzed the Spot Price history for your instance type, you choose a bid price at which the cost of the computing time is no more than the value of the job’s results. You create a persistent bid and allow it to run intermittently as the Spot Price fluctuates at or below your bid.
+  *Acquire Computing Capacity Quickly* You have an unanticipated, short-term need for additional capacity that is not available through On-Demand Instances. After you’ve analyzed the Spot Price history for your instance type, you bid above the highest historical price to provide a high likelihood that your request will be fulfilled quickly and continue computing until it completes.

After you choose your bid price, you are ready to request a Spot Instance. For the purposes of this tutorial, we will bid the On-Demand price (\$10.03) to maximize the chances that the bid will be fulfilled. You can determine the types of available instances and the On-Demand prices for instances by going to Amazon EC2 Pricing page. While a Spot Instancee is running, you pay the Spot price that’s in effect for the time period your instances are running. Spot Instance prices are set by Amazon EC2 and adjust gradually based on long-term trends in supply and demand for Spot Instance capacity. You can also specify the amount you are willing to pay for a Spot Instance as a % of the On-Demand Instance price.To request a Spot Instance, you simply need to build your request with the parameters you chose earlier. We start by creating a `RequestSpotInstanceRequest` object. The request object requires the number of instances you want to start and the bid price. Additionally, you need to set the `LaunchSpecification` for the request, which includes the instance type, AMI ID, and security group you want to use. Once the request is populated, you call the `requestSpotInstances` method on the `AmazonEC2Client` object. The following example shows how to request a Spot Instance.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Setup the specifications of the launch. This includes the
// instance type (e.g. t1.micro) and the latest Amazon Linux
// AMI id available. Note, you should always use the latest
// Amazon Linux AMI id or another of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specifications to the request.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
```

Running this code will launch a new Spot Instance Request. There are other options you can use to configure your Spot Requests. To learn more, please visit [Tutorial: Advanced Amazon EC2 Spot Request Management](tutorial-spot-adv-java.md) or the [RequestSpotInstances](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RequestSpotInstancesRequest.html) class in the AWS SDK for Java API Reference.

**Note**  
You will be charged for any Spot Instances that are actually launched, so make sure that you cancel any requests and terminate any instances you launch to reduce any associated fees.

## Step 4: Determining the State of Your Spot Request
<a name="tutor-spot-java-request-state"></a>

Next, we want to create code to wait until the Spot request reaches the "active" state before proceeding to the last step. To determine the state of our Spot request, we poll the [describeSpotInstanceRequests](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/AmazonEC2Client.html#describeSpotInstanceRequests) method for the state of the Spot request ID we want to monitor.

The request ID created in Step 2 is embedded in the response to our `requestSpotInstances` request. The following example code shows how to gather request IDs from the `requestSpotInstances` response and use them to populate an `ArrayList`.

```
// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
List<SpotInstanceRequest> requestResponses = requestResult.getSpotInstanceRequests();

// Setup an arraylist to collect all of the request ids we want to
// watch hit the running state.
ArrayList<String> spotInstanceRequestIds = new ArrayList<String>();

// Add all of the request ids to the hashset, so we can determine when they hit the
// active state.
for (SpotInstanceRequest requestResponse : requestResponses) {
    System.out.println("Created Spot Request: "+requestResponse.getSpotInstanceRequestId());
    spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId());
}
```

To monitor your request ID, call the `describeSpotInstanceRequests` method to determine the state of the request. Then loop until the request is not in the "open" state. Note that we monitor for a state of not "open", rather a state of, say, "active", because the request can go straight to "closed" if there is a problem with your request arguments. The following code example provides the details of how to accomplish this task.

```
// Create a variable that will track whether there are any
// requests still in the open state.
boolean anyOpen;

do {
    // Create the describeRequest object with all of the request ids
    // to monitor (e.g. that we started).
    DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest();
    describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);

    // Initialize the anyOpen variable to false - which assumes there
    // are no requests open unless we find one that is still open.
    anyOpen=false;

    try {
        // Retrieve all of the requests we want to monitor.
        DescribeSpotInstanceRequestsResult describeResult = ec2.describeSpotInstanceRequests(describeRequest);
        List<SpotInstanceRequest> describeResponses = describeResult.getSpotInstanceRequests();

        // Look through each request and determine if they are all in
        // the active state.
        for (SpotInstanceRequest describeResponse : describeResponses) {
            // If the state is open, it hasn't changed since we attempted
            // to request it. There is the potential for it to transition
            // almost immediately to closed or cancelled so we compare
            // against open instead of active.
        if (describeResponse.getState().equals("open")) {
            anyOpen = true;
            break;
        }
    }
} catch (AmazonServiceException e) {
      // If we have an exception, ensure we don't break out of
      // the loop. This prevents the scenario where there was
      // blip on the wire.
      anyOpen = true;
    }

    try {
        // Sleep for 60 seconds.
        Thread.sleep(60*1000);
    } catch (Exception e) {
        // Do nothing because it woke up early.
    }
} while (anyOpen);
```

After running this code, your Spot Instance Request will have completed or will have failed with an error that will be output to the screen. In either case, we can proceed to the next step to clean up any active requests and terminate any running instances.

## Step 5: Cleaning Up Your Spot Requests and Instances
<a name="tutor-spot-java-cleaning-up"></a>

Lastly, we need to clean up our requests and instances. It is important to both cancel any outstanding requests *and* terminate any instances. Just canceling your requests will not terminate your instances, which means that you will continue to pay for them. If you terminate your instances, your Spot requests may be canceled, but there are some scenarios such as if you use persistent bids where terminating your instances is not sufficient to stop your request from being re-fulfilled. Therefore, it is a best practice to both cancel any active bids and terminate any running instances.

The following code demonstrates how to cancel your requests.

```
try {
    // Cancel requests.
    CancelSpotInstanceRequestsRequest cancelRequest =
       new CancelSpotInstanceRequestsRequest(spotInstanceRequestIds);
    ec2.cancelSpotInstanceRequests(cancelRequest);
} catch (AmazonServiceException e) {
    // Write out any exceptions that may have occurred.
    System.out.println("Error cancelling instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

To terminate any outstanding instances, you will need the instance ID associated with the request that started them. The following code example takes our original code for monitoring the instances and adds an `ArrayList` in which we store the instance ID associated with the `describeInstance` response.

```
// Create a variable that will track whether there are any requests
// still in the open state.
boolean anyOpen;
// Initialize variables.
ArrayList<String> instanceIds = new ArrayList<String>();

do {
   // Create the describeRequest with all of the request ids to
   // monitor (e.g. that we started).
   DescribeSpotInstanceRequestsRequest describeRequest = new DescribeSpotInstanceRequestsRequest();
   describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);

   // Initialize the anyOpen variable to false, which assumes there
   // are no requests open unless we find one that is still open.
   anyOpen = false;

   try {
         // Retrieve all of the requests we want to monitor.
         DescribeSpotInstanceRequestsResult describeResult =
            ec2.describeSpotInstanceRequests(describeRequest);

         List<SpotInstanceRequest> describeResponses =
            describeResult.getSpotInstanceRequests();

         // Look through each request and determine if they are all
         // in the active state.
         for (SpotInstanceRequest describeResponse : describeResponses) {
           // If the state is open, it hasn't changed since we
           // attempted to request it. There is the potential for
           // it to transition almost immediately to closed or
           // cancelled so we compare against open instead of active.
           if (describeResponse.getState().equals("open")) {
              anyOpen = true; break;
           }
           // Add the instance id to the list we will
           // eventually terminate.
           instanceIds.add(describeResponse.getInstanceId());
         }
   } catch (AmazonServiceException e) {
      // If we have an exception, ensure we don't break out
      // of the loop. This prevents the scenario where there
      // was blip on the wire.
      anyOpen = true;
   }

    try {
        // Sleep for 60 seconds.
        Thread.sleep(60*1000);
    } catch (Exception e) {
        // Do nothing because it woke up early.
    }
} while (anyOpen);
```

Using the instance IDs, stored in the `ArrayList`, terminate any running instances using the following code snippet.

```
try {
    // Terminate instances.
    TerminateInstancesRequest terminateRequest = new TerminateInstancesRequest(instanceIds);
    ec2.terminateInstances(terminateRequest);
} catch (AmazonServiceException e) {
    // Write out any exceptions that may have occurred.
    System.out.println("Error terminating instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

## Bringing It All Together
<a name="tutor-spot-java-bring-together"></a>

To bring this all together, we provide a more object-oriented approach that combines the preceding steps we showed: initializing the EC2 Client, submitting the Spot Request, determining when the Spot Requests are no longer in the open state, and cleaning up any lingering Spot request and associated instances. We create a class called `Requests` that performs these actions.

We also create a `GettingStartedApp` class, which has a main method where we perform the high level function calls. Specifically, we initialize the `Requests` object described previously. We submit the Spot Instance request. Then we wait for the Spot request to reach the "Active" state. Finally, we clean up the requests and instances.

The complete source code for this example can be viewed or downloaded at [GitHub](https://github.com/aws/aws-sdk-java/tree/master/src/samples/AmazonEC2SpotInstances-GettingStarted).

Congratulations\$1 You have just completed the getting started tutorial for developing Spot Instance software with the AWS SDK for Java.

## Next Steps
<a name="tutor-spot-java-next"></a>

Proceed with [Tutorial: Advanced Amazon EC2 Spot Request Management](tutorial-spot-adv-java.md).

# Tutorial: Advanced Amazon EC2 Spot Request Management
<a name="tutorial-spot-adv-java"></a>

 Amazon EC2 Spot Instances allow you to bid on unused Amazon EC2 capacity and run those instances for as long as your bid exceeds the current *spot price*. Amazon EC2 changes the spot price periodically based on supply and demand. For more information about Spot Instances, see [Spot Instances](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) in the Amazon EC2 User Guide for Linux Instances.

## Prerequisites
<a name="tutor-spot-adv-java-prereq"></a>

To use this tutorial you must have the AWS SDK for Java installed, as well as having met its basic installation prerequisites. See [Set up the AWS SDK for Java](setup-install.md) for more information.

## Setting up your credentials
<a name="tutor-spot-adv-java-credentials"></a>

To begin using this code sample, you need to set up AWS credentials. See [Set up AWS Credentials and Region for Development](setup-credentials.md) for instructions on how to do that.

**Note**  
We recommend that you use the credentials of an IAM user to provide these values. For more information, see [Sign Up for AWS and Create an IAM User](signup-create-iam-user.md).

Now that you have configured your settings, you can get started using the code in the example.

## Setting up a security group
<a name="tutor-spot-adv-java-sg"></a>

A security group acts as a firewall that controls the traffic allowed in and out of a group of instances. By default, an instance is started without any security group, which means that all incoming IP traffic, on any TCP port will be denied. So, before submitting our Spot Request, we will set up a security group that allows the necessary network traffic. For the purposes of this tutorial, we will create a new security group called "GettingStarted" that allows Secure Shell (SSH) traffic from the IP address where you are running your application from. To set up a new security group, you need to include or run the following code sample that sets up the security group programmatically.

After we create an `AmazonEC2` client object, we create a `CreateSecurityGroupRequest` object with the name, "GettingStarted" and a description for the security group. Then we call the `ec2.createSecurityGroup` API to create the group.

To enable access to the group, we create an `ipPermission` object with the IP address range set to the CIDR representation of the subnet for the local computer; the "/10" suffix on the IP address indicates the subnet for the specified IP address. We also configure the `ipPermission` object with the TCP protocol and port 22 (SSH). The final step is to call `ec2 .authorizeSecurityGroupIngress` with the name of our security group and the `ipPermission` object.

(The following code is the same as what we used in the first tutorial.)

```
// Create the AmazonEC2Client object so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard()
                    .withCredentials(credentials)
                    .build();

// Create a new security group.
try {
    CreateSecurityGroupRequest securityGroupRequest =
        new CreateSecurityGroupRequest("GettingStartedGroup",
        "Getting Started Security Group");
    ec2.createSecurityGroup(securityGroupRequest);
} catch (AmazonServiceException ase) {
    // Likely this means that the group is already created, so ignore.
    System.out.println(ase.getMessage());
}

String ipAddr = "0.0.0.0/0";

// Get the IP of the current host, so that we can limit the Security Group
// by default to the ip range associated with your subnet.
try {
    // Get IP Address
    InetAddress addr = InetAddress.getLocalHost();
    ipAddr = addr.getHostAddress()+"/10";
}
catch (UnknownHostException e) {
    // Fail here...
}

// Create a range that you would like to populate.
ArrayList<String> ipRanges = new ArrayList<String>();
ipRanges.add(ipAddr);

// Open up port 22 for TCP traffic to the associated IP from
// above (e.g. ssh traffic).
ArrayList<IpPermission> ipPermissions = new ArrayList<IpPermission> ();
IpPermission ipPermission = new IpPermission();
ipPermission.setIpProtocol("tcp");
ipPermission.setFromPort(new Integer(22));
ipPermission.setToPort(new Integer(22));
ipPermission.setIpRanges(ipRanges);
ipPermissions.add(ipPermission);

try {
    // Authorize the ports to the used.
    AuthorizeSecurityGroupIngressRequest ingressRequest =
        new AuthorizeSecurityGroupIngressRequest(
            "GettingStartedGroup",ipPermissions);
    ec2.authorizeSecurityGroupIngress(ingressRequest);
}
catch (AmazonServiceException ase) {
    // Ignore because this likely means the zone has already
    // been authorized.
    System.out.println(ase.getMessage());
}
```

You can view this entire code sample in the `advanced.CreateSecurityGroupApp.java` code sample. Note you only need to run this application once to create a new security group.

**Note**  
You can also create the security group using the AWS Toolkit for Eclipse. See [Managing Security Groups from AWS Cost Explorer](https://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/tke-sg.html) in the AWS Toolkit for Eclipse User Guide for more information.

## Detailed Spot Instance request creation options
<a name="tutor-spot-adv-req-opts"></a>

As we explained in [Tutorial: Amazon EC2 Spot Instances](tutorial-spot-instances-java.md), you need to build your request with an instance type, an Amazon Machine Image (AMI), and maximum bid price.

Let’s start by creating a `RequestSpotInstanceRequest` object. The request object requires the number of instances you want and the bid price. Additionally, we need to set the `LaunchSpecification` for the request, which includes the instance type, AMI ID, and security group you want to use. After the request is populated, we call the `requestSpotInstances` method on the `AmazonEC2Client` object. An example of how to request a Spot Instance follows.

(The following code is the same as what we used in the first tutorial.)

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set up the specifications of the launch. This includes the
// instance type (e.g. t1.micro) and the latest Amazon Linux
// AMI id available. Note, you should always use the latest
// Amazon Linux AMI id or another of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

## Persistent vs. one-time requests
<a name="tutor-spot-adv-persist-v-one"></a>

When building a Spot request, you can specify several optional parameters. The first is whether your request is one-time only or persistent. By default, it is a one-time request. A one-time request can be fulfilled only once, and after the requested instances are terminated, the request will be closed. A persistent request is considered for fulfillment whenever there is no Spot Instance running for the same request. To specify the type of request, you simply need to set the Type on the Spot request. This can be done with the following code.

```
// Retrieves the credentials from an AWSCredentials.properties file.
AWSCredentials credentials = null;
try {
    credentials = new PropertiesCredentials(
        GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties"));
}
catch (IOException e1) {
    System.out.println(
        "Credentials were not properly entered into AwsCredentials.properties.");
    System.out.println(e1.getMessage());
    System.exit(-1);
}

// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest =
    new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set the type of the bid to persistent.
requestRequest.setType("persistent");

// Set up the specifications of the launch. This includes the
// instance type (e.g. t1.micro) and the latest Amazon Linux
// AMI id available. Note, you should always use the latest
// Amazon Linux AMI id or another of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

## Limiting the duration of a request
<a name="tutor-spot-adv-validity-period"></a>

You can also optionally specify the length of time that your request will remain valid. You can specify both a starting and ending time for this period. By default, a Spot request will be considered for fulfillment from the moment it is created until it is either fulfilled or canceled by you. However you can constrain the validity period if you need to. An example of how to specify this period is shown in the following code.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set the valid start time to be two minutes from now.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, 2);
requestRequest.setValidFrom(cal.getTime());

// Set the valid end time to be two minutes and two hours from now.
cal.add(Calendar.HOUR, 2);
requestRequest.setValidUntil(cal.getTime());

// Set up the specifications of the launch. This includes
// the instance type (e.g. t1.micro)

// and the latest Amazon Linux AMI id available.
// Note, you should always use the latest Amazon
// Linux AMI id or another of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType("t1.micro");

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
```

## Grouping your Amazon EC2 Spot Instance requests
<a name="tutor-spot-adv-grouping"></a>

You have the option of grouping your Spot Instance requests in several different ways. We’ll look at the benefits of using launch groups, Availability Zone groups, and placement groups.

If you want to ensure your Spot Instances are all launched and terminated together, then you have the option to leverage a launch group. A launch group is a label that groups a set of bids together. All instances in a launch group are started and terminated together. Note, if instances in a launch group have already been fulfilled, there is no guarantee that new instances launched with the same launch group will also be fulfilled. An example of how to set a Launch Group is shown in the following code example.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 5 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(5));

// Set the launch group.
requestRequest.setLaunchGroup("ADVANCED-DEMO-LAUNCH-GROUP");

// Set up the specifications of the launch. This includes
// the instance type (e.g. t1.micro) and the latest Amazon Linux
// AMI id available. Note, you should always use the latest
// Amazon Linux AMI id or another of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

If you want to ensure that all instances within a request are launched in the same Availability Zone, and you don’t care which one, you can leverage Availability Zone groups. An Availability Zone group is a label that groups a set of instances together in the same Availability Zone. All instances that share an Availability Zone group and are fulfilled at the same time will start in the same Availability Zone. An example of how to set an Availability Zone group follows.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 5 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(5));

// Set the availability zone group.
requestRequest.setAvailabilityZoneGroup("ADVANCED-DEMO-AZ-GROUP");

// Set up the specifications of the launch.  This includes the instance
// type (e.g.  t1.micro) and the latest Amazon Linux AMI id available.
// Note, you should always use the latest Amazon Linux AMI id or another
// of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

You can specify an Availability Zone that you want for your Spot Instances. The following code example shows you how to set an Availability Zone.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set up the specifications of the launch. This includes the instance
// type (e.g. t1.micro) and the latest Amazon Linux AMI id available.
// Note, you should always use the latest Amazon Linux AMI id or another
// of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Set up the availability zone to use. Note we could retrieve the
// availability zones using the ec2.describeAvailabilityZones() API. For
// this demo we will just use us-east-1a.
SpotPlacement placement = new SpotPlacement("us-east-1b");
launchSpecification.setPlacement(placement);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

Lastly, you can specify a *placement group* if you are using High Performance Computing (HPC) Spot Instances, such as cluster compute instances or cluster GPU instances. Placement groups provide you with lower latency and high-bandwidth connectivity between the instances. An example of how to set a placement group follows.

```
// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set up the specifications of the launch. This includes the instance
// type (e.g. t1.micro) and the latest Amazon Linux AMI id available.
// Note, you should always use the latest Amazon Linux AMI id or another
// of your choosing.

LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Set up the placement group to use with whatever name you desire.
// For this demo we will just use "ADVANCED-DEMO-PLACEMENT-GROUP".
SpotPlacement placement = new SpotPlacement();
placement.setGroupName("ADVANCED-DEMO-PLACEMENT-GROUP");
launchSpecification.setPlacement(placement);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

All of the parameters shown in this section are optional. It is also important to realize that most of these parameters—​with the exception of whether your bid is one-time or persistent—​can reduce the likelihood of bid fulfillment. So, it is important to leverage these options only if you need them. All of the preceding code examples are combined into one long code sample, which can be found in the `com.amazonaws.codesamples.advanced.InlineGettingStartedCodeSampleApp.java` class.

## How to persist a root partition after interruption or termination
<a name="tutor-spot-adv-persist-root"></a>

One of the easiest ways to manage interruption of your Spot Instances is to ensure that your data is checkpointed to an Amazon Elastic Block Store (Amazon Amazon EBS) volume on a regular cadence. By checkpointing periodically, if there is an interruption you will lose only the data created since the last checkpoint (assuming no other non-idempotent actions are performed in between). To make this process easier, you can configure your Spot Request to ensure that your root partition will not be deleted on interruption or termination. We’ve inserted new code in the following example that shows how to enable this scenario.

In the added code, we create a `BlockDeviceMapping` object and set its associated Amazon Elastic Block Store (Amazon EBS) to an Amazon EBS object that we’ve configured to `not` be deleted if the Spot Instance is terminated. We then add this `BlockDeviceMapping` to the ArrayList of mappings that we include in the launch specification.

```
// Retrieves the credentials from an AWSCredentials.properties file.
AWSCredentials credentials = null;
try {
    credentials = new PropertiesCredentials(
        GettingStartedApp.class.getResourceAsStream("AwsCredentials.properties"));
}
catch (IOException e1) {
    System.out.println(
        "Credentials were not properly entered into AwsCredentials.properties.");
    System.out.println(e1.getMessage());
    System.exit(-1);
}

// Create the AmazonEC2 client so we can call various APIs.
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

// Initializes a Spot Instance Request
RequestSpotInstancesRequest requestRequest = new RequestSpotInstancesRequest();

// Request 1 x t1.micro instance with a bid price of $0.03.
requestRequest.setSpotPrice("0.03");
requestRequest.setInstanceCount(Integer.valueOf(1));

// Set up the specifications of the launch. This includes the instance
// type (e.g. t1.micro) and the latest Amazon Linux AMI id available.
// Note, you should always use the latest Amazon Linux AMI id or another
// of your choosing.
LaunchSpecification launchSpecification = new LaunchSpecification();
launchSpecification.setImageId("ami-a9d09ed1");
launchSpecification.setInstanceType(InstanceType.T1Micro);

// Add the security group to the request.
ArrayList<String> securityGroups = new ArrayList<String>();
securityGroups.add("GettingStartedGroup");
launchSpecification.setSecurityGroups(securityGroups);

// Create the block device mapping to describe the root partition.
BlockDeviceMapping blockDeviceMapping = new BlockDeviceMapping();
blockDeviceMapping.setDeviceName("/dev/sda1");

// Set the delete on termination flag to false.
EbsBlockDevice ebs = new EbsBlockDevice();
ebs.setDeleteOnTermination(Boolean.FALSE);
blockDeviceMapping.setEbs(ebs);

// Add the block device mapping to the block list.
ArrayList<BlockDeviceMapping> blockList = new ArrayList<BlockDeviceMapping>();
blockList.add(blockDeviceMapping);

// Set the block device mapping configuration in the launch specifications.
launchSpecification.setBlockDeviceMappings(blockList);

// Add the launch specification.
requestRequest.setLaunchSpecification(launchSpecification);

// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult =
    ec2.requestSpotInstances(requestRequest);
```

Assuming you wanted to re-attach this volume to your instance on startup, you can also use the block device mapping settings. Alternatively, if you attached a non-root partition, you can specify the Amazon Amazon EBS volumes you want to attach to your Spot Instance after it resumes. You do this simply by specifying a snapshot ID in your `EbsBlockDevice` and alternative device name in your `BlockDeviceMapping` objects. By leveraging block device mappings, it can be easier to bootstrap your instance.

Using the root partition to checkpoint your critical data is a great way to manage the potential for interruption of your instances. For more methods on managing the potential of interruption, please visit the [Managing Interruption](https://www.youtube.com/watch?feature=player_embedded&v=wcPNnUo60pc) video.

## How to tag your spot requests and instances
<a name="tutor-spot-adv-tags"></a>

Adding tags to Amazon EC2 resources can simplify the administration of your cloud infrastructure. A form of metadata, tags can be used to create user-friendly names, enhance searchability, and improve coordination between multiple users. You can also use tags to automate scripts and portions of your processes. To read more about tagging Amazon EC2 resources, go to [Using Tags](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) in the Amazon EC2 User Guide for Linux Instances.

### Tagging requests
<a name="tagging-requests"></a>

To add tags to your spot requests, you need to tag them *after* they have been requested. The return value from `requestSpotInstances()` provides you with a [RequestSpotInstancesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RequestSpotInstancesResult.html) object that you can use to get the spot request IDs for tagging:

```
// Call the RequestSpotInstance API.
RequestSpotInstancesResult requestResult = ec2.requestSpotInstances(requestRequest);
List<SpotInstanceRequest> requestResponses = requestResult.getSpotInstanceRequests();

// A list of request IDs to tag
ArrayList<String> spotInstanceRequestIds = new ArrayList<String>();

// Add the request ids to the hashset, so we can determine when they hit the
// active state.
for (SpotInstanceRequest requestResponse : requestResponses) {
    System.out.println("Created Spot Request: "+requestResponse.getSpotInstanceRequestId());
    spotInstanceRequestIds.add(requestResponse.getSpotInstanceRequestId());
}
```

Once you have the IDs, you can tag the requests by adding their IDs to a [CreateTagsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateTagsRequest.html) and calling the Amazon EC2 client’s `createTags()` method:

```
// The list of tags to create
ArrayList<Tag> requestTags = new ArrayList<Tag>();
requestTags.add(new Tag("keyname1","value1"));

// Create the tag request
CreateTagsRequest createTagsRequest_requests = new CreateTagsRequest();
createTagsRequest_requests.setResources(spotInstanceRequestIds);
createTagsRequest_requests.setTags(requestTags);

// Tag the spot request
try {
    ec2.createTags(createTagsRequest_requests);
}
catch (AmazonServiceException e) {
    System.out.println("Error terminating instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

### Tagging instances
<a name="tagging-instances"></a>

Similarly to spot requests themselves, you can only tag an instance once it has been created, which will happen once the spot request has been met (it is no longer in the *open* state).

You can check the status of your requests by calling the Amazon EC2 client’s `describeSpotInstanceRequests()` method with a [DescribeSpotInstanceRequestsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeSpotInstanceRequestsRequest.html) object. The returned [DescribeSpotInstanceRequestsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeSpotInstanceRequestsResult.html) object contains a list of [SpotInstanceRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/SpotInstanceRequest.html) objects that you can use to query the status of your spot requests and obtain their instance IDs once they are no longer in the *open* state.

Once the spot request is no longer open, you can retrieve its instance ID from the `SpotInstanceRequest` object by calling its `getInstanceId()` method.

```
boolean anyOpen; // tracks whether any requests are still open

// a list of instances to tag.
ArrayList<String> instanceIds = new ArrayList<String>();

do {
    DescribeSpotInstanceRequestsRequest describeRequest =
        new DescribeSpotInstanceRequestsRequest();
    describeRequest.setSpotInstanceRequestIds(spotInstanceRequestIds);

    anyOpen=false; // assume no requests are still open

    try {
        // Get the requests to monitor
        DescribeSpotInstanceRequestsResult describeResult =
            ec2.describeSpotInstanceRequests(describeRequest);

        List<SpotInstanceRequest> describeResponses =
            describeResult.getSpotInstanceRequests();

        // are any requests open?
        for (SpotInstanceRequest describeResponse : describeResponses) {
                if (describeResponse.getState().equals("open")) {
                    anyOpen = true;
                    break;
                }
                // get the corresponding instance ID of the spot request
                instanceIds.add(describeResponse.getInstanceId());
        }
    }
    catch (AmazonServiceException e) {
        // Don't break the loop due to an exception (it may be a temporary issue)
        anyOpen = true;
    }

    try {
        Thread.sleep(60*1000); // sleep 60s.
    }
    catch (Exception e) {
        // Do nothing if the thread woke up early.
    }
} while (anyOpen);
```

Now you can tag the instances that are returned:

```
// Create a list of tags to create
ArrayList<Tag> instanceTags = new ArrayList<Tag>();
instanceTags.add(new Tag("keyname1","value1"));

// Create the tag request
CreateTagsRequest createTagsRequest_instances = new CreateTagsRequest();
createTagsRequest_instances.setResources(instanceIds);
createTagsRequest_instances.setTags(instanceTags);

// Tag the instance
try {
    ec2.createTags(createTagsRequest_instances);
}
catch (AmazonServiceException e) {
    // Write out any exceptions that may have occurred.
    System.out.println("Error terminating instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

## Canceling spot requests and terminating instances
<a name="canceling-spot-requests-and-terminating-instances"></a>

### Canceling a spot request
<a name="canceling-a-spot-request"></a>

To cancel a Spot Instance request, call `cancelSpotInstanceRequests` on the Amazon EC2 client with a [CancelSpotInstanceRequestsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CancelSpotInstanceRequestsRequest.html) object.

```
try {
    CancelSpotInstanceRequestsRequest cancelRequest = new CancelSpotInstanceRequestsRequest(spotInstanceRequestIds);
    ec2.cancelSpotInstanceRequests(cancelRequest);
} catch (AmazonServiceException e) {
    System.out.println("Error cancelling instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

### Terminating Spot Instances
<a name="terminating-spot-instances"></a>

You can terminate any Spot Instances that are running by passing their IDs to the Amazon EC2 client’s `terminateInstances()` method.

```
try {
    TerminateInstancesRequest terminateRequest = new TerminateInstancesRequest(instanceIds);
    ec2.terminateInstances(terminateRequest);
} catch (AmazonServiceException e) {
    System.out.println("Error terminating instances");
    System.out.println("Caught Exception: " + e.getMessage());
    System.out.println("Reponse Status Code: " + e.getStatusCode());
    System.out.println("Error Code: " + e.getErrorCode());
    System.out.println("Request ID: " + e.getRequestId());
}
```

## Bringing it all together
<a name="tutor-spot-adv-bring-together"></a>

To bring this all together, we provide a more object-oriented approach that combines the steps we showed in this tutorial into one easy to use class. We instantiate a class called `Requests` that performs these actions. We also create a `GettingStartedApp` class, which has a main method where we perform the high level function calls.

The complete source code for this example can be viewed or downloaded at [GitHub](https://github.com/aws/aws-sdk-java/tree/master/src/samples/AmazonEC2SpotInstances-Advanced).

Congratulations\$1 You’ve completed the Advanced Request Features tutorial for developing Spot Instance software with the AWS SDK for Java.

# Managing Amazon EC2 Instances
<a name="examples-ec2-instances"></a>

## Creating an Instance
<a name="creating-an-instance"></a>

Create a new Amazon EC2 instance by calling the AmazonEC2Client’s `runInstances` method, providing it with a [RunInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RunInstancesRequest.html) containing the [Amazon Machine Image (AMI)](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) to use and an [instance type](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html).

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.InstanceType;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.RunInstancesResult;
import com.amazonaws.services.ec2.model.Tag;
```

 **Code** 

```
RunInstancesRequest run_request = new RunInstancesRequest()
    .withImageId(ami_id)
    .withInstanceType(InstanceType.T1Micro)
    .withMaxCount(1)
    .withMinCount(1);

RunInstancesResult run_response = ec2.runInstances(run_request);

String reservation_id = run_response.getReservation().getInstances().get(0).getInstanceId();
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/CreateInstance.java).

## Starting an Instance
<a name="starting-an-instance"></a>

To start an Amazon EC2 instance, call the AmazonEC2Client’s `startInstances` method, providing it with a [StartInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/StartInstancesRequest.html) containing the ID of the instance to start.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.StartInstancesRequest;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

StartInstancesRequest request = new StartInstancesRequest()
    .withInstanceIds(instance_id);

ec2.startInstances(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/StartStopInstance.java).

## Stopping an Instance
<a name="stopping-an-instance"></a>

To stop an Amazon EC2 instance, call the AmazonEC2Client’s `stopInstances` method, providing it with a [StopInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/StopInstancesRequest.html) containing the ID of the instance to stop.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.StopInstancesRequest;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

StopInstancesRequest request = new StopInstancesRequest()
    .withInstanceIds(instance_id);

ec2.stopInstances(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/StartStopInstance.java).

## Rebooting an Instance
<a name="rebooting-an-instance"></a>

To reboot an Amazon EC2 instance, call the AmazonEC2Client’s `rebootInstances` method, providing it with a [RebootInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/RebootInstancesRequest.html) containing the ID of the instance to reboot.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.RebootInstancesRequest;
import com.amazonaws.services.ec2.model.RebootInstancesResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

RebootInstancesRequest request = new RebootInstancesRequest()
    .withInstanceIds(instance_id);

RebootInstancesResult response = ec2.rebootInstances(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/RebootInstance.java).

## Describing Instances
<a name="describing-instances"></a>

To list your instances, create a [DescribeInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeInstancesRequest.html) and call the AmazonEC2Client’s `describeInstances` method. It will return a [DescribeInstancesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeInstancesResult.html) object that you can use to list the Amazon EC2 instances for your account and region.

Instances are grouped by *reservation*. Each reservation corresponds to the call to `startInstances` that launched the instance. To list your instances, you must first call the `DescribeInstancesResult` class' `getReservations' method, and then call `getInstances` on each returned [Reservation](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/Reservation.html) object.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();
boolean done = false;

DescribeInstancesRequest request = new DescribeInstancesRequest();
while(!done) {
    DescribeInstancesResult response = ec2.describeInstances(request);

    for(Reservation reservation : response.getReservations()) {
        for(Instance instance : reservation.getInstances()) {
            System.out.printf(
                "Found instance with id %s, " +
                "AMI %s, " +
                "type %s, " +
                "state %s " +
                "and monitoring state %s",
                instance.getInstanceId(),
                instance.getImageId(),
                instance.getInstanceType(),
                instance.getState().getName(),
                instance.getMonitoring().getState());
        }
    }

    request.setNextToken(response.getNextToken());

    if(response.getNextToken() == null) {
        done = true;
    }
}
```

Results are paged; you can get further results by passing the value returned from the result object’s `getNextToken` method to your original request object’s `setNextToken` method, then using the same request object in your next call to `describeInstances`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeInstances.java).

## Monitoring an Instance
<a name="monitoring-an-instance"></a>

You can monitor various aspects of your Amazon EC2 instances, such as CPU and network utilization, available memory, and disk space remaining. To learn more about instance monitoring, see [Monitoring Amazon EC2](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring_ec2.html) in the Amazon EC2 User Guide for Linux Instances.

To start monitoring an instance, you must create a [MonitorInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/MonitorInstancesRequest.html) with the ID of the instance to monitor, and pass it to the AmazonEC2Client’s `monitorInstances` method.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.MonitorInstancesRequest;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

MonitorInstancesRequest request = new MonitorInstancesRequest()
        .withInstanceIds(instance_id);

ec2.monitorInstances(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/MonitorInstance.java).

## Stopping Instance Monitoring
<a name="stopping-instance-monitoring"></a>

To stop monitoring an instance, create an [UnmonitorInstancesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/UnmonitorInstancesRequest.html) with the ID of the instance to stop monitoring, and pass it to the AmazonEC2Client’s `unmonitorInstances` method.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.UnmonitorInstancesRequest;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

UnmonitorInstancesRequest request = new UnmonitorInstancesRequest()
    .withInstanceIds(instance_id);

ec2.unmonitorInstances(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/MonitorInstance.java).

## More Information
<a name="more-information"></a>
+  [RunInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) in the Amazon EC2 API Reference
+  [DescribeInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html) in the Amazon EC2 API Reference
+  [StartInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StartInstances.html) in the Amazon EC2 API Reference
+  [StopInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StopInstances.html) in the Amazon EC2 API Reference
+  [RebootInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RebootInstances.html) in the Amazon EC2 API Reference
+  [MonitorInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_MonitorInstances.html) in the Amazon EC2 API Reference
+  [UnmonitorInstances](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_UnmonitorInstances.html) in the Amazon EC2 API Reference

# Using Elastic IP Addresses in Amazon EC2
<a name="examples-ec2-elastic-ip"></a>

## EC2-Classic is retiring
<a name="retiringEC2Classic"></a>

**Warning**  
We are retiring EC2-Classic on August 15, 2022. We recommend that you migrate from EC2-Classic to a VPC. For more information, see the blog post [EC2-Classic-Classic Networking is Retiring – Here's How to Prepare](https://aws.amazon.com/blogs/aws/ec2-classic-is-retiring-heres-how-to-prepare/).

## Allocating an Elastic IP Address
<a name="allocating-an-elastic-ip-address"></a>

To use an Elastic IP address, you first allocate one to your account, and then associate it with your instance or a network interface.

To allocate an Elastic IP address, call the AmazonEC2Client’s `allocateAddress` method with an [AllocateAddressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AllocateAddressRequest.html) object containing the network type (classic EC2 or VPC).

The returned [AllocateAddressResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AllocateAddressResult.html) contains an allocation ID that you can use to associate the address with an instance, by passing the allocation ID and instance ID in a [AssociateAddressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AssociateAddressRequest.html) to the AmazonEC2Client’s `associateAddress` method.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.AllocateAddressRequest;
import com.amazonaws.services.ec2.model.AllocateAddressResult;
import com.amazonaws.services.ec2.model.AssociateAddressRequest;
import com.amazonaws.services.ec2.model.AssociateAddressResult;
import com.amazonaws.services.ec2.model.DomainType;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

AllocateAddressRequest allocate_request = new AllocateAddressRequest()
    .withDomain(DomainType.Vpc);

AllocateAddressResult allocate_response =
    ec2.allocateAddress(allocate_request);

String allocation_id = allocate_response.getAllocationId();

AssociateAddressRequest associate_request =
    new AssociateAddressRequest()
        .withInstanceId(instance_id)
        .withAllocationId(allocation_id);

AssociateAddressResult associate_response =
    ec2.associateAddress(associate_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/AllocateAddress.java).

## Describing Elastic IP Addresses
<a name="describing-elastic-ip-addresses"></a>

To list the Elastic IP addresses assigned to your account, call the AmazonEC2Client’s `describeAddresses` method. It returns a [DescribeAddressesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeAddressesResult.html) which you can use to get a list of [Address](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/Address.html) objects that represent the Elastic IP addresses on your account.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.Address;
import com.amazonaws.services.ec2.model.DescribeAddressesResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

DescribeAddressesResult response = ec2.describeAddresses();

for(Address address : response.getAddresses()) {
    System.out.printf(
            "Found address with public IP %s, " +
            "domain %s, " +
            "allocation id %s " +
            "and NIC id %s",
            address.getPublicIp(),
            address.getDomain(),
            address.getAllocationId(),
            address.getNetworkInterfaceId());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeAddresses.java).

## Releasing an Elastic IP Address
<a name="releasing-an-elastic-ip-address"></a>

To release an Elastic IP address, call the AmazonEC2Client’s `releaseAddress` method, passing it a [ReleaseAddressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/ReleaseAddressRequest.html) containing the allocation ID of the Elastic IP address you want to release.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.ReleaseAddressRequest;
import com.amazonaws.services.ec2.model.ReleaseAddressResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

ReleaseAddressRequest request = new ReleaseAddressRequest()
    .withAllocationId(alloc_id);

ReleaseAddressResult response = ec2.releaseAddress(request);
```

After you release an Elastic IP address, it is released to the AWS IP address pool and might be unavailable to you afterward. Be sure to update your DNS records and any servers or devices that communicate with the address. If you attempt to release an Elastic IP address that you already released, you’ll get an *AuthFailure* error if the address is already allocated to another AWS account.

If you are using *EC2-Classic* or a *default VPC*, then releasing an Elastic IP address automatically disassociates it from any instance that it’s associated with. To disassociate an Elastic IP address without releasing it, use the AmazonEC2Client’s `disassociateAddress` method.

If you are using a non-default VPC, you *must* use `disassociateAddress` to disassociate the Elastic IP address before you try to release it. Otherwise, Amazon EC2 returns an error (*InvalidIPAddress.InUse*).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/ReleaseAddress.java).

## More Information
<a name="more-information"></a>
+  [Elastic IP Addresses](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) in the Amazon EC2 User Guide for Linux Instances
+  [AllocateAddress](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AllocateAddress.html) in the Amazon EC2 API Reference
+  [DescribeAddresses](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAddresses.html) in the Amazon EC2 API Reference
+  [ReleaseAddress](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ReleaseAddress.html) in the Amazon EC2 API Reference

# Use regions and availability zones
<a name="examples-ec2-regions-zones"></a>

## Describe regions
<a name="describe-regions"></a>

To list the Regions available to your account, call the AmazonEC2Client’s `describeRegions` method. It returns a [DescribeRegionsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeRegionsResult.html). Call the returned object’s `getRegions` method to get a list of [Region](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/Region.html) objects that represent each Region.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeRegionsResult;
import com.amazonaws.services.ec2.model.Region;
import com.amazonaws.services.ec2.model.AvailabilityZone;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
```

 **Code** 

```
DescribeRegionsResult regions_response = ec2.describeRegions();

for(Region region : regions_response.getRegions()) {
    System.out.printf(
        "Found region %s " +
        "with endpoint %s",
        region.getRegionName(),
        region.getEndpoint());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeRegionsAndZones.java).

## Describe availability zones
<a name="describe-availability-zones"></a>

To list each Availability Zone available to your account, call the AmazonEC2Client’s `describeAvailabilityZones` method. It returns a [DescribeAvailabilityZonesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeAvailabilityZonesResult.html). Call its `getAvailabilityZones` method to get a list of [AvailabilityZone](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AvailabilityZone.html) objects that represent each Availability Zone.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeRegionsResult;
import com.amazonaws.services.ec2.model.Region;
import com.amazonaws.services.ec2.model.AvailabilityZone;
import com.amazonaws.services.ec2.model.DescribeAvailabilityZonesResult;
```

 **Code** 

```
DescribeAvailabilityZonesResult zones_response =
    ec2.describeAvailabilityZones();

for(AvailabilityZone zone : zones_response.getAvailabilityZones()) {
    System.out.printf(
        "Found availability zone %s " +
        "with status %s " +
        "in region %s",
        zone.getZoneName(),
        zone.getState(),
        zone.getRegionName());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeRegionsAndZones.java).

## Describe accounts
<a name="describe-accounts"></a>

To describe your account, call the AmazonEC2Client’s `describeAccountAttributes` method. This method returns a [DescribeAccountAttributesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeAccountAttributesResult.html) object. Invoke this objects `getAccountAttributes` method to get a list of [AccountAttribute](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AccountAttribute.html) objects. You can iterate through the list to retrieve an [AccountAttribute](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AccountAttribute.html) object.

You can get your account’s attribute values by invoking the [AccountAttribute](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AccountAttribute.html) object’s `getAttributeValues` method. This method returns a list of [AccountAttributeValue](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AccountAttributeValue.html) objects. You can iterate through this second list to display the value of attributes (see the following code example).

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.AccountAttributeValue;
import com.amazonaws.services.ec2.model.DescribeAccountAttributesResult;
import com.amazonaws.services.ec2.model.AccountAttribute;
import java.util.List;
import java.util.ListIterator;
```

 **Code** 

```
AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

try{
    DescribeAccountAttributesResult accountResults = ec2.describeAccountAttributes();
    List<AccountAttribute> accountList = accountResults.getAccountAttributes();

    for (ListIterator iter = accountList.listIterator(); iter.hasNext(); ) {

        AccountAttribute attribute = (AccountAttribute) iter.next();
        System.out.print("\n The name of the attribute is "+attribute.getAttributeName());
        List<AccountAttributeValue> values = attribute.getAttributeValues();

         //iterate through the attribute values
        for (ListIterator iterVals = values.listIterator(); iterVals.hasNext(); ) {
            AccountAttributeValue myValue = (AccountAttributeValue) iterVals.next();
            System.out.print("\n The value of the attribute is "+myValue.getAttributeValue());
        }
    }
    System.out.print("Done");
}
catch (Exception e)
{
    e.getStackTrace();
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeAccount.java) on GitHub.

## More information
<a name="more-information"></a>
+  [Regions and Availability Zones](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html) in the Amazon EC2 User Guide for Linux Instances
+  [DescribeRegions](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeRegions.html) in the Amazon EC2 API Reference
+  [DescribeAvailabilityZones](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html) in the Amazon EC2 API Reference

# Working with Amazon EC2 Key Pairs
<a name="examples-ec2-key-pairs"></a>

## Creating a Key Pair
<a name="creating-a-key-pair"></a>

To create a key pair, call the AmazonEC2Client’s `createKeyPair` method with a [CreateKeyPairRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateKeyPairRequest.html) that contains the key’s name.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateKeyPairRequest;
import com.amazonaws.services.ec2.model.CreateKeyPairResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

CreateKeyPairRequest request = new CreateKeyPairRequest()
    .withKeyName(key_name);

CreateKeyPairResult response = ec2.createKeyPair(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/CreateKeyPair.java).

## Describing Key Pairs
<a name="describing-key-pairs"></a>

To list your key pairs or to get information about them, call the AmazonEC2Client’s `describeKeyPairs` method. It returns a [DescribeKeyPairsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeKeyPairsResult.html) that you can use to access the list of key pairs by calling its `getKeyPairs` method, which returns a list of [KeyPairInfo](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/KeyPairInfo.html) objects.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeKeyPairsResult;
import com.amazonaws.services.ec2.model.KeyPairInfo;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

DescribeKeyPairsResult response = ec2.describeKeyPairs();

for(KeyPairInfo key_pair : response.getKeyPairs()) {
    System.out.printf(
        "Found key pair with name %s " +
        "and fingerprint %s",
        key_pair.getKeyName(),
        key_pair.getKeyFingerprint());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeKeyPairs.java).

## Deleting a Key Pair
<a name="deleting-a-key-pair"></a>

To delete a key pair, call the AmazonEC2Client’s `deleteKeyPair` method, passing it a [DeleteKeyPairRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DeleteKeyPairRequest.html) that contains the name of the key pair to delete.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DeleteKeyPairRequest;
import com.amazonaws.services.ec2.model.DeleteKeyPairResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

DeleteKeyPairRequest request = new DeleteKeyPairRequest()
    .withKeyName(key_name);

DeleteKeyPairResult response = ec2.deleteKeyPair(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DeleteKeyPair.java).

## More Information
<a name="more-information"></a>
+  [Amazon EC2 Key Pairs](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide for Linux Instances
+  [CreateKeyPair](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateKeyPair.html) in the Amazon EC2 API Reference
+  [DescribeKeyPairs](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeKeyPairs.html) in the Amazon EC2 API Reference
+  [DeleteKeyPair](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteKeyPair.html) in the Amazon EC2 API Reference

# Working with Security Groups in Amazon EC2
<a name="examples-ec2-security-groups"></a>

## Creating a Security Group
<a name="creating-a-security-group"></a>

To create a security group, call the AmazonEC2Client’s `createSecurityGroup` method with a [CreateSecurityGroupRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/CreateSecurityGroupRequest.html) that contains the key’s name.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

CreateSecurityGroupRequest create_request = new
    CreateSecurityGroupRequest()
        .withGroupName(group_name)
        .withDescription(group_desc)
        .withVpcId(vpc_id);

CreateSecurityGroupResult create_response =
    ec2.createSecurityGroup(create_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/CreateSecurityGroup.java).

## Configuring a Security Group
<a name="configuring-a-security-group"></a>

A security group can control both inbound (ingress) and outbound (egress) traffic to your Amazon EC2 instances.

To add ingress rules to your security group, use the AmazonEC2Client’s `authorizeSecurityGroupIngress` method, providing the name of the security group and the access rules ([IpPermission](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/IpPermission.html)) you want to assign to it within an [AuthorizeSecurityGroupIngressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AuthorizeSecurityGroupIngressRequest.html) object. The following example shows how to add IP permissions to a security group.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest;
import com.amazonaws.services.ec2.model.CreateSecurityGroupResult;
```

 **Code** 

```
IpRange ip_range = new IpRange()
    .withCidrIp("0.0.0.0/0");

IpPermission ip_perm = new IpPermission()
    .withIpProtocol("tcp")
    .withToPort(80)
    .withFromPort(80)
    .withIpv4Ranges(ip_range);

IpPermission ip_perm2 = new IpPermission()
    .withIpProtocol("tcp")
    .withToPort(22)
    .withFromPort(22)
    .withIpv4Ranges(ip_range);

AuthorizeSecurityGroupIngressRequest auth_request = new
    AuthorizeSecurityGroupIngressRequest()
        .withGroupName(group_name)
        .withIpPermissions(ip_perm, ip_perm2);

AuthorizeSecurityGroupIngressResult auth_response =
    ec2.authorizeSecurityGroupIngress(auth_request);
```

To add an egress rule to the security group, provide similar data in an [AuthorizeSecurityGroupEgressRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/AuthorizeSecurityGroupEgressRequest.html) to the AmazonEC2Client’s `authorizeSecurityGroupEgress` method.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/CreateSecurityGroup.java).

## Describing Security Groups
<a name="describing-security-groups"></a>

To describe your security groups or get information about them, call the AmazonEC2Client’s `describeSecurityGroups` method. It returns a [DescribeSecurityGroupsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DescribeSecurityGroupsResult.html) that you can use to access the list of security groups by calling its `getSecurityGroups` method, which returns a list of [SecurityGroup](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/ec2/model/SecurityGroup.html) objects.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest;
import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult;
```

 **Code** 

```
final String USAGE =
    "To run this example, supply a group id\n" +
    "Ex: DescribeSecurityGroups <group-id>\n";

if (args.length != 1) {
    System.out.println(USAGE);
    System.exit(1);
}

String group_id = args[0];
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DescribeSecurityGroups.java).

## Deleting a Security Group
<a name="deleting-a-security-group"></a>

To delete a security group, call the AmazonEC2Client’s `deleteSecurityGroup` method, passing it a [DeleteSecurityGroupRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/ec2/model/DeleteSecurityGroupRequest.html) that contains the ID of the security group to delete.

 **Imports** 

```
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
import com.amazonaws.services.ec2.model.DeleteSecurityGroupRequest;
import com.amazonaws.services.ec2.model.DeleteSecurityGroupResult;
```

 **Code** 

```
final AmazonEC2 ec2 = AmazonEC2ClientBuilder.defaultClient();

DeleteSecurityGroupRequest request = new DeleteSecurityGroupRequest()
    .withGroupId(group_id);

DeleteSecurityGroupResult response = ec2.deleteSecurityGroup(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/ec2/src/main/java/aws/example/ec2/DeleteSecurityGroup.java).

## More Information
<a name="more-information"></a>
+  [Amazon EC2 Security Groups](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in the Amazon EC2 User Guide for Linux Instances
+  [Authorizing Inbound Traffic for Your Linux Instances](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html) in the Amazon EC2 User Guide for Linux Instances
+  [CreateSecurityGroup](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateSecurityGroup.html) in the Amazon EC2 API Reference
+  [DescribeSecurityGroups](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html) in the Amazon EC2 API Reference
+  [DeleteSecurityGroup](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteSecurityGroup.html) in the Amazon EC2 API Reference
+  [AuthorizeSecurityGroupIngress](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html) in the Amazon EC2 API Reference

# IAM Examples Using the AWS SDK for Java
<a name="examples-iam"></a>

This section provides examples of programming [IAM](https://aws.amazon.com/iam/) by using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

 AWS Identity and Access Management (IAM) enables you to securely control access to AWS services and resources for your users. Using IAM, you can create and manage AWS users and groups, and use permissions to allow and deny their access to AWS resources. For a complete guide to IAM, visit the [IAM User Guide](http://docs.aws.amazon.com/IAM/latest/UserGuide/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Managing IAM Access Keys](examples-iam-access-keys.md)
+ [Managing IAM Users](examples-iam-users.md)
+ [Using IAM Account Aliases](examples-iam-account-aliases.md)
+ [Working with IAM Policies](examples-iam-policies.md)
+ [Working with IAM Server Certificates](examples-iam-server-certificates.md)

# Managing IAM Access Keys
<a name="examples-iam-access-keys"></a>

## Creating an Access Key
<a name="creating-an-access-key"></a>

To create an IAM access key, call the AmazonIdentityManagementClient`createAccessKey` method with an [CreateAccessKeyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/CreateAccessKeyRequest.html) object.

 `CreateAccessKeyRequest` has two constructors — one that takes a user name and another with no parameters. If you use the version that takes no parameters, you must set the user name using the `withUserName` setter method before passing it to the `createAccessKey` method.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.CreateAccessKeyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

CreateAccessKeyRequest request = new CreateAccessKeyRequest()
    .withUserName(user);

CreateAccessKeyResult response = iam.createAccessKey(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/CreateAccessKey.java) on GitHub.

## Listing Access Keys
<a name="listing-access-keys"></a>

To list the access keys for a given user, create a [ListAccessKeysRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListAccessKeysRequest.html) object that contains the user name to list keys for, and pass it to the AmazonIdentityManagementClient’s `listAccessKeys` method.

**Note**  
If you do not supply a user name to `listAccessKeys`, it will attempt to list access keys associated with the AWS account that signed the request.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.AccessKeyMetadata;
import com.amazonaws.services.identitymanagement.model.ListAccessKeysRequest;
import com.amazonaws.services.identitymanagement.model.ListAccessKeysResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

boolean done = false;
ListAccessKeysRequest request = new ListAccessKeysRequest()
        .withUserName(username);

while (!done) {

    ListAccessKeysResult response = iam.listAccessKeys(request);

    for (AccessKeyMetadata metadata :
            response.getAccessKeyMetadata()) {
        System.out.format("Retrieved access key %s",
                metadata.getAccessKeyId());
    }

    request.setMarker(response.getMarker());

    if (!response.getIsTruncated()) {
        done = true;
    }
}
```

The results of `listAccessKeys` are paged (with a default maximum of 100 records per call). You can call `getIsTruncated` on the returned [ListAccessKeysResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListAccessKeysResult.html) object to see if the query returned fewer results then are available. If so, then call `setMarker` on the `ListAccessKeysRequest` and pass it back to the next invocation of `listAccessKeys`.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/ListAccessKeys.java) on GitHub.

## Retrieving an Access Key’s Last Used Time
<a name="retrieving-an-access-key-s-last-used-time"></a>

To get the time an access key was last used, call the AmazonIdentityManagementClient’s `getAccessKeyLastUsed` method with the access key’s ID (which can be passed in using a [GetAccessKeyLastUsedRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/GetAccessKeyLastUsedRequest.html) object, or directly to the overload that takes the access key ID directly.

You can then use the returned [GetAccessKeyLastUsedResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/GetAccessKeyLastUsedResult.html) object to retrieve the key’s last used time.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetAccessKeyLastUsedRequest;
import com.amazonaws.services.identitymanagement.model.GetAccessKeyLastUsedResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

GetAccessKeyLastUsedRequest request = new GetAccessKeyLastUsedRequest()
    .withAccessKeyId(access_id);

GetAccessKeyLastUsedResult response = iam.getAccessKeyLastUsed(request);

System.out.println("Access key was last used at: " +
        response.getAccessKeyLastUsed().getLastUsedDate());
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/AccessKeyLastUsed.java) on GitHub.

## Activating or Deactivating Access Keys
<a name="iam-access-keys-update"></a>

You can activate or deactivate an access key by creating an [UpdateAccessKeyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/UpdateAccessKeyRequest.html) object, providing the access key ID, optionally the user name, and the desired [Status](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/StatusType.html), then passing the request object to the AmazonIdentityManagementClient’s `updateAccessKey` method.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.UpdateAccessKeyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

UpdateAccessKeyRequest request = new UpdateAccessKeyRequest()
    .withAccessKeyId(access_id)
    .withUserName(username)
    .withStatus(status);

UpdateAccessKeyResult response = iam.updateAccessKey(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/UpdateAccessKey.java) on GitHub.

## Deleting an Access Key
<a name="deleting-an-access-key"></a>

To permanently delete an access key, call the AmazonIdentityManagementClient’s `deleteKey` method, providing it with a [DeleteAccessKeyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/DeleteAccessKeyRequest.html) containing the access key’s ID and username.

**Note**  
Once deleted, a key can no longer be retrieved or used. To temporarily deactivate a key so that it can be activated again later, use [updateAccessKey](#iam-access-keys-update) method instead.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteAccessKeyRequest;
import com.amazonaws.services.identitymanagement.model.DeleteAccessKeyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

DeleteAccessKeyRequest request = new DeleteAccessKeyRequest()
    .withAccessKeyId(access_key)
    .withUserName(username);

DeleteAccessKeyResult response = iam.deleteAccessKey(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/DeleteAccessKey.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [CreateAccessKey](http://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccessKey.html) in the IAM API Reference
+  [ListAccessKeys](http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAccessKeys.html) in the IAM API Reference
+  [GetAccessKeyLastUsed](http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccessKeyLastUsed.html) in the IAM API Reference
+  [UpdateAccessKey](http://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateAccessKey.html) in the IAM API Reference
+  [DeleteAccessKey](http://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteAccessKey.html) in the IAM API Reference

# Managing IAM Users
<a name="examples-iam-users"></a>

## Creating a User
<a name="creating-a-user"></a>

Create a new IAM user by providing the user name to the AmazonIdentityManagementClient’s `createUser` method, either directly or using a [CreateUserRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/CreateUserRequest.html) object containing the user name.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateUserRequest;
import com.amazonaws.services.identitymanagement.model.CreateUserResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

CreateUserRequest request = new CreateUserRequest()
    .withUserName(username);

CreateUserResult response = iam.createUser(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/CreateUser.java) on GitHub.

## Listing Users
<a name="listing-users"></a>

To list the IAM users for your account, create a new [ListUsersRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListUsersRequest.html) and pass it to the AmazonIdentityManagementClient’s `listUsers` method. You can retrieve the list of users by calling `getUsers` on the returned [ListUsersResult](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/identitymanagement/model/ListUsersResult.html) object.

The list of users returned by `listUsers` is paged. You can check to see there are more results to retrieve by calling the response object’s `getIsTruncated` method. If it returns `true`, then call the request object’s `setMarker()` method, passing it the return value of the response object’s `getMarker()` method.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListUsersRequest;
import com.amazonaws.services.identitymanagement.model.ListUsersResult;
import com.amazonaws.services.identitymanagement.model.User;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

boolean done = false;
ListUsersRequest request = new ListUsersRequest();

while(!done) {
    ListUsersResult response = iam.listUsers(request);

    for(User user : response.getUsers()) {
        System.out.format("Retrieved user %s", user.getUserName());
    }

    request.setMarker(response.getMarker());

    if(!response.getIsTruncated()) {
        done = true;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/ListUsers.java) on GitHub.

## Updating a User
<a name="updating-a-user"></a>

To update a user, call the AmazonIdentityManagementClient object’s `updateUser` method, which takes a [UpdateUserRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/UpdateUserRequest.html) object that you can use to change the user’s *name* or *path*.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateUserRequest;
import com.amazonaws.services.identitymanagement.model.UpdateUserResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

UpdateUserRequest request = new UpdateUserRequest()
    .withUserName(cur_name)
    .withNewUserName(new_name);

UpdateUserResult response = iam.updateUser(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/UpdateUser.java) on GitHub.

## Deleting a User
<a name="deleting-a-user"></a>

To delete a user, call the AmazonIdentityManagementClient’s `deleteUser` request with a [UpdateUserRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/UpdateUserRequest.html) object set with the user name to delete.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteConflictException;
import com.amazonaws.services.identitymanagement.model.DeleteUserRequest;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

DeleteUserRequest request = new DeleteUserRequest()
    .withUserName(username);

try {
    iam.deleteUser(request);
} catch (DeleteConflictException e) {
    System.out.println("Unable to delete user. Verify user is not" +
            " associated with any resources");
    throw e;
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/DeleteUser.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [IAM Users](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) in the IAM User Guide
+  [Managing IAM Users](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html) in the IAM User Guide
+  [CreateUser](http://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateUser.html) in the IAM API Reference
+  [ListUsers](http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListUsers.html) in the IAM API Reference
+  [UpdateUser](http://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateUser.html) in the IAM API Reference
+  [DeleteUser](http://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteUser.html) in the IAM API Reference

# Using IAM Account Aliases
<a name="examples-iam-account-aliases"></a>

If you want the URL for your sign-in page to contain your company name or other friendly identifier instead of your AWS account ID, you can create an alias for your AWS account.

**Note**  
 AWS supports exactly one account alias per account.

## Creating an Account Alias
<a name="creating-an-account-alias"></a>

To create an account alias, call the AmazonIdentityManagementClient’s `createAccountAlias` method with a [CreateAccountAliasRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/CreateAccountAliasRequest.html) object that contains the alias name.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreateAccountAliasRequest;
import com.amazonaws.services.identitymanagement.model.CreateAccountAliasResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

CreateAccountAliasRequest request = new CreateAccountAliasRequest()
    .withAccountAlias(alias);

CreateAccountAliasResult response = iam.createAccountAlias(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/CreateAccountAlias.java) on GitHub.

## Listing Account Aliases
<a name="listing-account-aliases"></a>

To list your account’s alias, if any, call the AmazonIdentityManagementClient’s `listAccountAliases` method.

**Note**  
The returned [ListAccountAliasesResult](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/identitymanagement/model/ListAccountAliasesResult.html) supports the same `getIsTruncated` and `getMarker` methods as other AWS SDK for Java *list* methods, but an AWS account can have only *one* account alias.

 **imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListAccountAliasesResult;
```

 **code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

ListAccountAliasesResult response = iam.listAccountAliases();

for (String alias : response.getAccountAliases()) {
    System.out.printf("Retrieved account alias %s", alias);
}
```

see the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/ListAccountAliases.java) on GitHub.

## Deleting an account alias
<a name="deleting-an-account-alias"></a>

To delete your account’s alias, call the AmazonIdentityManagementClient’s `deleteAccountAlias` method. When deleting an account alias, you must supply its name using a [DeleteAccountAliasRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/DeleteAccountAliasRequest.html) object.

 **imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteAccountAliasRequest;
import com.amazonaws.services.identitymanagement.model.DeleteAccountAliasResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

DeleteAccountAliasRequest request = new DeleteAccountAliasRequest()
    .withAccountAlias(alias);

DeleteAccountAliasResult response = iam.deleteAccountAlias(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/DeleteAccountAlias.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Your AWS Account ID and Its Alias](http://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html) in the IAM User Guide
+  [CreateAccountAlias](http://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccountAlias.html) in the IAM API Reference
+  [ListAccountAliases](http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAccountAliases.html) in the IAM API Reference
+  [DeleteAccountAlias](http://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteAccountAlias.html) in the IAM API Reference

# Working with IAM Policies
<a name="examples-iam-policies"></a>

## Creating a Policy
<a name="creating-a-policy"></a>

To create a new policy, provide the policy’s name and a JSON-formatted policy document in a [CreatePolicyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/CreatePolicyRequest.html) to the AmazonIdentityManagementClient’s `createPolicy` method.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.CreatePolicyRequest;
import com.amazonaws.services.identitymanagement.model.CreatePolicyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

CreatePolicyRequest request = new CreatePolicyRequest()
    .withPolicyName(policy_name)
    .withPolicyDocument(POLICY_DOCUMENT);

CreatePolicyResult response = iam.createPolicy(request);
```

IAM policy documents are JSON strings with a [well-documented syntax](http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_grammar.html). Here is an example that provides access to make particular requests to DynamoDB.

```
public static final String POLICY_DOCUMENT =
    "{" +
    "  \"Version\": \"2012-10-17\",		 	 	 " +
    "  \"Statement\": [" +
    "    {" +
    "        \"Effect\": \"Allow\"," +
    "        \"Action\": \"logs:CreateLogGroup\"," +
    "        \"Resource\": \"%s\"" +
    "    }," +
    "    {" +
    "        \"Effect\": \"Allow\"," +
    "        \"Action\": [" +
    "            \"dynamodb:DeleteItem\"," +
    "            \"dynamodb:GetItem\"," +
    "            \"dynamodb:PutItem\"," +
    "            \"dynamodb:Scan\"," +
    "            \"dynamodb:UpdateItem\"" +
    "       ]," +
    "       \"Resource\": \"RESOURCE_ARN\"" +
    "    }" +
    "   ]" +
    "}";
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/CreatePolicy.java) on GitHub.

## Getting a Policy
<a name="getting-a-policy"></a>

To retrieve an existing policy, call the AmazonIdentityManagementClient’s `getPolicy` method, providing the policy’s ARN within a [GetPolicyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/GetPolicyRequest.html) object.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetPolicyRequest;
import com.amazonaws.services.identitymanagement.model.GetPolicyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

GetPolicyRequest request = new GetPolicyRequest()
    .withPolicyArn(policy_arn);

GetPolicyResult response = iam.getPolicy(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/GetPolicy.java) on GitHub.

## Attaching a Role Policy
<a name="attaching-a-role-policy"></a>

You can attach a policy to an IAMhttp://docs.aws.amazon.com/IAM/latest/UserGuide/id\$1roles.html[role] by calling the AmazonIdentityManagementClient’s `attachRolePolicy` method, providing it with the role name and policy ARN in an [AttachRolePolicyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/AttachRolePolicyRequest.html).

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.AttachRolePolicyRequest;
import com.amazonaws.services.identitymanagement.model.AttachedPolicy;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

AttachRolePolicyRequest attach_request =
    new AttachRolePolicyRequest()
        .withRoleName(role_name)
        .withPolicyArn(POLICY_ARN);

iam.attachRolePolicy(attach_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/AttachRolePolicy.java) on GitHub.

## Listing Attached Role Policies
<a name="listing-attached-role-policies"></a>

List attached policies on a role by calling the AmazonIdentityManagementClient’s `listAttachedRolePolicies` method. It takes a [ListAttachedRolePoliciesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListAttachedRolePoliciesRequest.html) object that contains the role name to list the policies for.

Call `getAttachedPolicies` on the returned [ListAttachedRolePoliciesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListAttachedRolePoliciesResult.html) object to get the list of attached policies. Results may be truncated; if the `ListAttachedRolePoliciesResult` object’s `getIsTruncated` method returns `true`, call the `ListAttachedRolePoliciesRequest` object’s `setMarker` method and use it to call `listAttachedRolePolicies` again to get the next batch of results.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListAttachedRolePoliciesRequest;
import com.amazonaws.services.identitymanagement.model.ListAttachedRolePoliciesResult;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

ListAttachedRolePoliciesRequest request =
    new ListAttachedRolePoliciesRequest()
        .withRoleName(role_name);

List<AttachedPolicy> matching_policies = new ArrayList<>();

boolean done = false;

while(!done) {
    ListAttachedRolePoliciesResult response =
        iam.listAttachedRolePolicies(request);

    matching_policies.addAll(
            response.getAttachedPolicies()
                    .stream()
                    .filter(p -> p.getPolicyName().equals(role_name))
                    .collect(Collectors.toList()));

    if(!response.getIsTruncated()) {
        done = true;
    }
    request.setMarker(response.getMarker());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/AttachRolePolicy.java) on GitHub.

## Detaching a Role Policy
<a name="detaching-a-role-policy"></a>

To detach a policy from a role, call the AmazonIdentityManagementClient’s `detachRolePolicy` method, providing it with the role name and policy ARN in a [DetachRolePolicyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/DetachRolePolicyRequest.html).

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DetachRolePolicyRequest;
import com.amazonaws.services.identitymanagement.model.DetachRolePolicyResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

DetachRolePolicyRequest request = new DetachRolePolicyRequest()
    .withRoleName(role_name)
    .withPolicyArn(policy_arn);

DetachRolePolicyResult response = iam.detachRolePolicy(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/DetachRolePolicy.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Overview of IAM Policies](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) in the IAM User Guide.
+  [AWS IAM Policy Reference](http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) in the IAM User Guide.
+  [CreatePolicy](http://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html) in the IAM API Reference
+  [GetPolicy](http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicy.html) in the IAM API Reference
+  [AttachRolePolicy](http://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html) in the IAM API Reference
+  [ListAttachedRolePolicies](http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAttachedRolePolicies.html) in the IAM API Reference
+  [DetachRolePolicy](http://docs.aws.amazon.com/IAM/latest/APIReference/API_DetachRolePolicy.html) in the IAM API Reference

# Working with IAM Server Certificates
<a name="examples-iam-server-certificates"></a>

To enable HTTPS connections to your website or application on AWS, you need an SSL/TLS *server certificate*. You can use a server certificate provided by AWS Certificate Manager or one that you obtained from an external provider.

We recommend that you use ACM to provision, manage, and deploy your server certificates. With ACM you can request a certificate, deploy it to your AWS resources, and let ACM handle certificate renewals for you. Certificates provided by ACM are free. For more information about ACM , see the [ACM User Guide](https://docs.aws.amazon.com/acm/latest/userguide/).

## Getting a Server Certificate
<a name="getting-a-server-certificate"></a>

You can retrieve a server certificate by calling the AmazonIdentityManagementClient’s `getServerCertificate` method, passing it a [GetServerCertificateRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/GetServerCertificateRequest.html) with the certificate’s name.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.GetServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.GetServerCertificateResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

GetServerCertificateRequest request = new GetServerCertificateRequest()
            .withServerCertificateName(cert_name);

GetServerCertificateResult response = iam.getServerCertificate(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/GetServerCertificate.java) on GitHub.

## Listing Server Certificates
<a name="listing-server-certificates"></a>

To list your server certificates, call the AmazonIdentityManagementClient’s `listServerCertificates` method with a [ListServerCertificatesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListServerCertificatesRequest.html). It returns a [ListServerCertificatesResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ListServerCertificatesResult.html).

Call the returned `ListServerCertificateResult` object’s `getServerCertificateMetadataList` method to get a list of [ServerCertificateMetadata](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/ServerCertificateMetadata.html) objects that you can use to get information about each certificate.

Results may be truncated; if the `ListServerCertificateResult` object’s `getIsTruncated` method returns `true`, call the `ListServerCertificatesRequest` object’s `setMarker` method and use it to call `listServerCertificates` again to get the next batch of results.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.ListServerCertificatesRequest;
import com.amazonaws.services.identitymanagement.model.ListServerCertificatesResult;
import com.amazonaws.services.identitymanagement.model.ServerCertificateMetadata;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

boolean done = false;
ListServerCertificatesRequest request =
        new ListServerCertificatesRequest();

while(!done) {

    ListServerCertificatesResult response =
        iam.listServerCertificates(request);

    for(ServerCertificateMetadata metadata :
            response.getServerCertificateMetadataList()) {
        System.out.printf("Retrieved server certificate %s",
                metadata.getServerCertificateName());
    }

    request.setMarker(response.getMarker());

    if(!response.getIsTruncated()) {
        done = true;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/ListServerCertificates.java) on GitHub.

## Updating a Server Certificate
<a name="updating-a-server-certificate"></a>

You can update a server certificate’s name or path by calling the AmazonIdentityManagementClient’s `updateServerCertificate` method. It takes a [UpdateServerCertificateRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/UpdateServerCertificateRequest.html) object set with the server certificate’s current name and either a new name or new path to use.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.UpdateServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.UpdateServerCertificateResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

UpdateServerCertificateRequest request =
    new UpdateServerCertificateRequest()
        .withServerCertificateName(cur_name)
        .withNewServerCertificateName(new_name);

UpdateServerCertificateResult response =
    iam.updateServerCertificate(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/UpdateServerCertificate.java) on GitHub.

## Deleting a Server Certificate
<a name="deleting-a-server-certificate"></a>

To delete a server certificate, call the AmazonIdentityManagementClient’s `deleteServerCertificate` method with a [DeleteServerCertificateRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/identitymanagement/model/DeleteServerCertificateRequest.html) containing the certificate’s name.

 **Imports** 

```
import com.amazonaws.services.identitymanagement.AmazonIdentityManagement;
import com.amazonaws.services.identitymanagement.AmazonIdentityManagementClientBuilder;
import com.amazonaws.services.identitymanagement.model.DeleteServerCertificateRequest;
import com.amazonaws.services.identitymanagement.model.DeleteServerCertificateResult;
```

 **Code** 

```
final AmazonIdentityManagement iam =
    AmazonIdentityManagementClientBuilder.defaultClient();

DeleteServerCertificateRequest request =
    new DeleteServerCertificateRequest()
        .withServerCertificateName(cert_name);

DeleteServerCertificateResult response =
    iam.deleteServerCertificate(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/iam/src/main/java/aws/example/iam/DeleteServerCertificate.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Working with Server Certificates](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html) in the IAM User Guide
+  [GetServerCertificate](http://docs.aws.amazon.com/IAM/latest/APIReference/API_GetServerCertificate.html) in the IAM API Reference
+  [ListServerCertificates](http://docs.aws.amazon.com/IAM/latest/APIReference/API_ListServerCertificates.html) in the IAM API Reference
+  [UpdateServerCertificate](http://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateServerCertificate.html) in the IAM API Reference
+  [DeleteServerCertificate](http://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteServerCertificate.html) in the IAM API Reference
+  [ACM User Guide](https://docs.aws.amazon.com/acm/latest/userguide/) 

# Lambda Examples Using the AWS SDK for Java
<a name="lambda-examples"></a>

This section provides examples of programming Lambda using the AWS SDK for Java.

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Service operations](examples-lambda.md)

# Invoking, Listing, and Deleting Lambda Functions
<a name="examples-lambda"></a>

This section provides examples of programming with the Lambda service client by using the AWS SDK for Java. To learn how to create a Lambda function, see [How to Create AWS Lambda functions](https://docs.aws.amazon.com/toolkit-for-eclipse/v1/user-guide/lambda-tutorial.html).

**Topics**
+ [Invoke a function](#invoke-function)
+ [List functions](#list-function)
+ [Delete a function](#delete-function)

## Invoke a function
<a name="invoke-function"></a>

You can invoke a Lambda function by creating an [AWSLambda](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambda.html) object and invoking its `invoke` method. Create an [InvokeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/InvokeRequest.html) object to specify additional information such as the function name and the payload to pass to the Lambda function. Function names appear as *arn:aws:lambda:us-east-1:555556330391:function:HelloFunction*. You can retrieve the value by looking at the function in the AWS Management Console.

To pass payload data to a function, invoke the [InvokeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/InvokeRequest.html) object’s `withPayload` method and specify a String in JSON format, as shown in the following code example.

 **Imports** 

```
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;
import com.amazonaws.services.lambda.model.ServiceException;

import java.nio.charset.StandardCharsets;
```

 **Code** 

The following code example demonstrates how to invoke a Lambda function.

```
        String functionName = args[0];

        InvokeRequest invokeRequest = new InvokeRequest()
                .withFunctionName(functionName)
                .withPayload("{\n" +
                        " \"Hello \": \"Paris\",\n" +
                        " \"countryCode\": \"FR\"\n" +
                        "}");
        InvokeResult invokeResult = null;

        try {
            AWSLambda awsLambda = AWSLambdaClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(Regions.US_WEST_2).build();

            invokeResult = awsLambda.invoke(invokeRequest);

            String ans = new String(invokeResult.getPayload().array(), StandardCharsets.UTF_8);

            //write out the return value
            System.out.println(ans);

        } catch (ServiceException e) {
            System.out.println(e);
        }

        System.out.println(invokeResult.getStatusCode());
```

See the complete example on [Github](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/lambda/src/main/java/com/example/lambda/LambdaInvokeFunction.java).

## List functions
<a name="list-function"></a>

Build an [AWSLambda](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambda.html) object and invoke its `listFunctions` method. This method returns a [ListFunctionsResult](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/ListFunctionsResult.html) object. You can invoke this object’s `getFunctions` method to return a list of [FunctionConfiguration](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/FunctionConfiguration.html) objects. You can iterate through the list to retrieve information about the functions. For example, the following Java code example shows how to get each function name.

 **Imports** 

```
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
import com.amazonaws.services.lambda.model.FunctionConfiguration;
import com.amazonaws.services.lambda.model.ListFunctionsResult;
import com.amazonaws.services.lambda.model.ServiceException;
import java.util.Iterator;
import java.util.List;
```

 **Code** 

The following Java code example demonstrates how to retrieve a list of Lambda function names.

```
        ListFunctionsResult functionResult = null;

        try {
            AWSLambda awsLambda = AWSLambdaClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(Regions.US_WEST_2).build();

            functionResult = awsLambda.listFunctions();

            List<FunctionConfiguration> list = functionResult.getFunctions();

            for (Iterator iter = list.iterator(); iter.hasNext(); ) {
                FunctionConfiguration config = (FunctionConfiguration)iter.next();

                System.out.println("The function name is "+config.getFunctionName());
            }

        } catch (ServiceException e) {
            System.out.println(e);
        }
```

See the complete example on [Github](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/lambda/src/main/java/com/example/lambda/ListFunctions.java).

## Delete a function
<a name="delete-function"></a>

Build an [AWSLambda](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambda.html) object and invoke its `deleteFunction` method. Create a [DeleteFunctionRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/model/DeleteFunctionRequest.html) object and pass it to the `deleteFunction` method. This object contains information such as the name of the function to delete. Function names appear as *arn:aws:lambda:us-east-1:555556330391:function:HelloFunction*. You can retrieve the value by looking at the function in the AWS Management Console.

 **Imports** 

```
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
import com.amazonaws.services.lambda.model.ServiceException;
import com.amazonaws.services.lambda.model.DeleteFunctionRequest;
```

 **Code** 

The following Java code demonstrates how to delete a Lambda function.

```
        String functionName = args[0];
        try {
            AWSLambda awsLambda = AWSLambdaClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(Regions.US_WEST_2).build();

            DeleteFunctionRequest delFunc = new DeleteFunctionRequest();
            delFunc.withFunctionName(functionName);

            //Delete the function
            awsLambda.deleteFunction(delFunc);
            System.out.println("The function is deleted");

        } catch (ServiceException e) {
            System.out.println(e);
        }
```

See the complete example on [Github](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/lambda/src/main/java/com/example/lambda/DeleteFunction.java).

# Amazon Pinpoint Examples Using the AWS SDK for Java
<a name="examples-pinpoint"></a>

This section provides examples of programming [Amazon Pinpoint](https://aws.amazon.com/pinpoint/) using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Creating and Deleting Apps in Amazon Pinpoint](examples-pinpoint-create-app.md)
+ [Creating Endpoints in Amazon Pinpoint](examples-pinpoint-create-endpoint.md)
+ [Creating Segments in Amazon Pinpoint](examples-pinpoint-create-segment.md)
+ [Creating Campaigns in Amazon Pinpoint](examples-pinpoint-create-campaign.md)
+ [Updating Channels in Amazon Pinpoint](examples-pinpoint-update-channel.md)

# Creating and Deleting Apps in Amazon Pinpoint
<a name="examples-pinpoint-create-app"></a>

An app is an Amazon Pinpoint project in which you define the audience for a distinct application, and you engage this audience with tailored messages. The examples on this page demonstrate how to create a new app or delete an existing one.

## Create an App
<a name="create-an-app"></a>

Create a new app in Amazon Pinpoint by providing an app name to the [CreateAppRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/CreateAppRequest.html) object, and then passing that object to the AmazonPinpointClient’s `createApp` method.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
import com.amazonaws.services.pinpoint.model.CreateAppRequest;
import com.amazonaws.services.pinpoint.model.CreateAppResult;
import com.amazonaws.services.pinpoint.model.CreateApplicationRequest;
```

 **Code** 

```
CreateApplicationRequest appRequest = new CreateApplicationRequest()
		.withName(appName);

CreateAppRequest request = new CreateAppRequest();
request.withCreateApplicationRequest(appRequest);
CreateAppResult result = pinpoint.createApp(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/CreateApp.java) on GitHub.

## Delete an App
<a name="delete-an-app"></a>

To delete an app, call the AmazonPinpointClient’s `deleteApp` request with a [DeleteAppRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/DeleteAppRequest.html) object that’s set with the app name to delete.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
```

 **Code** 

```
DeleteAppRequest deleteRequest = new DeleteAppRequest()
		.withApplicationId(appID);

pinpoint.deleteApp(deleteRequest);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/DeleteApp.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Apps](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-apps.html) in the Amazon Pinpoint API Reference
+  [App](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-app.html) in the Amazon Pinpoint API Reference

# Creating Endpoints in Amazon Pinpoint
<a name="examples-pinpoint-create-endpoint"></a>

An endpoint uniquely identifies a user device to which you can send push notifications with Amazon Pinpoint. If your app is enabled with Amazon Pinpoint support, your app automatically registers an endpoint with Amazon Pinpoint when a new user opens your app. The following example demonstrates how to add a new endpoint programmatically.

## Create an Endpoint
<a name="create-an-endpoint"></a>

Create a new endpoint in Amazon Pinpoint by providing the endpoint data in an [EndpointRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/EndpointRequest.html) object.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
import com.amazonaws.services.pinpoint.model.UpdateEndpointRequest;
import com.amazonaws.services.pinpoint.model.UpdateEndpointResult;
import com.amazonaws.services.pinpoint.model.EndpointDemographic;
import com.amazonaws.services.pinpoint.model.EndpointLocation;
import com.amazonaws.services.pinpoint.model.EndpointRequest;
import com.amazonaws.services.pinpoint.model.EndpointResponse;
import com.amazonaws.services.pinpoint.model.EndpointUser;
import com.amazonaws.services.pinpoint.model.GetEndpointRequest;
import com.amazonaws.services.pinpoint.model.GetEndpointResult;
```

 **Code** 

```
HashMap<String, List<String>> customAttributes = new HashMap<>();
List<String> favoriteTeams = new ArrayList<>();
favoriteTeams.add("Lakers");
favoriteTeams.add("Warriors");
customAttributes.put("team", favoriteTeams);


EndpointDemographic demographic = new EndpointDemographic()
        .withAppVersion("1.0")
        .withMake("apple")
        .withModel("iPhone")
        .withModelVersion("7")
        .withPlatform("ios")
        .withPlatformVersion("10.1.1")
        .withTimezone("America/Los_Angeles");

EndpointLocation location = new EndpointLocation()
        .withCity("Los Angeles")
        .withCountry("US")
        .withLatitude(34.0)
        .withLongitude(-118.2)
        .withPostalCode("90068")
        .withRegion("CA");

Map<String,Double> metrics = new HashMap<>();
metrics.put("health", 100.00);
metrics.put("luck", 75.00);

EndpointUser user = new EndpointUser()
        .withUserId(UUID.randomUUID().toString());

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
String nowAsISO = df.format(new Date());

EndpointRequest endpointRequest = new EndpointRequest()
        .withAddress(UUID.randomUUID().toString())
        .withAttributes(customAttributes)
        .withChannelType("APNS")
        .withDemographic(demographic)
        .withEffectiveDate(nowAsISO)
        .withLocation(location)
        .withMetrics(metrics)
        .withOptOut("NONE")
        .withRequestId(UUID.randomUUID().toString())
        .withUser(user);
```

Then create an [UpdateEndpointRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/UpdateEndpointRequest.html) object with that EndpointRequest object. Finally, pass the UpdateEndpointRequest object to the AmazonPinpointClient’s `updateEndpoint` method.

 **Code** 

```
UpdateEndpointRequest updateEndpointRequest = new UpdateEndpointRequest()
        .withApplicationId(appId)
        .withEndpointId(endpointId)
        .withEndpointRequest(endpointRequest);

UpdateEndpointResult updateEndpointResponse = client.updateEndpoint(updateEndpointRequest);
System.out.println("Update Endpoint Response: " + updateEndpointResponse.getMessageBody());
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/CreateEndpoint.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Adding Endpoint](http://docs.aws.amazon.com/pinpoint/latest/developerguide/endpoints.html) in the Amazon Pinpoint Developer Guide
+  [Endpoint](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-endpoint.html) in the Amazon Pinpoint API Reference

# Creating Segments in Amazon Pinpoint
<a name="examples-pinpoint-create-segment"></a>

A user segment represents a subset of your users that’s based on shared characteristics, such as how recently a user opened your app or which device they use. The following example demonstrates how to define a segment of users.

## Create a Segment
<a name="create-a-segment"></a>

Create a new segment in Amazon Pinpoint by defining dimensions of the segment in a [SegmentDimensions](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/SegmentDimensions.html) object.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
import com.amazonaws.services.pinpoint.model.CreateSegmentRequest;
import com.amazonaws.services.pinpoint.model.CreateSegmentResult;
import com.amazonaws.services.pinpoint.model.AttributeDimension;
import com.amazonaws.services.pinpoint.model.AttributeType;
import com.amazonaws.services.pinpoint.model.RecencyDimension;
import com.amazonaws.services.pinpoint.model.SegmentBehaviors;
import com.amazonaws.services.pinpoint.model.SegmentDemographics;
import com.amazonaws.services.pinpoint.model.SegmentDimensions;
import com.amazonaws.services.pinpoint.model.SegmentLocation;
import com.amazonaws.services.pinpoint.model.SegmentResponse;
import com.amazonaws.services.pinpoint.model.WriteSegmentRequest;
```

 **Code** 

```
Pinpoint pinpoint = AmazonPinpointClientBuilder.standard().withRegion(Regions.US_EAST_1).build();
Map<String, AttributeDimension> segmentAttributes = new HashMap<>();
segmentAttributes.put("Team", new AttributeDimension().withAttributeType(AttributeType.INCLUSIVE).withValues("Lakers"));

SegmentBehaviors segmentBehaviors = new SegmentBehaviors();
SegmentDemographics segmentDemographics = new SegmentDemographics();
SegmentLocation segmentLocation = new SegmentLocation();

RecencyDimension recencyDimension = new RecencyDimension();
recencyDimension.withDuration("DAY_30").withRecencyType("ACTIVE");
segmentBehaviors.setRecency(recencyDimension);

SegmentDimensions dimensions = new SegmentDimensions()
        .withAttributes(segmentAttributes)
        .withBehavior(segmentBehaviors)
        .withDemographic(segmentDemographics)
        .withLocation(segmentLocation);
```

Next set the [SegmentDimensions](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/SegmentDimensions.html) object in a [WriteSegmentRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/WriteSegmentRequest.html), which in turn is used to create a [CreateSegmentRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/CreateSegmentRequest.html) object. Then pass the CreateSegmentRequest object to the AmazonPinpointClient’s `createSegment` method.

 **Code** 

```
WriteSegmentRequest writeSegmentRequest = new WriteSegmentRequest()
        .withName("MySegment").withDimensions(dimensions);

CreateSegmentRequest createSegmentRequest = new CreateSegmentRequest()
        .withApplicationId(appId).withWriteSegmentRequest(writeSegmentRequest);

CreateSegmentResult createSegmentResult = client.createSegment(createSegmentRequest);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/CreateSegment.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Amazon Pinpoint Segments](https://docs.aws.amazon.com/pinpoint/latest/userguide/segments.html) in the Amazon Pinpoint User Guide
+  [Creating Segments](http://docs.aws.amazon.com/pinpoint/latest/developerguide/segments.html) in the Amazon Pinpoint Developer Guide
+  [Segments](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-segments.html) in the Amazon Pinpoint API Reference
+  [Segment](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-segment.html) in the Amazon Pinpoint API Reference

# Creating Campaigns in Amazon Pinpoint
<a name="examples-pinpoint-create-campaign"></a>

You can use campaigns to help increase engagement between your app and your users. You can create a campaign to reach out to a particular segment of your users with tailored messages or special promotions. This example demonstrates how to create a new standard campaign that sends a custom push notification to a specified segment.

## Create a Campaign
<a name="create-a-campaign"></a>

Before creating a new campaign, you must define a [Schedule](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/Schedule.html) and a [Message](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/Message.html) and set these values in a [WriteCampaignRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/WriteCampaignRequest.html) object.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
import com.amazonaws.services.pinpoint.model.CreateCampaignRequest;
import com.amazonaws.services.pinpoint.model.CreateCampaignResult;
import com.amazonaws.services.pinpoint.model.Action;
import com.amazonaws.services.pinpoint.model.CampaignResponse;
import com.amazonaws.services.pinpoint.model.Message;
import com.amazonaws.services.pinpoint.model.MessageConfiguration;
import com.amazonaws.services.pinpoint.model.Schedule;
import com.amazonaws.services.pinpoint.model.WriteCampaignRequest;
```

 **Code** 

```
Schedule schedule = new Schedule()
        .withStartTime("IMMEDIATE");

Message defaultMessage = new Message()
        .withAction(Action.OPEN_APP)
        .withBody("My message body.")
        .withTitle("My message title.");

MessageConfiguration messageConfiguration = new MessageConfiguration()
        .withDefaultMessage(defaultMessage);

WriteCampaignRequest request = new WriteCampaignRequest()
        .withDescription("My description.")
        .withSchedule(schedule)
        .withSegmentId(segmentId)
        .withName("MyCampaign")
        .withMessageConfiguration(messageConfiguration);
```

Then create a new campaign in Amazon Pinpoint by providing the [WriteCampaignRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/WriteCampaignRequest.html) with the campaign configuration to a [CreateCampaignRequest](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/pinpoint/model/CreateCampaignRequest.html) object. Finally, pass the CreateCampaignRequest object to the AmazonPinpointClient’s `createCampaign` method.

 **Code** 

```
CreateCampaignRequest createCampaignRequest = new CreateCampaignRequest()
        .withApplicationId(appId).withWriteCampaignRequest(request);

CreateCampaignResult result = client.createCampaign(createCampaignRequest);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/CreateApp.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Amazon Pinpoint Campaigns](https://docs.aws.amazon.com/pinpoint/latest/userguide/campaigns.html) in the Amazon Pinpoint User Guide
+  [Creating Campaigns](http://docs.aws.amazon.com/pinpoint/latest/developerguide/campaigns.html) in the Amazon Pinpoint Developer Guide
+  [Campaigns](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-campaigns.html) in the Amazon Pinpoint API Reference
+  [Campaign](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-campaign.html) in the Amazon Pinpoint API Reference
+  [Campaign Activities](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-campaign-activities.html) in the Amazon Pinpoint API Reference
+  [Campaign Versions](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-campaign-versions.html) in the Amazon Pinpoint API Reference
+  [Campaign Version](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-campaign-version.html) in the Amazon Pinpoint API Reference

# Updating Channels in Amazon Pinpoint
<a name="examples-pinpoint-update-channel"></a>

A channel defines the types of platforms to which you can deliver messages. This example shows how to use the APNs channel to send a message.

## Update a Channel
<a name="update-a-channel"></a>

Enable a channel in Amazon Pinpoint by providing an app ID and a request object of the channel type you want to update. This example updates the APNs channel, which requires the [APNSChannelRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/APNSChannelRequest.html) object. Set these in the [UpdateApnsChannelRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/pinpoint/model/UpdateApnsChannelRequest.html) and pass that object to the AmazonPinpointClient’s `updateApnsChannel` method.

 **Imports** 

```
import com.amazonaws.services.pinpoint.AmazonPinpoint;
import com.amazonaws.services.pinpoint.AmazonPinpointClientBuilder;
import com.amazonaws.services.pinpoint.model.APNSChannelRequest;
import com.amazonaws.services.pinpoint.model.APNSChannelResponse;
import com.amazonaws.services.pinpoint.model.GetApnsChannelRequest;
import com.amazonaws.services.pinpoint.model.GetApnsChannelResult;
import com.amazonaws.services.pinpoint.model.UpdateApnsChannelRequest;
import com.amazonaws.services.pinpoint.model.UpdateApnsChannelResult;
```

 **Code** 

```
APNSChannelRequest request = new APNSChannelRequest()
		.withEnabled(enabled);

UpdateApnsChannelRequest updateRequest = new UpdateApnsChannelRequest()
		.withAPNSChannelRequest(request)
		.withApplicationId(appId);
UpdateApnsChannelResult result = client.updateApnsChannel(updateRequest);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/pinpoint/src/main/java/com/example/pinpoint/UpdateChannel.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [Amazon Pinpoint Channels](https://docs.aws.amazon.com/pinpoint/latest/userguide/channels.html) in the Amazon Pinpoint User Guide
+  [ADM Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-adm-channel.html) in the Amazon Pinpoint API Reference
+  [APNs Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-apns-channel.html) in the Amazon Pinpoint API Reference
+  [APNs Sandbox Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-apns-sandbox-channel.html) in the Amazon Pinpoint API Reference
+  [APNs VoIP Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-apns-voip-channel.html) in the Amazon Pinpoint API Reference
+  [APNs VoIP Sandbox Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-apns-voip-sandbox-channel.html) in the Amazon Pinpoint API Reference
+  [Baidu Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-baidu-channel.html) in the Amazon Pinpoint API Reference
+  [Email Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-email-channel.html) in the Amazon Pinpoint API Reference
+  [GCM Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-gcm-channel.html) in the Amazon Pinpoint API Reference
+  [SMS Channel](http://docs.aws.amazon.com/pinpoint/latest/apireference/rest-api-sms-channel.html) in the Amazon Pinpoint API Reference

# Amazon S3 Examples Using the AWS SDK for Java
<a name="examples-s3"></a>

This section provides examples of programming [Amazon S3](https://aws.amazon.com/s3/) using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Creating, Listing, and Deleting Amazon S3 Buckets](examples-s3-buckets.md)
+ [Performing Operations on Amazon S3 Objects](examples-s3-objects.md)
+ [Managing Amazon S3 Access Permissions for Buckets and Objects](examples-s3-access-permissions.md)
+ [Managing Access to Amazon S3 Buckets Using Bucket Policies](examples-s3-bucket-policies.md)
+ [Using TransferManager for Amazon S3 Operations](examples-s3-transfermanager.md)
+ [Configuring an Amazon S3 Bucket as a Website](examples-s3-website-configuration.md)
+ [Use Amazon S3 client-side encryption](examples-crypto.md)

# Creating, Listing, and Deleting Amazon S3 Buckets
<a name="examples-s3-buckets"></a>

Every object (file) in Amazon S3 must reside within a *bucket*, which represents a collection (container) of objects. Each bucket is known by a *key* (name), which must be unique. For detailed information about buckets and their configuration, see [Working with Amazon S3 Buckets](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingBucket.html) in the Amazon Simple Storage Service User Guide.

**Note**  
Best Practice  
We recommend that you enable the [AbortIncompleteMultipartUpload](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html) lifecycle rule on your Amazon S3 buckets.  
This rule directs Amazon S3 to abort multipart uploads that don’t complete within a specified number of days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then deletes the incomplete upload data.  
For more information, see [Lifecycle Configuration for a Bucket with Versioning](http://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-bucket-with-versioning.html) in the Amazon S3 User Guide.

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

## Create a Bucket
<a name="create-bucket"></a>

Use the AmazonS3 client’s `createBucket` method. The new [Bucket](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Bucket.html) is returned. The `createBucket` method will raise an exception if the bucket already exists.

**Note**  
To check whether a bucket already exists before attempting to create one with the same name, call the `doesBucketExist` method. It will return `true` if the bucket exists, and `false` otherwise.

 **Imports** 

```
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.Bucket;

import java.util.List;
```

 **Code** 

```
if (s3.doesBucketExistV2(bucket_name)) {
    System.out.format("Bucket %s already exists.\n", bucket_name);
    b = getBucket(bucket_name);
} else {
    try {
        b = s3.createBucket(bucket_name);
    } catch (AmazonS3Exception e) {
        System.err.println(e.getErrorMessage());
    }
}
return b;
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/CreateBucket.java) on GitHub.

## List Buckets
<a name="list-buckets"></a>

Use the AmazonS3 client’s `listBucket` method. If successful, a list of [Bucket](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Bucket.html) is returned.

 **Imports** 

```
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;

import java.util.List;
```

 **Code** 

```
List<Bucket> buckets = s3.listBuckets();
System.out.println("Your {S3} buckets are:");
for (Bucket b : buckets) {
    System.out.println("* " + b.getName());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/ListBuckets.java) on GitHub.

## Delete a Bucket
<a name="delete-bucket"></a>

Before you can delete an Amazon S3 bucket, you must ensure that the bucket is empty or an error will result. If you have a [versioned bucket](http://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html), you must also delete any versioned objects associated with the bucket.

**Note**  
The [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteBucket.java) includes each of these steps in order, providing a complete solution for deleting an Amazon S3 bucket and its contents.

**Topics**
+ [Remove Objects from an Unversioned Bucket Before Deleting It](#remove-objects-from-an-unversioned-bucket-before-deleting-it)
+ [Remove Objects from a Versioned Bucket Before Deleting It](#remove-objects-from-a-versioned-bucket-before-deleting-it)
+ [Delete an Empty Bucket](#delete-an-empty-bucket)

### Remove Objects from an Unversioned Bucket Before Deleting It
<a name="remove-objects-from-an-unversioned-bucket-before-deleting-it"></a>

Use the AmazonS3 client’s `listObjects` method to retrieve the list of objects and `deleteObject` to delete each one.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import java.util.Iterator;
```

 **Code** 

```
System.out.println(" - removing objects from bucket");
ObjectListing object_listing = s3.listObjects(bucket_name);
while (true) {
    for (Iterator<?> iterator =
         object_listing.getObjectSummaries().iterator();
         iterator.hasNext(); ) {
        S3ObjectSummary summary = (S3ObjectSummary) iterator.next();
        s3.deleteObject(bucket_name, summary.getKey());
    }

    // more object_listing to retrieve?
    if (object_listing.isTruncated()) {
        object_listing = s3.listNextBatchOfObjects(object_listing);
    } else {
        break;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteBucket.java) on GitHub.

### Remove Objects from a Versioned Bucket Before Deleting It
<a name="remove-objects-from-a-versioned-bucket-before-deleting-it"></a>

If you’re using a [versioned bucket](http://docs.aws.amazon.com/AmazonS3/latest/dev/Versioning.html), you also need to remove any stored versions of the objects in the bucket before the bucket can be deleted.

Using a pattern similar to the one used when removing objects within a bucket, remove versioned objects by using the AmazonS3 client’s `listVersions` method to list any versioned objects, and then `deleteVersion` to delete each one.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import java.util.Iterator;
```

 **Code** 

```
System.out.println(" - removing versions from bucket");
VersionListing version_listing = s3.listVersions(
        new ListVersionsRequest().withBucketName(bucket_name));
while (true) {
    for (Iterator<?> iterator =
         version_listing.getVersionSummaries().iterator();
         iterator.hasNext(); ) {
        S3VersionSummary vs = (S3VersionSummary) iterator.next();
        s3.deleteVersion(
                bucket_name, vs.getKey(), vs.getVersionId());
    }

    if (version_listing.isTruncated()) {
        version_listing = s3.listNextBatchOfVersions(
                version_listing);
    } else {
        break;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteBucket.java) on GitHub.

### Delete an Empty Bucket
<a name="delete-an-empty-bucket"></a>

Once you remove the objects from a bucket (including any versioned objects), you can delete the bucket itself by using the AmazonS3 client’s `deleteBucket` method.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import java.util.Iterator;
```

 **Code** 

```
System.out.println(" OK, bucket ready to delete!");
s3.deleteBucket(bucket_name);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteBucket.java) on GitHub.

# Performing Operations on Amazon S3 Objects
<a name="examples-s3-objects"></a>

An Amazon S3 object represents a *file* or collection of data. Every object must reside within a [bucket](examples-s3-buckets.md).

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

**Topics**
+ [Upload an Object](#upload-object)
+ [List Objects](#list-objects)
+ [Download an Object](#download-object)
+ [Copy, Move, or Rename Objects](#copy-object)
+ [Delete an Object](#delete-object)
+ [Delete Multiple Objects at Once](#delete-objects)

## Upload an Object
<a name="upload-object"></a>

Use the AmazonS3 client’s `putObject` method, supplying a bucket name, key name, and file to upload. *The bucket must exist, or an error will result*.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
```

 **Code** 

```
System.out.format("Uploading %s to S3 bucket %s...\n", file_path, bucket_name);
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    s3.putObject(bucket_name, key_name, new File(file_path));
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/PutObject.java) on GitHub.

## List Objects
<a name="list-objects"></a>

To get a list of objects within a bucket, use the AmazonS3 client’s `listObjects` method, supplying the name of a bucket.

The `listObjects` method returns an [ObjectListing](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/ObjectListing.html) object that provides information about the objects in the bucket. To list the object names (keys), use the `getObjectSummaries` method to get a List of [S3ObjectSummary](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/S3ObjectSummary.html) objects, each of which represents a single object in the bucket. Then call its `getKey` method to retrieve the object’s name.

 **Imports** 

```
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ListObjectsV2Result;
import com.amazonaws.services.s3.model.S3ObjectSummary;
```

 **Code** 

```
System.out.format("Objects in S3 bucket %s:\n", bucket_name);
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
ListObjectsV2Result result = s3.listObjectsV2(bucket_name);
List<S3ObjectSummary> objects = result.getObjectSummaries();
for (S3ObjectSummary os : objects) {
    System.out.println("* " + os.getKey());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/ListObjects.java) on GitHub.

## Download an Object
<a name="download-object"></a>

Use the AmazonS3 client’s `getObject` method, passing it the name of a bucket and object to download. If successful, the method returns an [S3Object](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/S3Object.html). *The specified bucket and object key must exist, or an error will result*.

You can get the object’s contents by calling `getObjectContent` on the `S3Object`. This returns an [S3ObjectInputStream](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/S3ObjectInputStream.html) that behaves as a standard Java `InputStream` object.

The following example downloads an object from S3 and saves its contents to a file (using the same name as the object’s key).

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;

import java.io.File;
```

 **Code** 

```
System.out.format("Downloading %s from S3 bucket %s...\n", key_name, bucket_name);
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    S3Object o = s3.getObject(bucket_name, key_name);
    S3ObjectInputStream s3is = o.getObjectContent();
    FileOutputStream fos = new FileOutputStream(new File(key_name));
    byte[] read_buf = new byte[1024];
    int read_len = 0;
    while ((read_len = s3is.read(read_buf)) > 0) {
        fos.write(read_buf, 0, read_len);
    }
    s3is.close();
    fos.close();
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
} catch (FileNotFoundException e) {
    System.err.println(e.getMessage());
    System.exit(1);
} catch (IOException e) {
    System.err.println(e.getMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/GetObject.java) on GitHub.

## Copy, Move, or Rename Objects
<a name="copy-object"></a>

You can copy an object from one bucket to another by using the AmazonS3 client’s `copyObject` method. It takes the name of the bucket to copy from, the object to copy, and the destination bucket name.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
```

 **Code** 

```
try {
    s3.copyObject(from_bucket, object_key, to_bucket, object_key);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
System.out.println("Done!");
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/CopyObject.java) on GitHub.

**Note**  
You can use `copyObject` with [deleteObject](#delete-object) to **move** or **rename** an object, by first copying the object to a new name (you can use the same bucket as both the source and destination) and then deleting the object from its old location.

## Delete an Object
<a name="delete-object"></a>

Use the AmazonS3 client’s `deleteObject` method, passing it the name of a bucket and object to delete. *The specified bucket and object key must exist, or an error will result*.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    s3.deleteObject(bucket_name, object_key);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteObject.java) on GitHub.

## Delete Multiple Objects at Once
<a name="delete-objects"></a>

Using the AmazonS3 client’s `deleteObjects` method, you can delete multiple objects from the same bucket by passing their names to the link:sdk-for-java/v1/reference/com/amazonaws/services/s3/model/DeleteObjectsRequest.html`` method.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    DeleteObjectsRequest dor = new DeleteObjectsRequest(bucket_name)
            .withKeys(object_keys);
    s3.deleteObjects(dor);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteObjects.java) on GitHub.

# Managing Amazon S3 Access Permissions for Buckets and Objects
<a name="examples-s3-access-permissions"></a>

You can use access control lists (ACLs) for Amazon S3 buckets and objects for fine-grained control over your Amazon S3 resources.

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

## Get the Access Control List for a Bucket
<a name="get-the-access-control-list-for-a-bucket"></a>

To get the current ACL for a bucket, call the AmazonS3’s `getBucketAcl` method, passing it the *bucket name* to query. This method returns an [AccessControlList](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/AccessControlList.html) object. To get each access grant in the list, call its `getGrantsAsList` method, which will return a standard Java list of [Grant](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Grant.html) objects.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.Grant;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    AccessControlList acl = s3.getBucketAcl(bucket_name);
    List<Grant> grants = acl.getGrantsAsList();
    for (Grant grant : grants) {
        System.out.format("  %s: %s\n", grant.getGrantee().getIdentifier(),
                grant.getPermission().toString());
    }
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/GetAcl.java) on GitHub.

## Set the Access Control List for a Bucket
<a name="set-the-access-control-list-for-a-bucket"></a>

To add or modify permissions to an ACL for a bucket, call the AmazonS3’s `setBucketAcl` method. It takes an [AccessControlList](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/AccessControlList.html) object that contains a list of grantees and access levels to set.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.EmailAddressGrantee;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    // get the current ACL
    AccessControlList acl = s3.getBucketAcl(bucket_name);
    // set access for the grantee
    EmailAddressGrantee grantee = new EmailAddressGrantee(email);
    Permission permission = Permission.valueOf(access);
    acl.grantPermission(grantee, permission);
    s3.setBucketAcl(bucket_name, acl);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

**Note**  
You can provide the grantee’s unique identifier directly using the [Grantee](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Grantee.html) class, or use the [EmailAddressGrantee](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/EmailAddressGrantee.html) class to set the grantee by email, as we’ve done here.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/SetAcl.java) on GitHub.

## Get the Access Control List for an Object
<a name="get-the-access-control-list-for-an-object"></a>

To get the current ACL for an object, call the AmazonS3’s `getObjectAcl` method, passing it the *bucket name* and *object name* to query. Like `getBucketAcl`, this method returns an [AccessControlList](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/AccessControlList.html) object that you can use to examine each [Grant](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Grant.html).

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.Grant;
```

 **Code** 

```
try {
    AccessControlList acl = s3.getObjectAcl(bucket_name, object_key);
    List<Grant> grants = acl.getGrantsAsList();
    for (Grant grant : grants) {
        System.out.format("  %s: %s\n", grant.getGrantee().getIdentifier(),
                grant.getPermission().toString());
    }
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/GetAcl.java) on GitHub.

## Set the Access Control List for an Object
<a name="set-the-access-control-list-for-an-object"></a>

To add or modify permissions to an ACL for an object, call the AmazonS3’s `setObjectAcl` method. It takes an [AccessControlList](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/AccessControlList.html) object that contains a list of grantees and access levels to set.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.EmailAddressGrantee;
```

 **Code** 

```
    try {
        // get the current ACL
        AccessControlList acl = s3.getObjectAcl(bucket_name, object_key);
        // set access for the grantee
        EmailAddressGrantee grantee = new EmailAddressGrantee(email);
        Permission permission = Permission.valueOf(access);
        acl.grantPermission(grantee, permission);
        s3.setObjectAcl(bucket_name, object_key, acl);
    } catch (AmazonServiceException e) {
        System.err.println(e.getErrorMessage());
        System.exit(1);
    }
}
```

**Note**  
You can provide the grantee’s unique identifier directly using the [Grantee](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/Grantee.html) class, or use the [EmailAddressGrantee](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/EmailAddressGrantee.html) class to set the grantee by email, as we’ve done here.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/SetAcl.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [GET Bucket acl](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETacl.html) in the Amazon S3 API Reference
+  [PUT Bucket acl](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTacl.html) in the Amazon S3 API Reference
+  [GET Object acl](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGETacl.html) in the Amazon S3 API Reference
+  [PUT Object acl](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUTacl.html) in the Amazon S3 API Reference

# Managing Access to Amazon S3 Buckets Using Bucket Policies
<a name="examples-s3-bucket-policies"></a>

You can set, get, or delete a *bucket policy* to manage access to your Amazon S3 buckets.

## Set a Bucket Policy
<a name="set-s3-bucket-policy"></a>

You can set the bucket policy for a particular S3 bucket by:
+ Calling the AmazonS3 client’s `setBucketPolicy` and providing it with a [SetBucketPolicyRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/SetBucketPolicyRequest.html) 
+ Setting the policy directly by using the `setBucketPolicy` overload that takes a bucket name and policy text (in JSON format)

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Principal;
```

 **Code** 

```
    s3.setBucketPolicy(bucket_name, policy_text);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

### Use the Policy Class to Generate or Validate a Policy
<a name="use-s3-bucket-policy-class"></a>

When providing a bucket policy to `setBucketPolicy`, you can do the following:
+ Specify the policy directly as a string of JSON-formatted text
+ Build the policy using the [Policy](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/auth/policy/Policy.html) class

By using the `Policy` class, you don’t have to be concerned about correctly formatting your text string. To get the JSON policy text from the `Policy` class, use its `toJson` method.

 **Imports** 

```
import com.amazonaws.auth.policy.Resource;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.auth.policy.actions.S3Actions;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
```

 **Code** 

```
        new Statement(Statement.Effect.Allow)
                .withPrincipals(Principal.AllUsers)
                .withActions(S3Actions.GetObject)
                .withResources(new Resource(
                        "{region-arn}s3:::" + bucket_name + "/*")));
return bucket_policy.toJson();
```

The `Policy` class also provides a `fromJson` method that can attempt to build a policy using a passed-in JSON string. The method validates it to ensure that the text can be transformed into a valid policy structure, and will fail with an `IllegalArgumentException` if the policy text is invalid.

```
Policy bucket_policy = null;
try {
    bucket_policy = Policy.fromJson(file_text.toString());
} catch (IllegalArgumentException e) {
    System.out.format("Invalid policy text in file: \"%s\"",
            policy_file);
    System.out.println(e.getMessage());
}
```

You can use this technique to prevalidate a policy that you read in from a file or other means.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/SetBucketPolicy.java) on GitHub.

## Get a Bucket Policy
<a name="get-s3-bucket-policy"></a>

To retrieve the policy for an Amazon S3 bucket, call the AmazonS3 client’s `getBucketPolicy` method, passing it the name of the bucket to get the policy from.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
```

 **Code** 

```
  try {
      BucketPolicy bucket_policy = s3.getBucketPolicy(bucket_name);
      policy_text = bucket_policy.getPolicyText();
  } catch (AmazonServiceException e) {
      System.err.println(e.getErrorMessage());
      System.exit(1);
  }
```

If the named bucket doesn’t exist, if you don’t have access to it, or if it has no bucket policy, an `AmazonServiceException` is thrown.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/GetBucketPolicy.java) on GitHub.

## Delete a Bucket Policy
<a name="delete-s3-bucket-policy"></a>

To delete a bucket policy, call the AmazonS3 client’s `deleteBucketPolicy`, providing it with the bucket name.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
```

 **Code** 

```
  try {
      s3.deleteBucketPolicy(bucket_name);
  } catch (AmazonServiceException e) {
      System.err.println(e.getErrorMessage());
      System.exit(1);
  }
```

This method succeeds even if the bucket doesn’t already have a policy. If you specify a bucket name that doesn’t exist or if you don’t have access to the bucket, an `AmazonServiceException` is thrown.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteBucketPolicy.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Access Policy Language Overview](http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html) in the Amazon Simple Storage Service User Guide
+  [Bucket Policy Examples](http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html) in the Amazon Simple Storage Service User Guide

# Using TransferManager for Amazon S3 Operations
<a name="examples-s3-transfermanager"></a>

You can use the AWS SDK for Java TransferManager class to reliably transfer files from the local environment to Amazon S3 and to copy objects from one S3 location to another. `TransferManager` can get the progress of a transfer and pause or resume uploads and downloads.

**Note**  
Best Practice  
We recommend that you enable the [AbortIncompleteMultipartUpload](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html) lifecycle rule on your Amazon S3 buckets.  
This rule directs Amazon S3 to abort multipart uploads that don’t complete within a specified number of days after being initiated. When the set time limit is exceeded, Amazon S3 aborts the upload and then deletes the incomplete upload data.  
For more information, see [Lifecycle Configuration for a Bucket with Versioning](http://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-configuration-bucket-with-versioning.html) in the Amazon S3 User Guide.

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

## Upload Files and Directories
<a name="transfermanager-uploading"></a>

TransferManager can upload files, file lists, and directories to any Amazon S3 buckets that you’ve [previously created](examples-s3-buckets.md#create-bucket).

**Topics**
+ [Upload a Single File](#transfermanager-upload-file)
+ [Upload a List of Files](#transfermanager-upload-file-list)
+ [Upload a Directory](#transfermanager-upload-directory)

### Upload a Single File
<a name="transfermanager-upload-file"></a>

Call TransferManager’s `upload` method, providing an Amazon S3 bucket name, a key (object) name, and a standard Java [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) object that represents the file to upload.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
```

 **Code** 

```
File f = new File(file_path);
TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    Upload xfer = xfer_mgr.upload(bucket_name, key_name, f);
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    //  or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

The `upload` method returns *immediately*, providing an `Upload` object to use to check the transfer state or to wait for it to complete.

See [Wait for a Transfer to Complete](#transfermanager-wait-for-completion) for information about using `waitForCompletion` to successfully complete a transfer before calling TransferManager’s `shutdownNow` method. While waiting for the transfer to complete, you can poll or listen for updates about its status and progress. See [Get Transfer Status and Progress](#transfermanager-get-status-and-progress) for more information.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrUpload.java) on GitHub.

### Upload a List of Files
<a name="transfermanager-upload-file-list"></a>

To upload multiple files in one operation, call the TransferManager`uploadFileList` method, providing the following:
+ An Amazon S3 bucket name
+ A *key prefix* to prepend to the names of the created objects (the path within the bucket in which to place the objects)
+ A [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) object that represents the relative directory from which to create file paths
+ A [List](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/List.html) object containing a set of [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) objects to upload

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
```

 **Code** 

```
ArrayList<File> files = new ArrayList<File>();
for (String path : file_paths) {
    files.add(new File(path));
}

TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    MultipleFileUpload xfer = xfer_mgr.uploadFileList(bucket_name,
            key_prefix, new File("."), files);
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    // or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See [Wait for a Transfer to Complete](#transfermanager-wait-for-completion) for information about using `waitForCompletion` to successfully complete a transfer before calling TransferManager’s `shutdownNow` method. While waiting for the transfer to complete, you can poll or listen for updates about its status and progress. See [Get Transfer Status and Progress](#transfermanager-get-status-and-progress) for more information.

The [MultipleFileUpload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/MultipleFileUpload.html) object returned by `uploadFileList` can be used to query the transfer state or progress. See [Poll the Current Progress of a Transfer](#transfermanager-get-progress-polling) and [Get Transfer Progress with a ProgressListener](#transfermanager-progress-listener) for more information.

You can also use `MultipleFileUpload`'s `getSubTransfers` method to get the individual `Upload` objects for each file being transferred. For more information, see [Get the Progress of Subtransfers](#transfermanager-get-subtransfer-progress).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrUpload.java) on GitHub.

### Upload a Directory
<a name="transfermanager-upload-directory"></a>

You can use TransferManager’s `uploadDirectory` method to upload an entire directory of files, with the option to copy files in subdirectories recursively. You provide an Amazon S3 bucket name, an S3 key prefix, a [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) object representing the local directory to copy, and a `boolean` value indicating whether you want to copy subdirectories recursively (*true* or *false*).

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
```

 **Code** 

```
TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    MultipleFileUpload xfer = xfer_mgr.uploadDirectory(bucket_name,
            key_prefix, new File(dir_path), recursive);
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    // or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See [Wait for a Transfer to Complete](#transfermanager-wait-for-completion) for information about using `waitForCompletion` to successfully complete a transfer before calling TransferManager’s `shutdownNow` method. While waiting for the transfer to complete, you can poll or listen for updates about its status and progress. See [Get Transfer Status and Progress](#transfermanager-get-status-and-progress) for more information.

The [MultipleFileUpload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/MultipleFileUpload.html) object returned by `uploadFileList` can be used to query the transfer state or progress. See [Poll the Current Progress of a Transfer](#transfermanager-get-progress-polling) and [Get Transfer Progress with a ProgressListener](#transfermanager-progress-listener) for more information.

You can also use `MultipleFileUpload`'s `getSubTransfers` method to get the individual `Upload` objects for each file being transferred. For more information, see [Get the Progress of Subtransfers](#transfermanager-get-subtransfer-progress).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrUpload.java) on GitHub.

## Download Files or Directories
<a name="transfermanager-downloading"></a>

Use the TransferManager class to download either a single file (Amazon S3 object) or a directory (an Amazon S3 bucket name followed by an object prefix) from Amazon S3.

**Topics**
+ [Download a Single File](#transfermanager-download-file)
+ [Download a Directory](#tranfermanager-download-directory)

### Download a Single File
<a name="transfermanager-download-file"></a>

Use the TransferManager’s `download` method, providing the Amazon S3 bucket name containing the object you want to download, the key (object) name, and a [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) object that represents the file to create on your local system.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.Download;
import com.amazonaws.services.s3.transfer.MultipleFileDownload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;

import java.io.File;
```

 **Code** 

```
File f = new File(file_path);
TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    Download xfer = xfer_mgr.download(bucket_name, key_name, f);
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    // or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See [Wait for a Transfer to Complete](#transfermanager-wait-for-completion) for information about using `waitForCompletion` to successfully complete a transfer before calling TransferManager’s `shutdownNow` method. While waiting for the transfer to complete, you can poll or listen for updates about its status and progress. See [Get Transfer Status and Progress](#transfermanager-get-status-and-progress) for more information.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrDownload.java) on GitHub.

### Download a Directory
<a name="tranfermanager-download-directory"></a>

To download a set of files that share a common key prefix (analogous to a directory on a file system) from Amazon S3, use the TransferManager`downloadDirectory` method. The method takes the Amazon S3 bucket name containing the objects you want to download, the object prefix shared by all of the objects, and a [File](https://docs.oracle.com/javase/8/docs/api/index.html?java/io/File.html) object that represents the directory to download the files into on your local system. If the named directory doesn’t exist yet, it will be created.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.Download;
import com.amazonaws.services.s3.transfer.MultipleFileDownload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;

import java.io.File;
```

 **Code** 

```
TransferManager xfer_mgr = TransferManagerBuilder.standard().build();

try {
    MultipleFileDownload xfer = xfer_mgr.downloadDirectory(
            bucket_name, key_prefix, new File(dir_path));
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    // or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See [Wait for a Transfer to Complete](#transfermanager-wait-for-completion) for information about using `waitForCompletion` to successfully complete a transfer before calling TransferManager’s `shutdownNow` method. While waiting for the transfer to complete, you can poll or listen for updates about its status and progress. See [Get Transfer Status and Progress](#transfermanager-get-status-and-progress) for more information.

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrDownload.java) on GitHub.

## Copy Objects
<a name="transfermanager-copy-object"></a>

To copy an object from one S3 bucket to another, use the TransferManager`copy` method.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.s3.transfer.Copy;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
```

 **Code** 

```
System.out.println("Copying s3 object: " + from_key);
System.out.println("      from bucket: " + from_bucket);
System.out.println("     to s3 object: " + to_key);
System.out.println("        in bucket: " + to_bucket);

TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    Copy xfer = xfer_mgr.copy(from_bucket, from_key, to_bucket, to_key);
    // loop with Transfer.isDone()
    XferMgrProgress.showTransferProgress(xfer);
    // or block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(xfer);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrCopy.java) on GitHub.

## Wait for a Transfer to Complete
<a name="transfermanager-wait-for-completion"></a>

If your application (or thread) can block until the transfer completes, you can use the [Transfer](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Transfer.html) interface’s `waitForCompletion` method to block until the transfer is complete or an exception occurs.

```
try {
    xfer.waitForCompletion();
} catch (AmazonServiceException e) {
    System.err.println("Amazon service error: " + e.getMessage());
    System.exit(1);
} catch (AmazonClientException e) {
    System.err.println("Amazon client error: " + e.getMessage());
    System.exit(1);
} catch (InterruptedException e) {
    System.err.println("Transfer interrupted: " + e.getMessage());
    System.exit(1);
}
```

You get progress of transfers if you poll for events *before* calling `waitForCompletion`, implement a polling mechanism on a separate thread, or receive progress updates asynchronously using a [ProgressListener](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/event/ProgressListener.html).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrProgress.java) on GitHub.

## Get Transfer Status and Progress
<a name="transfermanager-get-status-and-progress"></a>

Each of the classes returned by the TransferManager`upload*`, `download*`, and `copy` methods returns an instance of one of the following classes, depending on whether it’s a single-file or multiple-file operation.


**​**  

| Class | Returned by | 
| --- | --- | 
|   [Copy](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Copy.html)   |   `copy`   | 
|   [Download](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Download.html)   |   `download`   | 
|   [MultipleFileDownload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/MultipleFileDownload.html)   |   `downloadDirectory`   | 
|   [Upload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Upload.html)   |   `upload`   | 
|   [MultipleFileUpload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/MultipleFileUpload.html)   |   `uploadFileList`, `uploadDirectory`   | 

All of these classes implement the [Transfer](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Transfer.html) interface. `Transfer` provides useful methods to get the progress of a transfer, pause or resume the transfer, and get the transfer’s current or final status.

**Topics**
+ [Poll the Current Progress of a Transfer](#transfermanager-get-progress-polling)
+ [Get Transfer Progress with a ProgressListener](#transfermanager-progress-listener)
+ [Get the Progress of Subtransfers](#transfermanager-get-subtransfer-progress)

### Poll the Current Progress of a Transfer
<a name="transfermanager-get-progress-polling"></a>

This loop prints the progress of a transfer, examines its current progress while running and, when complete, prints its final state.

 **Imports** 

```
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.services.s3.transfer.*;
import com.amazonaws.services.s3.transfer.Transfer.TransferState;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
```

 **Code** 

```
// print the transfer's human-readable description
System.out.println(xfer.getDescription());
// print an empty progress bar...
printProgressBar(0.0);
// update the progress bar while the xfer is ongoing.
do {
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        return;
    }
    // Note: so_far and total aren't used, they're just for
    // documentation purposes.
    TransferProgress progress = xfer.getProgress();
    long so_far = progress.getBytesTransferred();
    long total = progress.getTotalBytesToTransfer();
    double pct = progress.getPercentTransferred();
    eraseProgressBar();
    printProgressBar(pct);
} while (xfer.isDone() == false);
// print the final state of the transfer.
TransferState xfer_state = xfer.getState();
System.out.println(": " + xfer_state);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrProgress.java) on GitHub.

### Get Transfer Progress with a ProgressListener
<a name="transfermanager-progress-listener"></a>

You can attach a [ProgressListener](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/event/ProgressListener.html) to any transfer by using the [Transfer](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Transfer.html) interface’s `addProgressListener` method.

A [ProgressListener](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/event/ProgressListener.html) requires only one method, `progressChanged`, which takes a [ProgressEvent](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/event/ProgressEvent.html) object. You can use the object to get the total bytes of the operation by calling its `getBytes` method, and the number of bytes transferred so far by calling `getBytesTransferred`.

 **Imports** 

```
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.services.s3.transfer.*;
import com.amazonaws.services.s3.transfer.Transfer.TransferState;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
```

 **Code** 

```
File f = new File(file_path);
TransferManager xfer_mgr = TransferManagerBuilder.standard().build();
try {
    Upload u = xfer_mgr.upload(bucket_name, key_name, f);
    // print an empty progress bar...
    printProgressBar(0.0);
    u.addProgressListener(new ProgressListener() {
        public void progressChanged(ProgressEvent e) {
            double pct = e.getBytesTransferred() * 100.0 / e.getBytes();
            eraseProgressBar();
            printProgressBar(pct);
        }
    });
    // block with Transfer.waitForCompletion()
    XferMgrProgress.waitForCompletion(u);
    // print the final state of the transfer.
    TransferState xfer_state = u.getState();
    System.out.println(": " + xfer_state);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
xfer_mgr.shutdownNow();
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrProgress.java) on GitHub.

### Get the Progress of Subtransfers
<a name="transfermanager-get-subtransfer-progress"></a>

The [MultipleFileUpload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/MultipleFileUpload.html) class can return information about its subtransfers by calling its `getSubTransfers` method. It returns an unmodifiable [Collection](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Collection.html) of [Upload](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/transfer/Upload.html) objects that provide the individual transfer status and progress of each sub-transfer.

 **Imports** 

```
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.services.s3.transfer.*;
import com.amazonaws.services.s3.transfer.Transfer.TransferState;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
```

 **Code** 

```
Collection<? extends Upload> sub_xfers = new ArrayList<Upload>();
sub_xfers = multi_upload.getSubTransfers();

do {
    System.out.println("\nSubtransfer progress:\n");
    for (Upload u : sub_xfers) {
        System.out.println("  " + u.getDescription());
        if (u.isDone()) {
            TransferState xfer_state = u.getState();
            System.out.println("  " + xfer_state);
        } else {
            TransferProgress progress = u.getProgress();
            double pct = progress.getPercentTransferred();
            printProgressBar(pct);
            System.out.println();
        }
    }

    // wait a bit before the next update.
    try {
        Thread.sleep(200);
    } catch (InterruptedException e) {
        return;
    }
} while (multi_upload.isDone() == false);
// print the final state of the transfer.
TransferState xfer_state = multi_upload.getState();
System.out.println("\nMultipleFileUpload " + xfer_state);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/XferMgrProgress.java) on GitHub.

## More Info
<a name="transfermanager-see-also"></a>
+  [Object Keys](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html) in the Amazon Simple Storage Service User Guide

# Configuring an Amazon S3 Bucket as a Website
<a name="examples-s3-website-configuration"></a>

You can configure an Amazon S3 bucket to behave as a website. To do this, you need to set its website configuration.

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

## Set a Bucket’s Website Configuration
<a name="set-a-bucket-s-website-configuration"></a>

To set an Amazon S3 bucket’s website configuration, call the AmazonS3’s `setWebsiteConfiguration` method with the bucket name to set the configuration for, and a [BucketWebsiteConfiguration](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/BucketWebsiteConfiguration.html) object containing the bucket’s website configuration.

Setting an index document is *required*; all other parameters are optional.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketWebsiteConfiguration;
```

 **Code** 

```
    String bucket_name, String index_doc, String error_doc) {
BucketWebsiteConfiguration website_config = null;

if (index_doc == null) {
    website_config = new BucketWebsiteConfiguration();
} else if (error_doc == null) {
    website_config = new BucketWebsiteConfiguration(index_doc);
} else {
    website_config = new BucketWebsiteConfiguration(index_doc, error_doc);
}

final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    s3.setBucketWebsiteConfiguration(bucket_name, website_config);
} catch (AmazonServiceException e) {
    System.out.format(
            "Failed to set website configuration for bucket '%s'!\n",
            bucket_name);
    System.err.println(e.getErrorMessage());
    System.exit(1);
}
```

**Note**  
Setting a website configuration does not modify the access permissions for your bucket. To make your files visible on the web, you will also need to set a *bucket policy* that allows public read access to the files in the bucket. For more information, see [Managing Access to Amazon S3 Buckets Using Bucket Policies](examples-s3-bucket-policies.md).

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/SetWebsiteConfiguration.java) on GitHub.

## Get a Bucket’s Website Configuration
<a name="get-a-bucket-s-website-configuration"></a>

To get an Amazon S3 bucket’s website configuration, call the AmazonS3’s `getWebsiteConfiguration` method with the name of the bucket to retrieve the configuration for.

The configuration will be returned as a [BucketWebsiteConfiguration](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/BucketWebsiteConfiguration.html) object. If there is no website configuration for the bucket, then `null` will be returned.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.BucketWebsiteConfiguration;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    BucketWebsiteConfiguration config =
            s3.getBucketWebsiteConfiguration(bucket_name);
    if (config == null) {
        System.out.println("No website configuration found!");
    } else {
        System.out.format("Index document: %s\n",
                config.getIndexDocumentSuffix());
        System.out.format("Error document: %s\n",
                config.getErrorDocument());
    }
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.out.println("Failed to get website configuration!");
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/GetWebsiteConfiguration.java) on GitHub.

## Delete a Bucket’s Website Configuration
<a name="delete-a-bucket-s-website-configuration"></a>

To delete an Amazon S3 bucket’s website configuration, call the AmazonS3’s `deleteWebsiteConfiguration` method with the name of the bucket to delete the configuration from.

 **Imports** 

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
```

 **Code** 

```
final AmazonS3 s3 = AmazonS3ClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
try {
    s3.deleteBucketWebsiteConfiguration(bucket_name);
} catch (AmazonServiceException e) {
    System.err.println(e.getErrorMessage());
    System.out.println("Failed to delete website configuration!");
    System.exit(1);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/DeleteWebsiteConfiguration.java) on GitHub.

## More Information
<a name="more-information"></a>
+  [PUT Bucket website](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html) in the Amazon S3 API Reference
+  [GET Bucket website](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETwebsite.html) in the Amazon S3 API Reference
+  [DELETE Bucket website](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketDELETEwebsite.html) in the Amazon S3 API Reference

# Use Amazon S3 client-side encryption
<a name="examples-crypto"></a>

Encrypting data using the Amazon S3 encryption client is one way you can provide an additional layer of protection for sensitive information you store in Amazon S3. The examples in this section demonstrate how to create and configure the Amazon S3 encryption client for your application.

If you are new to cryptography, see the [Cryptography Basics](https://docs.aws.amazon.com/kms/latest/developerguide/crypto-intro.html) in the AWS KMS Developer Guide for a basic overview of cryptography terms and algorithms. For information about cryptography support across all AWS SDKs, see [AWS SDK Support for Amazon S3 Client-Side Encryption](http://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html) in the Amazon Web Services General Reference.

**Note**  
These code examples assume that you understand the material in [Using the AWS SDK for Java](basics.md) and have configured default AWS credentials using the information in [Set up AWS Credentials and Region for Development](setup-credentials.md).

If you are using version 1.11.836 or earlier of the AWS SDK for Java, see [Amazon S3 Encryption Client Migration](s3-encryption-migration.md) for information on migrating your applications to later versions. If you cannot migrate, see [this complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/s3/src/main/java/aws/example/s3/S3Encrypt.java) on GitHub.

Otherwise, if you are using version 1.11.837 or later of the AWS SDK for Java, explore the example topics listed below to use Amazon S3 client-side encryption.

**Topics**
+ [Amazon S3 client-side encryption with client master keys](examples-crypto-masterkey.md)
+ [Amazon S3 client-side encryption with AWS KMS managed keys](examples-crypto-kms.md)

# Amazon S3 client-side encryption with client master keys
<a name="examples-crypto-masterkey"></a>

The following examples use the [AmazonS3EncryptionClientV2Builder](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/AmazonS3EncryptionClientV2Builder.html) class to create an Amazon S3 client with client-side encryption enabled. Once enabled, any objects you upload to Amazon S3 using this client will be encrypted. Any objects you get from Amazon S3 using this client will automatically be decrypted.

**Note**  
The following examples demonstrate using the Amazon S3 client-side encryption with customer-managed client master keys. To learn how to use encryption with AWS KMS managed keys, see [Amazon S3 client-side encryption with AWS KMS managed keys](examples-crypto-kms.md).

You can choose from two encryption modes when enabling client-side Amazon S3 encryption: strict authenticated or authenticated. The following sections show how to enable each type. To learn which algorithms each mode uses, see the [CryptoMode](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/CryptoMode.html) definition.

## Required imports
<a name="required-imports"></a>

Import the following classes for these examples.

 **Imports** 

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3EncryptionClientV2Builder;
import com.amazonaws.services.s3.AmazonS3EncryptionV2;
import com.amazonaws.services.s3.model.CryptoConfigurationV2;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider;
```

## Strict authenticated encryption
<a name="strict-authenticated-encryption"></a>

Strict authenticated encryption is the default mode if no `CryptoMode` is specified.

To explicitly enable this mode, specify the `StrictAuthenticatedEncryption` value in the `withCryptoConfiguration` method.

**Note**  
To use client-side authenticated encryption, you must include the latest [Bouncy Castle jar](https://www.bouncycastle.org/download/bouncy-castle-java/) file in the classpath of your application.

 **Code** 

```
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
         .withRegion(Regions.US_WEST_2)
         .withCryptoConfiguration(new CryptoConfigurationV2().withCryptoMode((CryptoMode.StrictAuthenticatedEncryption)))
         .withEncryptionMaterialsProvider(new StaticEncryptionMaterialsProvider(new EncryptionMaterials(secretKey)))
         .build();

s3Encryption.putObject(bucket_name, ENCRYPTED_KEY2, "This is the 2nd content to encrypt");
```

## Authenticated encryption mode
<a name="authenticated-encryption-mode"></a>

When you use `AuthenticatedEncryption` mode, an improved key wrapping algorithm is applied during encryption. When decrypting in this mode, the algorithm can verify the integrity of the decrypted object and throw an exception if the check fails. For more details about how authenticated encryption works, see the [Amazon S3 Client-Side Authenticated Encryption](https://aws.amazon.com/blogs/developer/amazon-s3-client-side-authenticated-encryption) blog post.

**Note**  
To use client-side authenticated encryption, you must include the latest [Bouncy Castle jar](https://www.bouncycastle.org/download/bouncy-castle-java/) file in the classpath of your application.

To enable this mode, specify the `AuthenticatedEncryption` value in the `withCryptoConfiguration` method.

 **Code** 

```
AmazonS3EncryptionV2 s3EncryptionClientV2 = AmazonS3EncryptionClientV2Builder.standard()
         .withRegion(Regions.DEFAULT_REGION)
         .withClientConfiguration(new ClientConfiguration())
         .withCryptoConfiguration(new CryptoConfigurationV2().withCryptoMode(CryptoMode.AuthenticatedEncryption))
         .withEncryptionMaterialsProvider(new StaticEncryptionMaterialsProvider(new EncryptionMaterials(secretKey)))
         .build();

s3EncryptionClientV2.putObject(bucket_name, ENCRYPTED_KEY1, "This is the 1st content to encrypt");
```

# Amazon S3 client-side encryption with AWS KMS managed keys
<a name="examples-crypto-kms"></a>

The following examples use the [AmazonS3EncryptionClientV2Builder](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/AmazonS3EncryptionClientV2Builder.html) class to create an Amazon S3 client with client-side encryption enabled. Once configured, any objects you upload to Amazon S3 using this client will be encrypted. Any objects you get from Amazon S3 using this client are automatically decrypted.

**Note**  
The following examples demonstrate how to use the Amazon S3 client-side encryption with AWS KMS managed keys. To learn how to use encryption with your own keys, see [Amazon S3 client-side encryption with client master keys](examples-crypto-masterkey.md).

You can choose from two encryption modes when enabling client-side Amazon S3 encryption: strict authenticated or authenticated. The following sections show how to enable each type. To learn which algorithms each mode uses, see the [CryptoMode](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/s3/model/CryptoMode.html) definition.

## Required imports
<a name="required-imports"></a>

Import the following classes for these examples.

 **Imports** 

```
import com.amazonaws.ClientConfiguration;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.AWSKMSClientBuilder;
import com.amazonaws.services.kms.model.GenerateDataKeyRequest;
import com.amazonaws.services.kms.model.GenerateDataKeyResult;
import com.amazonaws.services.s3.AmazonS3EncryptionClientV2Builder;
import com.amazonaws.services.s3.AmazonS3EncryptionV2;
import com.amazonaws.services.s3.model.CryptoConfigurationV2;
import com.amazonaws.services.s3.model.CryptoMode;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.KMSEncryptionMaterialsProvider;
```

## Strict authenticated encryption
<a name="strict-authenticated-encryption-kms"></a>

Strict authenticated encryption is the default mode if no `CryptoMode` is specified.

To explicitly enable this mode, specify the `StrictAuthenticatedEncryption` value in the `withCryptoConfiguration` method.

**Note**  
To use client-side authenticated encryption, you must include the latest [Bouncy Castle jar](https://www.bouncycastle.org/download/bouncy-castle-java/) file in the classpath of your application.

 **Code** 

```
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
         .withRegion(Regions.US_WEST_2)
         .withCryptoConfiguration(new CryptoConfigurationV2().withCryptoMode((CryptoMode.StrictAuthenticatedEncryption)))
         .withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
         .build();

s3Encryption.putObject(bucket_name, ENCRYPTED_KEY3, "This is the 3rd content to encrypt with a key created in the {console}");
System.out.println(s3Encryption.getObjectAsString(bucket_name, ENCRYPTED_KEY3));
```

Call the `putObject` method on the Amazon S3 encryption client to upload objects.

 **Code** 

```
s3Encryption.putObject(bucket_name, ENCRYPTED_KEY3, "This is the 3rd content to encrypt with a key created in the {console}");
```

You can retrieve the object using the same client. This example calls the `getObjectAsString` method to retrieve the string that was stored.

 **Code** 

```
System.out.println(s3Encryption.getObjectAsString(bucket_name, ENCRYPTED_KEY3));
```

## Authenticated encryption mode
<a name="authenticated-encryption-kms"></a>

When you use `AuthenticatedEncryption` mode, an improved key wrapping algorithm is applied during encryption. When decrypting in this mode, the algorithm can verify the integrity of the decrypted object and throw an exception if the check fails. For more details about how authenticated encryption works, see the [Amazon S3 Client-Side Authenticated Encryption](https://aws.amazon.com/blogs/developer/amazon-s3-client-side-authenticated-encryption) blog post.

**Note**  
To use client-side authenticated encryption, you must include the latest [Bouncy Castle jar](https://www.bouncycastle.org/download/bouncy-castle-java/) file in the classpath of your application.

To enable this mode, specify the `AuthenticatedEncryption` value in the `withCryptoConfiguration` method.

 **Code** 

```
AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
         .withRegion(Regions.US_WEST_2)
         .withCryptoConfiguration(new CryptoConfigurationV2().withCryptoMode((CryptoMode.AuthenticatedEncryption)))
         .withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
         .build();
```

## Configuring the AWS KMS client
<a name="configure-kms"></a>

The Amazon S3 encryption client creates a AWS KMS client by default, unless one is explicitly specified.

To set the region for this automatically-created AWS KMS client, set the `awsKmsRegion`.

 **Code** 

```
Region kmsRegion = Region.getRegion(Regions.AP_NORTHEAST_1);

AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
        .withRegion(Regions.US_WEST_2)
        .withCryptoConfiguration(new CryptoConfigurationV2().withAwsKmsRegion(kmsRegion))
        .withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
        .build();
```

Alternatively, you can use your own AWS KMS client to initialize the encryption client.

 **Code** 

```
AWSKMS kmsClient = AWSKMSClientBuilder.standard()
        .withRegion(Regions.US_WEST_2);
        .build();

AmazonS3EncryptionV2 s3Encryption = AmazonS3EncryptionClientV2Builder.standard()
        .withRegion(Regions.US_WEST_2)
        .withKmsClient(kmsClient)
        .withCryptoConfiguration(new CryptoConfigurationV2().withCryptoMode((CryptoMode.AuthenticatedEncryption)))
        .withEncryptionMaterialsProvider(new KMSEncryptionMaterialsProvider(keyId))
        .build();
```

# Amazon SQS Examples Using the AWS SDK for Java
<a name="examples-sqs"></a>

This section provides examples of programming [Amazon SQS](https://aws.amazon.com/sqs/) using the [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).

**Note**  
The examples include only the code needed to demonstrate each technique. The [complete example code is available on GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java). From there, you can download a single source file or clone the repository locally to get all the examples to build and run.

**Topics**
+ [Working with Amazon SQS Message Queues](examples-sqs-message-queues.md)
+ [Sending, Receiving, and Deleting Amazon SQS Messages](examples-sqs-messages.md)
+ [Enabling Long Polling for Amazon SQS Message Queues](examples-sqs-long-polling.md)
+ [Setting Visibility Timeout in Amazon SQS](examples-sqs-visibility-timeout.md)
+ [Using Dead Letter Queues in Amazon SQS](examples-sqs-dead-letter-queues.md)

# Working with Amazon SQS Message Queues
<a name="examples-sqs-message-queues"></a>

A *message queue* is the logical container used for sending messages reliably in Amazon SQS. There are two types of queues: *standard* and *first-in, first-out* (FIFO). To learn more about queues and the differences between these types, see the [Amazon SQS Developer Guide](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/).

This topic describes how to create, list, delete, and get the URL of an Amazon SQS queue by using the AWS SDK for Java.

## Create a Queue
<a name="sqs-create-queue"></a>

Use the AmazonSQS client’s `createQueue` method, providing a [CreateQueueRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/CreateQueueRequest.html) object that describes the queue parameters.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
CreateQueueRequest create_request = new CreateQueueRequest(QUEUE_NAME)
        .addAttributesEntry("DelaySeconds", "60")
        .addAttributesEntry("MessageRetentionPeriod", "86400");

try {
    sqs.createQueue(create_request);
} catch (AmazonSQSException e) {
    if (!e.getErrorCode().equals("QueueAlreadyExists")) {
        throw e;
    }
}
```

You can use the simplified form of `createQueue`, which needs only a queue name, to create a standard queue.

```
sqs.createQueue("MyQueue" + new Date().getTime());
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/UsingQueues.java) on GitHub.

## Listing Queues
<a name="sqs-list-queues"></a>

To list the Amazon SQS queues for your account, call the AmazonSQS client’s `listQueues` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.ListQueuesResult;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
ListQueuesResult lq_result = sqs.listQueues();
System.out.println("Your SQS Queue URLs:");
for (String url : lq_result.getQueueUrls()) {
    System.out.println(url);
}
```

Using the `listQueues` overload without any parameters returns *all queues*. You can filter the returned results by passing it a `ListQueuesRequest` object.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.ListQueuesRequest;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
String name_prefix = "Queue";
lq_result = sqs.listQueues(new ListQueuesRequest(name_prefix));
System.out.println("Queue URLs with prefix: " + name_prefix);
for (String url : lq_result.getQueueUrls()) {
    System.out.println(url);
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/UsingQueues.java) on GitHub.

## Get the URL for a Queue
<a name="sqs-get-queue-url"></a>

Call the AmazonSQS client’s `getQueueUrl` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
String queue_url = sqs.getQueueUrl(QUEUE_NAME).getQueueUrl();
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/UsingQueues.java) on GitHub.

## Delete a Queue
<a name="sqs-delete-queue"></a>

Provide the queue’s [URL](#sqs-get-queue-url) to the AmazonSQS client’s `deleteQueue` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();
sqs.deleteQueue(queue_url);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/UsingQueues.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [How Amazon SQS Queues Work](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-how-it-works.html) in the Amazon SQS Developer Guide
+  [CreateQueue](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html) in the Amazon SQS API Reference
+  [GetQueueUrl](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_GetQueueUrl.html) in the Amazon SQS API Reference
+  [ListQueues](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ListQueues.html) in the Amazon SQS API Reference
+  [DeleteQueues](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteQueues.html) in the Amazon SQS API Reference

# Sending, Receiving, and Deleting Amazon SQS Messages
<a name="examples-sqs-messages"></a>

This topic describes how to send, receive and delete Amazon SQS messages. Messages are always delivered using an [SQS Queue](examples-sqs-message-queues.md).

## Send a Message
<a name="sqs-message-send"></a>

Add a single message to an Amazon SQS queue by calling the AmazonSQS client’s `sendMessage` method. Provide a [SendMessageRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/SendMessageRequest.html) object that contains the queue’s [URL](examples-sqs-message-queues.md#sqs-get-queue-url), message body, and optional delay value (in seconds).

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.SendMessageRequest;
```

 **Code** 

```
SendMessageRequest send_msg_request = new SendMessageRequest()
        .withQueueUrl(queueUrl)
        .withMessageBody("hello world")
        .withDelaySeconds(5);
sqs.sendMessage(send_msg_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/SendReceiveMessages.java) on GitHub.

### Send Multiple Messages at Once
<a name="sqs-messages-send-multiple"></a>

You can send more than one message in a single request. To send multiple messages, use the AmazonSQS client’s `sendMessageBatch` method, which takes a [SendMessageBatchRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/SendMessageBatchRequest.html) containing the queue URL and a list of messages (each one a [SendMessageBatchRequestEntry](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/SendMessageBatchRequestEntry.html)) to send. You can also set an optional delay value per message.

 **Imports** 

```
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
import com.amazonaws.services.sqs.model.SendMessageBatchRequestEntry;
```

 **Code** 

```
SendMessageBatchRequest send_batch_request = new SendMessageBatchRequest()
        .withQueueUrl(queueUrl)
        .withEntries(
                new SendMessageBatchRequestEntry(
                        "msg_1", "Hello from message 1"),
                new SendMessageBatchRequestEntry(
                        "msg_2", "Hello from message 2")
                        .withDelaySeconds(10));
sqs.sendMessageBatch(send_batch_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/SendReceiveMessages.java) on GitHub.

## Receive Messages
<a name="sqs-messages-receive"></a>

Retrieve any messages that are currently in the queue by calling the AmazonSQS client’s `receiveMessage` method, passing it the queue’s URL. Messages are returned as a list of [Message](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/Message.html) objects.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.SendMessageBatchRequest;
```

 **Code** 

```
List<Message> messages = sqs.receiveMessage(queueUrl).getMessages();
```

## Delete Messages after Receipt
<a name="sqs-messages-delete"></a>

After receiving a message and processing its contents, delete the message from the queue by sending the message’s receipt handle and queue URL to the AmazonSQS client’s `deleteMessage` method.

 **Code** 

```
for (Message m : messages) {
    sqs.deleteMessage(queueUrl, m.getReceiptHandle());
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/SendReceiveMessages.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [How Amazon SQS Queues Work](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-how-it-works.html) in the Amazon SQS Developer Guide
+  [SendMessage](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html) in the Amazon SQS API Reference
+  [SendMessageBatch](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html) in the Amazon SQS API Reference
+  [ReceiveMessage](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon SQS API Reference
+  [DeleteMessage](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html) in the Amazon SQS API Reference

# Enabling Long Polling for Amazon SQS Message Queues
<a name="examples-sqs-long-polling"></a>

 Amazon SQS uses *short polling* by default, querying only a subset of the servers—​based on a weighted random distribution—​to determine whether any messages are available for inclusion in the response.

Long polling helps reduce your cost of using Amazon SQS by reducing the number of empty responses when there are no messages available to return in reply to a ReceiveMessage request sent to an Amazon SQS queue and eliminating false empty responses.

**Note**  
You can set a long polling frequency from *1-20 seconds*.

## Enabling Long Polling when Creating a Queue
<a name="sqs-long-polling-create-queue"></a>

To enable long polling when creating an Amazon SQS queue, set the `ReceiveMessageWaitTimeSeconds` attribute on the [CreateQueueRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/CreateQueueRequest.html) object before calling the AmazonSQS class' `createQueue` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
```

 **Code** 

```
final AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();

// Enable long polling when creating a queue
CreateQueueRequest create_request = new CreateQueueRequest()
        .withQueueName(queue_name)
        .addAttributesEntry("ReceiveMessageWaitTimeSeconds", "20");

try {
    sqs.createQueue(create_request);
} catch (AmazonSQSException e) {
    if (!e.getErrorCode().equals("QueueAlreadyExists")) {
        throw e;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/LongPolling.java) on GitHub.

## Enabling Long Polling on an Existing Queue
<a name="sqs-long-polling-existing-queue"></a>

In addition to enabling long polling when creating a queue, you can also enable it on an existing queue by setting `ReceiveMessageWaitTimeSeconds` on the [SetQueueAttributesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/SetQueueAttributesRequest.html) before calling the AmazonSQS class' `setQueueAttributes` method.

 **Imports** 

```
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
```

 **Code** 

```
SetQueueAttributesRequest set_attrs_request = new SetQueueAttributesRequest()
        .withQueueUrl(queue_url)
        .addAttributesEntry("ReceiveMessageWaitTimeSeconds", "20");
sqs.setQueueAttributes(set_attrs_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/LongPolling.java) on GitHub.

## Enabling Long Polling on Message Receipt
<a name="sqs-long-polling-receive-message"></a>

You can enable long polling when receiving a message by setting the wait time in seconds on the [ReceiveMessageRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/ReceiveMessageRequest.html) that you supply to the AmazonSQS class' `receiveMessage` method.

**Note**  
You should make sure that the AWS client’s request timeout is larger than the maximum long poll time (20s) so that your `receiveMessage` requests don’t time out while waiting for the next poll event\$1

 **Imports** 

```
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
```

 **Code** 

```
ReceiveMessageRequest receive_request = new ReceiveMessageRequest()
        .withQueueUrl(queue_url)
        .withWaitTimeSeconds(20);
sqs.receiveMessage(receive_request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/LongPolling.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Amazon SQS Long Polling](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html) in the Amazon SQS Developer Guide
+  [CreateQueue](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html) in the Amazon SQS API Reference
+  [ReceiveMessage](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon SQS API Reference
+  [SetQueueAttributes](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon SQS API Reference

# Setting Visibility Timeout in Amazon SQS
<a name="examples-sqs-visibility-timeout"></a>

When a message is received in Amazon SQS, it remains on the queue until it’s deleted in order to ensure receipt. A message that was received, but not deleted, will be available in subsequent requests after a given *visibility timeout* to help prevent the message from being received more than once before it can be processed and deleted.

**Note**  
When using [standard queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html), visibility timeout isn’t a guarantee against receiving a message twice. If you are using a standard queue, be sure that your code can handle the case where the same message has been delivered more than once.

## Setting the Message Visibility Timeout for a Single Message
<a name="sqs-visibility-timeout-receipt"></a>

When you have received a message, you can modify its visibility timeout by passing its receipt handle in a [ChangeMessageVisibilityRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/ChangeMessageVisibilityRequest.html) that you pass to the AmazonSQS class' `changeMessageVisibility` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();

// Get the receipt handle for the first message in the queue.
String receipt = sqs.receiveMessage(queue_url)
                    .getMessages()
                    .get(0)
                    .getReceiptHandle();

sqs.changeMessageVisibility(queue_url, receipt, timeout);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/VisibilityTimeout.java) on GitHub.

## Setting the Message Visibility Timeout for Multiple Messages at Once
<a name="setting-the-message-visibility-timeout-for-multiple-messages-at-once"></a>

To set the message visibility timeout for multiple messages at once, create a list of [ChangeMessageVisibilityBatchRequestEntry](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/ChangeMessageVisibilityBatchRequestEntry.html) objects, each containing a unique ID string and a receipt handle. Then, pass the list to the Amazon SQS client class' `changeMessageVisibilityBatch` method.

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.ChangeMessageVisibilityBatchRequestEntry;
import java.util.ArrayList;
import java.util.List;
```

 **Code** 

```
AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();

List<ChangeMessageVisibilityBatchRequestEntry> entries =
    new ArrayList<ChangeMessageVisibilityBatchRequestEntry>();

entries.add(new ChangeMessageVisibilityBatchRequestEntry(
            "unique_id_msg1",
            sqs.receiveMessage(queue_url)
               .getMessages()
               .get(0)
               .getReceiptHandle())
        .withVisibilityTimeout(timeout));

entries.add(new ChangeMessageVisibilityBatchRequestEntry(
            "unique_id_msg2",
            sqs.receiveMessage(queue_url)
               .getMessages()
               .get(0)
               .getReceiptHandle())
        .withVisibilityTimeout(timeout + 200));

sqs.changeMessageVisibilityBatch(queue_url, entries);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/VisibilityTimeout.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Visibility Timeout](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) in the Amazon SQS Developer Guide
+  [SetQueueAttributes](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon SQS API Reference
+  [GetQueueAttributes](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_GetQueueAttributes.html) in the Amazon SQS API Reference
+  [ReceiveMessage](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) in the Amazon SQS API Reference
+  [ChangeMessageVisibility](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibility.html) in the Amazon SQS API Reference
+  [ChangeMessageVisibilityBatch](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibilityBatch.html) in the Amazon SQS API Reference

# Using Dead Letter Queues in Amazon SQS
<a name="examples-sqs-dead-letter-queues"></a>

 Amazon SQS provides support for *dead letter queues*. A dead letter queue is a queue that other (source) queues can target for messages that can’t be processed successfully. You can set aside and isolate these messages in the dead letter queue to determine why their processing did not succeed.

## Creating a Dead Letter Queue
<a name="sqs-dead-letter-queue-create-dl-queue"></a>

A dead letter queue is created the same way as a regular queue, but it has the following restrictions:
+ A dead letter queue must be the same type of queue (FIFO or standard) as the source queue.
+ A dead letter queue must be created using the same AWS account and region as the source queue.

Here we create two identical Amazon SQS queues, one of which will serve as the dead letter queue:

 **Imports** 

```
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.AmazonSQSException;
```

 **Code** 

```
final AmazonSQS sqs = AmazonSQSClientBuilder.defaultClient();

// Create source queue
try {
    sqs.createQueue(src_queue_name);
} catch (AmazonSQSException e) {
    if (!e.getErrorCode().equals("QueueAlreadyExists")) {
        throw e;
    }
}

// Create dead-letter queue
try {
    sqs.createQueue(dl_queue_name);
} catch (AmazonSQSException e) {
    if (!e.getErrorCode().equals("QueueAlreadyExists")) {
        throw e;
    }
}
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/DeadLetterQueues.java) on GitHub.

## Designating a Dead Letter Queue for a Source Queue
<a name="sqs-dead-letter-queue-set-redrive-policy"></a>

To designate a dead letter queue, you must first create a *redrive policy*, and then set the policy in the queue’s attributes. A redrive policy is specified in JSON, and specifies the ARN of the dead letter queue and the maximum number of times the message can be received and not processed before it’s sent to the dead letter queue.

To set the redrive policy for your source queue, call the AmazonSQS class' `setQueueAttributes` method with a [SetQueueAttributesRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/sqs/model/SetQueueAttributesRequest.html) object for which you’ve set the `RedrivePolicy` attribute with your JSON redrive policy.

 **Imports** 

```
import com.amazonaws.services.sqs.model.GetQueueAttributesRequest;
import com.amazonaws.services.sqs.model.GetQueueAttributesResult;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
```

 **Code** 

```
String dl_queue_url = sqs.getQueueUrl(dl_queue_name)
                         .getQueueUrl();

GetQueueAttributesResult queue_attrs = sqs.getQueueAttributes(
        new GetQueueAttributesRequest(dl_queue_url)
            .withAttributeNames("QueueArn"));

String dl_queue_arn = queue_attrs.getAttributes().get("QueueArn");

// Set dead letter queue with redrive policy on source queue.
String src_queue_url = sqs.getQueueUrl(src_queue_name)
                          .getQueueUrl();

SetQueueAttributesRequest request = new SetQueueAttributesRequest()
        .withQueueUrl(src_queue_url)
        .addAttributesEntry("RedrivePolicy",
                "{\"maxReceiveCount\":\"5\", \"deadLetterTargetArn\":\""
                + dl_queue_arn + "\"}");

sqs.setQueueAttributes(request);
```

See the [complete example](https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/java/example_code/sqs/src/main/java/aws/example/sqs/DeadLetterQueues.java) on GitHub.

## More Info
<a name="more-info"></a>
+  [Using Amazon SQS Dead Letter Queues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html) in the Amazon SQS Developer Guide
+  [SetQueueAttributes](http://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SetQueueAttributes.html) in the Amazon SQS API Reference

# Amazon SWF Examples Using the AWS SDK for Java
<a name="prog-services-swf"></a>

 [Amazon SWF](https://aws.amazon.com/swf/) is a workflow-management service that helps developers build and scale distributed workflows that can have parallel or sequential steps consisting of activities, child workflows or even [Lambda](https://aws.amazon.com/lambda/) tasks.

There are two ways to work with Amazon SWF using the AWS SDK for Java, by using the SWF *client* object, or by using the AWS Flow Framework for Java. The AWS Flow Framework for Java is more difficult to configure initially, since it makes heavy use of annotations and relies on additional libraries such as AspectJ and the Spring Framework. However, for large or complex projects, you will save coding time by using the AWS Flow Framework for Java. For more information, see the [AWS Flow Framework for Java Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/awsflowguide/).

This section provides examples of programming Amazon SWF by using the AWS SDK for Java client directly.

**Topics**
+ [SWF basics](swf-basics.md)
+ [Building a Simple Amazon SWF Application](swf-hello.md)
+ [Lambda Tasks](swf-lambda-task.md)
+ [Shutting Down Activity and Workflow Workers Gracefully](swf-graceful-shutdown.md)
+ [Registering Domains](prog-services-swf-register-domain.md)
+ [Listing Domains](prog-services-swf-list-domains.md)

# SWF basics
<a name="swf-basics"></a>

These are general patterns for working with Amazon SWF using the AWS SDK for Java. It is meant primarily for reference. For a more complete introductory tutorial, see [Building a Simple Amazon SWF Application](swf-hello.md).

## Dependencies
<a name="dependencies"></a>

Basic Amazon SWF applications will require the following dependencies, which are included with the AWS SDK for Java:
+ aws-java-sdk-1.12.\$1.jar
+ commons-logging-1.2.\$1.jar
+ httpclient-4.3.\$1.jar
+ httpcore-4.3.\$1.jar
+ jackson-annotations-2.12.\$1.jar
+ jackson-core-2.12.\$1.jar
+ jackson-databind-2.12.\$1.jar
+ joda-time-2.8.\$1.jar

**Note**  
The version numbers of these packages will differ depending on the version of the SDK that you have, but the versions that are supplied with the SDK have been tested for compatibility, and are the ones you should use.

 AWS Flow Framework for Java applications require additional setup, *and* additional dependencies. See the [AWS Flow Framework for Java Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/awsflowguide/) for more information about using the framework.

## Imports
<a name="imports"></a>

In general, you can use the following imports for code development:

```
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.model.*;
```

It’s a good practice to import only the classes you require, however. You will likely end up specifying particular classes in the `com.amazonaws.services.simpleworkflow.model` workspace:

```
import com.amazonaws.services.simpleworkflow.model.PollForActivityTaskRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskCompletedRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskFailedRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;
```

If you are using the AWS Flow Framework for Java, you will import classes from the `com.amazonaws.services.simpleworkflow.flow` workspace. For example:

```
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.flow.ActivityWorker;
```

**Note**  
The AWS Flow Framework for Java has additional requirements beyond those of the base AWS SDK for Java. For more information, see the [AWS Flow Framework for Java Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/awsflowguide/).

## Using the SWF client class
<a name="using-the-swf-client-class"></a>

Your basic interface to Amazon SWF is through either the [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) or [AmazonSimpleWorkflowAsyncClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowAsyncClient.html) classes. The main difference between these is that the `\*AsyncClient` class return [Future](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/Future.html) objects for concurrent (asynchronous) programming.

```
AmazonSimpleWorkflowClient swf = AmazonSimpleWorkflowClientBuilder.defaultClient();
```

# Building a Simple Amazon SWF Application
<a name="swf-hello"></a>

This topic will introduce you to programming [Amazon SWF](https://aws.amazon.com/swf/) applications with the AWS SDK for Java, while presenting a few important concepts along the way.

## About the example
<a name="about-the-example"></a>

The example project will create a workflow with a single activity that accepts workflow data passed through the AWS cloud (In the tradition of HelloWorld, it’ll be the name of someone to greet) and then prints a greeting in response.

While this seems very simple on the surface, Amazon SWF applications consist of a number of parts working together:
+ A **domain**, used as a logical container for your workflow execution data.
+ One or more **workflows** which represent code components that define logical order of execution of your workflow’s activities and child workflows.
+ A **workflow worker**, also known as a *decider*, that polls for decision tasks and schedules activities or child workflows in response.
+ One or more **activities**, each of which represents a unit of work in the workflow.
+ An **activity worker** that polls for activity tasks and runs activity methods in response.
+ One or more **task lists**, which are queues maintained by Amazon SWF used to issue requests to the workflow and activity workers. Tasks on a task list meant for workflow workers are called *decision tasks*. Those meant for activity workers are called *activity tasks*.
+ A **workflow starter** that begins your workflow execution.

Behind the scenes, Amazon SWF orchestrates the operation of these components, coordinating their flow from the AWS cloud, passing data between them, handling timeouts and heartbeat notifications, and logging workflow execution history.

## Prerequisites
<a name="prerequisitesswf"></a>

### Development environment
<a name="development-environment"></a>

The development environment used in this tutorial consists of:
+ The [AWS SDK for Java](https://aws.amazon.com/sdk-for-java/).
+  [Apache Maven](http://maven.apache.org/) (3.3.1).
+ JDK 1.7 or later. This tutorial was developed and tested using JDK 1.8.0.
+ A good Java text editor (your choice).

**Note**  
If you use a different build system than Maven, you can still create a project using the appropriate steps for your environment and use the concepts provided here to follow along. More information about configuring and using the AWS SDK for Java with various build systems is provided in [Getting Started](getting-started.md).  
Likewise, but with more effort, the steps shown here can be implemented using any of the AWS SDKs with support for Amazon SWF.

All of the necessary external dependencies are included with the AWS SDK for Java, so there’s nothing additional to download.

### AWS Access
<a name="aws-access"></a>

To successfully work through this tutorial, you must have access to the AWS access portal as [described in the basic setup section](signup-create-iam-user.md#signup-create-iam-user-overview) of this guide.

The instructions describe how to access temporary credentials that you copy and paste to your local shared `credentials` file. The temporary credentials that you paste must be associated with an IAM role in AWS IAM Identity Center that has permissions to access Amazon SWF. After pasting the temporary credentials, your `credentials` file will look similar to the following.

```
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token=IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE
```

These temporary credentials are associated with the `default` profile.

## Create a SWF project
<a name="create-a-swf-project"></a>

1. Start a new project with Maven:

   ```
   mvn archetype:generate -DartifactId=helloswf \
   -DgroupId=aws.example.helloswf -DinteractiveMode=false
   ```

   This will create a new project with a standard maven project structure:

   ```
   helloswf
   ├── pom.xml
   └── src
       ├── main
       │   └── java
       │       └── aws
       │           └── example
       │               └── helloswf
       │                   └── App.java
       └── test
           └── ...
   ```

   You can ignore or delete the `test` directory and all it contains, we won’t be using it for this tutorial. You can also delete `App.java`, since we’ll be replacing it with new classes.

1. Edit the project’s `pom.xml` file and add the **aws-java-sdk-simpleworkflow** module by adding a dependency for it within the `<dependencies>` block.

   ```
   <dependencies>
     <dependency>
       <groupId>com.amazonaws</groupId>
       <artifactId>aws-java-sdk-simpleworkflow</artifactId>
       <version>1.11.1000</version>
     </dependency>
   </dependencies>
   ```

1.  *Make sure that Maven builds your project with JDK 1.7\$1 support*. Add the following to your project (either before or after the `<dependencies>` block) in `pom.xml`:

   ```
   <build>
     <plugins>
       <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.6.1</version>
         <configuration>
             <source>1.8</source>
             <target>1.8</target>
         </configuration>
       </plugin>
     </plugins>
   </build>
   ```

## Code the project
<a name="code-the-project"></a>

The example project will consist of four separate applications, which we’ll visit one by one:
+  **HelloTypes.java**--contains the project’s domain, activity and workflow type data, shared with the other components. It also handles registering these types with SWF.
+  **ActivityWorker.java**--contains the activity worker, which polls for activity tasks and runs activities in response.
+  **WorkflowWorker.java**--contains the workflow worker (decider), which polls for decision tasks and schedules new activities.
+  **WorkflowStarter.java**--contains the workflow starter, which starts a new workflow execution, which will cause SWF to start generating decision and workflow tasks for your workers to consume.

### Common steps for all source files
<a name="swf-hello-common"></a>

All of the files that you create to house your Java classes will have a few things in common. In the interest of time, these steps *will be implied every time you add a new file to the project*:

1. Create the file in the in the project’s `src/main/java/aws/example/helloswf/` directory.

1. Add a `package` declaration to the beginning of each file to declare its namespace. The example project uses:

   ```
   package aws.example.helloswf;
   ```

1. Add `import` declarations for the [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) class and for multiple classes in the `com.amazonaws.services.simpleworkflow.model` namespace. To simplify things, we’ll use:

   ```
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
   import com.amazonaws.services.simpleworkflow.model.*;
   ```

### Register a domain, workflow and activity types
<a name="swf-hello-hellotypes"></a>

We’ll begin by creating a new executable class, `HelloTypes.java`. This file will contain shared data that different parts of your workflow will need to know about, such as the name and version of your activity and workflow types, the domain name and the task list name.

1. Open your text editor and create the file `HelloTypes.java`, adding a package declaration and imports according to the [common steps](#swf-hello-common).

1. Declare the `HelloTypes` class and provide it with values to use for your registered activity and workflow types:

   ```
       public static final String DOMAIN = "HelloDomain";
       public static final String TASKLIST = "HelloTasklist";
       public static final String WORKFLOW = "HelloWorkflow";
       public static final String WORKFLOW_VERSION = "1.0";
       public static final String ACTIVITY = "HelloActivity";
       public static final String ACTIVITY_VERSION = "1.0";
   ```

   These values will be used throughout the code.

1. After the String declarations, create an instance of the [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) class. This is the basic interface to the Amazon SWF methods provided by the AWS SDK for Java.

   ```
   private static final AmazonSimpleWorkflow swf =
       AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
   ```

   The previous snippet assumes that temporary credentials are associated with the `default` profile. If you use a different profile, modify the code above as follows and replace *profile\$1name *with the name of actual profile name.

   ```
   private static final AmazonSimpleWorkflow swf =
           AmazonSimpleWorkflowClientBuilder
                   .standard()
                   .withCredentials(new ProfileCredentialsProvider("profile_name"))
                   .withRegion(Regions.DEFAULT_REGION)
                   .build();
   ```

1. Add a new function to register a SWF domain. A *domain* is a logical container for a number of related SWF activity and workflow types. SWF components can only communicate with each other if they exist within the same domain.

   ```
       try {
           System.out.println("** Registering the domain '" + DOMAIN + "'.");
           swf.registerDomain(new RegisterDomainRequest()
               .withName(DOMAIN)
               .withWorkflowExecutionRetentionPeriodInDays("1"));
       } catch (DomainAlreadyExistsException e) {
           System.out.println("** Domain already exists!");
       }
   ```

   When you register a domain, you provide it with a *name* (any set of 1 - 256 characters excluding `:`, `/`, `|`, control characters or the literal string '`arn') and a *retention period*, which is the number of days that Amazon SWF will keep your workflow’s execution history data after a workflow execution has completed. The maximum workflow execution retention period is 90 days. See [RegisterDomainRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterDomainRequest.html) for more information.

   If a domain with that name already exists, a [DomainAlreadyExistsException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainAlreadyExistsException.html) is raised. Because we’re unconcerned if the domain has already been created, we can ignore the exception.
**Note**  
This code demonstrates a common pattern when working with AWS SDK for Java methods, data for the method is supplied by a class in the `simpleworkflow.model` namespace, which you instantiate and populate using the chainable `0with*` methods.

1. Add a function to register a new activity type. An *activity* represents a unit of work in your workflow.

   ```
       try {
           System.out.println("** Registering the activity type '" + ACTIVITY +
               "-" + ACTIVITY_VERSION + "'.");
           swf.registerActivityType(new RegisterActivityTypeRequest()
               .withDomain(DOMAIN)
               .withName(ACTIVITY)
               .withVersion(ACTIVITY_VERSION)
               .withDefaultTaskList(new TaskList().withName(TASKLIST))
               .withDefaultTaskScheduleToStartTimeout("30")
               .withDefaultTaskStartToCloseTimeout("600")
               .withDefaultTaskScheduleToCloseTimeout("630")
               .withDefaultTaskHeartbeatTimeout("10"));
       } catch (TypeAlreadyExistsException e) {
           System.out.println("** Activity type already exists!");
       }
   ```

   An activity type is identified by a *name* and a *version*, which are used to uniquely identify the activity from any others in the domain that it’s registered in. Activities also contain a number of optional parameters, such as the default task-list used to receive tasks and data from SWF and a number of different timeouts that you can use to place constraints upon how long different parts of the activity execution can take. See [RegisterActivityTypeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterActivityTypeRequest.html) for more information.
**Note**  
All timeout values are specified in *seconds*. See [Amazon SWF Timeout Types](https://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-timeout-types.html) for a full description of how timeouts affect your workflow executions.

If the activity type that you’re trying to register already exists, an [TypeAlreadyExistsException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/TypeAlreadyExistsException.html) is raised. . Add a function to register a new workflow type. A *workflow*, also known as a *decider* represents the logic of your workflow’s execution.

\$1

```
    try {
        System.out.println("** Registering the workflow type '" + WORKFLOW +
            "-" + WORKFLOW_VERSION + "'.");
        swf.registerWorkflowType(new RegisterWorkflowTypeRequest()
            .withDomain(DOMAIN)
            .withName(WORKFLOW)
            .withVersion(WORKFLOW_VERSION)
            .withDefaultChildPolicy(ChildPolicy.TERMINATE)
            .withDefaultTaskList(new TaskList().withName(TASKLIST))
            .withDefaultTaskStartToCloseTimeout("30"));
    } catch (TypeAlreadyExistsException e) {
        System.out.println("** Workflow type already exists!");
    }
```

\$1

Similar to activity types, workflow types are identified by a *name* and a *version* and also have configurable timeouts. See [RegisterWorkflowTypeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterWorkflowTypeRequest.html) for more information.

\$1

If the workflow type that you’re trying to register already exists, an [TypeAlreadyExistsException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/TypeAlreadyExistsException.html) is raised. . Finally, make the class executable by providing it a `main` method, which will register the domain, the activity type, and the workflow type in turn:

\$1

```
    registerDomain();
    registerWorkflowType();
    registerActivityType();
```

You can [build](#swf-hello-build) and [run](#swf-hello-run-register) the application now to run the registration script, or continue with coding the activity and workflow workers. Once the domain, workflow and activity have been registered, you won’t need to run this again—​these types persist until you deprecate them yourself.

### Implement the activity worker
<a name="implement-the-activity-worker"></a>

An *activity* is the basic unit of work in a workflow. A workflow provides the logic, scheduling activities to be run (or other actions to be taken) in response to decision tasks. A typical workflow usually consists of a number of activities that can run synchronously, asynchronously, or a combination of both.

The *activity worker* is the bit of code that polls for activity tasks that are generated by Amazon SWF in response to workflow decisions. When it receives an activity task, it runs the corresponding activity and returns a success/failure response back to the workflow.

We’ll implement a simple activity worker that drives a single activity.

1. Open your text editor and create the file `ActivityWorker.java`, adding a package declaration and imports according to the [common steps](#swf-hello-common).

   ```
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
   import com.amazonaws.services.simpleworkflow.model.*;
   ```

1. Add the `ActivityWorker` class to the file, and give it a data member to hold a SWF client that we’ll use to interact with Amazon SWF:

   ```
       private static final AmazonSimpleWorkflow swf =
               AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
   ```

1. Add the method that we’ll use as an activity:

   ```
   private static String sayHello(String input) throws Throwable {
       return "Hello, " + input + "!";
   }
   ```

   The activity simply takes a string, combines it into a greeting and returns the result. Although there is little chance that this activity will raise an exception, it’s a good idea to design activities that can raise an error if something goes wrong.

1. Add a `main` method that we’ll use as the activity task polling method. We’ll start it by adding some code to poll the task list for activity tasks:

   ```
           System.out.println("Polling for an activity task from the tasklist '"
                   + HelloTypes.TASKLIST + "' in the domain '" +
                   HelloTypes.DOMAIN + "'.");
   
           ActivityTask task = swf.pollForActivityTask(
               new PollForActivityTaskRequest()
                   .withDomain(HelloTypes.DOMAIN)
                   .withTaskList(
                       new TaskList().withName(HelloTypes.TASKLIST)));
   
           String task_token = task.getTaskToken();
   ```

   The activity receives tasks from Amazon SWF by calling the SWF client’s `pollForActivityTask` method, specifying the domain and task list to use in the passed-in [PollForActivityTaskRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/PollForActivityTaskRequest.html).

   Once a task is received, we retrieve a unique identifier for it by calling the task’s `getTaskToken` method.

1. Next, write some code to process the tasks that come in. Add the following to your `main` method, right after the code that polls for the task and retrieves its task token.

   ```
       if (task_token != null) {
           String result = null;
           Throwable error = null;
   
           try {
               System.out.println("Executing the activity task with input '" +
                       task.getInput() + "'.");
               result = sayHello(task.getInput());
           } catch (Throwable th) {
               error = th;
           }
   
           if (error == null) {
               System.out.println("The activity task succeeded with result '"
                       + result + "'.");
               swf.respondActivityTaskCompleted(
                   new RespondActivityTaskCompletedRequest()
                       .withTaskToken(task_token)
                       .withResult(result));
           } else {
               System.out.println("The activity task failed with the error '"
                       + error.getClass().getSimpleName() + "'.");
               swf.respondActivityTaskFailed(
                   new RespondActivityTaskFailedRequest()
                       .withTaskToken(task_token)
                       .withReason(error.getClass().getSimpleName())
                       .withDetails(error.getMessage()));
           }
       }
   ```

   If the task token is not `null`, then we can start running the activity method (`sayHello`), providing it with the input data that was sent with the task.

   If the task *succeeded* (no error was generated), then the worker responds to SWF by calling the SWF client’s `respondActivityTaskCompleted` method with a [RespondActivityTaskCompletedRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RespondActivityTaskCompletedRequest.html) object containing the task token and the activity’s result data.

   On the other hand, if the task *failed*, then we respond by calling the `respondActivityTaskFailed` method with a [RespondActivityTaskFailedRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RespondActivityTaskFailedRequest.html) object, passing it the task token and information about the error.

**Note**  
This activity will not shut down gracefully if killed. Although it is beyond the scope of this tutorial, an alternative implementation of this activity worker is provided in the accompanying topic, [Shutting Down Activity and Workflow Workers Gracefully](swf-graceful-shutdown.md).

### Implement the workflow worker
<a name="implement-the-workflow-worker"></a>

Your workflow logic resides in a piece of code known as a **workflow worker**. The workflow worker polls for decision tasks that are sent by Amazon SWF in the domain, and on the default tasklist, that the workflow type was registered with.

When the workflow worker receives a task, it makes some sort of decision (usually whether to schedule a new activity or not) and takes an appropriate action (such as scheduling the activity).

1. Open your text editor and create the file `WorkflowWorker.java`, adding a package declaration and imports according to the [common steps](#swf-hello-common).

1. Add a few additional imports to the file:

   ```
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
   import com.amazonaws.services.simpleworkflow.model.*;
   import java.util.ArrayList;
   import java.util.List;
   import java.util.UUID;
   ```

1. Declare the `WorkflowWorker` class, and create an instance of the [AmazonSimpleWorkflowClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html) class used to access SWF methods.

   ```
       private static final AmazonSimpleWorkflow swf =
               AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
   ```

1. Add the `main` method. The method loops continuously, polling for decision tasks using the SWF client’s `pollForDecisionTask` method. The [PollForDecisionTaskRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/PollForDecisionTaskRequest.html) provides the details.

   ```
       PollForDecisionTaskRequest task_request =
           new PollForDecisionTaskRequest()
               .withDomain(HelloTypes.DOMAIN)
               .withTaskList(new TaskList().withName(HelloTypes.TASKLIST));
   
       while (true) {
           System.out.println(
                   "Polling for a decision task from the tasklist '" +
                   HelloTypes.TASKLIST + "' in the domain '" +
                   HelloTypes.DOMAIN + "'.");
   
           DecisionTask task = swf.pollForDecisionTask(task_request);
   
           String taskToken = task.getTaskToken();
           if (taskToken != null) {
               try {
                   executeDecisionTask(taskToken, task.getEvents());
               } catch (Throwable th) {
                   th.printStackTrace();
               }
           }
       }
   ```

   Once a task is received, we call its `getTaskToken` method, which returns a string that can be used to identify the task. If the returned token is not `null`, then we process it further in the `executeDecisionTask` method, passing it the task token and the list of [HistoryEvent](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/HistoryEvent.html) objects sent with the task.

1. Add the `executeDecisionTask` method, taking the task token (a `String`) and the `HistoryEvent` list.

   ```
       List<Decision> decisions = new ArrayList<Decision>();
       String workflow_input = null;
       int scheduled_activities = 0;
       int open_activities = 0;
       boolean activity_completed = false;
       String result = null;
   ```

   We also set up some data members to keep track of things such as:
   + A list of [Decision](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/Decision.html) objects used to report the results of processing the task.
   + A String to hold workflow input provided by the "WorkflowExecutionStarted" event
   + a count of the scheduled and open (running) activities to avoid scheduling the same activity when it has already been scheduled or is currently running.
   + a boolean to indicate that the activity has completed.
   + A String to hold the activity results, for returning it as our workflow result.

1. Next, add some code to `executeDecisionTask` to process the `HistoryEvent` objects that were sent with the task, based on the event type reported by the `getEventType` method.

   ```
   System.out.println("Executing the decision task for the history events: [");
   for (HistoryEvent event : events) {
       System.out.println("  " + event);
       switch(event.getEventType()) {
           case "WorkflowExecutionStarted":
               workflow_input =
                   event.getWorkflowExecutionStartedEventAttributes()
                        .getInput();
               break;
           case "ActivityTaskScheduled":
               scheduled_activities++;
               break;
           case "ScheduleActivityTaskFailed":
               scheduled_activities--;
               break;
           case "ActivityTaskStarted":
               scheduled_activities--;
               open_activities++;
               break;
           case "ActivityTaskCompleted":
               open_activities--;
               activity_completed = true;
               result = event.getActivityTaskCompletedEventAttributes()
                             .getResult();
               break;
           case "ActivityTaskFailed":
               open_activities--;
               break;
           case "ActivityTaskTimedOut":
               open_activities--;
               break;
       }
   }
   System.out.println("]");
   ```

   For the purposes of our workflow, we are most interested in:
   + the "WorkflowExecutionStarted" event, which indicates that the workflow execution has started (typically meaning that you should run the first activity in the workflow), and that provides the initial input provided to the workflow. In this case, it’s the name portion of our greeting, so it’s saved in a String for use when scheduling the activity to run.
   + the "ActivityTaskCompleted" event, which is sent once the scheduled activity is complete. The event data also includes the return value of the completed activity. Since we have only one activity, we’ll use that value as the result of the entire workflow.

   The other event types can be used if your workflow requires them. See the [HistoryEvent](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/HistoryEvent.html) class description for information about each event type.

   \$1 NOTE: Strings in `switch` statements were introduced in Java 7. If you’re using an earlier version of Java, you can make use of the [EventType](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/simpleworkflow/model/EventType.html) class to convert the `String` returned by `history_event.getType()` to an enum value and then back to a `String` if necessary:

```
EventType et = EventType.fromValue(event.getEventType());
```

1. After the `switch` statement, add more code to respond with an appropriate *decision* based on the task that was received.

   ```
   if (activity_completed) {
       decisions.add(
           new Decision()
               .withDecisionType(DecisionType.CompleteWorkflowExecution)
               .withCompleteWorkflowExecutionDecisionAttributes(
                   new CompleteWorkflowExecutionDecisionAttributes()
                       .withResult(result)));
   } else {
       if (open_activities == 0 && scheduled_activities == 0) {
   
           ScheduleActivityTaskDecisionAttributes attrs =
               new ScheduleActivityTaskDecisionAttributes()
                   .withActivityType(new ActivityType()
                       .withName(HelloTypes.ACTIVITY)
                       .withVersion(HelloTypes.ACTIVITY_VERSION))
                   .withActivityId(UUID.randomUUID().toString())
                   .withInput(workflow_input);
   
           decisions.add(
                   new Decision()
                       .withDecisionType(DecisionType.ScheduleActivityTask)
                       .withScheduleActivityTaskDecisionAttributes(attrs));
       } else {
           // an instance of HelloActivity is already scheduled or running. Do nothing, another
           // task will be scheduled once the activity completes, fails or times out
       }
   }
   
   System.out.println("Exiting the decision task with the decisions " + decisions);
   ```
   + If the activity hasn’t been scheduled yet, we respond with a `ScheduleActivityTask` decision, which provides information in a [ScheduleActivityTaskDecisionAttributes](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/ScheduleActivityTaskDecisionAttributes.html) structure about the activity that Amazon SWF should schedule next, also including any data that Amazon SWF should send to the activity.
   + If the activity was completed, then we consider the entire workflow completed and respond with a `CompletedWorkflowExecution` decision, filling in a [CompleteWorkflowExecutionDecisionAttributes](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/CompleteWorkflowExecutionDecisionAttributes.html) structure to provide details about the completed workflow. In this case, we return the result of the activity.

   In either case, the decision information is added to the `Decision` list that was declared at the top of the method.

1. Complete the decision task by returning the list of `Decision` objects collected while processing the task. Add this code at the end of the `executeDecisionTask` method that we’ve been writing:

   ```
   swf.respondDecisionTaskCompleted(
       new RespondDecisionTaskCompletedRequest()
           .withTaskToken(taskToken)
           .withDecisions(decisions));
   ```

   The SWF client’s `respondDecisionTaskCompleted` method takes the task token that identifies the task as well as the list of `Decision` objects.

### Implement the workflow starter
<a name="implement-the-workflow-starter"></a>

Finally, we’ll write some code to start the workflow execution.

1. Open your text editor and create the file `WorkflowStarter.java`, adding a package declaration and imports according to the [common steps](#swf-hello-common).

1. Add the `WorkflowStarter` class:

   ```
   package aws.example.helloswf;
   
   
   import com.amazonaws.regions.Regions;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
   import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
   import com.amazonaws.services.simpleworkflow.model.*;
   
   public class WorkflowStarter {
       private static final AmazonSimpleWorkflow swf =
               AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
       public static final String WORKFLOW_EXECUTION = "HelloWorldWorkflowExecution";
   
       public static void main(String[] args) {
           String workflow_input = "{SWF}";
           if (args.length > 0) {
               workflow_input = args[0];
           }
   
           System.out.println("Starting the workflow execution '" + WORKFLOW_EXECUTION +
                   "' with input '" + workflow_input + "'.");
   
           WorkflowType wf_type = new WorkflowType()
               .withName(HelloTypes.WORKFLOW)
               .withVersion(HelloTypes.WORKFLOW_VERSION);
   
           Run run = swf.startWorkflowExecution(new StartWorkflowExecutionRequest()
               .withDomain(HelloTypes.DOMAIN)
               .withWorkflowType(wf_type)
               .withWorkflowId(WORKFLOW_EXECUTION)
               .withInput(workflow_input)
               .withExecutionStartToCloseTimeout("90"));
   
           System.out.println("Workflow execution started with the run id '" +
                   run.getRunId() + "'.");
       }
   }
   ```

   The `WorkflowStarter` class consists of a single method, `main`, which takes an optional argument passed on the command-line as input data for the workflow.

   The SWF client method, `startWorkflowExecution`, takes a [StartWorkflowExecutionRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/StartWorkflowExecutionRequest.html) object as input. Here, in addition to specifying the domain and workflow type to run, we provide it with:
   + a human-readable workflow execution name
   + workflow input data (provided on the command-line in our example)
   + a timeout value that represents how long, in seconds, that the entire workflow should take to run.

   The [Run](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/Run.html) object that `startWorkflowExecution` returns provides a *run ID*, a value that can be used to identify this particular workflow execution in Amazon SWF's history of your workflow executions.

   \$1 NOTE: The run ID is generated by Amazon SWF, and is *not* the same as the workflow execution name that you pass in when starting the workflow execution.

## Build the example
<a name="swf-hello-build"></a>

To build the example project with Maven, go to the `helloswf` directory and type:

```
mvn package
```

The resulting `helloswf-1.0.jar` will be generated in the `target` directory.

## Run the example
<a name="run-the-example"></a>

The example consists of four separate executable classes, which are run independently of each other.

**Note**  
If you are using a Linux, macOS, or Unix system, you can run all of them, one after another, in a single terminal window. If you are running Windows, you should open two additional command-line instances and navigate to the `helloswf` directory in each.

### Setting the Java classpath
<a name="swf-hello-set-classpath"></a>

Although Maven has handled the dependencies for you, to run the example, you’ll need to provide the AWS SDK library and its dependencies on your Java classpath. You can either set the `CLASSPATH` environment variable to the location of your AWS SDK libraries and the `third-party/lib` directory in the SDK, which includes necessary dependencies:

```
export CLASSPATH='target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/*'
java example.swf.hello.HelloTypes
```

or use the ** ` java ` ** command’s `-cp` option to set the classpath while running each applications.

```
java -cp target/helloswf-1.0.jar:/path/to/sdk/lib/*:/path/to/sdk/third-party/lib/* \
  example.swf.hello.HelloTypes
```

The style that you use is up to you. If you had no trouble building the code, both then try to run the examples and get a series of "NoClassDefFound" errors, it is likely because the classpath is set incorrectly.

### Register the domain, workflow and activity types
<a name="swf-hello-run-register"></a>

Before running your workers and the workflow starter, you’ll need to register the domain and your workflow and activity types. The code to do this was implemented in [Register a domain workflow and activity types](#swf-hello-hellotypes).

After building, and if you’ve [set the CLASSPATH](#swf-hello-set-classpath), you can run the registration code by executing the command:

```
    echo 'Supply the name of one of the example classes as an argument.'
```

### Start the activity and workflow workers
<a name="swf-hello-run-workers"></a>

Now that the types have been registered, you can start the activity and workflow workers. These will continue to run and poll for tasks until they are killed, so you should either run them in separate terminal windows, or, if you’re running on Linux, macOS, or Unix you can use the `&` operator to cause each of them to spawn a separate process when run.

```
    echo 'If there are arguments to the class, put them in quotes after the class name.'
    exit 1
```

If you’re running these commands in separate windows, omit the final `&` operator from each line.

### Start the workflow execution
<a name="swf-hello-start-execution"></a>

Now that your activity and workflow workers are polling, you can start the workflow execution. This process will run until the workflow returns a completed status. You should run it in a new terminal window (unless you ran your workers as new spawned processes by using the `&` operator).

```
fi
```

**Note**  
If you want to provide your own input data, which will be passed first to the workflow and then to the activity, add it to the command-line. For example:  

```
echo "## Running $className..."
```

Once you begin the workflow execution, you should start seeing output delivered by both workers and by the workflow execution itself. When the workflow finally completes, its output will be printed to the screen.

## Complete source for this example
<a name="complete-source-for-this-example"></a>

You can browse the [complete source](https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/java/example_code/swf) for this example on Github in the *aws-java-developer-guide* repository.

## For more information
<a name="for-more-information"></a>
+ The workers presented here can result in lost tasks if they are shutdown while a workflow poll is still going on. To find out how to shut down workers gracefully, see [Shutting Down Activity and Workflow Workers Gracefully](swf-graceful-shutdown.md).
+ To learn more about Amazon SWF, visit the [Amazon SWF](https://aws.amazon.com/swf/) home page or view the [Amazon SWF Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/developerguide/).
+ You can use the AWS Flow Framework for Java to write more complex workflows in an elegant Java style using annotations. To learn more, see the [AWS Flow Framework for Java Developer Guide](https://docs.aws.amazon.com/amazonswf/latest/awsflowguide/).

# Lambda Tasks
<a name="swf-lambda-task"></a>

As an alternative to, or in conjunction with, Amazon SWF activities, you can use [Lambda](https://aws.amazon.com/lambda/) functions to represent units of work in your workflows, and schedule them similarly to activities.

This topic focuses on how to implement Amazon SWF Lambda tasks using the AWS SDK for Java. For more information about Lambda tasks in general, see [AWS Lambda Tasks](https://docs.aws.amazon.com/amazonswf/latest/developerguide/lambda-task.html) in the Amazon SWF Developer Guide.

## Set up a cross-service IAM role to run your Lambda function
<a name="set-up-a-cross-service-iam-role-to-run-your-lambda-function"></a>

Before Amazon SWF can run your Lambda function, you need to set up an IAM role to give Amazon SWF permission to run Lambda functions on your behalf. For complete information about how to do this, see [AWS Lambda Tasks](https://docs.aws.amazon.com/amazonswf/latest/developerguide/lambda-task.html).

You will need the Amazon Resource Name (ARN) of this IAM role when you register a workflow that will use Lambda tasks.

## Create a Lambda function
<a name="create-a-lambda-function"></a>

You can write Lambda functions in a number of different languages, including Java. For complete information about how to author, deploy and use Lambda functions, see the [AWS Lambda Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/).

**Note**  
It doesn’t matter what language you use to write your Lambda function, it can be scheduled and run by *any* Amazon SWF workflow, regardless of the language that your workflow code is written in. Amazon SWF handles the details of running the function and passing data to and from it.

Here’s a simple Lambda function that could be used in place of the activity in [Building a Simple Amazon SWF Application](swf-hello.md).
+ This version is written in JavaScript, which can be entered directly using the [AWS Management Console](https://console.aws.amazon.com/console/home):

  ```
  exports.handler = function(event, context) {
      context.succeed("Hello, " + event.who + "!");
  };
  ```
+ Here is the same function written in Java, which you could also deploy and run on Lambda:

  ```
  package example.swf.hellolambda;
  
  import com.amazonaws.services.lambda.runtime.Context;
  import com.amazonaws.services.lambda.runtime.RequestHandler;
  import com.amazonaws.util.json.JSONException;
  import com.amazonaws.util.json.JSONObject;
  
  public class SwfHelloLambdaFunction implements RequestHandler<Object, Object> {
      @Override
      public Object handleRequest(Object input, Context context) {
          String who = "{SWF}";
          if (input != null) {
              JSONObject jso = null;
              try {
                  jso = new JSONObject(input.toString());
                  who = jso.getString("who");
              } catch (JSONException e) {
                  e.printStackTrace();
              }
          }
          return ("Hello, " + who + "!");
      }
  }
  ```
**Note**  
To learn more about deploying Java functions to Lambda, see [Creating a Deployment Package (Java)](https://docs.aws.amazon.com/lambda/latest/dg/lambda-java-how-to-create-deployment-package.html) in the AWS Lambda Developer Guide. You will also want to look at the section titled [Programming Model for Authoring Lambda Functions in Java](https://docs.aws.amazon.com/lambda/latest/dg/java-programming-model.html).

 Lambda functions take an *event* or *input* object as the first parameter, and a *context* object as the second, which provides information about the request to run the Lambda function. This particular function expects input to be in JSON, with a `who` field set to the name used to create the greeting.

## Register a workflow for use with Lambda
<a name="register-a-workflow-for-use-with-lam"></a>

For a workflow to schedule a Lambda function, you must provide the name of the IAM role that provides Amazon SWF with permission to invoke Lambda functions. You can set this during workflow registration by using the `withDefaultLambdaRole` or `setDefaultLambdaRole` methods of [RegisterWorkflowTypeRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterWorkflowTypeRequest.html).

```
System.out.println("** Registering the workflow type '" + WORKFLOW + "-" + WORKFLOW_VERSION
        + "'.");
try {
    swf.registerWorkflowType(new RegisterWorkflowTypeRequest()
        .withDomain(DOMAIN)
        .withName(WORKFLOW)
        .withDefaultLambdaRole(lambda_role_arn)
        .withVersion(WORKFLOW_VERSION)
        .withDefaultChildPolicy(ChildPolicy.TERMINATE)
        .withDefaultTaskList(new TaskList().withName(TASKLIST))
        .withDefaultTaskStartToCloseTimeout("30"));
}
catch (TypeAlreadyExistsException e) {
```

## Schedule a Lambda task
<a name="schedule-a-lam-task"></a>

Schedule a Lambda task is similar to scheduling an activity. You provide a [Decision](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/Decision.html) with a `ScheduleLambdaFunction`[DecisionType](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DecisionType.html) and with [ScheduleLambdaFunctionDecisionAttributes](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/ScheduleLambdaFunctionDecisionAttributes.html).

```
running_functions == 0 && scheduled_functions == 0) {
AWSLambda lam = AWSLambdaClientBuilder.defaultClient();
GetFunctionConfigurationResult function_config =
    lam.getFunctionConfiguration(
            new GetFunctionConfigurationRequest()
                .withFunctionName("HelloFunction"));
String function_arn = function_config.getFunctionArn();

ScheduleLambdaFunctionDecisionAttributes attrs =
    new ScheduleLambdaFunctionDecisionAttributes()
        .withId("HelloFunction (Lambda task example)")
        .withName(function_arn)
        .withInput(workflow_input);

decisions.add(
```

In the `ScheduleLambdaFuntionDecisionAttributes`, you must supply a *name*, which is the ARN of the Lambda function to call, and an *id*, which is the name that Amazon SWF will use to identify the Lambda function in history logs.

You can also provide optional *input* for the Lambda function and set its *start to close timeout* value, which is the number of seconds that the Lambda function is allowed to run before generating a `LambdaFunctionTimedOut` event.

**Note**  
This code uses the [AWSLambdaClient](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/lambda/AWSLambdaClient.html) to retrieve the ARN of the Lambda function, given the function name. You can use this technique to avoid hard-coding the full ARN (which includes your AWS account ID) in your code.

## Handle Lambda function events in your decider
<a name="handle-lam-function-events-in-your-decider"></a>

 Lambda tasks will generate a number of events that you can take action on when polling for decision tasks in your workflow worker, corresponding to the lifecycle of your Lambda task, with [EventType](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/EventType.html) values such as `LambdaFunctionScheduled`, `LambdaFunctionStarted`, and `LambdaFunctionCompleted`. If the Lambda function fails, or takes longer to run than its set timeout value, you will receive either a `LambdaFunctionFailed` or `LambdaFunctionTimedOut` event type, respectively.

```
boolean function_completed = false;
String result = null;

System.out.println("Executing the decision task for the history events: [");
for (HistoryEvent event : events) {
    System.out.println("  " + event);
    EventType event_type = EventType.fromValue(event.getEventType());
    switch(event_type) {
    case WorkflowExecutionStarted:
        workflow_input =
            event.getWorkflowExecutionStartedEventAttributes()
                 .getInput();
        break;
    case LambdaFunctionScheduled:
        scheduled_functions++;
        break;
    case ScheduleLambdaFunctionFailed:
        scheduled_functions--;
        break;
    case LambdaFunctionStarted:
        scheduled_functions--;
        running_functions++;
        break;
    case LambdaFunctionCompleted:
        running_functions--;
        function_completed = true;
        result = event.getLambdaFunctionCompletedEventAttributes()
                      .getResult();
        break;
    case LambdaFunctionFailed:
        running_functions--;
        break;
    case LambdaFunctionTimedOut:
        running_functions--;
        break;
```

## Receive output from your Lambda function
<a name="receive-output-from-your-lam-function"></a>

When you receive a `LambdaFunctionCompleted`[EventType](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/EventType.html), you can retrieve your 0 function’s return value by first calling `getLambdaFunctionCompletedEventAttributes` on the [HistoryEvent](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/HistoryEvent.html) to get a [LambdaFunctionCompletedEventAttributes](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/LambdaFunctionCompletedEventAttributes.html) object, and then calling its `getResult` method to retrieve the output of the Lambda function:

```
 LambdaFunctionCompleted:
running_functions--;
```

## Complete source for this example
<a name="complete-source-for-this-example"></a>

You can browse the *complete source :github:`<awsdocs/aws-java-developer-guide/tree/master/doc\$1source/snippets/helloswf\$1lambda/>* for this example on Github in the *aws-java-developer-guide* repository.

# Shutting Down Activity and Workflow Workers Gracefully
<a name="swf-graceful-shutdown"></a>

The [Building a Simple Amazon SWF Application](swf-hello.md) topic provided a complete implementation of a simple workflow application consisting of a registration application, an activity and workflow worker, and a workflow starter.

Worker classes are designed to run continuously, polling for tasks sent by Amazon SWF in order to run activities or return decisions. Once a poll request is made, Amazon SWF records the poller and will attempt to assign a task to it.

If the workflow worker is terminated during a long poll, Amazon SWF may still try to send a task to the terminated worker, resulting in a lost task (until the task times out).

One way to handle this situation is to wait for all long poll requests to return before the worker terminates.

In this topic, we’ll rewrite the activity worker from `helloswf`, using Java’s shutdown hooks to attempt a graceful shutdown of the activity worker.

Here is the complete code:

```
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow;
import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClientBuilder;
import com.amazonaws.services.simpleworkflow.model.ActivityTask;
import com.amazonaws.services.simpleworkflow.model.PollForActivityTaskRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskCompletedRequest;
import com.amazonaws.services.simpleworkflow.model.RespondActivityTaskFailedRequest;
import com.amazonaws.services.simpleworkflow.model.TaskList;

public class ActivityWorkerWithGracefulShutdown {

    private static final AmazonSimpleWorkflow swf =
        AmazonSimpleWorkflowClientBuilder.standard().withRegion(Regions.DEFAULT_REGION).build();
    private static final CountDownLatch waitForTermination = new CountDownLatch(1);
    private static volatile boolean terminate = false;

    private static String executeActivityTask(String input) throws Throwable {
        return "Hello, " + input + "!";
    }

    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    terminate = true;
                    System.out.println("Waiting for the current poll request" +
                            " to return before shutting down.");
                    waitForTermination.await(60, TimeUnit.SECONDS);
                }
                catch (InterruptedException e) {
                    // ignore
                }
            }
        });
        try {
            pollAndExecute();
        }
        finally {
            waitForTermination.countDown();
        }
    }

    public static void pollAndExecute() {
        while (!terminate) {
            System.out.println("Polling for an activity task from the tasklist '"
                    + HelloTypes.TASKLIST + "' in the domain '" +
                    HelloTypes.DOMAIN + "'.");

            ActivityTask task = swf.pollForActivityTask(new PollForActivityTaskRequest()
                .withDomain(HelloTypes.DOMAIN)
                .withTaskList(new TaskList().withName(HelloTypes.TASKLIST)));

            String taskToken = task.getTaskToken();

            if (taskToken != null) {
                String result = null;
                Throwable error = null;

                try {
                    System.out.println("Executing the activity task with input '"
                            + task.getInput() + "'.");
                    result = executeActivityTask(task.getInput());
                }
                catch (Throwable th) {
                    error = th;
                }

                if (error == null) {
                    System.out.println("The activity task succeeded with result '"
                            + result + "'.");
                    swf.respondActivityTaskCompleted(
                        new RespondActivityTaskCompletedRequest()
                            .withTaskToken(taskToken)
                            .withResult(result));
                }
                else {
                    System.out.println("The activity task failed with the error '"
                            + error.getClass().getSimpleName() + "'.");
                    swf.respondActivityTaskFailed(
                        new RespondActivityTaskFailedRequest()
                            .withTaskToken(taskToken)
                            .withReason(error.getClass().getSimpleName())
                            .withDetails(error.getMessage()));
                }
            }
        }
    }
}
```

In this version, the polling code that was in the `main` function in the original version has been moved into its own method, `pollAndExecute`.

The `main` function now uses a [CountDownLatch](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CountDownLatch.html) in conjunction with a [shutdown hook](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Runtime.html) to cause the thread to wait for up to 60 seconds after its termination is requested before letting the thread shut down.

# Registering Domains
<a name="prog-services-swf-register-domain"></a>

Every workflow and activity in [Amazon SWF](https://aws.amazon.com/swf/) needs a *domain* to run in.

1. Create a new [RegisterDomainRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/RegisterDomainRequest.html) object, providing it with at least the domain name and workflow execution retention period (these parameters are both required).

1. Call the [AmazonSimpleWorkflowClient.registerDomain](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html#registerDomain-com.amazonaws.services.simpleworkflow.model.RegisterDomainRequest-) method with the *RegisterDomainRequest* object.

1. Catch the [DomainAlreadyExistsException](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainAlreadyExistsException.html) if the domain you’re requesting already exists (in which case, no action is usually required).

The following code demonstrates this procedure:

```
public void register_swf_domain(AmazonSimpleWorkflowClient swf, String name)
{
    RegisterDomainRequest request = new RegisterDomainRequest().withName(name);
    request.setWorkflowExecutionRetentionPeriodInDays("10");
    try
    {
        swf.registerDomain(request);
    }
    catch (DomainAlreadyExistsException e)
    {
        System.out.println("Domain already exists!");
    }
}
```

# Listing Domains
<a name="prog-services-swf-list-domains"></a>

You can list the [Amazon SWF](https://aws.amazon.com/swf/) domains associated with your account and AWS region by registration type.

1. Create a [ListDomainsRequest](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/ListDomainsRequest.html) object, and specify the registration status of the domains that you’re interested in—​this is required.

1. Call [AmazonSimpleWorkflowClient.listDomains](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/AmazonSimpleWorkflowClient.html#listDomains-com.amazonaws.services.simpleworkflow.model.ListDomainsRequest-) with the *ListDomainRequest* object. Results are provided in a [DomainInfos](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainInfos.html) object.

1. Call [getDomainInfos](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainInfos.html#getDomainInfos--) on the returned object to get a list of [DomainInfo](https://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainInfo.html) objects.

1. Call [getName](http://docs.aws.amazon.com/sdk-for-java/v1/reference/com/amazonaws/services/simpleworkflow/model/DomainInfo.html#getName--) on each *DomainInfo* object to get its name.

The following code demonstrates this procedure:

```
public void list_swf_domains(AmazonSimpleWorkflowClient swf)
{
    ListDomainsRequest request = new ListDomainsRequest();
    request.setRegistrationStatus("REGISTERED");
    DomainInfos domains = swf.listDomains(request);
    System.out.println("Current Domains:");
    for (DomainInfo di : domains.getDomainInfos())
    {
        System.out.println(" * " + di.getName());
    }
}
```

# Code Samples included with the SDK
<a name="java-dg-samples"></a>

The AWS SDK for Java comes packaged with code samples that demonstrate many of the features of the SDK in buildable, runnable programs. You can study or modify these to implement your own AWS solutions using the AWS SDK for Java.

## How to Get the Samples
<a name="how-to-get-the-samples"></a>

The AWS SDK for Java code samples are provided in the *samples* directory of the SDK. If you downloaded and installed the SDK using the information in [Set up the AWS SDK for Java](setup-install.md), you already have the samples on your system.

You can also view the latest samples on the AWS SDK for Java GitHub repository, in the [src/samples](https://github.com/aws/aws-sdk-java/tree/master/src/samples) directory.

## Building and Running the Samples Using the Command Line
<a name="samples-cmdline"></a>

The samples include [Ant](http://ant.apache.org/) build scripts so that you can easily build and run them from the command line. Each sample also contains a README file in HTML format that contains information specific to each sample.

**Note**  
If you’re browsing the sample code on GitHub, click the **Raw** button in the source code display when viewing the sample’s README.html file. In raw mode, the HTML will render as intended in your browser.

### Prerequisites
<a name="prerequisitessamples"></a>

Before running any of the AWS SDK for Java samples, you need to set your AWS credentials in the environment or with the AWS CLI, as specified in [Set up AWS Credentials and Region for Development](setup-credentials.md). The samples use the default credential provider chain whenever possible. So by setting your credentials in this way, you can avoid the risky practice of inserting your AWS credentials in files within the source code directory (where they may inadvertently be checked in and shared publicly).

### Running the Samples
<a name="running-the-samples"></a>

1. Change to the directory containing the sample’s code. For example, if you’re in the root directory of the AWS SDK download and want to run the `AwsConsoleApp` sample, you would type:

   ```
   cd samples/AwsConsoleApp
   ```

1. Build and run the sample with Ant. The default build target performs both actions, so you can just enter:

   ```
   ant
   ```

The sample prints information to standard output—​for example:

```
===========================================

Welcome to the {AWS} Java SDK!

===========================================
You have access to 4 Availability Zones.

You have 0 {EC2} instance(s) running.

You have 13 Amazon SimpleDB domain(s) containing a total of 62 items.

You have 23 {S3} bucket(s), containing 44 objects with a total size of 154767691 bytes.
```

## Building and Running the Samples Using the Eclipse IDE
<a name="building-and-running-the-samples-using-the-eclipse-ide"></a>

If you use the AWS Toolkit for Eclipse, you can also start a new project in Eclipse based on the AWS SDK for Java or add the SDK to an existing Java project.

### Prerequisites
<a name="id1samples"></a>

After installing the AWS Toolkit for Eclipse, we recommend configuring the Toolkit with your security credentials. You can do this anytime by choosing **Preferences** from the **Window** menu in Eclipse, and then choosing the ** AWS Toolkit** section.

### Running the Samples
<a name="id2"></a>

1. Open Eclipse.

1. Create a new AWS Java project. In Eclipse, on the **File** menu, choose **New**, and then click **Project**. The **New Project** wizard opens.

1. Expand the ** AWS ** category, then choose ** AWS Java Project**.

1. Choose **Next**. The project settings page is displayed.

1. Enter a name in the **Project Name** box. The AWS SDK for Java Samples group displays the samples available in the SDK, as described previously.

1. Select the samples you want to include in your project by selecting each check box.

1. Enter your AWS credentials. If you’ve already configured the AWS Toolkit for Eclipse with your credentials, this is automatically filled in.

1. Choose **Finish**. The project is created and added to the **Project Explorer**.

1. Choose the sample `.java` file you want to run. For example, for the Amazon S3 sample, choose `S3Sample.java`.

1. Choose **Run** from the **Run** menu.

1. Right-click the project in **Project Explorer**, point to **Build Path**, and then choose **Add Libraries**.

1. Choose ** AWS Java SDK**, choose **Next**, and then follow the remaining on-screen instructions.