Browse Source

Merge pull request #1166 from donovanmuller/master

Updated all benchmarks to Play 2.3.6 and Scala 2.11.4.
Mike Smith 10 years ago
parent
commit
2f20af98e7
77 changed files with 1046 additions and 152 deletions
  1. 34 12
      frameworks/Java/play2-java/benchmark_config
  2. 5 4
      frameworks/Java/play2-java/generate_config.py
  3. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/.gitignore
  4. 35 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/README.md
  5. 59 12
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/controllers/Application.java
  6. 26 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/models/Fortune.java
  7. 37 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/models/World.java
  8. 21 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Headers.java
  9. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Predicate.java
  10. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Predicated.java
  11. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/PredicatedAction.java
  12. 16 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/views/fortunes.scala.html
  13. 12 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/app/views/main.scala.html
  14. 13 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/build.sbt
  15. 3 3
      frameworks/Java/play2-java/play2-java-ebean-bonecp/conf/application.conf
  16. 13 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/conf/routes
  17. 1 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/project/build.properties
  18. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/project/plugins.sbt
  19. 0 0
      frameworks/Java/play2-java/play2-java-ebean-bonecp/source_code
  20. 0 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/.gitignore
  21. 35 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/README.md
  22. 144 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/controllers/Application.java
  23. 26 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/models/Fortune.java
  24. 37 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/models/World.java
  25. 21 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Headers.java
  26. 0 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Predicate.java
  27. 0 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Predicated.java
  28. 3 3
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/PredicatedAction.java
  29. 16 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/views/fortunes.scala.html
  30. 12 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/views/main.scala.html
  31. 16 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/build.sbt
  32. 78 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/application.conf
  33. 1 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/play.plugins
  34. 13 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/routes
  35. 1 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/project/build.properties
  36. 1 1
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/project/plugins.sbt
  37. 11 0
      frameworks/Java/play2-java/play2-java-ebean-hikaricp/source_code
  38. 0 20
      frameworks/Java/play2-java/play2-java-ebean/README.md
  39. 0 20
      frameworks/Java/play2-java/play2-java-ebean/app/models/World.java
  40. 0 11
      frameworks/Java/play2-java/play2-java-ebean/build.sbt
  41. 0 10
      frameworks/Java/play2-java/play2-java-ebean/conf/routes
  42. 0 1
      frameworks/Java/play2-java/play2-java-ebean/project/build.properties
  43. 0 9
      frameworks/Java/play2-java/play2-java-ebean/source_code
  44. 30 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/.gitignore
  45. 35 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/README.md
  46. 12 7
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/controllers/Application.java
  47. 34 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/models/Fortune.java
  48. 38 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/models/World.java
  49. 21 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Headers.java
  50. 8 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Predicate.java
  51. 26 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Predicated.java
  52. 23 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/PredicatedAction.java
  53. 16 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/views/fortunes.scala.html
  54. 12 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/app/views/main.scala.html
  55. 2 2
      frameworks/Java/play2-java/play2-java-jpa-bonecp/build.sbt
  56. 0 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/META-INF/persistence.xml
  57. 1 1
      frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/application.conf
  58. 0 1
      frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/routes
  59. 0 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/project/build.properties
  60. 8 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/project/plugins.sbt
  61. 11 0
      frameworks/Java/play2-java/play2-java-jpa-bonecp/source_code
  62. 0 4
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/README.md
  63. 16 12
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/controllers/Application.java
  64. 1 1
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/utils/Headers.java
  65. 1 1
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/build.sbt
  66. 4 6
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/application.conf
  67. 0 1
      frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/routes
  68. 5 1
      frameworks/Java/play2-java/play2-java/README.md
  69. 7 0
      frameworks/Java/play2-java/play2-java/app/controllers/Application.java
  70. 21 0
      frameworks/Java/play2-java/play2-java/app/utils/Headers.java
  71. 2 0
      frameworks/Java/play2-java/play2-java/build.sbt
  72. 3 2
      frameworks/Java/play2-java/play2-java/conf/routes
  73. 1 1
      frameworks/Java/play2-java/play2-java/project/plugins.sbt
  74. 0 6
      frameworks/Java/play2-java/play2-java/source_code
  75. 6 0
      frameworks/Java/play2-java/setup_java_ebean_bonecp.py
  76. 6 0
      frameworks/Java/play2-java/setup_java_ebean_hikaricp.py
  77. 6 0
      frameworks/Java/play2-java/setup_java_jpa_bonecp.py

+ 34 - 12
frameworks/Java/play2-java/benchmark_config

@@ -18,11 +18,12 @@
         "notes": "", 
         "versus": "netty", 
         "port": "9000", 
-        "json_url": "/json"
+        "json_url": "/json", 
+        "plaintext_url": "/plaintext"
       }, 
-      "java-ebean": {
-        "display_name": "play2-java-ebean", 
-        "setup_file": "setup_java_ebean", 
+      "java-ebean-bonecp": {
+        "display_name": "play2-java-ebean-bonecp", 
+        "setup_file": "setup_java_ebean_bonecp", 
         "framework": "play2", 
         "language": "Java", 
         "orm": "Full", 
@@ -37,11 +38,13 @@
         "versus": "netty", 
         "port": "9000", 
         "db_url": "/db", 
-        "query_url": "/queries?queries="
+        "query_url": "/queries?queries=", 
+        "fortune_url": "/fortunes", 
+        "update_url": "/update?queries="
       }, 
-      "java-jpa": {
-        "display_name": "play2-java-jpa", 
-        "setup_file": "setup_java_jpa", 
+      "java-ebean-hikaricp": {
+        "display_name": "play2-java-ebean-hikaricp", 
+        "setup_file": "setup_java_ebean_hikaricp", 
         "framework": "play2", 
         "language": "Java", 
         "orm": "Full", 
@@ -58,8 +61,28 @@
         "db_url": "/db", 
         "query_url": "/queries?queries=", 
         "fortune_url": "/fortunes", 
-        "update_url": "/update?queries=", 
-        "plaintext_url": "/plaintext"
+        "update_url": "/update?queries="
+      }, 
+      "java-jpa-bonecp": {
+        "display_name": "play2-java-jpa-bonecp", 
+        "setup_file": "setup_java_jpa_bonecp", 
+        "framework": "play2", 
+        "language": "Java", 
+        "orm": "Full", 
+        "os": "Linux", 
+        "database": "MySQL", 
+        "approach": "Realistic", 
+        "classification": "Fullstack", 
+        "platform": "Netty", 
+        "webserver": "None", 
+        "database_os": "Linux", 
+        "notes": "", 
+        "versus": "netty", 
+        "port": "9000", 
+        "db_url": "/db", 
+        "query_url": "/queries?queries=", 
+        "fortune_url": "/fortunes", 
+        "update_url": "/update?queries="
       }, 
       "java-jpa-hikaricp": {
         "display_name": "play2-java-jpa-hikaricp", 
@@ -80,8 +103,7 @@
         "db_url": "/db", 
         "query_url": "/queries?queries=", 
         "fortune_url": "/fortunes", 
-        "update_url": "/update?queries=", 
-        "plaintext_url": "/plaintext"
+        "update_url": "/update?queries="
       }
     }
   ]

