Skip to content

Commit

Permalink
Updated IoT samples
Browse files Browse the repository at this point in the history
- added a web socket sample
- improved readme and other misc fixes
  • Loading branch information
AWS committed May 16, 2016
1 parent af7642c commit 9632580
Show file tree
Hide file tree
Showing 19 changed files with 984 additions and 86 deletions.
86 changes: 64 additions & 22 deletions AndroidPubSub/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,83 @@ This sample demonstrates use of the AWS IoT APIs to securely publish to and subs
* aws-android-sdk-core-X.X.X.jar
* aws-android-sdk-iot-X.X.X.jar

1. In the [Amazon Cognito console](https://console.aws.amazon.com/cognito/), use Amazon Cognito to create a new identity pool. Obtain the `PoolID` constant. Make sure the [role](https://console.aws.amazon.com/iam/home?region=us-east-1#roles) has full permissions to access the AWS IoT APIs, as shown in this example:
**Note**: Adding support for MQTT over WebSocket connections is only available in the Paho project nightly builds. The Gradle file is currently configured to add the Paho snapshot repository. This project will be updated to the official build after release as part of [Eclipse Neon](https://projects.eclipse.org/projects/technology.paho/releases/1.2.0).

```
{
"Version": "2012-10-17",
"Statement": [
1. This sample requires Cognito to authorize to AWS IoT in order to create a device certificate. Use Amazon Cognito to create a new identity pool.
1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), select`Create Identity Pool`.
1. Ensure`Enable access to unauthenticated identities` is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool.

**Important**: see note below on unauthenticated user access.

1. Obtain the `PoolID` constant. This will be used in the application.
1. As part of creating the identity pool Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to:`Cognito_PoolNameAuth_Role` and`Cognito_PoolNameUnauth_Role`.
1. Now we will attach a policy to the unauthenticated role which has permissions to access the required AWS IoT APIs. This is done by first creating an IAM Policy in the [IAM Console](https://console.aws.amazon.com/iam/home#policies) and then attaching it to the unauthenticated role. Below is an example policy which can be used with the sample application. This policy allows the application to create a new certificate (including private key) as well as attach an existing policy to a certificate.

```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:*"
],
"Resource": "*"
}
]
}
```

To access the service any certificate needs to have a policy associated. This policy contols what actions are able to be performed by the client authenticating with that particular certificate. This sample application does not create its own policy, rather it assumes a policy has been created in the service. When the application creates a certificate it makes a service call to associate the pre-existing policy with the newly created certificate.

1. In the [Amazon AWS IoT console](https://console.aws.amazon.com/iot/), create a policy with full permissions to access AWS IoT as shown in this example. Select 'Create a Policy', fill in the 'Name' field, set 'Action' to 'iot:\*', set 'Resource' to '\*', and then click 'Create'.
"Effect": "Allow",
"Action": [
"iot:AttachPrincipalPolicy",
"iot:CreateKeysAndCertificate"
],
"Resource": [
"*"
]
}
]
}
```

More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on AWS IoT policies can be found [here](http://docs.aws.amazon.com/iot/latest/developerguide/authorization.html).

**Note**: to keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions if used in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).

