Skip to content

Commit 8f698e1

Browse files
committed
Merge branch 'master' into sql
2 parents 31451ef + 7f83505 commit 8f698e1

File tree

7 files changed

+84
-5
lines changed

7 files changed

+84
-5
lines changed

.ebextensions/env.config

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Parameters:
2+
EmailAddress:
3+
Type: String
4+
5+
16
option_settings:
7+
aws:elasticbeanstalk:customoption:
8+
NotificationEmail: [email protected]
29
aws:elasticbeanstalk:application:environment:
310
AWS_REGION: '`{"Ref" : "AWS::Region"}`'
11+
NOTIFICATION_TOPIC: '`{"Ref" : "NotificationTopic"}`'
12+
NOTIFICATION_EMAIL: '`{"Ref" : "EmailAddress"}`'

.ebextensions/sns-topic.config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Resources:
2+
NotificationTopic:
3+
Type: AWS::SNS::Topic
4+
Properties:
5+
Subscription:
6+
- Endpoint: {"Ref" : "EmailAddress"}
7+
Protocol: email

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The project shows the use of Spring, Angular, nginx, the AWS SDK for Java, Dynam
88
- [`lambda`](https://github.com/awslabs/eb-java-scorekeep/tree/lambda) - Call a Lambda function to generate random names.
99
- [`sql`](https://github.com/awslabs/eb-java-scorekeep/tree/sql) - Use JDBC to store game histories in an attached PostgreSQL database instance.
1010
- [`xray`](https://github.com/awslabs/eb-java-scorekeep/tree/xray) - Use the AWS X-Ray SDK to instrument incoming requests, SDK clients, SQL queries, HTTP clients, and sections of code.
11-
- [`xray-gettingstarted`](https://github.com/awslabs/eb-java-scorekeep/tree/xray-gettingstarted) - Use the AWS X-Ray to instrument incoming requests and SDK clients (no additional configuration required).
11+
- [`xray-gettingstarted`](https://github.com/awslabs/eb-java-scorekeep/tree/xray-gettingstarted) ([tutorial](https://docs.aws.amazon.com/xray/latest/devguide/xray-gettingstarted.html)) - Use the AWS X-Ray to instrument incoming requests and SDK clients (no additional configuration required).
1212

1313
Use the procedures in the following sections to run the project on AWS Elastic Beanstalk and configure it for local testing and development.
1414

@@ -22,14 +22,15 @@ Create a Java 8 SE environment in Elastic Beanstalk to host the application.
2222
3. When your environment is ready, the console redirects you to the environment Dashboard.
2323
4. Click the URL at the top of the page to open the site.
2424

25-
## Give the application permission to use DynamoDB
26-
When the Scorekeep API runs in AWS Elastic Beanstalk, it uses the permissions of its EC2 instance to call AWS. Elastic Beanstalk provides a default instance profile that you can extend to grant the application the permissions it needs to read from and write to resource tables in DynamoDB.
25+
## Give the application permission to use DynamoDB and SNS
26+
When the Scorekeep API runs in AWS Elastic Beanstalk, it uses the permissions of its EC2 instance to call AWS. Elastic Beanstalk provides a default instance profile that you can extend to grant the application the permissions it needs to read from and write to resource tables in DynamoDB, and send notifications with SNS.
2727

28-
*To add DynamoDB permissions to the instances in your Elastic Beanstalk environment*
28+
*To add DynamoDB and SNS permissions to the instances in your Elastic Beanstalk environment*
2929

3030
1. Open the Elastic Beanstalk instance profile in the IAM console: [aws-elasticbeanstalk-ec2-role](https://console.aws.amazon.com/iam/home#roles/aws-elasticbeanstalk-ec2-role)
3131
2. Click **Attach Policy**.
3232
3. Select [AmazonDynamoDBFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess) and click **Attach Policy**.
33+
3. Select [AmazonSNSFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonSNSFullAccess) and click **Attach Policy**.
3334

3435
## Deploy the application
3536
Deploy the source code for the project to your Elastic Beanstalk environment.
@@ -47,6 +48,17 @@ Deploy the source code for the project to your Elastic Beanstalk environment.
4748

4849
Click through the app to explore its functionality. Use the network console in your browser to see the HTTP requests that it sends to the API to read and write users, sessions, games, moves and game state to DynamoDB via the API.
4950

51+
## Configure Notifications
52+
The API uses Amazon SNS to send a notification email when a game ends. To enable notifications, configure your email address in an environment variable.
53+
54+
*To enable notifications*
55+
1. Open your environment's page in the [environment management console](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-console.html).
56+
2. Choose **Configuration**.
57+
3. Choose **Software Configuration**
58+
4. Under **Environment Properties**, set **NOTIFICATION_TOPIC** to your email address.
59+
5. Check your email for a subscription confirmation.
60+
6. Complete a game to trigger a notification.
61+
5062
# How it works
5163
The project includes two independent components, an HTML and JavaScript frontend in Angular 1.5 and a Java backend that uses Spring to provide a public API.
5264

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
compile("org.springframework.boot:spring-boot-starter-data-jpa")
3232
testCompile("org.springframework.boot:spring-boot-starter-test")
3333
compile("com.amazonaws:aws-java-sdk-dynamodb")
34+
compile("com.amazonaws:aws-java-sdk-sns")
3435
compile("org.postgresql:postgresql:9.4.1211.jre7")
3536
testCompile("junit:junit:4.11")
3637
compile("com.fasterxml.jackson.core:jackson-databind:2.8.4")

src/main/java/scorekeep/MoveFactory.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public Move newMove(String sessionId, String gameId, String userId, String moveT
5555
} catch ( ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { throw new RulesException(rulesName); }
5656
// save new game state
5757
State newState = new State(stateId, sessionId, gameId, newStateText, newTurn);
58+
// send notification on game end
59+
if ( newStateText.startsWith("A") || newStateText.startsWith("B")) {
60+
Utils.sendNotification("Scorekeep game completed", "Winner: " + userId);
61+
}
5862
// register state and move id to game
5963
gameController.setGameMove(sessionId, gameId, moveId);
6064
gameController.setGameState(sessionId, gameId, stateId);

src/main/java/scorekeep/Utils.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package scorekeep;
2+
3+
import com.amazonaws.regions.Regions;
4+
import com.amazonaws.services.sns.AmazonSNS;
5+
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
6+
import com.amazonaws.services.sns.model.PublishRequest;
7+
import com.amazonaws.services.sns.model.PublishResult;
8+
import com.amazonaws.services.sns.model.SubscribeRequest;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
12+
public class Utils {
13+
private static final Logger logger = LoggerFactory.getLogger("scorekeep.Utils");
14+
private static AmazonSNS snsclient = AmazonSNSClientBuilder.standard()
15+
.withRegion(Regions.fromName(System.getenv("AWS_REGION")))
16+
.build();
17+
/*
18+
* Send a notification email.
19+
*/
20+
public static void sendNotification(String subject, String body) {
21+
String topicarn = System.getenv("NOTIFICATION_TOPIC");
22+
PublishRequest publishRequest = new PublishRequest(topicarn, body, subject);
23+
PublishResult publishResult = snsclient.publish(publishRequest);
24+
logger.info("Email sent: " + publishResult.getMessageId());
25+
}
26+
27+
/*
28+
* Create an SNS subscription.
29+
*/
30+
public static void createSubscription() {
31+
String topicarn = System.getenv("NOTIFICATION_TOPIC");
32+
String emailaddress = System.getenv("NOTIFICATION_EMAIL");
33+
SubscribeRequest subRequest = new SubscribeRequest(topicarn, "email", emailaddress);
34+
snsclient.subscribe(subRequest);
35+
}
36+
37+
}

src/main/java/scorekeep/WebConfig.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@
1010

1111
import javax.servlet.Filter;
1212

13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
1315

1416
@Configuration
1517
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
1618
@Profile("nodb")
1719
public class WebConfig {
20+
private static final Logger logger = LoggerFactory.getLogger(WebConfig.class);
1821

1922
@Bean
2023
public Filter SimpleCORSFilter() {
2124
return new SimpleCORSFilter();
2225
}
23-
}
26+
27+
static {
28+
if ( System.getenv("NOTIFICATION_EMAIL") != null ){
29+
Utils.createSubscription();
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)