+ 5 - 4
frameworks/Java/play2-java/generate_config.py

@@ -9,10 +9,11 @@ import collections, json, os, textwrap
 # Format is: (language, orm, (opsys, ...), (test, ...))
 # See the dir_name logic below to see the directory name for each test application.
 configurations = [
-  ('Java',  None,    			['Linux'],            ['json']),
-  ('Java',  'Ebean', 			['Linux'],            ['db', 'query']),
-  ('Java',  'JPA',   			['Linux'],            ['db', 'query', 'fortune', 'update', 'plaintext']),
-  ('Java',  'JPA HikariCP',   	['Linux'],            ['db', 'query', 'fortune', 'update', 'plaintext']),
+  ('Java',  None,    			['Linux'],            ['json', 'plaintext']),
+  ('Java',  'Ebean BoneCP', 	['Linux'],            ['db', 'query', 'fortune', 'update']),
+  ('Java',  'Ebean HikariCP', 	['Linux'],            ['db', 'query', 'fortune', 'update']),
+  ('Java',  'JPA BoneCP',		['Linux'],            ['db', 'query', 'fortune', 'update']),
+  ('Java',  'JPA HikariCP',		['Linux'],            ['db', 'query', 'fortune', 'update']),
   ('Scala', None,    			['Linux'],            ['json']),
   ('Scala', 'Anorm', 			['Linux', 'Windows'], ['db', 'query', 'fortune', 'update']),
   ('Scala', 'Slick', 			['Linux'],            ['db', 'query', 'fortune', 'update']),

+ 0 - 0
frameworks/Java/play2-java/play2-java-ebean/.gitignore → frameworks/Java/play2-java/play2-java-ebean-bonecp/.gitignore


+ 35 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/README.md

@@ -0,0 +1,35 @@
+#Play Benchmarking Test
+
+This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test controller](app/controllers/Application.java)
+
+### Data-Store/Database Mapping Test
+
+* [Database test controller](app/controllers/Application.java)
+* [Database World test model](app/models/World.java)
+* [Database Fortune test model](app/models/Fortune.java)
+
+### Plain Text Test
+
+* [Plain text test controller](app/controllers/Application.java)
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* [Java OpenJDK 1.7](http://openjdk.java.net/)
+* [Play 2.3.6](http://http://www.playframework.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+* http://localhost/json
+
+### Data-Store/Database Mapping Test
+
+* http://localhost/db
+* http://localhost/queries?queries=10
+* http://localhost/fortunes
+* http://localhost/update?queries=10

+ 59 - 12
frameworks/Java/play2-java/play2-java-ebean/app/controllers/Application.java → frameworks/Java/play2-java/play2-java-ebean-bonecp/app/controllers/Application.java

@@ -1,26 +1,29 @@
 package controllers;
 
 import akka.dispatch.ExecutionContexts;
+import models.Fortune;
 import models.World;
 import play.Play;
 import play.core.NamedThreadFactory;
 import play.libs.F;
 import play.libs.Json;
-
 import play.mvc.Controller;
 import play.mvc.Result;
+import play.mvc.With;
 import scala.concurrent.ExecutionContext;
+import utils.Headers;
 import utils.Predicate;
 import utils.Predicated;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.*;
+import java.util.*;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
+@With(Headers.class)
 public class Application extends Controller {
 
-    private static final int MAX_QUERIES_PER_REQUEST = 20;
     private static final int TEST_DATABASE_ROWS = 10000;
 
     private static final int partitionCount = Play.application().configuration().getInt("db.default.partitionCount");
@@ -58,6 +61,54 @@ public class Application extends Controller {
 
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> queries(final String queryCountString) {
+        return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
+            @Override
+            public Result apply(List<World> worlds) {
+                return ok(Json.toJson(worlds));
+            }
+        });
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> fortunes() {
+        return F.Promise.promise(new F.Function0<Result>() {
+
+            @Override
+            public Result apply() throws Throwable {
+                List<Fortune> fortunes = Fortune.find.all();
+                fortunes.add(new Fortune("Additional fortune added at request time."));
+                Collections.sort(fortunes, new Comparator<Fortune>() {
+
+                    @Override
+                    public int compare(Fortune f1, Fortune f2) {
+                        return f1.message.compareTo(f2.message);
+                    }
+                });
+
+                return ok(views.html.fortunes.render(fortunes));
+            }
+        }, dbEc);
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> update(final String queryCountString) {
+        return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
+            @Override
+            public Result apply(List<World> worlds) throws Throwable {
+                Random random = ThreadLocalRandom.current();
+                for (World world : worlds) {
+                    world.randomNumber = (long) (random.nextInt(10000) + 1);
+                }
+
+                List<World> updatedWorlds = World.save(worlds);
+                return ok(Json.toJson(updatedWorlds));
+            }
+        }, dbEc);
+    }
+
+    private static int queryCount(String queryCountString) {
         int queryCount;
         try {
             queryCount = Integer.parseInt(queryCountString, 10);
@@ -70,16 +121,12 @@ public class Application extends Controller {
             queryCount = 500;
         }
 
-        return getRandomWorlds(queryCount).map(new F.Function<List<World>, Result>() {
-            @Override
-            public Result apply(List<World> worlds) {
-                return ok(Json.toJson(worlds));
-            }
-        });
+        return queryCount;
     }
 
     private static F.Promise<List<World>> getRandomWorlds(final int n) {
         return F.Promise.promise(new F.Function0<List<World>>() {
+
             @Override
             public List<World> apply() {
                 Random random = ThreadLocalRandom.current();

+ 26 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/app/models/Fortune.java

@@ -0,0 +1,26 @@
+package models;
+
+import play.db.ebean.Model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Fortune extends Model {
+
+    @Id
+    public Long id = 0L;
+
+    public String message;
+
+    public Fortune() {
+    }
+
+    public Fortune(String message) {
+        this.message = message;
+    }
+
+    public static Finder<Long, Fortune> find = new Finder<Long, Fortune>(
+            Long.class, Fortune.class
+    );
+}

+ 37 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/app/models/World.java

@@ -0,0 +1,37 @@
+package models;
+
+import com.avaje.ebean.Ebean;
+import play.db.ebean.Model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Entity
+public class World extends Model {
+
+    @Id
+    public Long id;
+
+    @Column(name = "randomNumber")
+    public Long randomNumber;
+
+    public static Finder<Long, World> find = new Finder<Long, World>(
+            Long.class, World.class
+    );
+
+    public static List<World> save(final List<World> worlds) throws Throwable {
+        Set<String> updateProperties = new HashSet<>();
+        updateProperties.add("randomNumber");
+
+        for (World world : worlds) {
+            Ebean.update(world, updateProperties);
+        }
+
+        return worlds;
+    }
+
+}

+ 21 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Headers.java

@@ -0,0 +1,21 @@
+package utils;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import play.libs.F;
+import play.mvc.Action;
+import play.mvc.Http;
+import play.mvc.Result;
+
+public class Headers extends Action.Simple {
+
+    private static final DateTimeFormatter RFC_1123_DATE_TIME = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'").withZoneUTC();
+
+    @Override
+    public F.Promise<Result> call(Http.Context context) throws Throwable {
+        context.response().setHeader("Server", "Play2");
+        context.response().setHeader("Date", RFC_1123_DATE_TIME.print(new DateTime()));
+        return delegate.call(context);
+    }
+}

+ 0 - 0
frameworks/Java/play2-java/play2-java-ebean/app/utils/Predicate.java → frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Predicate.java


+ 0 - 0
frameworks/Java/play2-java/play2-java-ebean/app/utils/Predicated.java → frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/Predicated.java


+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/app/utils/PredicatedAction.java → frameworks/Java/play2-java/play2-java-ebean-bonecp/app/utils/PredicatedAction.java


+ 16 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/app/views/fortunes.scala.html

@@ -0,0 +1,16 @@
+@(fortunes: List[Fortune])
+
+@main() {
+    <table>
+        <tr>
+            <th>id</th>
+            <th>message</th>
+        </tr>
+        @for(fortune <- fortunes) {
+        <tr>
+            <td>@fortune.id</td>
+            <td>@fortune.message</td>
+        </tr>
+        }
+    </table>
+}

+ 12 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/app/views/main.scala.html

@@ -0,0 +1,12 @@
+@()(content: Html)
+
+<!DOCTYPE html>
+
+<html>
+    <head>
+        <title>Fortunes</title>
+    </head>
+    <body>
+    @content
+    </body>
+</html>

+ 13 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/build.sbt

@@ -0,0 +1,13 @@
+name := "play2-java-ebean-bonecp"
+
+version := "1.0-SNAPSHOT"
+
+lazy val root = (project in file(".")).enablePlugins(PlayJava)
+
+scalaVersion := "2.11.4"
+
+libraryDependencies ++= Seq(
+  javaJdbc,
+  javaEbean,
+  "mysql" % "mysql-connector-java" % "5.1.33"
+)

+ 3 - 3
frameworks/Java/play2-java/play2-java-ebean/conf/application.conf → frameworks/Java/play2-java/play2-java-ebean-bonecp/conf/application.conf

@@ -30,7 +30,7 @@ application.langs="en"
 # You can expose this datasource via JNDI if needed (Useful for JPA)
 # db.default.jndiName=DefaultDS
 db.default.driver= com.mysql.jdbc.Driver
-db.default.url="jdbc:mysql://localhost:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
+db.default.url="jdbc:mysql://127.0.0.1:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
 db.default.user=benchmarkdbuser
 db.default.password=benchmarkdbpass
 db.default.jndiName=DefaultDS
@@ -64,10 +64,10 @@ ebean.default="models.*"
 # You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory .
 
 # Root logger:
-logger.root=ERROR
+logger.root=INFO
 
 # Logger used by the framework:
-logger.play=ERROR
+logger.play=INFO
 
 # Logger provided to your application:
 logger.application=ERROR

+ 13 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/conf/routes

@@ -0,0 +1,13 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+
+# Home page
+GET        /db                  controllers.Application.db()
+GET        /queries             controllers.Application.queries(queries ?= "1")
+GET        /fortunes            controllers.Application.fortunes
+GET        /update              controllers.Application.update(queries ?= "1")
+
+
+# Map static resources from the /public folder to the /assets URL path
+GET        /assets/*file        controllers.Assets.at(path="/public", file)

+ 1 - 0
frameworks/Java/play2-java/play2-java-ebean-bonecp/project/build.properties

@@ -0,0 +1 @@
+sbt.version=0.13.5

+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/project/plugins.sbt → frameworks/Java/play2-java/play2-java-ebean-bonecp/project/plugins.sbt


+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/source_code → frameworks/Java/play2-java/play2-java-ebean-bonecp/source_code


+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/.gitignore → frameworks/Java/play2-java/play2-java-ebean-hikaricp/.gitignore


+ 35 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/README.md

@@ -0,0 +1,35 @@
+#Play Benchmarking Test
+
+This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test controller](app/controllers/Application.java)
+
+### Data-Store/Database Mapping Test
+
+* [Database test controller](app/controllers/Application.java)
+* [Database World test model](app/models/World.java)
+* [Database Fortune test model](app/models/Fortune.java)
+
+### Plain Text Test
+
+* [Plain text test controller](app/controllers/Application.java)
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* [Java OpenJDK 1.7](http://openjdk.java.net/)
+* [Play 2.3.6](http://http://www.playframework.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+* http://localhost/json
+
+### Data-Store/Database Mapping Test
+
+* http://localhost/db
+* http://localhost/queries?queries=10
+* http://localhost/fortunes
+* http://localhost/update?queries=10

+ 144 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/controllers/Application.java

@@ -0,0 +1,144 @@
+package controllers;
+
+import akka.dispatch.ExecutionContexts;
+import models.Fortune;
+import models.World;
+import play.Play;
+import play.core.NamedThreadFactory;
+import play.libs.F;
+import play.libs.Json;
+import play.mvc.Controller;
+import play.mvc.Result;
+import play.mvc.With;
+import scala.concurrent.ExecutionContext;
+import utils.Headers;
+import utils.Predicate;
+import utils.Predicated;
+
+import java.util.*;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+@With(Headers.class)
+public class Application extends Controller {
+
+    private static final int TEST_DATABASE_ROWS = 10000;
+
+    private static final int partitionCount = Play.application().configuration().getInt("db.default.partitionCount");
+    private static final int maxConnections =
+            partitionCount * Play.application().configuration().getInt("db.default.maxConnectionsPerPartition");
+    private static final int minConnections =
+            partitionCount * Play.application().configuration().getInt("db.default.minConnectionsPerPartition");
+
+    private static final ThreadPoolExecutor tpe = new ThreadPoolExecutor(minConnections, maxConnections,
+            0L, TimeUnit.MILLISECONDS,
+            new LinkedBlockingQueue<Runnable>(),
+            new NamedThreadFactory("dbEc"));
+    private static final ExecutionContext dbEc = ExecutionContexts.fromExecutorService(tpe);
+
+    // If the thread-pool used by the database grows too large then our server
+    // is probably struggling, and we should start dropping requests. Set
+    // the max size of our queue something above the number of concurrent
+    // connections that we need to handle.
+    public static class IsDbAvailable implements Predicate {
+        @Override
+        public boolean condition() {
+            return tpe.getQueue().size() <= 1024;
+        }
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> db() {
+        return getRandomWorlds(1).map(new F.Function<List<World>, Result>() {
+            @Override
+            public Result apply(List<World> worlds) {
+                return ok(Json.toJson(worlds.get(0)));
+            }
+        });
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> queries(final String queryCountString) {
+        return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
+            @Override
+            public Result apply(List<World> worlds) {
+                return ok(Json.toJson(worlds));
+            }
+        });
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> fortunes() {
+        return F.Promise.promise(new F.Function0<Result>() {
+
+            @Override
+            public Result apply() throws Throwable {
+                List<Fortune> fortunes = Fortune.find.all();
+                fortunes.add(new Fortune("Additional fortune added at request time."));
+                Collections.sort(fortunes, new Comparator<Fortune>() {
+
+                    @Override
+                    public int compare(Fortune f1, Fortune f2) {
+                        return f1.message.compareTo(f2.message);
+                    }
+                });
+
+                return ok(views.html.fortunes.render(fortunes));
+            }
+        }, dbEc);
+    }
+
+    @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
+    public static F.Promise<Result> update(final String queryCountString) {
+        return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
+            @Override
+            public Result apply(List<World> worlds) throws Throwable {
+                Random random = ThreadLocalRandom.current();
+                for (World world : worlds) {
+                    world.randomNumber = (long) (random.nextInt(10000) + 1);
+                }
+
+                List<World> updatedWorlds = World.save(worlds);
+                return ok(Json.toJson(updatedWorlds));
+            }
+        }, dbEc);
+    }
+
+    private static int queryCount(String queryCountString) {
+        int queryCount;
+        try {
+            queryCount = Integer.parseInt(queryCountString, 10);
+        } catch (NumberFormatException e) {
+            queryCount = 1;
+        }
+        if (queryCount < 1) {
+            queryCount = 1;
+        } else if (queryCount > 500) {
+            queryCount = 500;
+        }
+
+        return queryCount;
+    }
+
+    private static F.Promise<List<World>> getRandomWorlds(final int n) {
+        return F.Promise.promise(new F.Function0<List<World>>() {
+
+            @Override
+            public List<World> apply() {
+                Random random = ThreadLocalRandom.current();
+                List<World> worlds = new ArrayList<World>(n);
+                for (int i = 0; i < n; ++i) {
+                    long randomId = random.nextInt(TEST_DATABASE_ROWS) + 1;
+                    World world = World.find.byId(randomId);
+                    worlds.add(world);
+                }
+                return worlds;
+            }
+        }, dbEc);
+    }
+
+}

+ 26 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/models/Fortune.java

@@ -0,0 +1,26 @@
+package models;
+
+import play.db.ebean.Model;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Fortune extends Model {
+
+    @Id
+    public Long id = 0L;
+
+    public String message;
+
+    public Fortune() {
+    }
+
+    public Fortune(String message) {
+        this.message = message;
+    }
+
+    public static Finder<Long, Fortune> find = new Finder<Long, Fortune>(
+            Long.class, Fortune.class
+    );
+}

+ 37 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/models/World.java

@@ -0,0 +1,37 @@
+package models;
+
+import com.avaje.ebean.Ebean;
+import play.db.ebean.Model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Entity
+public class World extends Model {
+
+    @Id
+    public Long id;
+
+    @Column(name = "randomNumber")
+    public Long randomNumber;
+
+    public static Finder<Long, World> find = new Finder<Long, World>(
+            Long.class, World.class
+    );
+
+    public static List<World> save(final List<World> worlds) throws Throwable {
+        Set<String> updateProperties = new HashSet<>();
+        updateProperties.add("randomNumber");
+
+        for (World world : worlds) {
+            Ebean.update(world, updateProperties);
+        }
+
+        return worlds;
+    }
+
+}

+ 21 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Headers.java

@@ -0,0 +1,21 @@
+package utils;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import play.libs.F;
+import play.mvc.Action;
+import play.mvc.Http;
+import play.mvc.Result;
+
+public class Headers extends Action.Simple {
+
+    private static final DateTimeFormatter RFC_1123_DATE_TIME = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'").withZoneUTC();
+
+    @Override
+    public F.Promise<Result> call(Http.Context context) throws Throwable {
+        context.response().setHeader("Server", "Play2");
+        context.response().setHeader("Date", RFC_1123_DATE_TIME.print(new DateTime()));
+        return delegate.call(context);
+    }
+}

+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/app/utils/Predicate.java → frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Predicate.java


+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/app/utils/Predicated.java → frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/Predicated.java


+ 3 - 3
frameworks/Java/play2-java/play2-java-ebean/app/utils/PredicatedAction.java → frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/utils/PredicatedAction.java

@@ -8,16 +8,16 @@ package utils;
 import play.libs.F;
 import play.mvc.Action;
 import play.mvc.Http;
-import play.mvc.SimpleResult;
+import play.mvc.Result;
 
 public class PredicatedAction extends Action<Predicated> {
     @Override
-    public F.Promise<SimpleResult> call(final Http.Context ctx) throws Throwable {
+    public F.Promise<Result> call(final Http.Context ctx) throws Throwable {
         final Predicate p = configuration.predicate().newInstance();
         if (p.condition()) {
             return delegate.call(ctx);
         } else {
-            return F.Promise.<SimpleResult>pure(status(configuration.failed()));
+            return F.Promise.<Result>pure(status(configuration.failed()));
         }
     }
 }

+ 16 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/views/fortunes.scala.html

@@ -0,0 +1,16 @@
+@(fortunes: List[Fortune])
+
+@main() {
+    <table>
+        <tr>
+            <th>id</th>
+            <th>message</th>
+        </tr>
+        @for(fortune <- fortunes) {
+        <tr>
+            <td>@fortune.id</td>
+            <td>@fortune.message</td>
+        </tr>
+        }
+    </table>
+}

+ 12 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/app/views/main.scala.html

@@ -0,0 +1,12 @@
+@()(content: Html)
+
+<!DOCTYPE html>
+
+<html>
+    <head>
+        <title>Fortunes</title>
+    </head>
+    <body>
+    @content
+    </body>
+</html>

+ 16 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/build.sbt

@@ -0,0 +1,16 @@
+name := "play2-java-ebean-hikaricp"
+
+version := "1.0-SNAPSHOT"
+
+lazy val root = (project in file(".")).enablePlugins(PlayJava)
+
+scalaVersion := "2.11.4"
+
+libraryDependencies ++= Seq(
+  javaJdbc,
+  javaEbean,
+  "mysql" % "mysql-connector-java" % "5.1.33",
+  "com.edulify" %% "play-hikaricp" % "1.5.0"
+)
+
+resolvers += Resolver.url("Edulify Repository", url("http://edulify.github.io/modules/releases/"))(Resolver.ivyStylePatterns)

+ 78 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/application.conf

@@ -0,0 +1,78 @@
+# This is the main configuration file for the application.
+# ~~~~~
+
+# Secret key
+# ~~~~~
+# The secret key is used to secure cryptographics functions.
+# If you deploy your application to several instances be sure to use the same key!
+application.secret="RItx1I:80?W@]8GAtPDuF8Ydd3mXM85p/<7og]Q;uBOdijQAauRDgu73B6`wQP59"
+
+# The application languages
+# ~~~~~
+application.langs="en"
+
+# Global object class
+# ~~~~~
+# Define the Global object class for this application.
+# Default to Global in the root package.
+# global=Global
+
+# Database configuration
+# ~~~~~ 
+# You can declare as many datasources as you want.
+# By convention, the default datasource is named `default`
+#
+# db.default.driver=org.h2.Driver
+# db.default.url="jdbc:h2:mem:play"
+# db.default.user=sa
+# db.default.password=
+#
+# You can expose this datasource via JNDI if needed (Useful for JPA)
+# db.default.jndiName=DefaultDS
+db.default.driver= com.mysql.jdbc.Driver
+db.default.url="jdbc:mysql://127.0.0.1:3306/hello_world?jdbcCompliantTruncation=false&elideSetAutoCommits=true&useLocalSessionState=true&cachePrepStmts=true&cacheCallableStmts=true&alwaysSendSetIsolation=false&prepStmtCacheSize=4096&cacheServerConfiguration=true&prepStmtCacheSqlLimit=2048&zeroDateTimeBehavior=convertToNull&traceProtocol=false&useUnbufferedInput=false&useReadAheadInput=false&maintainTimeStats=false&useServerPrepStmts&cacheRSMetadata=true"
+db.default.user=benchmarkdbuser
+db.default.password=benchmarkdbpass
+db.default.jndiName=DefaultDS
+
+db.default.partitionCount=4
+
+# The number of connections to create per partition. Setting this to 
+# 5 with 3 partitions means you will have 15 unique connections to the 
+# database.
+
+# This value maps to the maximumPoolSize for HickariCP (db.default.partitionCount * db.default.maxConnectionsPerPartition)
+db.default.maxConnectionsPerPartition=64
+
+# The number of initial connections, per partition.
+#
+# This maps to the minimumIdle connections for HikariCP (db.default.partitionCount * db.default.minConnectionsPerPartition)
+db.default.minConnectionsPerPartition=64
+
+dbplugin=disabled
+
+# Evolutions
+# ~~~~~
+# You can disable evolutions if needed
+evolutionplugin=disabled
+
+# Ebean configuration
+# ~~~~~
+# You can declare as many Ebean servers as you want.
+# By convention, the default server is named `default`
+#
+ebean.default="models.*"
+
+# Logger
+# ~~~~~
+# You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory .
+
+# Root logger:
+logger.root=INFO
+
+# Logger used by the framework:
+logger.play=ERROR
+
+# Logger provided to your application:
+logger.application=ERROR
+

+ 1 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/play.plugins

@@ -0,0 +1 @@
+200:com.edulify.play.hikaricp.HikariCPPlugin

+ 13 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/conf/routes

@@ -0,0 +1,13 @@
+# Routes
+# This file defines all application routes (Higher priority routes first)
+# ~~~~
+
+# Home page
+GET        /db                  controllers.Application.db()
+GET        /queries             controllers.Application.queries(queries ?= "1")
+GET        /fortunes            controllers.Application.fortunes
+GET        /update              controllers.Application.update(queries ?= "1")
+
+
+# Map static resources from the /public folder to the /assets URL path
+GET        /assets/*file        controllers.Assets.at(path="/public", file)

+ 1 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/project/build.properties

@@ -0,0 +1 @@
+sbt.version=0.13.5

+ 1 - 1
frameworks/Java/play2-java/play2-java-ebean/project/plugins.sbt → frameworks/Java/play2-java/play2-java-ebean-hikaricp/project/plugins.sbt

@@ -5,4 +5,4 @@ logLevel := Level.Warn
 resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
 
 // Use the Play sbt plugin for Play projects
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.6")

+ 11 - 0
frameworks/Java/play2-java/play2-java-ebean-hikaricp/source_code

@@ -0,0 +1,11 @@
+./play-java-jpa/app/
+./play-java-jpa/app/controllers
+./play-java-jpa/app/controllers/Application.java
+./play-java-jpa/app/utils
+./play-java-jpa/app/utils/Headers.java
+./play-java-jpa/app/utils/Predicate.java
+./play-java-jpa/app/utils/PredicatedAction.java
+./play-java-jpa/app/utils/Predicated.java
+./play-java-jpa/app/models
+./play-java-jpa/app/models/World.java
+./play-java-jpa/app/models/Fortune.java

+ 0 - 20
frameworks/Java/play2-java/play2-java-ebean/README.md

@@ -1,20 +0,0 @@
-#Play Benchmarking Test
-
-This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
-
-### Data-Store/Database Mapping Test
-
-* [Database test controller](app/controllers/Application.java)
-* [Database test model](app/models/World.java)
-
-## Infrastructure Software Versions
-The tests were run with:
-
-* [Java OpenJDK 1.7](http://openjdk.java.net/)
-* [Play 2.2.0](http://http://www.playframework.com/)
-
-## Test URLs
-
-### Data-Store/Database Mapping Test
-
-http://localhost/db?queries=5

+ 0 - 20
frameworks/Java/play2-java/play2-java-ebean/app/models/World.java

@@ -1,20 +0,0 @@
-package models;
-
-import javax.persistence.*;
-
-import play.db.ebean.*;
-
-@Entity
-public class World extends Model {
-
-    @Id
-    public Long id;
-
-    @Column(name = "randomNumber")
-    public Long randomNumber;
-
-    public static Finder<Long, World> find = new Finder<Long, World>(
-            Long.class, World.class
-    );
-
-}

+ 0 - 11
frameworks/Java/play2-java/play2-java-ebean/build.sbt

@@ -1,11 +0,0 @@
-name := "play2-java-ebean"
-
-version := "1.0-SNAPSHOT"
-
-libraryDependencies ++= Seq(
-  javaJdbc,
-  javaEbean,
-  "mysql" % "mysql-connector-java" % "5.1.32"
-  )
-
-playJavaSettings

+ 0 - 10
frameworks/Java/play2-java/play2-java-ebean/conf/routes

@@ -1,10 +0,0 @@
-# Routes
-# This file defines all application routes (Higher priority routes first)
-# ~~~~
-
-# Home page
-GET     /db                             controllers.Application.db()
-GET     /queries                        controllers.Application.queries(queries ?= "1")
-
-# Map static resources from the /public folder to the /assets URL path
-GET     /assets/*file               controllers.Assets.at(path="/public", file)

+ 0 - 1
frameworks/Java/play2-java/play2-java-ebean/project/build.properties

@@ -1 +0,0 @@
-sbt.version=0.13.0

+ 0 - 9
frameworks/Java/play2-java/play2-java-ebean/source_code

@@ -1,9 +0,0 @@
-./play-java/app/
-./play-java/app/controllers
-./play-java/app/controllers/Application.java
-./play-java/app/utils
-./play-java/app/utils/Predicate.java
-./play-java/app/utils/PredicatedAction.java
-./play-java/app/utils/Predicated.java
-./play-java/app/models
-./play-java/app/models/World.java

+ 30 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/.gitignore

@@ -0,0 +1,30 @@
+logs
+project/project
+project/target
+target
+tmp
+.history
+dist
+
+# Ignore all dotfiles...
+.*
+# except for .gitignore
+!.gitignore
+
+# Ignore Play! working directory #
+db
+eclipse
+lib
+log
+logs
+modules
+precompiled
+project/project
+project/target
+target
+tmp
+test-result
+server.pid
+*.iml
+*.eml
+

+ 35 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/README.md

@@ -0,0 +1,35 @@
+#Play Benchmarking Test
+
+This is the Play portion of a [benchmarking test suite](../) comparing a variety of web development platforms.
+
+### JSON Encoding Test
+
+* [JSON test controller](app/controllers/Application.java)
+
+### Data-Store/Database Mapping Test
+
+* [Database test controller](app/controllers/Application.java)
+* [Database World test model](app/models/World.java)
+* [Database Fortune test model](app/models/Fortune.java)
+
+### Plain Text Test
+
+* [Plain text test controller](app/controllers/Application.java)
+
+## Infrastructure Software Versions
+The tests were run with:
+
+* [Java OpenJDK 1.7](http://openjdk.java.net/)
+* [Play 2.3.6](http://http://www.playframework.com/)
+
+## Test URLs
+### JSON Encoding Test
+
+* http://localhost/json
+
+### Data-Store/Database Mapping Test
+
+* http://localhost/db
+* http://localhost/queries?queries=10
+* http://localhost/fortunes
+* http://localhost/update?queries=10

+ 12 - 7
frameworks/Java/play2-java/play2-java-jpa/app/controllers/Application.java → frameworks/Java/play2-java/play2-java-jpa-bonecp/app/controllers/Application.java

@@ -11,7 +11,9 @@ import play.libs.F;
 import play.libs.Json;
 import play.mvc.Controller;
 import play.mvc.Result;
+import play.mvc.With;
 import scala.concurrent.ExecutionContext;
+import utils.Headers;
 import utils.Predicate;
 import utils.Predicated;
 
@@ -21,6 +23,7 @@ import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+@With(Headers.class)
 public class Application extends Controller {
 
     private static final int TEST_DATABASE_ROWS = 10000;
@@ -58,6 +61,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> db() {
         return getRandomWorlds(1).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) {
                 return ok(Json.toJson(worlds.get(0)));
@@ -68,6 +72,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> queries(final String queryCountString) {
         return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) {
                 return ok(Json.toJson(worlds));
@@ -84,11 +89,13 @@ public class Application extends Controller {
                 List<Fortune> fortunes = Fortune.findAll();
                 fortunes.add(new Fortune("Additional fortune added at request time."));
                 Collections.sort(fortunes, new Comparator<Fortune>() {
+
                     @Override
                     public int compare(Fortune f1, Fortune f2) {
                         return f1.message.compareTo(f2.message);
                     }
                 });
+
                 return ok(views.html.fortunes.render(fortunes));
             }
         }, dbEc);
@@ -97,6 +104,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> update(final String queryCountString) {
         return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) throws Throwable {
                 Random random = ThreadLocalRandom.current();
@@ -104,14 +112,10 @@ public class Application extends Controller {
                     world.randomNumber = (long) (random.nextInt(10000) + 1);
                 }
 
-                worlds = World.save(worlds);
-                return ok(Json.toJson(worlds));
+                List<World> updatedWorlds = World.save(worlds);
+                return ok(Json.toJson(updatedWorlds));
             }
-        });
-    }
-
-    public static Result plainText() {
-        return ok("Hello, World!");
+        }, dbEc);
     }
 
     private static int queryCount(String queryCountString) {
@@ -132,6 +136,7 @@ public class Application extends Controller {
 
     private static F.Promise<List<World>> getRandomWorlds(final int n) {
         return F.Promise.promise(new F.Function0<List<World>>() {
+
             @Override
             public List<World> apply() throws Throwable {
                 Random random = ThreadLocalRandom.current();

+ 34 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/models/Fortune.java

@@ -0,0 +1,34 @@
+package models;
+
+import play.db.jpa.JPA;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.criteria.CriteriaQuery;
+import java.util.List;
+
+@Entity
+public class Fortune {
+
+    @Id
+    public Long id = 0L;
+
+    public String message;
+
+    public Fortune() {
+    }
+
+    public Fortune(String message) {
+        this.message = message;
+    }
+
+    public static List<Fortune> findAll() throws Throwable {
+        return JPA.withTransaction("default", true, new play.libs.F.Function0<List<Fortune>>() {
+            public List<Fortune> apply() {
+                CriteriaQuery<Fortune> criteria = JPA.em().getCriteriaBuilder().createQuery(Fortune.class);
+                criteria.select(criteria.from(Fortune.class));
+                return JPA.em().createQuery(criteria).getResultList();
+            }
+        });
+    }
+}

+ 38 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/models/World.java

@@ -0,0 +1,38 @@
+package models;
+
+import play.db.jpa.JPA;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import java.util.List;
+
+@Entity
+public class World {
+
+    @Id
+    public Long id;
+
+    @Column(name = "randomNumber")
+    public Long randomNumber;
+
+    public static World findById(final Long id) throws Throwable {
+        return JPA.withTransaction("default", true, new play.libs.F.Function0<World>() {
+            public World apply() {
+                return JPA.em().find(World.class, id);
+            }
+        });
+    }
+
+    public static List<World> save(final List<World> worlds) throws Throwable {
+        for (final World world : worlds) {
+            JPA.withTransaction("default", false, new play.libs.F.Function0<World>() {
+                public World apply() {
+                    return JPA.em().merge(world);
+                }
+            });
+        }
+
+        return worlds;
+    }
+}

+ 21 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Headers.java

@@ -0,0 +1,21 @@
+package utils;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import play.libs.F;
+import play.mvc.Action;
+import play.mvc.Http;
+import play.mvc.Result;
+
+public class Headers extends Action.Simple {
+
+    private static final DateTimeFormatter RFC_1123_DATE_TIME = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'").withZoneUTC();
+
+    @Override
+    public F.Promise<Result> call(Http.Context context) throws Throwable {
+        context.response().setHeader("Server", "Play2");
+        context.response().setHeader("Date", RFC_1123_DATE_TIME.print(new DateTime()));
+        return delegate.call(context);
+    }
+}

+ 8 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Predicate.java

@@ -0,0 +1,8 @@
+package utils;
+
+/**
+ * Predicates for PredicatedActions.
+ */
+public interface Predicate {
+    boolean condition();
+}

+ 26 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/Predicated.java

@@ -0,0 +1,26 @@
+package utils;
+
+import play.mvc.With;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Declares a composing action that will check for a condition before deciding on whether to proceed with the request.
+ */
+@With(PredicatedAction.class)
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Predicated {
+    /**
+     * The condition.
+     */
+    Class<? extends Predicate> predicate();
+
+    /**
+     * The http status code to return if the condition fails.
+     */
+    int failed();
+}

+ 23 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/utils/PredicatedAction.java

@@ -0,0 +1,23 @@
+package utils;
+
+/**
+ * A predicated action is one where a condition must be satisfied in order to proceed with the request. If the
+ * condition is not satisfied then a supplied status result is yielded.
+ */
+
+import play.libs.F;
+import play.mvc.Action;
+import play.mvc.Http;
+import play.mvc.Result;
+
+public class PredicatedAction extends Action<Predicated> {
+    @Override
+    public F.Promise<Result> call(final Http.Context ctx) throws Throwable {
+        final Predicate p = configuration.predicate().newInstance();
+        if (p.condition()) {
+            return delegate.call(ctx);
+        } else {
+            return F.Promise.<Result>pure(status(configuration.failed()));
+        }
+    }
+}

+ 16 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/views/fortunes.scala.html

@@ -0,0 +1,16 @@
+@(fortunes: List[Fortune])
+
+@main() {
+    <table>
+        <tr>
+            <th>id</th>
+            <th>message</th>
+        </tr>
+        @for(fortune <- fortunes) {
+        <tr>
+            <td>@fortune.id</td>
+            <td>@fortune.message</td>
+        </tr>
+        }
+    </table>
+}

+ 12 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/app/views/main.scala.html

@@ -0,0 +1,12 @@
+@()(content: Html)
+
+<!DOCTYPE html>
+
+<html>
+    <head>
+        <title>Fortunes</title>
+    </head>
+    <body>
+    @content
+    </body>
+</html>

+ 2 - 2
frameworks/Java/play2-java/play2-java-jpa/build.sbt → frameworks/Java/play2-java/play2-java-jpa-bonecp/build.sbt

@@ -1,8 +1,8 @@
-name := "play2-java-jpa"
+name := "play2-java-jpa-bonecp"
 
 version := "1.0-SNAPSHOT"
 
-scalaVersion := "2.11.2"
+scalaVersion := "2.11.4"
 
 lazy val root = (project in file(".")).enablePlugins(PlayJava)
 

+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/conf/META-INF/persistence.xml → frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/META-INF/persistence.xml


+ 1 - 1
frameworks/Java/play2-java/play2-java-jpa/conf/application.conf → frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/application.conf

@@ -65,7 +65,7 @@ db.default.minConnectionsPerPartition=64
 # You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory .
 
 # Root logger:
-logger.root=ERROR
+logger.root=INFO
 
 # Logger used by the framework:
 logger.play=ERROR

+ 0 - 1
frameworks/Java/play2-java/play2-java-jpa/conf/routes → frameworks/Java/play2-java/play2-java-jpa-bonecp/conf/routes

@@ -7,7 +7,6 @@ GET        /db                  controllers.Application.db()
 GET        /queries             controllers.Application.queries(queries ?= "1")
 GET        /fortunes            controllers.Application.fortunes
 GET        /update              controllers.Application.update(queries ?= "1")
-GET        /plaintext           controllers.Application.plainText
 
 # Map static resources from the /public folder to the /assets URL path
 GET        /assets/*file        controllers.Assets.at(path="/public", file)

+ 0 - 0
frameworks/Java/play2-java/play2-java-jpa/project/build.properties → frameworks/Java/play2-java/play2-java-jpa-bonecp/project/build.properties


+ 8 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/project/plugins.sbt

@@ -0,0 +1,8 @@
+// Comment to get more information during initialization
+logLevel := Level.Warn
+
+// The Typesafe repository 
+resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
+
+// Use the Play sbt plugin for Play projects
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.6")

+ 11 - 0
frameworks/Java/play2-java/play2-java-jpa-bonecp/source_code

@@ -0,0 +1,11 @@
+./play-java-jpa/app/
+./play-java-jpa/app/controllers
+./play-java-jpa/app/controllers/Application.java
+./play-java-jpa/app/utils
+./play-java-jpa/app/utils/Headers.java
+./play-java-jpa/app/utils/Predicate.java
+./play-java-jpa/app/utils/PredicatedAction.java
+./play-java-jpa/app/utils/Predicated.java
+./play-java-jpa/app/models
+./play-java-jpa/app/models/World.java
+./play-java-jpa/app/models/Fortune.java

+ 0 - 4
frameworks/Java/play2-java/play2-java-jpa-hikaricp/README.md

@@ -34,7 +34,3 @@ The tests were run with:
 * http://localhost/fortunes
 * http://localhost/update?queries=10
 
-### Plain Text Test
-
-* http://localhost/plaintext
-

+ 16 - 12
frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/controllers/Application.java

@@ -5,16 +5,17 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import models.Fortune;
 import models.World;
-import play.*;
+import play.Play;
 import play.core.NamedThreadFactory;
 import play.libs.F;
 import play.libs.Json;
-import play.mvc.*;
-
+import play.mvc.Controller;
+import play.mvc.Result;
+import play.mvc.With;
 import scala.concurrent.ExecutionContext;
+import utils.Headers;
 import utils.Predicate;
 import utils.Predicated;
-import views.html.*;
 
 import java.util.*;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -22,9 +23,9 @@ import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+@With(Headers.class)
 public class Application extends Controller {
 
-    private static final int MAX_QUERIES_PER_REQUEST = 20;
     private static final int TEST_DATABASE_ROWS = 10000;
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
@@ -51,6 +52,7 @@ public class Application extends Controller {
     // the max size of our queue something above the number of concurrent
     // connections that we need to handle.
     public static class IsDbAvailable implements Predicate {
+
         @Override
         public boolean condition() {
             return tpe.getQueue().size() <= 1024;
@@ -60,6 +62,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> db() {
         return getRandomWorlds(1).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) {
                 return ok(Json.toJson(worlds.get(0)));
@@ -70,6 +73,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> queries(final String queryCountString) {
         return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) {
                 return ok(Json.toJson(worlds));
@@ -86,11 +90,13 @@ public class Application extends Controller {
                 List<Fortune> fortunes = Fortune.findAll();
                 fortunes.add(new Fortune("Additional fortune added at request time."));
                 Collections.sort(fortunes, new Comparator<Fortune>() {
+
                     @Override
                     public int compare(Fortune f1, Fortune f2) {
                         return f1.message.compareTo(f2.message);
                     }
                 });
+
                 return ok(views.html.fortunes.render(fortunes));
             }
         }, dbEc);
@@ -99,6 +105,7 @@ public class Application extends Controller {
     @Predicated(predicate = IsDbAvailable.class, failed = SERVICE_UNAVAILABLE)
     public static F.Promise<Result> update(final String queryCountString) {
         return getRandomWorlds(queryCount(queryCountString)).map(new F.Function<List<World>, Result>() {
+
             @Override
             public Result apply(List<World> worlds) throws Throwable {
                 Random random = ThreadLocalRandom.current();
@@ -106,14 +113,10 @@ public class Application extends Controller {
                     world.randomNumber = (long) (random.nextInt(10000) + 1);
                 }
 
-                worlds = World.save(worlds);
-                return ok(Json.toJson(worlds));
+                List<World> updatedWorlds = World.save(worlds);
+                return ok(Json.toJson(updatedWorlds));
             }
-        });
-    }
-
-    public static Result plainText() {
-        return ok("Hello, World!");
+        }, dbEc);
     }
 
     private static int queryCount(String queryCountString) {
@@ -134,6 +137,7 @@ public class Application extends Controller {
 
     private static F.Promise<List<World>> getRandomWorlds(final int n) {
         return F.Promise.promise(new F.Function0<List<World>>() {
+
             @Override
             public List<World> apply() throws Throwable {
                 Random random = ThreadLocalRandom.current();

+ 1 - 1
frameworks/Java/play2-java/play2-java-jpa-hikaricp/app/utils/Headers.java

@@ -14,7 +14,7 @@ public class Headers extends Action.Simple {
 
     @Override
     public F.Promise<Result> call(Http.Context context) throws Throwable {
-        context.response().setHeader("Server", "play2-java-jpa");
+        context.response().setHeader("Server", "Play2");
         context.response().setHeader("Date", RFC_1123_DATE_TIME.print(new DateTime()));
         return delegate.call(context);
     }

+ 1 - 1
frameworks/Java/play2-java/play2-java-jpa-hikaricp/build.sbt

@@ -4,7 +4,7 @@ version := "1.0-SNAPSHOT"
 
 lazy val root = (project in file(".")).enablePlugins(PlayJava)
 
-scalaVersion := "2.11.2"
+scalaVersion := "2.11.4"
 
 libraryDependencies ++= Seq(
   javaJdbc,

+ 4 - 6
frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/application.conf

@@ -55,9 +55,7 @@ db.default.partitionCount=4
 
 # The number of connections to create per partition. Setting this to
 # 5 with 3 partitions means you will have 15 unique connections to the
-# database. Note that BoneCP will not create all these connections in
-# one go but rather start off with minConnectionsPerPartition and
-# gradually increase connections as required.
+# database..
 #
 # This value maps to the maximumPoolSize for HickariCP (db.default.partitionCount * db.default.maxConnectionsPerPartition)
 db.default.maxConnectionsPerPartition=64
@@ -87,11 +85,11 @@ evolutionplugin=disabled
 # by providing an application-logger.xml file in the conf directory.
 
 # Root logger:
-logger.root=ERROR
+logger.root=INFO
 
 # Logger used by the framework:
-logger.play=INFO
+logger.play=ERROR
 
 # Logger provided to your application:
-logger.application=DEBUG
+logger.application=ERROR
 

+ 0 - 1
frameworks/Java/play2-java/play2-java-jpa-hikaricp/conf/routes

@@ -7,7 +7,6 @@ GET        /db                  controllers.Application.db()
 GET        /queries             controllers.Application.queries(queries ?= "1")
 GET        /fortunes            controllers.Application.fortunes
 GET        /update              controllers.Application.update(queries ?= "1")
-GET        /plaintext           controllers.Application.plainText
 
 # Map static resources from the /public folder to the /assets URL path
 GET        /assets/*file        controllers.Assets.at(path="/public", file)

+ 5 - 1
frameworks/Java/play2-java/play2-java/README.md

@@ -15,4 +15,8 @@ The tests were run with:
 ## Test URLs
 ### JSON Encoding Test
 
-http://localhost/json
+* http://localhost/json
+
+### Plain Text Test
+
+* http://localhost/plaintext

+ 7 - 0
frameworks/Java/play2-java/play2-java/app/controllers/Application.java

@@ -4,7 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import play.mvc.Controller;
 import play.mvc.Result;
+import play.mvc.With;
+import utils.Headers;
 
+@With(Headers.class)
 public class Application extends Controller {
 
     //http://stackoverflow.com/questions/3907929/should-i-make-jacksons-objectmapper-as-static-final
@@ -16,4 +19,8 @@ public class Application extends Controller {
         return ok(result);
     }
 
+    public static Result plainText() {
+        return ok("Hello, World!");
+    }
+
 }

+ 21 - 0
frameworks/Java/play2-java/play2-java/app/utils/Headers.java

@@ -0,0 +1,21 @@
+package utils;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import play.libs.F;
+import play.mvc.Action;
+import play.mvc.Http;
+import play.mvc.Result;
+
+public class Headers extends Action.Simple {
+
+    private static final DateTimeFormatter RFC_1123_DATE_TIME = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'").withZoneUTC();
+
+    @Override
+    public F.Promise<Result> call(Http.Context context) throws Throwable {
+        context.response().setHeader("Server", "Play2");
+        context.response().setHeader("Date", RFC_1123_DATE_TIME.print(new DateTime()));
+        return delegate.call(context);
+    }
+}

+ 2 - 0
frameworks/Java/play2-java/play2-java/build.sbt

@@ -3,3 +3,5 @@ name := "play2-java"
 version := "1.0-SNAPSHOT"
 
 lazy val root = (project in file(".")).enablePlugins(PlayJava)
+
+scalaVersion := "2.11.4"

+ 3 - 2
frameworks/Java/play2-java/play2-java/conf/routes

@@ -3,7 +3,8 @@
 # ~~~~
 
 # Home page
-GET     /json                           controllers.Application.json
+GET        /json                controllers.Application.json
+GET        /plaintext           controllers.Application.plainText
 
 # Map static resources from the /public folder to the /assets URL path
-GET     /assets/*file               controllers.Assets.at(path="/public", file)
+GET        /assets/*file        controllers.Assets.at(path="/public", file)

+ 1 - 1
frameworks/Java/play2-java/play2-java/project/plugins.sbt

@@ -5,4 +5,4 @@ logLevel := Level.Warn
 resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
 
 // Use the Play sbt plugin for Play projects
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.4")
+addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.6")

+ 0 - 6
frameworks/Java/play2-java/play2-java/source_code

@@ -1,9 +1,3 @@
 ./play-java/app/
 ./play-java/app/controllers
 ./play-java/app/controllers/Application.java
-./play-java/app/utils
-./play-java/app/utils/Predicate.java
-./play-java/app/utils/PredicatedAction.java
-./play-java/app/utils/Predicated.java
-./play-java/app/models
-./play-java/app/models/World.java

+ 6 - 0
frameworks/Java/play2-java/setup_java_ebean_bonecp.py

@@ -0,0 +1,6 @@
+
+# This file was generated by frameworks/Java/play2-java/generate_config.py.
+# Do not edit this file directly, use the script to regenerate.
+from .setup_common import make_setup_for_dir
+
+make_setup_for_dir(globals(), 'play2-java-ebean-bonecp')

+ 6 - 0
frameworks/Java/play2-java/setup_java_ebean_hikaricp.py

@@ -0,0 +1,6 @@
+
+# This file was generated by frameworks/Java/play2-java/generate_config.py.
+# Do not edit this file directly, use the script to regenerate.
+from .setup_common import make_setup_for_dir
+
+make_setup_for_dir(globals(), 'play2-java-ebean-hikaricp')

+ 6 - 0
frameworks/Java/play2-java/setup_java_jpa_bonecp.py

@@ -0,0 +1,6 @@
+
+# This file was generated by frameworks/Java/play2-java/generate_config.py.
+# Do not edit this file directly, use the script to regenerate.
+from .setup_common import make_setup_for_dir
+
+make_setup_for_dir(globals(), 'play2-java-jpa-bonecp')