1. Note that the application does not actually create the AWS IoT policy itself, rather it relies on a policy to already be created in AWS IoT and then makes a call to attach that policy to the newly created certificate. To create a policy in AWS IoT,
1. navigate to the [AWS IoT Console](https://console.aws.amazon.com/iot/home)
1. Click on Create a Resource
1. Click on Create a Policy
1. Give the policy a name. Note this name as this is the string you will use in the application when making the attach policy API call.
1. The policy should be created to allow connecting to AWS IoT as well as allowing publishing, subscribing and receiving messages on whatever topics you will use in the sample application. Below is an example policy. This policy allows access to all topics under your AWS IoT account. To scope this policy down to specific toipcs specify them explicitly as ARNs in the resource section: `"Resource": "arn:aws:iot:<REGION>:<ACCOUNT ID>:topic/mytopic/mysubtopic"`. Note that the first `topic` is an ARN specifer so this example actually specifies the topic `mytopic/mysubtopic`.

```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:Connect",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Receive"
],
"Resource": "*"
}
]
}
```

1. Open the AndroidPubSub project.

1. Open `PubSubActivity.java` and update the following constants with the appropriate values:

```
CUSTOMER_SPECIFIC_ENDPOINT_PREFIX = "<CUSTOMER SPECIFIC ENDPOINT PREFIX>";
COGNITO_POOL_ID = "<COGNITO POOL ID GOES HERE>";
AWS_IOT_POLICY_NAME = "<YOUR IOT POLICY GOES HERE>";
CUSTOMER_SPECIFIC_ENDPOINT = "<CHANGE_ME>";
COGNITO_POOL_ID = "<CHANGE_ME>";
AWS_IOT_POLICY_NAME = "CHANGE_ME";
MY_REGION = Regions.US_EAST_1;
KEYSTORE_NAME = "iot_keystore";
KEYSTORE_PASSWORD = "password";
CERTIFICATE_ID = "default";
```
The customer specific endpoint, Cognito pool ID, Region and AWS IoT policy name will need to be updated to reflect the values in your account. For the others the default values will work, however you can update them to reflect your setup.
The customer specific endpoint, Cognito pool ID, Region and AWS IoT policy name will need to be updated to reflect the values in your account. The policy name is the name used when creating the IoT policy above. For the other parameters the default values will work for this sample application. The following describes these parameters in case they need to be updated going forward past this sample. The keystore name is the name used when writing the keystore file to the application's file directory. The password is the password given to protect the keystore when written. Certificate ID is the alias in the keystore for the certificate and private key entry. If you end up creating a keystore off of the device you will need to update this to match the alias given when importing the certificate into the keystore.

1. Build and run the sample app.

Expand Down
5 changes: 3 additions & 2 deletions AndroidPubSub/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
repositories {
jcenter()
maven { url "https://repo.eclipse.org/content/repositories/paho-snapshots" }
}

buildscript {
Expand All @@ -8,14 +9,14 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.android.tools.build:gradle:1.5.0'
}
}

apply plugin: 'com.android.application'

dependencies {
compile 'com.amazonaws:aws-android-sdk-iot:2.2.12+'
compile 'com.amazonaws:aws-android-sdk-iot:2.2.+'
}

