Skip to content
This repository was archived by the owner on Feb 3, 2022. It is now read-only.

Commit fd70dce

Browse files
authored
Merge pull request #27 from rossiam/PI-373
[PI-373] Add AWS Lamba example and documentation.
2 parents c3d4f08 + 21a15f9 commit fd70dce

File tree

14 files changed

+752
-7
lines changed

14 files changed

+752
-7
lines changed

.circleci/config.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ workflows:
243243
jobs:
244244
- 'Checkout':
245245
filters:
246+
branches:
247+
only: /.*/ # unblocking branch builds
246248
tags:
247249
only: /.*/ # ensure this job does not block publishing via tag
248250
- 'Dependencies':
@@ -293,5 +295,3 @@ workflows:
293295
only: *semVerRegExp # allow publish tag matches any semVer
294296
branches:
295297
ignore: /.*/ # ignore all branch builds
296-
297-

docs/aws-logo.png

2.94 KB
Loading
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# java-lambda-smartapp ![java-logo](../../docs/java-logo.png) ![aws-logo](../../docs/aws-logo.png)
2+
3+
This sample demonstrates a simple [Java](https://www.oracle.com/java/) server using
4+
[AWS Lambdas](https://aws.amazon.com).
5+
6+
## Requirements
7+
8+
* Java 1.8
9+
* [SmartThings developer](https://devworkspace.developer.samsung.com) account
10+
* [Amazon Web Services](https://aws.amazon.com/) account
11+
12+
## Installing the Example
13+
14+
Follow the steps below to install and run this sample SmartApp.
15+
16+
1. Install the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
17+
2. Configure the CLI to use your account.
18+
19+
1. Get an access key to use when deploying and configuring your SmartApp.
20+
21+
1. Find "My Security Credentials" under your account settings.
22+
2. Expand "Access keys (access key ID and secret access key)".
23+
3. If you already have an access key _and_ you know the secret for it, you can use that one.
24+
4. Otherwise, create a new key and note the id and secret.
25+
26+
1. Run `aws configure` and populate as follows:
27+
28+
| Option | Value |
29+
|-----------------------|-------------------------------------|
30+
| AWS Access Key ID | id from above |
31+
| AWS Secret Access Key | secret from above |
32+
| Default region name | choose an [AWS region](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html) geographically close to your end-user's location |
33+
| AWS Access Key ID | enter 'json' here |
34+
35+
3. Create a role for the lambda to use. You'll find "Roles" under "My Security Credentials".
36+
Create the role with the following options:
37+
38+
39+
| Option | Value |
40+
|-----------|-----------------------------------|
41+
| Service | Lambda |
42+
| Policy | AWSLambdaFullAccess |
43+
| Tags | None |
44+
| Role Name | Something like "LambdaFullAccess" |
45+
46+
3. To build the zip file, un the following command from the root project directory:
47+
48+
```
49+
./gradlew examples:java-lambda-smartapp:buildZip
50+
```
51+
52+
1. Deploy the zip file by running the following command. Be sure to update your
53+
[account id](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html)
54+
and the version.
55+
56+
```
57+
aws lambda create-function --function-name smartapp-example \
58+
--zip-file fileb://build/distributions/java-lambda-smartapp-<version>.zip \
59+
--role arn:aws:iam::<account id>:role/lambda_full_access \
60+
--handler app.App \
61+
--runtime java8 \
62+
--timeout 15 \
63+
--memory-size 256
64+
```
65+
66+
Later, when you want to deploy an updated zip file, use `aws lambda update-function-code` instead:
67+
68+
```
69+
aws lambda update-function-code --function-name smartapp-example \
70+
--zip-file fileb://build/distributions/java-lambda-smartapp-<version>.zip
71+
```
72+
73+
(If you need to update configuration later, use the `aws lambda update-function-configuration`.)
74+
75+
4. Add permissions for SmartThings access to Lambda. This gives SmartThings (which has a principle
76+
id of 906037444270) permission to call the Lambda.
77+
78+
```
79+
aws lambda add-permission \
80+
--function-name <my-function-name> \
81+
--statement-id smartthings \
82+
--principal 906037444270 \
83+
--action lambda:InvokeFunction
84+
```
85+
86+
### Create SmartApp
87+
88+
First, you'll need to determine the target ARN for the function you just deployed. Find the
89+
function you just deployed in the AWS Console and you will find the ARN in the upper right
90+
corner.
91+
92+
In the [developer workspace](https://devworkspace.developer.samsung.com/smartthingsconsole/iotweb/site/index.html),
93+
choose "Automations" on the left navigation bar and create a new WebHook endpoint automation using the following
94+
settings:
95+
96+
| Option | Value |
97+
|--------------------|-------------------------------------|
98+
| SmartApp Instances | Single |
99+
| Hosting Type | AWS Lambda |
100+
| Target ARN | The ARN you found above |
101+
| Scopes | `r:devices:*` and `x:devices:*` |
102+
| App Settings | leave blank |
103+
104+
Once created, self-publish the automation for testing and you will be ready to test it.
105+
106+
### Install SmartApp
107+
108+
First, be sure to enable
109+
[developer mode](https://smartthings.developer.samsung.com/docs/guides/testing/developer-mode.html#Enable-Developer-Mode)
110+
in your SmartThings application to see the self-published automation.
111+
112+
Now you should see your SmartApp listed (near the bottom) when you add a new Automation.
113+
114+
There are lots of sample log messages in this example. You should see the results of this
115+
in the AWS console. Look for "View logs in CloudWatch" under the "Monitoring" tab of the
116+
function.
117+
118+
## References
119+
120+
- [SmartThings Developer Workspace](https://devworkspace.developer.samsung.com)
121+
- [Hosting with AWS Lambda](https://smartthings.developer.samsung.com/docs/guides/smartapps/aws-lambda.html)
122+
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
123+
- [AWS Lambda](https://aws.amazon.com/lambda/)
124+
- [Lambda Functions in Java](https://docs.aws.amazon.com/lambda/latest/dg/java-programming-model.html)
125+
- [AWS Lambda Execution Role](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)
126+
127+
## More about SmartThings
128+
129+
If you are not familiar with SmartThings, we have
130+
[extensive on-line documentation](https://smartthings.developer.samsung.com/develop/index.html).
131+
132+
To create and manage your services and devices on SmartThings, create an account in the
133+
[developer workspace](https://devworkspace.developer.samsung.com/).
134+
135+
The [SmartThings Community](https://community.smartthings.com/c/developers/) is a good place share and
136+
ask questions.
137+
138+
There is also a [SmartThings reddit community](https://www.reddit.com/r/SmartThings/) where you
139+
can read and share information.
140+
141+
## License and Copyright
142+
143+
Licensed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0)
144+
145+
Copyright 2019 SmartThings, Inc.
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
buildscript {
2+
repositories {
3+
jcenter()
4+
}
5+
}
6+
7+
plugins {
8+
id 'jacoco'
9+
id 'java'
10+
id 'groovy'
11+
id 'application'
12+
id 'idea'
13+
id 'eclipse'
14+
}
15+
16+
group = "examples"
17+
sourceCompatibility = '1.8'
18+
mainClassName = 'app.App'
19+
20+
test {
21+
jacoco {
22+
destinationFile = file("${buildDir}/jacoco/test.exec")
23+
}
24+
}
25+
jacocoTestReport {
26+
reports {
27+
xml.enabled true
28+
html.enabled false
29+
}
30+
}
31+
test.finalizedBy(jacocoTestReport)
32+
33+
repositories {
34+
jcenter()
35+
}
36+
37+
dependencies {
38+
implementation deps.projects.smartappcore
39+
implementation deps.projects.smartthingsclient
40+
implementation deps.aws.lambdaJavaCore
41+
implementation deps.aws.lambdaLogging
42+
43+
testImplementation deps.groovy.all
44+
testImplementation deps.test.spockCore
45+
}
46+
47+
jacocoTestReport.dependsOn(test)
48+
49+
task buildZip(type: Zip) {
50+
from compileJava
51+
from processResources
52+
into('lib') {
53+
// AWS docs seem to be a bit off here.
54+
// https://docs.aws.amazon.com/lambda/latest/dg/create-deployment-pkg-zip-java.html
55+
// They use compileClasspath here but when we use a library that uses others, we
56+
// need runtimeClasspath to avoid class not found exceptions.
57+
from configurations.runtimeClasspath
58+
}
59+
}
60+
61+
build.dependsOn buildZip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package app;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import com.amazonaws.services.lambda.runtime.Context;
7+
import com.amazonaws.services.lambda.runtime.RequestHandler;
8+
import com.smartthings.sdk.smartapp.core.Response;
9+
import com.smartthings.sdk.smartapp.core.SmartApp;
10+
import com.smartthings.sdk.smartapp.core.internal.handlers.DefaultPingHandler;
11+
import com.smartthings.sdk.smartapp.core.models.ExecutionRequest;
12+
import com.smartthings.sdk.smartapp.core.models.ExecutionResponse;
13+
import com.smartthings.sdk.smartapp.core.models.UninstallResponseData;
14+
import app.handlers.AppConfigurationHandler;
15+
import app.handlers.AppEventHandler;
16+
import app.handlers.AppUpdateInstallHandler;
17+
18+
19+
public class App implements RequestHandler<ExecutionRequest, ExecutionResponse> {
20+
private final Logger LOG = LoggerFactory.getLogger(App.class);
21+
22+
private final SmartApp smartApp = SmartApp.of(spec ->
23+
spec
24+
// We don't need to include a PingHandler because the default is sufficient. This is included
25+
// here to help with debugging a new SmartApp.
26+
.ping(new DefaultPingHandler() {
27+
@Override
28+
public ExecutionResponse handle(ExecutionRequest executionRequest) throws Exception {
29+
LOG.debug("PING: executionRequest = " + executionRequest);
30+
return super.handle(executionRequest);
31+
}
32+
})
33+
.configuration(new AppConfigurationHandler())
34+
.install(new AppUpdateInstallHandler.AppInstallHandler())
35+
.update(new AppUpdateInstallHandler.AppUpdateHandler())
36+
.event(new AppEventHandler())
37+
.uninstall(request -> {
38+
LOG.debug("UNINSTALL: executionRequest = " + request);
39+
return Response.ok(new UninstallResponseData());
40+
})
41+
);
42+
43+
@Override
44+
public ExecutionResponse handleRequest(ExecutionRequest request, Context context) {
45+
LOG.info("got request with input " + request);
46+
ExecutionResponse response = smartApp.execute(request);
47+
LOG.info("returning " + response);
48+
return response;
49+
}
50+
}

0 commit comments

Comments
 (0)