Browse Source

Update Grizzly (#4603)

* Update Grizzly

* Updated Grizzly-Jersey or Jersey-Grizzly?
Radoslav Petrov 6 years ago
parent
commit
83748aa53a
25 changed files with 766 additions and 656 deletions
  1. 68 0
      frameworks/Java/grizzly/README.md
  2. 3 2
      frameworks/Java/grizzly/benchmark_config.json
  3. 183 140
      frameworks/Java/grizzly/pom-jersey.xml
  4. 2 2
      frameworks/Java/grizzly/pom.xml
  5. 6 11
      frameworks/Java/grizzly/src-jersey/main/java/hello/Common.java
  6. 0 71
      frameworks/Java/grizzly/src-jersey/main/java/hello/DbResource.java
  7. 23 31
      frameworks/Java/grizzly/src-jersey/main/java/hello/FortunesResource.java
  8. 28 0
      frameworks/Java/grizzly/src-jersey/main/java/hello/Jackson2MapperProvider.java
  9. 0 85
      frameworks/Java/grizzly/src-jersey/main/java/hello/JerseyWebServer.java
  10. 0 56
      frameworks/Java/grizzly/src-jersey/main/java/hello/JsonMessageBodyWriter.java
  11. 6 6
      frameworks/Java/grizzly/src-jersey/main/java/hello/JsonResource.java
  12. 0 42
      frameworks/Java/grizzly/src-jersey/main/java/hello/MustacheViewProcessor.java
  13. 7 7
      frameworks/Java/grizzly/src-jersey/main/java/hello/PlaintextResource.java
  14. 19 10
      frameworks/Java/grizzly/src-jersey/main/java/hello/ServerHeaderFilter.java
  15. 39 0
      frameworks/Java/grizzly/src-jersey/main/java/hello/SessionFactoryFactory.java
  16. 0 36
      frameworks/Java/grizzly/src-jersey/main/java/hello/SessionFactoryProvider.java
  17. 25 0
      frameworks/Java/grizzly/src-jersey/main/java/hello/TFBApplication.java
  18. 78 0
      frameworks/Java/grizzly/src-jersey/main/java/hello/WebServer.java
  19. 121 0
      frameworks/Java/grizzly/src-jersey/main/java/hello/WorldResource.java
  20. 2 0
      frameworks/Java/grizzly/src-jersey/main/resources/hibernate.cfg.xml
  21. 27 25
      frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/JsonHttpHandler.java
  22. 18 16
      frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/PlainText2HttpHandler.java
  23. 15 14
      frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/PlainTextHttpHandler.java
  24. 30 26
      frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/RootHttpHandler.java
  25. 66 76
      frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/Server.java

+ 68 - 0
frameworks/Java/grizzly/README.md

@@ -0,0 +1,68 @@
+# Eclipse Grizzly Benchmarking Test
+
+[Eclipse Grizzly](https://projects.eclipse.org/projects/ee4j.grizzly) - HTTP Protocol framework and HTTP server framework.
+
+### Test sources
+
+Currently implemented tests are:
+
+ * [Plaintext](src/main/java/org/glassfish/grizzly/bm/PlainText2HttpHandler.java)
+ * [JSON](src/main/java/org/glassfish/grizzly/bm/JsonHttpHandler.java)
+
+The [Server.java](src/main/java/org/glassfish/grizzly/bm/Server.java) is modifying the standard configuration a lot. It is utilizing the ["Same thread I/O strategy"](https://javaee.github.io/grizzly/iostrategies.html). Note: this needs confirmation!
+
+Also the command line arguments are modified: `java -Dorg.glassfish.grizzly.nio.transport.TCPNIOTransport.max-receive-buffer-size=16384 -Dorg.glassfish.grizzly.http.io.OutputBuffer.default-buffer-size=1024 -Dorg.glassfish.grizzly.memory.BuffersBuffer.bb-cache-size=32 -jar app.jar`
+
+## Software Versions
+
+The tests were run with:
+
+ * [Oracle Java 10](https://www.oracle.com/java/)
+ * [Jackson](https://github.com/FasterXML/jackson/wiki/Jackson-Releases)
+
+Please check the versions in the install and build scripts of TFB project.
+
+## Test URLs
+
+ * Plaintext - `http://localhost:8080/plaintext`
+ * JSON - `http://localhost:8080/json`
+
+
+# Eclipse Jersey with Grizzly Benchmarking Test
+
+[Eclipse Jersey](https://projects.eclipse.org/projects/ee4j.jersey) - REST framework that provides a JAX-RS (JSR-370) implementation and more.
+
+### Test sources
+
+Currently implemented tests are:
+
+ * [Plaintext](src/main/java/org/glassfish/grizzly/bm/PlainText2HttpHandler.java)
+ * [JSON](src/main/java/org/glassfish/grizzly/bm/JsonHttpHandler.java)
+ * [DB test source](src/main/java/hello/WorldResource.java)
+ * [Queries test source](src/main/java/hello/WorldResource.java)
+ * [Updates test source](src/main/java/hello/WorldResource.java)
+ * [Fortune test source](src/main/java/hello/FortunesResource.java)
+
+ The [WebServer.java](src/main/java/hello/WebServer.java) is modifying the standard configuration. It is made to mimic the configuration in the Grizzly benchmark implementation.
+
+## Software Versions
+
+The tests were run with:
+
+ * [Oracle Java 10](https://www.oracle.com/java/)
+ * [PostgreSQL](http://www.postgresql.org/)
+ * [Eclipse Grizzly](https://projects.eclipse.org/projects/ee4j.grizzly)
+ * [Jackson](https://github.com/FasterXML/jackson/wiki/Jackson-Releases)
+ * [Hibernate ORM](https://hibernate.org/orm/)
+ * [mustache.java](https://github.com/spullara/mustache.java)
+
+Please check the versions in the install and build scripts of TFB project.
+
+## Test URLs
+
+ * Plaintext - `http://localhost:8080/plaintext`
+ * JSON - `http://localhost:8080/json`
+ * DB - `http://localhost:8080/db?single=true`
+ * Queries - `http://localhost:8080/db?queries=`
+ * Updates - `http://localhost:8080/update?queries=`
+ * Fortune - `http://localhost:8080/fortunes`

+ 3 - 2
frameworks/Java/grizzly/benchmark_config.json

@@ -22,8 +22,9 @@
     },
     },
     "jersey": {
     "jersey": {
       "json_url": "/json",
       "json_url": "/json",
-      "db_url": "/db?single=true",
-      "query_url": "/db?queries=",
+      "db_url": "/db",
+      "query_url": "/db/queries?queries=",
+      "update_url": "/db/updates?queries=",
       "fortune_url": "/fortunes",
       "fortune_url": "/fortunes",
       "plaintext_url": "/plaintext",
       "plaintext_url": "/plaintext",
       "port": 8080,
       "port": 8080,

+ 183 - 140
frameworks/Java/grizzly/pom-jersey.xml

@@ -1,148 +1,191 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
 
-  <modelVersion>4.0.0</modelVersion>
+	<modelVersion>4.0.0</modelVersion>
 
 
-  <groupId>com.techempower</groupId>
-  <artifactId>grizzly-jersey-example</artifactId>
-  <version>0.1</version>
+	<groupId>com.techempower</groupId>
+	<artifactId>grizzly-jersey-example</artifactId>
+	<version>0.1</version>
 
 
-  <packaging>jar</packaging>
+	<packaging>jar</packaging>
 
 
-  <prerequisites>
-    <maven>3.0</maven>
-  </prerequisites>
+	<prerequisites>
+		<maven>3.0</maven>
+	</prerequisites>
 
 
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
-    <activation.version>1.1.1</activation.version>
-    <commons-cli.version>1.4</commons-cli.version>
-    <grizzly.version>2.3.35</grizzly.version>
-    <hibernate.version>4.3.11.Final</hibernate.version>
-    <hibernate-jpa-api.version>1.0.0.Final</hibernate-jpa-api.version>
-    <jackson.version>2.9.7</jackson.version>
-    <jaxb.version>2.3.0</jaxb.version>
-    <jersey.version>1.19.4</jersey.version>
-    <jsr311-api.version>1.1.1</jsr311-api.version>
-    <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
-    <maven-shade-plugin.version>3.1.0</maven-shade-plugin.version>
-    <mustache.version>0.9.5</mustache.version>
-    <mysql-connector.version>5.1.47</mysql-connector.version>
-  </properties>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<maven.compiler.source>1.8</maven.compiler.source>
+		<maven.compiler.target>1.8</maven.compiler.target>
+		<activation.version>1.1.1</activation.version>
+		<commons-cli.version>1.4</commons-cli.version>
+		<grizzly.version>2.4.4</grizzly.version>
+		<hibernate.version>4.3.11.Final</hibernate.version>
+		<hibernate-jpa-api.version>1.0.0.Final</hibernate-jpa-api.version>
+		<jackson.version>2.9.8</jackson.version>
+		<jaxb.version>2.3.0</jaxb.version>
+		<jersey.version>2.28</jersey.version>
+		<maven-compiler-plugin.version>3.7.0</maven-compiler-plugin.version>
+		<maven-shade-plugin.version>3.1.0</maven-shade-plugin.version>
+		<mustache.version>0.9.6</mustache.version>
+		<mysql-connector.version>5.1.47</mysql-connector.version>
+	</properties>
 
 
-  <dependencies>
-    <dependency>
-      <groupId>javax.ws.rs</groupId>
-      <artifactId>jsr311-api</artifactId>
-      <version>${jsr311-api.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-core</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-server</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-grizzly2</artifactId>
-      <version>${jersey.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.glassfish.grizzly</groupId>
-      <artifactId>grizzly-http</artifactId>
-      <version>${grizzly.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.glassfish.grizzly</groupId>
-      <artifactId>grizzly-http-server</artifactId>
-      <version>${grizzly.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.github.spullara.mustache.java</groupId>
-      <artifactId>compiler</artifactId>
-      <version>${mustache.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>com.fasterxml.jackson.core</groupId>
-      <artifactId>jackson-databind</artifactId>
-      <version>${jackson.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.hibernate</groupId>
-      <artifactId>hibernate-core</artifactId>
-      <version>${hibernate.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.hibernate</groupId>
-      <artifactId>hibernate-hikaricp</artifactId>
-      <version>${hibernate.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.hibernate.javax.persistence</groupId>
-      <artifactId>hibernate-jpa-2.1-api</artifactId>
-      <version>${hibernate-jpa-api.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>mysql</groupId>
-      <artifactId>mysql-connector-java</artifactId>
-      <version>${mysql-connector.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>commons-cli</groupId>
-      <artifactId>commons-cli</artifactId>
-      <version>${commons-cli.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.glassfish.jaxb</groupId>
-      <artifactId>jaxb-runtime</artifactId>
-      <version>${jaxb.version}</version>
-    </dependency>
-    <dependency>
-      <groupId>javax.activation</groupId>
-      <artifactId>activation</artifactId>
-      <version>${activation.version}</version>
-    </dependency>
-  </dependencies>
+	<dependencies>
+		<dependency>
+			<groupId>javax.ws.rs</groupId>
+			<artifactId>javax.ws.rs-api</artifactId>
+			<version>2.1</version>
+		</dependency>
 
 
-  <build>
-    <finalName>${project.artifactId}</finalName>
-    <plugins>
-      <plugin>
-        <inherited>true</inherited>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>${maven-compiler-plugin.version}</version>
-        <configuration>
-          <debug>false</debug>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-shade-plugin</artifactId>
-        <version>${maven-shade-plugin.version}</version>
-        <executions>
-          <execution>
-            <phase>package</phase>
-            <goals>
-              <goal>shade</goal>
-            </goals>
-            <configuration>
-              <transformers>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
-                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
-                  <mainClass>hello.JerseyWebServer</mainClass>
-                </transformer>
-              </transformers>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
-</project>
+		<dependency>
+			<groupId>org.glassfish.jersey.containers</groupId>
+			<artifactId>jersey-container-grizzly2-http</artifactId>
+			<version>${jersey.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.glassfish.jersey.inject</groupId>
+			<artifactId>jersey-hk2</artifactId>
+			<version>${jersey.version}</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>javax.inject</artifactId>
+					<groupId>javax.inject</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+
+		<dependency>
+			<groupId>org.glassfish.jersey.ext</groupId>
+			<artifactId>jersey-mvc-mustache</artifactId>
+			<version>${jersey.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.glassfish.jersey.media</groupId>
+			<artifactId>jersey-media-json-jackson</artifactId>
+			<version>${jersey.version}</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>com.fasterxml.jackson.module</artifactId>
+					<groupId>jackson-module-jaxb-annotations</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<!-- <artifactId>jersey-container-grizzly2-http</artifactId> <artifactId>jersey-container-servlet</artifactId> 
+			<artifactId>jersey-container-grizzly2-servlet</artifactId> <dependency> <groupId>com.sun.jersey</groupId> 
+			<artifactId>jersey-grizzly2</artifactId> <version>${jersey.version}</version> 
+			</dependency> <dependency> <groupId>org.glassfish.grizzly</groupId> <artifactId>grizzly-http</artifactId> 
+			<version>${grizzly.version}</version> </dependency> <dependency> <groupId>org.glassfish.grizzly</groupId> 
+			<artifactId>grizzly-http-server</artifactId> <version>${grizzly.version}</version> 
+			</dependency> -->
+
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<version>1.8.0-beta2</version>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-simple</artifactId>
+			<version>1.8.0-beta2</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.github.spullara.mustache.java</groupId>
+			<artifactId>compiler</artifactId>
+			<version>${mustache.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>${jackson.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-annotations</artifactId>
+			<version>${jackson.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.module</groupId>
+			<artifactId>jackson-module-afterburner</artifactId>
+			<version>${jackson.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-core</artifactId>
+			<version>${hibernate.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>hibernate-hikaricp</artifactId>
+			<version>${hibernate.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate.javax.persistence</groupId>
+			<artifactId>hibernate-jpa-2.1-api</artifactId>
+			<version>${hibernate-jpa-api.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+			<version>${mysql-connector.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-cli</groupId>
+			<artifactId>commons-cli</artifactId>
+			<version>${commons-cli.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.glassfish.jaxb</groupId>
+			<artifactId>jaxb-runtime</artifactId>
+			<version>${jaxb.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.activation</groupId>
+			<artifactId>activation</artifactId>
+			<version>${activation.version}</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<finalName>${project.artifactId}</finalName>
+		<plugins>
+			<plugin>
+				<inherited>true</inherited>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>${maven-compiler-plugin.version}</version>
+				<configuration>
+					<optimize>true</optimize>
+					<debug>false</debug>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-shade-plugin</artifactId>
+				<version>${maven-shade-plugin.version}</version>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<goals>
+							<goal>shade</goal>
+						</goals>
+						<configuration>
+							<transformers>
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+									<!-- <mainClass>hello.JerseyWebServer</mainClass> -->
+									<mainClass>hello.WebServer</mainClass>
+								</transformer>
+							</transformers>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>

+ 2 - 2
frameworks/Java/grizzly/pom.xml

@@ -67,12 +67,12 @@
         <dependency>
         <dependency>
             <groupId>org.glassfish.grizzly</groupId>
             <groupId>org.glassfish.grizzly</groupId>
             <artifactId>grizzly-http-server</artifactId>
             <artifactId>grizzly-http-server</artifactId>
-            <version>2.3.35</version>
+            <version>2.4.4</version>
         </dependency>
         </dependency>
         <dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
             <artifactId>jackson-databind</artifactId>
-            <version>2.9.7</version>
+            <version>2.9.8</version>
         </dependency>
         </dependency>
     </dependencies>
     </dependencies>
 </project>
 </project>

+ 6 - 11
frameworks/Java/grizzly/src-jersey/main/java/hello/Common.java

@@ -9,17 +9,12 @@ import java.util.concurrent.TimeUnit;
  * @author denkab
  * @author denkab
  */
  */
 final class Common {
 final class Common {
-  private Common() {}
+	private Common() {
+	}
 
 
-  private static final int cpuCount =
-      Runtime.getRuntime().availableProcessors();
+	private static final int cpuCount = Runtime.getRuntime().availableProcessors();
 
 
-  static ExecutorService EXECUTOR =
-      new ThreadPoolExecutor(
-          cpuCount * 2,
-          cpuCount * 25,
-          200,
-          TimeUnit.MILLISECONDS,
-          new LinkedBlockingQueue<>(cpuCount * 100),
-          new ThreadPoolExecutor.CallerRunsPolicy());
+	static ExecutorService EXECUTOR = new ThreadPoolExecutor(cpuCount * 2, cpuCount * 25, 200,
+			TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(cpuCount * 100),
+			new ThreadPoolExecutor.CallerRunsPolicy());
 }
 }

+ 0 - 71
frameworks/Java/grizzly/src-jersey/main/java/hello/DbResource.java

@@ -1,71 +0,0 @@
-package hello;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import com.sun.jersey.spi.resource.Singleton;
-import hello.domain.World;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadLocalRandom;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-
-@Singleton
-@Path("/db")
-public class DbResource {
-
-  @Context
-  private SessionFactory sessionFactory;
-
-  @GET
-  @Produces(APPLICATION_JSON)
-  public Object db(@QueryParam("queries") String queryParam,
-                   @QueryParam("single") boolean isSingle)
-      throws ExecutionException, InterruptedException {
-
-    int queries = getQueries(queryParam);
-
-    @SuppressWarnings("unchecked")
-    Future<World>[] futureWorlds = new Future[queries];
-    for (int i = 0; i < queries; i++) {
-      Callable<World> callable =
-          () -> {
-            int id = ThreadLocalRandom.current().nextInt(DB_ROWS) + 1;
-            Session session = sessionFactory.openSession();
-            session.setDefaultReadOnly(true);
-            try {
-              return (World) session.byId(World.class).load(id);
-            } finally {
-              session.close();
-            }
-          };
-      futureWorlds[i] = Common.EXECUTOR.submit(callable);
-    }
-
-    World[] worlds = new World[queries];
-    for (int i = 0; i < queries; i++) {
-      worlds[i] = futureWorlds[i].get();
-    }
-
-    return isSingle ? worlds[0] : worlds;
-  }
-
-  private static int getQueries(String proto) {
-    int result = 1;
-    try {
-      if (proto != null && !proto.trim().isEmpty()) {
-        result = Integer.parseInt(proto);
-      }
-    } catch (NumberFormatException ignored) {/* by test contract */}
-
-    return Math.min(500, Math.max(1, result));
-  }
-
-  private static final int DB_ROWS = 10000;
-}

+ 23 - 31
frameworks/Java/grizzly/src-jersey/main/java/hello/FortunesResource.java

@@ -1,16 +1,18 @@
 package hello;
 package hello;
 
 
 import static javax.ws.rs.core.MediaType.TEXT_HTML;
 import static javax.ws.rs.core.MediaType.TEXT_HTML;
-
-import com.sun.jersey.api.view.Viewable;
-import com.sun.jersey.spi.resource.Singleton;
 import hello.domain.Fortune;
 import hello.domain.Fortune;
+
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.GET;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
+
+import org.glassfish.jersey.server.mvc.Template;
 import org.hibernate.Criteria;
 import org.hibernate.Criteria;
 import org.hibernate.Session;
 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.SessionFactory;
@@ -18,31 +20,21 @@ import org.hibernate.SessionFactory;
 @Singleton
 @Singleton
 @Path("/fortunes")
 @Path("/fortunes")
 public class FortunesResource {
 public class FortunesResource {
+	@Inject
+	private SessionFactory sessionFactory;
 
 
-  @Context
-  private SessionFactory sessionFactory;
-
-  @GET
-  @Produces(TEXT_HTML + "; charset=utf-8")
-  public Viewable fortunes() {
-    Session session = sessionFactory.openSession();
-    Criteria criteria = session.createCriteria(Fortune.class);
-    @SuppressWarnings("unchecked")
-    List<Fortune> fortunes = new ArrayList<>(criteria.list());
-    session.close();
-    fortunes.add(new Fortune(0, "Additional fortune added at request time."));
-    fortunes.sort(null);
-    return new ViewableFortunes(fortunes);
-  }
-
-  private static final class ViewableFortunes extends Viewable {
-    ViewableFortunes(List<Fortune> fortunes) {
-      super("fortunes.mustache", fortunes);
-    }
-
-    @Override
-    public boolean isTemplateNameAbsolute() {
-      return true;
-    }
-  }
-}
+	@SuppressWarnings("unchecked")
+	@GET
+	@Produces(TEXT_HTML + "; charset=utf-8")
+	@Template(name = "/fortunes.mustache")
+	public List<Fortune> fortunes() {
+		List<Fortune> fortunes = null;
+		Session session = sessionFactory.openSession();
+		Criteria criteria = session.createCriteria(Fortune.class);
+		fortunes = new ArrayList<>(criteria.list());
+		session.close();
+		fortunes.add(new Fortune(0, "Additional fortune added at request time."));
+		fortunes.sort(null);
+		return fortunes;
+	}
+}

+ 28 - 0
frameworks/Java/grizzly/src-jersey/main/java/hello/Jackson2MapperProvider.java

@@ -0,0 +1,28 @@
+package hello;
+
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
+
+@Provider
+public class Jackson2MapperProvider implements ContextResolver<ObjectMapper> {
+	final ObjectMapper defaultObjectMapper;
+
+	public Jackson2MapperProvider() {
+		defaultObjectMapper = createDefaultMapper();
+	}
+
+	@Override
+	public ObjectMapper getContext(Class<?> type) {
+		return defaultObjectMapper;
+	}
+
+	private static ObjectMapper createDefaultMapper() {
+		final ObjectMapper result = new ObjectMapper();
+		result.registerModule(new AfterburnerModule());
+
+		return result;
+	}
+}

+ 0 - 85
frameworks/Java/grizzly/src-jersey/main/java/hello/JerseyWebServer.java

@@ -1,85 +0,0 @@
-package hello;
-
-import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
-import com.sun.jersey.api.core.PackagesResourceConfig;
-import com.sun.jersey.api.core.ResourceConfig;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import javax.ws.rs.core.UriBuilder;
-import org.apache.commons.cli.BasicParser;
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.Options;
-import org.glassfish.grizzly.Grizzly;
-import org.glassfish.grizzly.http.server.HttpHandler;
-import org.glassfish.grizzly.http.server.HttpServer;
-
-public class JerseyWebServer {
-
-  public static void main(String[] args) throws Exception {
-    CommandLineParser parser = new BasicParser();
-    CommandLine cmd = parser.parse(options(), args);
-
-    int port = Integer.parseInt(cmd.getOptionValue("port", "8080"));
-    String dbHost = cmd.getOptionValue("dbhost", "localhost");
-    int dbPort = Integer.parseInt(cmd.getOptionValue("dbport", "3306"));
-
-    new JerseyWebServer(port,dbHost, dbPort).run();
-  }
-
-  private final int port;
-  private final String dbHost;
-  private final int dbPort;
-
-  public JerseyWebServer(int port, String dbHost, int dbPort) {
-    this.port = port;
-    this.dbHost = dbHost;
-    this.dbPort = dbPort;
-  }
-
-  public void run() throws Exception {
-    URI baseUri = getBaseUrl(port);
-    ResourceConfig rc = new PackagesResourceConfig("hello");
-    rc.setPropertiesAndFeatures(properties());
-    rc.getContainerResponseFilters().add(new ServerHeaderFilter());
-    HttpServer server = GrizzlyServerFactory.createHttpServer(baseUri, rc);
-
-    // There will be *a lot* of broken connections during the plaintext test.
-    // That's not a good thing, but what would make matters even worse would be
-    // to log the full stack trace of an IOException for each broken connection.
-    // That's what Grizzly does by default, and it logs those messages at the
-    // WARNING level, so setting the threshold to SEVERE hides those messages.
-    Grizzly.logger(HttpHandler.class).setLevel(Level.SEVERE);
-
-    try {
-        server.start();
-        System.err.print("Server started.\n");
-        synchronized (JerseyWebServer.class) {
-            JerseyWebServer.class.wait();
-        }
-    } finally {
-        server.stop();
-    }
-  }
-
-  private Map<String, Object> properties() {
-    Map<String, Object> properties = new HashMap<>();
-    properties.put("dbhost", dbHost);
-    properties.put("dbport", dbPort);
-    return properties;
-  }
-
-  private static URI getBaseUrl(int port) {
-    return UriBuilder.fromUri("http://0.0.0.0/").port(port).build();
-  }
-
-  private static Options options() {
-    Options options = new Options();
-    options.addOption("port", true, "server port");
-    options.addOption("dbhost", true, "database host");
-    options.addOption("dbport", true, "database port");
-    return options;
-  }
-}

+ 0 - 56
frameworks/Java/grizzly/src-jersey/main/java/hello/JsonMessageBodyWriter.java

@@ -1,56 +0,0 @@
-package hello;
-
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sun.jersey.spi.resource.Singleton;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-
-@Singleton
-@Provider
-@Produces(APPLICATION_JSON)
-public class JsonMessageBodyWriter implements MessageBodyWriter<Object> {
-
-  private final ObjectMapper mapper = new ObjectMapper();
-
-  @Override
-  public boolean isWriteable(
-      Class<?> type,
-      Type genericType,
-      Annotation[] annotations,
-      MediaType mediaType) {
-    return "json".equals(mediaType.getSubtype());
-  }
-
-  @Override
-  public long getSize(
-      Object t,
-      Class<?> type,
-      Type genericType,
-      Annotation[] annotations,
-      MediaType mediaType) {
-    return -1; // We can't predict the output size at this point
-  }
-
-  @Override
-  public void writeTo(
-      Object t,
-      Class<?> type,
-      Type genericType,
-      Annotation[] annotations,
-      MediaType mediaType,
-      MultivaluedMap<String, Object> httpHeaders,
-      OutputStream entityStream)
-      throws IOException, WebApplicationException {
-    mapper.writeValue(entityStream, t);
-  }
-}

+ 6 - 6
frameworks/Java/grizzly/src-jersey/main/java/hello/JsonResource.java

@@ -2,7 +2,7 @@ package hello;
 
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
 
-import com.sun.jersey.spi.resource.Singleton;
+import javax.inject.Singleton;
 import java.util.Collections;
 import java.util.Collections;
 import javax.ws.rs.GET;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Path;
@@ -12,9 +12,9 @@ import javax.ws.rs.Produces;
 @Path("/json")
 @Path("/json")
 public class JsonResource {
 public class JsonResource {
 
 
-  @GET
-  @Produces(APPLICATION_JSON)
-  public Object json() {
-    return Collections.singletonMap("message", "Hello, World!");
-  }
+	@GET
+	@Produces(APPLICATION_JSON)
+	public Object json() {
+		return Collections.singletonMap("message", "Hello, World!");
+	}
 }
 }

+ 0 - 42
frameworks/Java/grizzly/src-jersey/main/java/hello/MustacheViewProcessor.java

@@ -1,42 +0,0 @@
-package hello;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import com.github.mustachejava.DefaultMustacheFactory;
-import com.github.mustachejava.Mustache;
-import com.github.mustachejava.MustacheFactory;
-import com.github.mustachejava.resolver.ClasspathResolver;
-import com.sun.jersey.api.view.Viewable;
-import com.sun.jersey.spi.resource.Singleton;
-import com.sun.jersey.spi.template.ViewProcessor;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import javax.ws.rs.ext.Provider;
-
-@Singleton
-@Provider
-public class MustacheViewProcessor implements ViewProcessor<Mustache> {
-
-  private final MustacheFactory factory;
-
-  public MustacheViewProcessor() {
-    factory = new DefaultMustacheFactory(new ClasspathResolver());
-  }
-
-  @Override
-  public Mustache resolve(String name) {
-    return factory.compile(name);
-  }
-
-  @Override
-  public void writeTo(Mustache t,
-                      Viewable viewable,
-                      OutputStream out) throws IOException {
-    try (BufferedWriter writer =
-             new BufferedWriter(new OutputStreamWriter(out, UTF_8))) {
-      t.execute(writer, viewable.getModel());
-    }
-  }
-}

+ 7 - 7
frameworks/Java/grizzly/src-jersey/main/java/hello/PlaintextResource.java

@@ -1,6 +1,6 @@
 package hello;
 package hello;
 
 
-import com.sun.jersey.spi.resource.Singleton;
+import javax.inject.Singleton;
 import javax.ws.rs.GET;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 import javax.ws.rs.Produces;
@@ -9,9 +9,9 @@ import javax.ws.rs.Produces;
 @Path("/plaintext")
 @Path("/plaintext")
 public class PlaintextResource {
 public class PlaintextResource {
 
 
-  @GET
-  @Produces("text/plain")
-  public Object plaintext() {
-    return "Hello, World!";
-  }
-}
+	@GET
+	@Produces("text/plain")
+	public Object plaintext() {
+		return "Hello, World!";
+	}
+}

+ 19 - 10
frameworks/Java/grizzly/src-jersey/main/java/hello/ServerHeaderFilter.java

@@ -1,15 +1,24 @@
 package hello;
 package hello;
 
 
-import com.sun.jersey.spi.container.ContainerRequest;
-import com.sun.jersey.spi.container.ContainerResponse;
-import com.sun.jersey.spi.container.ContainerResponseFilter;
+import java.io.IOException;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.glassfish.grizzly.http.util.FastHttpDateFormat;
+import org.glassfish.grizzly.http.util.Header;
 
 
 public class ServerHeaderFilter implements ContainerResponseFilter {
 public class ServerHeaderFilter implements ContainerResponseFilter {
 
 
-  @Override
-  public ContainerResponse filter(ContainerRequest request,
-                                  ContainerResponse response) {
-    response.getHttpHeaders().add("Server", "Grizzly");
-    return response;
-  }
-}
+	@Override
+	public void filter(ContainerRequestContext request, ContainerResponseContext response)
+			throws IOException {
+		MultivaluedMap<String, Object> headers = response.getHeaders();
+		headers.putSingle(Header.Server.toString(), "GRZLY"); // The same as raw
+																// Grizzly test
+																// implementation
+		headers.putSingle(Header.Date.toString(), FastHttpDateFormat.getCurrentDate());
+	}
+}

+ 39 - 0
frameworks/Java/grizzly/src-jersey/main/java/hello/SessionFactoryFactory.java

@@ -0,0 +1,39 @@
+package hello;
+
+import hello.domain.Fortune;
+import hello.domain.World;
+
+import javax.ws.rs.ext.Provider;
+
+import org.glassfish.hk2.api.Factory;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+
+@Provider
+public class SessionFactoryFactory implements Factory<SessionFactory> {
+	private final SessionFactory factory;
+
+	public SessionFactoryFactory() {
+		factory = createSessionFactory();
+	}
+
+	@Override
+	public SessionFactory provide() {
+		return factory;
+	}
+
+	@Override
+	public void dispose(SessionFactory factory) {
+		factory.close();
+	}
+
+	private static SessionFactory createSessionFactory() {
+		Configuration configuration = new Configuration().configure();
+		configuration.addAnnotatedClass(World.class);
+		configuration.addAnnotatedClass(Fortune.class);
+		StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
+		builder.applySettings(configuration.getProperties());
+		return configuration.buildSessionFactory(builder.build());
+	}
+}

+ 0 - 36
frameworks/Java/grizzly/src-jersey/main/java/hello/SessionFactoryProvider.java

@@ -1,36 +0,0 @@
-package hello;
-
-import com.sun.jersey.api.core.ResourceConfig;
-import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
-import com.sun.jersey.spi.resource.Singleton;
-import hello.domain.Fortune;
-import hello.domain.World;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.ext.Provider;
-import org.hibernate.SessionFactory;
-import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
-import org.hibernate.cfg.Configuration;
-
-@Singleton
-@Provider
-public class SessionFactoryProvider
-    extends SingletonTypeInjectableProvider<Context, SessionFactory> {
-
-  public SessionFactoryProvider(@Context ResourceConfig rc) {
-    super(SessionFactory.class, createSessionFactory(rc));
-  }
-
-  private static SessionFactory createSessionFactory(ResourceConfig rc) {
-    Configuration configuration = new Configuration().configure();
-//    String url = configuration.getProperty("hibernate.hikari.dataSource.url");
-//    url = url.replace(
-//        "//localhost:3306/",
-//        "//" + rc.getProperty("dbhost") + ":" + rc.getProperty("dbport") + "/");
-//    configuration.setProperty("hibernate.hikari.dataSource.url", url);
-    configuration.addAnnotatedClass(World.class);
-    configuration.addAnnotatedClass(Fortune.class);
-    StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();
-    builder.applySettings(configuration.getProperties());
-    return configuration.buildSessionFactory(builder.build());
-  }
-}

+ 25 - 0
frameworks/Java/grizzly/src-jersey/main/java/hello/TFBApplication.java

@@ -0,0 +1,25 @@
+package hello;
+
+import javax.inject.Singleton;
+
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
+import org.glassfish.jersey.jackson.JacksonFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.mvc.mustache.MustacheMvcFeature;
+import org.hibernate.SessionFactory;
+
+public class TFBApplication extends ResourceConfig {
+	public TFBApplication() {
+		super(ServerHeaderFilter.class, JacksonFeature.class, Jackson2MapperProvider.class,
+				MustacheMvcFeature.class, PlaintextResource.class, JsonResource.class,
+				FortunesResource.class, WorldResource.class);
+		property("jersey.config.server.mvc.caching.mustache", "true");
+		register(new AbstractBinder() {
+			@Override
+			protected void configure() {
+				bindFactory(SessionFactoryFactory.class).to(SessionFactory.class).in(
+						Singleton.class);
+			}
+		});
+	}
+}

+ 78 - 0
frameworks/Java/grizzly/src-jersey/main/java/hello/WebServer.java

@@ -0,0 +1,78 @@
+package hello;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.glassfish.grizzly.filterchain.FilterChainBuilder;
+import org.glassfish.grizzly.http.server.AddOn;
+import org.glassfish.grizzly.http.server.FileCacheFilter;
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.grizzly.http.server.NetworkListener;
+import org.glassfish.grizzly.http.server.util.HttpPipelineOptAddOn;
+import org.glassfish.grizzly.memory.PooledMemoryManager;
+import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
+import org.glassfish.grizzly.utils.IdleTimeoutFilter;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+
+public class WebServer {
+	private static final URI BASE_URI = URI.create("http://0.0.0.0:8080/");
+
+	public static void main(String[] args) {
+		try {
+			final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI,
+					createApp(), false);
+			Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+				@Override
+				public void run() {
+					server.shutdownNow();
+				}
+			}));
+
+			// Some modifications
+			NetworkListener defaultListener = server.getListener("grizzly");
+			defaultListener.getKeepAlive().setIdleTimeoutInSeconds(-1);
+			defaultListener.getKeepAlive().setMaxRequestsCount(-1);
+			defaultListener.getFileCache().setEnabled(false);
+			defaultListener.registerAddOn(new SimplifyAddOn());
+			defaultListener.registerAddOn(new HttpPipelineOptAddOn());
+
+			final TCPNIOTransport transport = defaultListener.getTransport();
+			transport.setWorkerThreadPoolConfig(null); // force to not
+														// initialize worker
+														// thread pool
+			transport.setSelectorRunnersCount(Runtime.getRuntime().availableProcessors() * 2);
+			transport.setMemoryManager(new PooledMemoryManager());
+
+			server.start();
+
+			System.out.println(String
+					.format("TFBApplication started.%nStop the application using CTRL+C"));
+
+			Thread.currentThread().join();
+		} catch (IOException | InterruptedException ex) {
+			Logger.getLogger(WebServer.class.getName()).log(Level.SEVERE, null, ex);
+		}
+	}
+
+	public static ResourceConfig createApp() {
+		return new TFBApplication();
+	}
+
+	private static class SimplifyAddOn implements AddOn {
+		@Override
+		public void setup(final NetworkListener networkListener, final FilterChainBuilder builder) {
+			final int fcIdx = builder.indexOfType(FileCacheFilter.class);
+			if (fcIdx != -1) {
+				builder.remove(fcIdx);
+			}
+
+			final int itIdx = builder.indexOfType(IdleTimeoutFilter.class);
+			if (itIdx != -1) {
+				builder.remove(itIdx);
+			}
+		}
+	}
+}

+ 121 - 0
frameworks/Java/grizzly/src-jersey/main/java/hello/WorldResource.java

@@ -0,0 +1,121 @@
+package hello;
+
+import hello.domain.World;
+
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadLocalRandom;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+
+@Singleton
+@Produces(MediaType.APPLICATION_JSON)
+@Path("/db")
+public class WorldResource {
+	@Inject
+	private SessionFactory sessionFactory;
+
+	@GET
+	public Object db() throws InterruptedException, ExecutionException {
+		Callable<World> callable = () -> {
+			Session session = sessionFactory.openSession();
+			session.setDefaultReadOnly(true);
+			try {
+				return (World) session.byId(World.class).load(randomWorld());
+			} finally {
+				session.close();
+			}
+		};
+		Future<World> futureWorld = Common.EXECUTOR.submit(callable);
+		return futureWorld.get();
+	}
+
+	@GET
+	@Path("/queries")
+	public Object queries(@QueryParam("queries") String queriesParam) throws InterruptedException,
+			ExecutionException {
+		final int queries = getQueries(queriesParam);
+		final World[] worlds = new World[queries];
+
+		Callable<World[]> callable = () -> {
+			Session session = sessionFactory.openSession();
+			session.setDefaultReadOnly(true);
+			try {
+				for (int i = 0; i < queries; i++) {
+					worlds[i] = (World) session.byId(World.class).load(randomWorld());
+				}
+				return worlds;
+			} finally {
+				session.close();
+			}
+		};
+		Future<World[]> futureWorlds = Common.EXECUTOR.submit(callable);
+		return futureWorlds.get();
+	}
+
+	@GET
+	@Path("/updates")
+	public World[] updates(@QueryParam("queries") String queriesParam) throws InterruptedException,
+			ExecutionException {
+		final int queries = getQueries(queriesParam);
+		final World[] worlds = new World[queries];
+
+		Callable<World[]> callable = () -> {
+			Session session = sessionFactory.openSession();
+			session.setDefaultReadOnly(false);
+			Transaction txn = session.beginTransaction();
+
+			try {
+				// using write batching. See the data source properties provided
+				// in the configuration file
+				for (int i = 0; i < queries; i++) {
+					final World world = (World) session.byId(World.class).load(randomWorld());
+					world.randomNumber = randomWorld();
+					session.persist(world);
+					worlds[i] = world;
+				}
+				session.flush();
+				session.clear();
+				txn.commit();
+
+				return worlds;
+			} catch (RuntimeException e) {
+				if (txn != null && txn.isActive())
+					txn.rollback();
+				throw e;
+			} finally {
+				session.close();
+			}
+		};
+		Future<World[]> futureWorlds = Common.EXECUTOR.submit(callable);
+		return futureWorlds.get();
+	}
+
+	private static int getQueries(String proto) {
+		int result = 1;
+		try {
+			if (proto != null && !proto.trim().isEmpty()) {
+				result = Integer.parseInt(proto);
+			}
+		} catch (NumberFormatException ignored) {/* by test contract */
+		}
+
+		return Math.min(500, Math.max(1, result));
+	}
+
+	private static int randomWorld() {
+		return 1 + ThreadLocalRandom.current().nextInt(10000);
+	}
+}

+ 2 - 0
frameworks/Java/grizzly/src-jersey/main/resources/hibernate.cfg.xml

@@ -5,6 +5,8 @@
     <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
     <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
     <property name="hibernate.cache.use_query_cache">false</property>
     <property name="hibernate.cache.use_query_cache">false</property>
     <property name="hibernate.show_sql">false</property>
     <property name="hibernate.show_sql">false</property>
+    <property name="hibernate.jdbc.batch_size">30</property>
+    <property name="hibernate.jdbc.batch_versioned_data">true</property>
     <property name="hibernate.hikari.minimumIdle">256</property>
     <property name="hibernate.hikari.minimumIdle">256</property>
     <property name="hibernate.hikari.maximumPoolSize">256</property>
     <property name="hibernate.hikari.maximumPoolSize">256</property>
     <property name="hibernate.hikari.idleTimeout">30000</property>
     <property name="hibernate.hikari.idleTimeout">30000</property>

+ 27 - 25
frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/JsonHttpHandler.java

@@ -1,39 +1,41 @@
 package org.glassfish.grizzly.bm;
 package org.glassfish.grizzly.bm;
 
 
 import com.fasterxml.jackson.databind.*;
 import com.fasterxml.jackson.databind.*;
+
 import org.glassfish.grizzly.http.server.HttpHandler;
 import org.glassfish.grizzly.http.server.HttpHandler;
 import org.glassfish.grizzly.http.server.Request;
 import org.glassfish.grizzly.http.server.Request;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.util.ContentType;
 import org.glassfish.grizzly.http.util.ContentType;
+import org.glassfish.grizzly.http.util.FastHttpDateFormat;
 import org.glassfish.grizzly.http.util.Header;
 import org.glassfish.grizzly.http.util.Header;
 
 
 /**
 /**
- * Json usecase
+ * JSON test
  */
  */
 public class JsonHttpHandler extends HttpHandler {
 public class JsonHttpHandler extends HttpHandler {
-    private static final ObjectMapper MAPPER = new ObjectMapper();
-    
-    private static final ContentType CONTENT_TYPE =
-            ContentType.newContentType("application/json").prepare();
-    
-    // Response message class.
-    public static class HelloMessage {
-      public final String message = "Hello, World!";
-    }
-
-    @Override
-    public void service(final Request request, final Response response)
-            throws Exception {
-        response.setContentType(CONTENT_TYPE);
-        response.setHeader(Header.Server, Server.SERVER_VERSION);
-
-        // Write JSON encoded message to the response.
-        MAPPER.writeValue(response.getOutputStream(), new HelloMessage());
-    }
-
-    @Override
-    public RequestExecutorProvider getRequestExecutorProvider() {
-        return Server.EXECUTOR_PROVIDER;
-    }
+	private static final ObjectMapper MAPPER = new ObjectMapper();
+
+	private static final ContentType CONTENT_TYPE = ContentType.newContentType("application/json")
+			.prepare();
+
+	// Response message class.
+	public static class HelloMessage {
+		public final String message = "Hello, World!";
+	}
+
+	@Override
+	public void service(final Request request, final Response response) throws Exception {
+		response.setContentType(CONTENT_TYPE);
+		response.setHeader(Header.Server, Server.SERVER_VERSION);
+		response.setHeader(Header.Date, FastHttpDateFormat.getCurrentDate());
+
+		// Write JSON encoded message to the response.
+		MAPPER.writeValue(response.getOutputStream(), new HelloMessage());
+	}
+
+	@Override
+	public RequestExecutorProvider getRequestExecutorProvider() {
+		return Server.EXECUTOR_PROVIDER;
+	}
 }
 }

+ 18 - 16
frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/PlainText2HttpHandler.java

@@ -5,29 +5,31 @@ import org.glassfish.grizzly.http.server.Request;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.util.ContentType;
 import org.glassfish.grizzly.http.util.ContentType;
+import org.glassfish.grizzly.http.util.FastHttpDateFormat;
 import org.glassfish.grizzly.http.util.Header;
 import org.glassfish.grizzly.http.util.Header;
 import org.glassfish.grizzly.utils.Charsets;
 import org.glassfish.grizzly.utils.Charsets;
 
 
 /**
 /**
- * Binary version of plain text usecase
+ * Binary version of plaintext test case
  * 
  * 
  * @see PlainTextHttpHandler
  * @see PlainTextHttpHandler
  */
  */
 public class PlainText2HttpHandler extends HttpHandler {
 public class PlainText2HttpHandler extends HttpHandler {
-    private static final ContentType CONTENT_TYPE =
-            ContentType.newContentType("text/plain").prepare();
-    private static final byte[] HELLO_WORLD_BYTES = "Hello, World!".getBytes(Charsets.UTF8_CHARSET);
-            
-    @Override
-    public void service(final Request request, final Response response)
-            throws Exception {
-        response.setContentType(CONTENT_TYPE);
-        response.setHeader(Header.Server, Server.SERVER_VERSION);
-        response.getOutputStream().write(HELLO_WORLD_BYTES);
-    }
+	private static final ContentType CONTENT_TYPE = ContentType.newContentType("text/plain")
+			.prepare();
+	private static final byte[] HELLO_WORLD_BYTES = "Hello, World!".getBytes(Charsets.UTF8_CHARSET);
 
 
-    @Override
-    public RequestExecutorProvider getRequestExecutorProvider() {
-        return Server.EXECUTOR_PROVIDER;
-    }
+	@Override
+	public void service(final Request request, final Response response) throws Exception {
+		response.setContentType(CONTENT_TYPE);
+		response.setHeader(Header.Server, Server.SERVER_VERSION);
+		response.setHeader(Header.Date, FastHttpDateFormat.getCurrentDate());
+
+		response.getOutputStream().write(HELLO_WORLD_BYTES);
+	}
+
+	@Override
+	public RequestExecutorProvider getRequestExecutorProvider() {
+		return Server.EXECUTOR_PROVIDER;
+	}
 }
 }

+ 15 - 14
frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/PlainTextHttpHandler.java

@@ -5,25 +5,26 @@ import org.glassfish.grizzly.http.server.Request;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.util.ContentType;
 import org.glassfish.grizzly.http.util.ContentType;
+import org.glassfish.grizzly.http.util.FastHttpDateFormat;
 import org.glassfish.grizzly.http.util.Header;
 import org.glassfish.grizzly.http.util.Header;
 
 
 /**
 /**
- * Plain text usecase
+ * Plaintext test case
  */
  */
 public class PlainTextHttpHandler extends HttpHandler {
 public class PlainTextHttpHandler extends HttpHandler {
-    private static final ContentType CONTENT_TYPE =
-            ContentType.newContentType("text/plain").prepare();
+	private static final ContentType CONTENT_TYPE = ContentType.newContentType("text/plain")
+			.prepare();
 
 
-    @Override
-    public void service(final Request request, final Response response)
-            throws Exception {
-        response.setContentType(CONTENT_TYPE);
-        response.setHeader(Header.Server, Server.SERVER_VERSION);
-        response.getWriter().write("Hello, World!");
-    }
+	@Override
+	public void service(final Request request, final Response response) throws Exception {
+		response.setContentType(CONTENT_TYPE);
+		response.setHeader(Header.Server, Server.SERVER_VERSION);
+		response.setHeader(Header.Date, FastHttpDateFormat.getCurrentDate());
+		response.getWriter().write("Hello, World!");
+	}
 
 
-    @Override
-    public RequestExecutorProvider getRequestExecutorProvider() {
-        return Server.EXECUTOR_PROVIDER;
-    }
+	@Override
+	public RequestExecutorProvider getRequestExecutorProvider() {
+		return Server.EXECUTOR_PROVIDER;
+	}
 }
 }

+ 30 - 26
frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/RootHttpHandler.java

@@ -5,34 +5,38 @@ import org.glassfish.grizzly.http.server.Request;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.RequestExecutorProvider;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.server.Response;
 import org.glassfish.grizzly.http.util.DataChunk;
 import org.glassfish.grizzly.http.util.DataChunk;
+import org.glassfish.grizzly.http.util.HttpStatus;
 
 
 /**
 /**
  * Root {@link HttpHandler} to be used to avoid mapping overhead
  * Root {@link HttpHandler} to be used to avoid mapping overhead
  */
  */
 public class RootHttpHandler extends HttpHandler {
 public class RootHttpHandler extends HttpHandler {
-//  Uncomment for real text benchmark
-//    private final HttpHandler plainTextHandler = new PlainTextHttpHandler();
-    
-//  Binary PlainText handler  
-    private final HttpHandler plainTextHandler = new PlainText2HttpHandler();
-    private final HttpHandler jsonHandler = new JsonHttpHandler();
-    
-    @Override
-    public void service(final Request request, final Response response)
-            throws Exception {
-        // don't decode and avoid creating a string
-        final DataChunk requestURIBC = request.getRequest()
-                .getRequestURIRef().getRequestURIBC();
-        
-        if (requestURIBC.equals("/json")) {
-            jsonHandler.service(request, response);
-        } else {
-            plainTextHandler.service(request, response);
-        }
-    }
-    
-    @Override
-    public RequestExecutorProvider getRequestExecutorProvider() {
-        return Server.EXECUTOR_PROVIDER;
-    }
-}
+	// Uncomment for real text benchmark
+	// private final HttpHandler plainTextHandler = new PlainTextHttpHandler();
+
+	// Binary PlainText handler
+	private final HttpHandler plainTextHandler = new PlainText2HttpHandler();
+	private final HttpHandler jsonHandler = new JsonHttpHandler();
+
+	@Override
+	public void service(final Request request, final Response response) throws Exception {
+		// don't decode and avoid creating a string
+		final DataChunk requestURIBC = request.getRequest().getRequestURIRef().getRequestURIBC();
+
+		if (requestURIBC.equals("/json")) {
+			jsonHandler.service(request, response);
+		} else if (requestURIBC.equals("/plaintext")) {
+			plainTextHandler.service(request, response);
+		} else {
+			response.getOutputBuffer().write(
+					getErrorPageGenerator(request).generate(request,
+							HttpStatus.NOT_FOUND_404.getStatusCode(),
+							HttpStatus.NOT_FOUND_404.getReasonPhrase(), null, null));
+		}
+	}
+
+	@Override
+	public RequestExecutorProvider getRequestExecutorProvider() {
+		return Server.EXECUTOR_PROVIDER;
+	}
+}

+ 66 - 76
frameworks/Java/grizzly/src/main/java/org/glassfish/grizzly/bm/Server.java

@@ -16,80 +16,70 @@ import org.glassfish.grizzly.utils.IdleTimeoutFilter;
  * HttpServer
  * HttpServer
  */
  */
 public class Server {
 public class Server {
-    public static final HeaderValue SERVER_VERSION =
-            HeaderValue.newHeaderValue("GRZLY").prepare();
-    
-    // The RequestExecutorProvider, which will run HTTP request processing
-    // in the same thread
-    static final RequestExecutorProvider EXECUTOR_PROVIDER =
-            new RequestExecutorProvider.SameThreadProvider();
-    
-    public static void main(String[] args) throws Exception {
-        final int port = args.length > 0
-                ? Integer.parseInt(args[0]) : 8080;
-        
-        final HttpServer httpServer = new HttpServer();
-        final NetworkListener networkListener = new NetworkListener(
-                "http-listener", "0.0.0.0", port);
-        final TCPNIOTransport transport = networkListener.getTransport();
-        
-        // force to not initialize worker thread pool
-        transport.setWorkerThreadPoolConfig(null);
-        transport.setSelectorRunnersCount(Runtime.getRuntime().availableProcessors() * 2);
-        
-        // set PooledMemoryManager
-        transport.setMemoryManager(new PooledMemoryManager());
-        
-        // always keep-alive
-        networkListener.getKeepAlive().setIdleTimeoutInSeconds(-1);
-        networkListener.getKeepAlive().setMaxRequestsCount(-1);
-        
-        // disable transaction timeout
-        networkListener.setTransactionTimeout(-1);
-        
-        // remove the features we don't need
-        networkListener.registerAddOn(new SimplifyAddOn());
-        // add HTTP pipeline optimization
-        networkListener.registerAddOn(new HttpPipelineOptAddOn());
-        
-        // disable file-cache
-        networkListener.getFileCache().setEnabled(false);
-        
-        httpServer.addListener(networkListener);
-        
-        httpServer.getServerConfiguration().addHttpHandler(
-                new RootHttpHandler(), "/");
-//        httpServer.getServerConfiguration().addHttpHandler(
-//                new PlainTextHttpHandler(), "/plaintext");
-//        httpServer.getServerConfiguration().addHttpHandler(
-//                new JsonHttpHandler(), "/json");
-        
-        try {
-            httpServer.start();
-            
-            System.err.print("Server started.\n");
-            synchronized (Server.class) {
-		Server.class.wait();
-            }
-        } finally {
-            httpServer.shutdown();
-        }
-    }
-    
-    private static class SimplifyAddOn implements AddOn {
-
-        @Override
-        public void setup(final NetworkListener networkListener,
-                final FilterChainBuilder builder) {
-            final int fcIdx = builder.indexOfType(FileCacheFilter.class);
-            if (fcIdx != -1) {
-                builder.remove(fcIdx);
-            }
-            
-            final int itIdx = builder.indexOfType(IdleTimeoutFilter.class);
-            if (itIdx != -1) {
-                builder.remove(itIdx);
-            }
-        }
-    }    
+	public static final HeaderValue SERVER_VERSION = HeaderValue.newHeaderValue("GRZLY").prepare();
+
+	// The RequestExecutorProvider, which will run HTTP request processing
+	// in the same thread
+	static final RequestExecutorProvider EXECUTOR_PROVIDER = new RequestExecutorProvider.SameThreadProvider();
+
+	public static void main(String[] args) throws Exception {
+		final int port = args.length > 0 ? Integer.parseInt(args[0]) : 8080;
+
+		final HttpServer httpServer = new HttpServer();
+
+		final NetworkListener networkListener = new NetworkListener("http-listener", "0.0.0.0",
+				port);
+		final TCPNIOTransport transport = networkListener.getTransport();
+
+		// force to not initialize worker thread pool
+		transport.setWorkerThreadPoolConfig(null);
+		transport.setSelectorRunnersCount(Runtime.getRuntime().availableProcessors() * 2);
+
+		// set PooledMemoryManager
+		transport.setMemoryManager(new PooledMemoryManager());
+
+		// always keep-alive
+		networkListener.getKeepAlive().setIdleTimeoutInSeconds(-1);
+		networkListener.getKeepAlive().setMaxRequestsCount(-1);
+
+		// disable transaction timeout
+		networkListener.setTransactionTimeout(-1);
+
+		// remove the features we don't need
+		networkListener.registerAddOn(new SimplifyAddOn());
+		// add HTTP pipeline optimization
+		networkListener.registerAddOn(new HttpPipelineOptAddOn());
+
+		// disable file-cache
+		networkListener.getFileCache().setEnabled(false);
+
+		httpServer.addListener(networkListener);
+
+		httpServer.getServerConfiguration().addHttpHandler(new RootHttpHandler(), "/");
+
+		try {
+			httpServer.start();
+			synchronized (Server.class) {
+				Server.class.wait();
+			}
+		} finally {
+			httpServer.shutdown();
+		}
+	}
+
+	private static class SimplifyAddOn implements AddOn {
+
+		@Override
+		public void setup(final NetworkListener networkListener, final FilterChainBuilder builder) {
+			final int fcIdx = builder.indexOfType(FileCacheFilter.class);
+			if (fcIdx != -1) {
+				builder.remove(fcIdx);
+			}
+
+			final int itIdx = builder.indexOfType(IdleTimeoutFilter.class);
+			if (itIdx != -1) {
+				builder.remove(itIdx);
+			}
+		}
+	}
 }
 }