Skip to content

Commit ed34543

Browse files
authored
Merge pull request #2 from sanepal/sql
Add SQL implementation and demo
2 parents 58429c7 + d4b067a commit ed34543

21 files changed

+511
-51
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ targetCompatibility = 1.8
2828

2929
dependencies {
3030
compile("org.springframework.boot:spring-boot-starter-web")
31+
compile("org.springframework.boot:spring-boot-starter-data-jpa")
3132
testCompile("org.springframework.boot:spring-boot-starter-test")
3233
compile("com.amazonaws:aws-java-sdk-dynamodb")
34+
compile("org.postgresql:postgresql:9.4.1211.jre7")
3335
testCompile("junit:junit:4.11")
3436
compile("com.fasterxml.jackson.core:jackson-databind:2.8.4")
3537
}

public/app/demo-controller.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
var module = angular.module('scorekeep');
2+
3+
module.controller('DemoController', DemoController);
4+
function DemoController($scope, $http, $location, SessionCollection, UserCollection, GameCollection, GameHistoryModel, api, $sce) {
5+
var ddbOutput = "Click the button above to generate traces to AWS DynamoDB.";
6+
var rdsDefaultOutput = "Click the button above to populate the table and generate traces to AWS RDS.";
7+
var rdsRunningOutput = "Populating table...";
8+
var ddbRunning = false;
9+
var rdsRunning = false;
10+
var shouldRunDdbDemo = false;
11+
var shouldRunRdsDemo = false;
12+
$scope.gameHistory = [];
13+
14+
$scope.isRdsConfigured = false;
15+
var isRdsConfigured = function() {
16+
GameHistoryModel.get().then(
17+
function(success) {
18+
$scope.isRdsConfigured = true;
19+
},
20+
function(error) {
21+
$scope.isRdsConfigured = false;
22+
}
23+
);
24+
};
25+
isRdsConfigured();
26+
27+
var runDdbDemo = function() {
28+
ddbRunning = true;
29+
var user1, user2, session, game;
30+
ddbOutput = "Creating users...<br/>";
31+
32+
// Sick chaining
33+
UserCollection.createUser("random", null)
34+
.then(function(result) {
35+
console.log(result);
36+
user1 = result;
37+
ddbOutput += "Created user " + user1.name + ".<br/>";
38+
return UserCollection.createUser("random", null);
39+
})
40+
.then(function(result) {
41+
console.log(result);
42+
user2 = result;
43+
ddbOutput += "Created user " + user2.name + ".<br/>";
44+
ddbOutput += "Initializing session...<br/>";
45+
return SessionCollection.createSession(null, null);
46+
})
47+
.then(function(result) {
48+
console.log(result);
49+
session = result;
50+
ddbOutput += "Creating tic-tac-toe game...<br/>";
51+
return GameCollection.createGame(session.id, "tic-tac-toe", "TICTACTOE");
52+
})
53+
.then(function(result) {
54+
console.log(result);
55+
game = result;
56+
ddbOutput += "Game is about to begin...<br/>";
57+
return GameCollection.setUsers(session.id, game.id, [user1.id, user2.id]);
58+
})
59+
.then(function(result) {
60+
console.log(result);
61+
// Avoid NPE in service
62+
return GameCollection.setField(session.id, game.id, "rules", "TICTACTOE");
63+
})
64+
.then(function(result) {
65+
console.log(result);
66+
ddbOutput += "Playing game<br/>";
67+
ddbOutput += user1.name + " made move X1<br/>";
68+
return GameCollection.move(session.id, game.id, user1.id, "X1");
69+
})
70+
.then(function(result) {
71+
console.log(result);
72+
ddbOutput += user2.name + " made move O2<br/>";
73+
return GameCollection.move(session.id, game.id, user2.id, "O2");
74+
})
75+
.then(function(result) {
76+
console.log(result);
77+
ddbOutput += user1.name + " made move X3<br/>";
78+
return GameCollection.move(session.id, game.id, user1.id, "X3");
79+
})
80+
.then(function(result) {
81+
console.log(result);
82+
ddbOutput += user2.name + " made move O4<br/>";
83+
return GameCollection.move(session.id, game.id, user2.id, "O4");
84+
})
85+
.then(function(result) {
86+
console.log(result);
87+
ddbOutput += user1.name + " made move X5<br/>";
88+
return GameCollection.move(session.id, game.id, user1.id, "X5");
89+
})
90+
.then(function(result) {
91+
console.log(result);
92+
ddbOutput += user2.name + " made move O6<br/>";
93+
return GameCollection.move(session.id, game.id, user2.id, "O6");
94+
})
95+
.then(function(result) {
96+
console.log(result);
97+
ddbOutput += user1.name + " made move X7<br/>";
98+
return GameCollection.move(session.id, game.id, user1.id, "X7");
99+
})
100+
.then(function(result) {
101+
console.log(result);
102+
ddbOutput += user2.name + " made move O8<br/>";
103+
return GameCollection.move(session.id, game.id, user2.id, "O8");
104+
})
105+
.then(function(result) {
106+
console.log(result);
107+
ddbOutput += user1.name + " made move X9<br/>";
108+
return GameCollection.move(session.id, game.id, user1.id, "X9");
109+
})
110+
.then(function(result) {
111+
ddbOutput += "Game Over!<br/>";
112+
// Keep repeating
113+
if (shouldRunDdbDemo) {
114+
runDdbDemo();
115+
} else {
116+
ddbRunning = false;
117+
}
118+
});
119+
};
120+
121+
var runRdsDemo = function() {
122+
rdsRunning = true;
123+
GameHistoryModel.create()
124+
.then(function(result) {
125+
console.log(result);
126+
return GameHistoryModel.get();
127+
})
128+
.then(function(result) {
129+
console.log(result);
130+
$scope.gameHistory = result;
131+
if (shouldRunRdsDemo) {
132+
runRdsDemo();
133+
} else {
134+
rdsRunning = false;
135+
}
136+
});
137+
}
138+
139+
$scope.getDdbOutput = function() {
140+
return $sce.trustAsHtml(ddbOutput);
141+
};
142+
143+
$scope.getRdsOutput = function() {
144+
var output = rdsRunning ? rdsRunningOutput : rdsDefaultOutput;
145+
return $sce.trustAsHtml(output);
146+
};
147+
148+
$scope.getDdbDemoPrompt = function() {
149+
if (shouldRunDdbDemo) {
150+
return "Stop AWS DynamoDB Demo";
151+
} else if (ddbRunning) {
152+
return "Finishing AWS DynamoDB Demo";
153+
} else {
154+
return "Start AWS DynamoDB Demo";
155+
}
156+
};
157+
158+
$scope.getRdsDemoPrompt = function() {
159+
if (shouldRunRdsDemo) {
160+
return "Stop AWS RDS Demo";
161+
} else if (rdsRunning) {
162+
return "Finishing AWS RDS Demo";
163+
} else {
164+
return "Start AWS RDS Demo";
165+
}
166+
};
167+
168+
$scope.toggleDdbDemo = function() {
169+
shouldRunDdbDemo = !shouldRunDdbDemo;
170+
if (shouldRunDdbDemo && !ddbRunning) {
171+
runDdbDemo();
172+
}
173+
};
174+
175+
$scope.toggleRdsDemo = function() {
176+
shouldRunRdsDemo = !shouldRunRdsDemo;
177+
if (shouldRunRdsDemo && !rdsRunning) {
178+
runRdsDemo();
179+
}
180+
};
181+
}