android {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ public class PubSubActivity extends Activity {

// --- Constants to modify per your configuration ---

// Endpoint Prefix = random characters at the beginning of the custom AWS
// IoT endpoint
// describe endpoint call returns: XXXXXXXXXX.iot.<region>.amazonaws.com,
// endpoint prefix string is XXXXXXX
private static final String CUSTOMER_SPECIFIC_ENDPOINT_PREFIX = "CHANGE_ME";
// AWS Iot CLI describe-endpoint call returns: XXXXXXXXXX.iot.<region>.amazonaws.com
private static final String CUSTOMER_SPECIFIC_ENDPOINT = "CHANGE_ME";
// Cognito pool ID. For this app, pool needs to be unauthenticated pool with
// AWS IoT permissions.
private static final String COGNITO_POOL_ID = "CHANGE_ME";
Expand Down Expand Up @@ -134,7 +132,7 @@ protected void onCreate(Bundle savedInstanceState) {
Region region = Region.getRegion(MY_REGION);

// MQTT Client
mqttManager = new AWSIotMqttManager(clientId, region, CUSTOMER_SPECIFIC_ENDPOINT_PREFIX);
mqttManager = new AWSIotMqttManager(clientId, CUSTOMER_SPECIFIC_ENDPOINT);

// Set keepalive to 10 seconds. Will recognize disconnects more quickly but will also send
// MQTT pings every 10 seconds.
Expand Down
26 changes: 26 additions & 0 deletions AndroidPubSubWebSocket/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amazonaws.demo.androidpubsubwebsocket"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name="com.amazonaws.demo.androidpubsubwebsocket.PubSubActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
88 changes: 88 additions & 0 deletions AndroidPubSubWebSocket/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Android PubSub with WebSockets Sample

This sample demonstrates use of the AWS IoT APIs to securely publish to and subscribe from MQTT topics with a WebSocket. Authentication of the WebSocket connection is done with Amazon Cognito. Once a connection to the AWS IoT platform has been established, the application presents a simple UI to publish and subscribe over MQTT.

## Requirements

* AndroidStudio or Eclipse
* Android API 10 or greater

## Using the Sample

1. Import the AndroidPubSubWebSocket project into your IDE.
- If you are using Android Studio:
* From the Welcome screen, click on "Import project".
* Browse to the AndroidPubSubWebSocket directory and press OK.
* Accept the messages about adding Gradle to the project.
* If the SDK reports some missing Android SDK packages (like Build Tools or the Android API package), follow the instructions to install them.
- If you are using Eclipse:
* Go to File -> Import. Import Wizard will open.
* Select General -> Existing Projects into Workspace. Click Next.
* In Select root directory, browse to the samples directory.
* Select the AndroidPubSubWebSocket project to import.
* Click Finish.

1. Import the libraries :
- If you use Android Studio, Gradle will take care of downloading these dependencies for you.
- If you use Eclipse, you will need to download the AWS SDK for Android (http://aws.amazon.com/mobile/sdk/) and extract and copy these jars into the 'libs' directory for the project:
* aws-android-sdk-core-X.X.X.jar
* aws-android-sdk-iot-X.X.X.jar

**Note**: Adding support for MQTT over WebSocket connections is only available in the Paho project nightly builds. The Gradle file is currently configured to add the Paho snapshot repository. This project will be updated to the official build after release as part of [Eclipse Neon](https://projects.eclipse.org/projects/technology.paho/releases/1.2.0).

1. This sample requires Cognito to authorize to AWS IoT and establish a WebSocket connection. Use Amazon Cognito to create a new identity pool:
1. In the [Amazon Cognito Console](https://console.aws.amazon.com/cognito/), select`Create Identity Pool`.
1. Ensure`Enable access to unauthenticated identities` is checked. This allows the sample application to assume the unauthenticated role associated with this identity pool.

**Important**: see note below on unauthenticated user access.

1. Obtain the `PoolID` constant. This will be used in the application.
1. As part of creating the identity pool Cognito will setup two roles in [Identity and Access Management (IAM)](https://console.aws.amazon.com/iam/home#roles). These will be named something similar to:`Cognito_PoolNameAuth_Role` and`Cognito_PoolNameUnauth_Role`.
1. Now we will attach a policy to the unauthenticated role which has permissions to access the required AWS IoT APIs. This is done by first creating an IAM Policy in the [IAM Console](https://console.aws.amazon.com/iam/home#policies) and then attaching it to the unauthenticated role. Below is an example policy which can be used with the sample application. This policy allows any client ID to connect and allows publishing, subscribing and receiving messages on the topic:`mytopic/mysubtopic`.

```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:<REGION>:<ACCOUNT ID>:topic/mytopic/mysubtopic"
]
}
]
}
```

More information on AWS IAM roles and policies can be found [here](http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html). More information on AWS IoT policies can be found [here](http://docs.aws.amazon.com/iot/latest/developerguide/authorization.html).

**Note**: to keep this example simple it makes use of unauthenticated users in the identity pool. This can be used for getting started and prototypes but unauthenticated users should typically only be given read-only permissions if used in production applications. More information on Cognito identity pools including the Cognito developer guide can be found [here](http://aws.amazon.com/cognito/).

1. Open the AndroidPubSubWebSocket project.

1. Open `PubSubActivity.java` and update the following constants with the appropriate values:

```
CUSTOMER_SPECIFIC_ENDPOINT = "<CHANGE_ME>";
COGNITO_POOL_ID = "<CHANGE_ME>";
MY_REGION = Regions.US_EAST_1;
```

1. Build and run the sample app.

1. The sample application will allow you to connect to the AWS IoT platform, and then publish or subscribe to a topic using MQTT.

48 changes: 48 additions & 0 deletions AndroidPubSubWebSocket/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
repositories {
jcenter()
maven { url "https://repo.eclipse.org/content/repositories/paho-snapshots" }
}

buildscript {
repositories {
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}

apply plugin: 'com.android.application'

dependencies {
compile 'com.amazonaws:aws-android-sdk-iot:2.2.+'
}

android {
buildToolsVersion "23.0.2"
compileSdkVersion 23

defaultConfig {
versionCode 1
versionName "1.0.0"
minSdkVersion 10
targetSdkVersion 23
}

lintOptions {
abortOnError false
}

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Tue Mar 01 13:56:18 PST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
Loading

0 comments on commit 9632580

Please sign in to comment.