Prechádzať zdrojové kódy

Merge pull request #1166 from donovanmuller/master

Updated all benchmarks to Play 2.3.6 and Scala 2.11.4.
Mike Smith 11 rokov pred
rodič
commit
2f20af98e7
77 zmenil súbory, kde vykonal 1046 pridanie a 152 odobranie
  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')