public/app/game-history-model.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var module = angular.module('scorekeep');
2+
module.service('GameHistoryModel', function($http, GameHistoryService, api) {
3+
var model = {};
4+
5+
model.get = function() {
6+
return GameHistoryService.query().$promise;
7+
};
8+
9+
model.create = function() {
10+
var service = new GameHistoryService();
11+
return service.$save();
12+
};
13+
return model;
14+
});

public/app/routes.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ module.config(function($routeProvider) {
55
templateUrl : "main.html",
66
controller : "MainController"
77
})
8+
.when("/demo", {
9+
templateUrl: "demo.html",
10+
controller: "DemoController"
11+
})
812
.when("/sessions", {
913
templateUrl : "sessions.html",
1014
controller : "SessionsController"

public/app/services.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ module.factory('RulesService', function($resource, api) {
2727
module.factory('StateService', function($resource, api) {
2828
return $resource(api + 'state/:sessionid/:gameid/:id', { sessionid: '@_sessionid', gameid: '@_gameid', id: '@_id' }, {
2929
});
30+
});
31+
module.factory('GameHistoryService', function($resource, api) {
32+
return $resource(api + 'history', {}, {
33+
});
3034
});

public/demo.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<div class="jumbotron">
2+
<div class="container">
3+
<h1 class="display-3">Scorekeep Demo</h1>
4+
<p class="lead"></p>
5+
</div>
6+
</div>
7+
<div class="container">
8+
<div class="row">
9+
<div class="col-md-6">
10+
<div class="row">
11+
<div class="col-md-10 offset-md-1">
12+
<button type="button" class="btn btn-outline-primary btn-lg btn-block" ng-click="toggleDdbDemo()">{{ getDdbDemoPrompt() }}</button>
13+
<hr>
14+
<p ng-bind-html="getDdbOutput()"></p>
15+
</div>
16+
</div>
17+
</div>
18+
<div class="col-md-6">
19+
<div class="row">
20+
<div class="col-md-10 offset-md-1" ng-show="isRdsConfigured">
21+
<button type="button" class="btn btn-outline-primary btn-lg btn-block" ng-click="toggleRdsDemo()">{{ getRdsDemoPrompt() }}</button>
22+
<hr>
23+
<p ng-bind-html="getRdsOutput()"></p>
24+
<table class="table">
25+
<thead>
26+
<tr>
27+
<th>ID</th>
28+
<th>Winner</th>
29+
<th>Loser</th>
30+
</tr>
31+
</thead>
32+
<tbody>
33+
<tr ng-repeat="game in gameHistory">
34+
<td>{{game.id}}</td>
35+
<td>{{game.winningPlayer}}</td>
36+
<td>{{game.losingPlayer}}</td>
37+
</tr>
38+
</tbody>
39+
</table>
40+
</div>
41+
<div class="col-md-10 offset-md-1" ng-hide="isRdsConfigured">
42+
<p>Use AWS Elastic Beanstalk to attach a database instance to this environment for the RDS demo.</p>
43+
</div>
44+
</div>
45+
</div>
46+
</div>
47+
</div>
48+
<nav class="navbar navbar-fixed-bottom navbar-light bg-faded">
49+
<div class="container">
50+
<div class="row">
51+
<div class="col-md-4 offset-md-4">
52+
</div>
53+
</div>
54+
</div>
55+
</nav>

public/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<script src="app/scorekeep.js"></script>
1010
<script src="app/routes.js"></script>
1111
<script src="app/services.js"></script>
12+
<script src="app/game-history-model.js"></script>
13+
<script src="app/demo-controller.js"></script>
1214
<script src="app/sessionController.js"></script>
1315
<script src="app/sessionsController.js"></script>
1416
<script src="app/gamesController.js"></script>
@@ -18,16 +20,14 @@
1820
<script src="app/sessionCollection.js"></script>
1921
<script src="app/gameCollection.js"></script>
2022
<script src="app/mainController.js"></script>
21-
<link rel="stylesheet" href="css/scorekeep.css"></link>
22-
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous"></link>
23-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/css/tether.css"></link>
23+
<link rel="stylesheet" href="css/scorekeep.css"/>
24+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi" crossorigin="anonymous"/>
25+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/css/tether.css"/>
2426
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.js"></script>
2527
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
2628
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js" integrity="sha384-BLiI7JTZm+JWlgKa0M0kGRpJbF2J8q+qreVrKBC47e3K6BW78kGLrCkeRX6I9RoK" crossorigin="anonymous"></script>
2729
</head>
28-
2930
<body>
30-
<div class="navbar">Scorekeep</div>
3131
<div ng-view></div>
3232
</body>
3333
</html>
Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,53 @@
11
package scorekeep;
22

33
import org.springframework.boot.SpringApplication;
4-
import org.springframework.boot.autoconfigure.SpringBootApplication;
4+
import org.springframework.boot.builder.SpringApplicationBuilder;
5+
import org.springframework.context.annotation.ComponentScan;
6+
import org.springframework.context.annotation.Configuration;
7+
import org.springframework.core.env.AbstractEnvironment;
58

6-
@SpringBootApplication
9+
@Configuration
10+
@ComponentScan
711
public class Application {
812

13+
enum Profile {
14+
NODB("nodb"),
15+
PGSQL("pgsql");
16+
17+
private final String name;
18+
19+
Profile(final String name) {
20+
this.name = name;
21+
}
22+
23+
@Override
24+
public String toString() {
25+
return this.name;
26+
}
27+
}
28+
929
public static void main(String[] args) {
30+
System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, getProfile());
1031
SpringApplication.run(Application.class, args);
1132
}
33+
34+
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
35+
return application.sources(Application.class);
36+
}
37+
38+
public static String getProfile() {
39+
if (isRdsEnabled()) {
40+
return Profile.PGSQL.toString();
41+
} else {
42+
return Profile.NODB.toString();
43+
}
44+
}
45+
46+
public static boolean isRdsEnabled() {
47+
// Only enabled if the relevant environment variables are set
48+
return (null != System.getenv("RDS_HOSTNAME")
49+
&& null != System.getenv("RDS_USERNAME")
50+
&& null != System.getenv("RDS_PASSWORD")
51+
&& null != System.getenv("RDS_PORT"));
52+
}
1253
}

0 commit comments

Comments
 (0)