Merge branch 'jetty-9.4.x' of github.com:eclipse/jetty.project into jetty-9.4.x
This commit is contained in:
commit
beb9c90892
|
@ -56,15 +56,15 @@
|
||||||
<classifier>sources</classifier>
|
<classifier>sources</classifier>
|
||||||
<includes>**/*</includes>
|
<includes>**/*</includes>
|
||||||
<excludes>
|
<excludes>
|
||||||
META-INF/**
|
META-INF/**,
|
||||||
**/Servlet3Continuation*
|
**/Servlet3Continuation*,
|
||||||
**/Jetty6Continuation*
|
**/Jetty6Continuation*,
|
||||||
**/AppContextLeakPreventer*.java
|
**/AppContextLeakPreventer*.java,
|
||||||
**/AWTLeakPreventer*.java
|
**/AWTLeakPreventer*.java,
|
||||||
**/IntrospectorCleaner*.java
|
**/IntrospectorCleaner*.java,
|
||||||
**/PostConstructAnnotationHandler*.java
|
**/PostConstructAnnotationHandler*.java,
|
||||||
**/PreDestroyAnnotationHandler*.java
|
**/PreDestroyAnnotationHandler*.java,
|
||||||
**/ResourceAnnotationHandler*.java
|
**/ResourceAnnotationHandler*.java,
|
||||||
**/ResourcesAnnotationHandler*.java
|
**/ResourcesAnnotationHandler*.java
|
||||||
</excludes>
|
</excludes>
|
||||||
<includeGroupIds>org.eclipse.jetty,org.eclipse.jetty.websocket</includeGroupIds>
|
<includeGroupIds>org.eclipse.jetty,org.eclipse.jetty.websocket</includeGroupIds>
|
||||||
|
@ -78,23 +78,15 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>package</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifest>
|
<manifest>
|
||||||
</manifest>
|
</manifest>
|
||||||
<manifestEntries>
|
<manifestEntries>
|
||||||
<mode>development</mode>
|
<mode>development</mode>
|
||||||
<url>http://eclipse.org/jetty</url>
|
<url>https://eclipse.org/jetty</url>
|
||||||
<Built-By>${user.name}</Built-By>
|
<Built-By>${user.name}</Built-By>
|
||||||
<package>org.eclipse.jetty</package>
|
<package>org.eclipse.jetty</package>
|
||||||
<Bundle-License>https://raw.githubusercontent.com/eclipse/jetty.project/master/NOTICE.txt</Bundle-License>
|
<Bundle-License>https://raw.githubusercontent.com/eclipse/jetty.project/master/NOTICE.txt</Bundle-License>
|
||||||
|
@ -102,8 +94,6 @@
|
||||||
</manifestEntries>
|
</manifestEntries>
|
||||||
</archive>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
<version>2.7</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>massage-manifest</id>
|
<id>massage-manifest</id>
|
||||||
|
@ -44,7 +43,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.3</version>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||||
|
@ -99,7 +97,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
<version>1.9.1</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>attach-artifacts</id>
|
<id>attach-artifacts</id>
|
||||||
|
|
|
@ -30,29 +30,6 @@
|
||||||
</instructions>
|
</instructions>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<groupId>org.eclipse.jetty.examples</groupId>
|
<groupId>org.eclipse.jetty.examples</groupId>
|
||||||
<artifactId>examples-parent</artifactId>
|
<artifactId>examples-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<groupId>org.eclipse.jetty.examples</groupId>
|
<groupId>org.eclipse.jetty.examples</groupId>
|
||||||
<artifactId>examples-parent</artifactId>
|
<artifactId>examples-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-project</artifactId>
|
<artifactId>jetty-project</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.eclipse.jetty.examples</groupId>
|
<groupId>org.eclipse.jetty.examples</groupId>
|
||||||
<artifactId>examples-parent</artifactId>
|
<artifactId>examples-parent</artifactId>
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
<version>1.7</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>parse-version</id>
|
<id>parse-version</id>
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.webapp.FragmentDescriptor;
|
import org.eclipse.jetty.webapp.FragmentDescriptor;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
@ -40,7 +41,7 @@ public class TestAnnotationConfiguration
|
||||||
@Test
|
@Test
|
||||||
public void testGetFragmentFromJar() throws Exception
|
public void testGetFragmentFromJar() throws Exception
|
||||||
{
|
{
|
||||||
String dir = System.getProperty("basedir", ".");
|
String dir = MavenTestingUtils.getTargetTestingDir("getFragmentFromJar").getAbsolutePath();
|
||||||
File file = new File(dir);
|
File file = new File(dir);
|
||||||
file=new File(file.getCanonicalPath());
|
file=new File(file.getCanonicalPath());
|
||||||
URL url=file.toURL();
|
URL url=file.toURL();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
org.jboss.LEVEL=DEBUG
|
# org.jboss.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.LEVEL=INFO
|
org.eclipse.jetty.LEVEL=INFO
|
||||||
|
|
||||||
org.eclipse.jetty.util.DecoratedObjectFactory.LEVEL=DEBUG
|
# org.eclipse.jetty.util.DecoratedObjectFactory.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.cdi.LEVEL=DEBUG
|
# org.eclipse.jetty.cdi.LEVEL=DEBUG
|
||||||
|
|
||||||
# org.eclipse.jetty.LEVEL=DEBUG
|
# org.eclipse.jetty.LEVEL=DEBUG
|
||||||
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.LEVEL=DEBUG
|
||||||
|
|
|
@ -91,7 +91,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>2.17</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
|
@ -104,7 +103,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
<version>1.7</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>start-jetty</id>
|
<id>start-jetty</id>
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>2.5.3</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>with-weld</id>
|
<id>with-weld</id>
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4.2</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
|
|
@ -491,6 +491,12 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
|
|
||||||
protected HttpDestination destinationFor(String scheme, String host, int port)
|
protected HttpDestination destinationFor(String scheme, String host, int port)
|
||||||
{
|
{
|
||||||
|
if (!HttpScheme.HTTP.is(scheme) && !HttpScheme.HTTPS.is(scheme) &&
|
||||||
|
!HttpScheme.WS.is(scheme) && !HttpScheme.WSS.is(scheme))
|
||||||
|
throw new IllegalArgumentException("Invalid protocol " + scheme);
|
||||||
|
|
||||||
|
scheme = scheme.toLowerCase(Locale.ENGLISH);
|
||||||
|
host = host.toLowerCase(Locale.ENGLISH);
|
||||||
port = normalizePort(scheme, port);
|
port = normalizePort(scheme, port);
|
||||||
|
|
||||||
Origin origin = new Origin(scheme, host, port);
|
Origin origin = new Origin(scheme, host, port);
|
||||||
|
@ -530,9 +536,7 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
|
|
||||||
protected void send(final HttpRequest request, List<Response.ResponseListener> listeners)
|
protected void send(final HttpRequest request, List<Response.ResponseListener> listeners)
|
||||||
{
|
{
|
||||||
String scheme = request.getScheme().toLowerCase(Locale.ENGLISH);
|
HttpDestination destination = destinationFor(request.getScheme(), request.getHost(), request.getPort());
|
||||||
String host = request.getHost().toLowerCase(Locale.ENGLISH);
|
|
||||||
HttpDestination destination = destinationFor(scheme, host, request.getPort());
|
|
||||||
destination.send(request, listeners);
|
destination.send(request, listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ public class HttpClientRedirectTest extends AbstractHttpClientServerTest
|
||||||
{
|
{
|
||||||
baseRequest.setHandled(true);
|
baseRequest.setHandled(true);
|
||||||
response.setStatus(303);
|
response.setStatus(303);
|
||||||
response.setHeader("Location", "ssh://localhost/path");
|
response.setHeader("Location", "ssh://localhost:" + connector.getLocalPort() + "/path");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,24 +10,12 @@
|
||||||
<name>Jetty :: Documentation</name>
|
<name>Jetty :: Documentation</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<asciidoctor.version>1.5.3</asciidoctor.version>
|
|
||||||
<html.directory>${project.build.directory}/current</html.directory>
|
<html.directory>${project.build.directory}/current</html.directory>
|
||||||
</properties>
|
</properties>
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.felix</groupId>
|
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
|
||||||
<version>3.0.1</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</pluginManagement>
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
<version>2.6</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>copy-assets</id>
|
<id>copy-assets</id>
|
||||||
|
@ -52,7 +40,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||||
<version>${asciidoctor.version}</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>output-html</id>
|
<id>output-html</id>
|
||||||
|
@ -83,7 +70,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.agilejava.docbkx</groupId>
|
<groupId>com.agilejava.docbkx</groupId>
|
||||||
<artifactId>docbkx-maven-plugin</artifactId>
|
<artifactId>docbkx-maven-plugin</artifactId>
|
||||||
<version>2.0.14</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>html</id>
|
<id>html</id>
|
||||||
|
@ -132,7 +118,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sf.docbook</groupId>
|
<groupId>net.sf.docbook</groupId>
|
||||||
<artifactId>docbook-xml</artifactId>
|
<artifactId>docbook-xml</artifactId>
|
||||||
<!--version>5.0-all</version-->
|
|
||||||
<version>5.1b4-all</version>
|
<version>5.1b4-all</version>
|
||||||
<classifier>resources</classifier>
|
<classifier>resources</classifier>
|
||||||
<type>zip</type>
|
<type>zip</type>
|
||||||
|
@ -154,7 +139,6 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>2.6</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<descriptors>
|
<descriptors>
|
||||||
<descriptor>src/main/assembly/html.xml</descriptor>
|
<descriptor>src/main/assembly/html.xml</descriptor>
|
||||||
|
@ -210,7 +194,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||||
<version>${asciidoctor.version}</version>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
|
|
|
@ -17,144 +17,97 @@
|
||||||
[[session-clustering-gcloud-datastore]]
|
[[session-clustering-gcloud-datastore]]
|
||||||
=== Session Clustering with Google Cloud Datastore
|
=== Session Clustering with Google Cloud Datastore
|
||||||
|
|
||||||
Jetty can support session clustering by persisting sessions to
|
Jetty can support session clustering by persisting sessions to https://cloud.google.com/datastore/docs/concepts/overview[Google Cloud Datastore].
|
||||||
https://cloud.google.com/datastore/docs/concepts/overview[Google Cloud
|
Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the Datastore as the request exits the server.
|
||||||
Datastore]. Each Jetty instance locally caches sessions for which it has
|
Sessions must obey the Serialization contract, and servlets must call the `Session.setAttribute()` method to ensure that changes are persisted.
|
||||||
received requests, writing any changes to the session through to the
|
|
||||||
Datastore as the request exits the server. Sessions must obey the
|
|
||||||
Serialization contract, and servlets must call the
|
|
||||||
Session.setAttribute() method to ensure that changes are persisted.
|
|
||||||
|
|
||||||
The persistent session mechanism works in conjunction with a load
|
The persistent session mechanism works in conjunction with a load balancer that supports stickiness.
|
||||||
balancer that supports stickiness. Stickiness can be based on various
|
Stickiness can be based on various data items, such as source IP address or characteristics of the session ID or a load-balancer specific mechanism.
|
||||||
data items, such as source IP address or characteristics of the session
|
For those load balancers that examine the session ID, the Jetty persistent session mechanism appends a node ID to the session ID, which can be used for routing.
|
||||||
ID or a load-balancer specific mechanism. For those load balancers that
|
|
||||||
examine the session ID, the Jetty persistent session mechanism appends a
|
|
||||||
node ID to the session ID, which can be used for routing.
|
|
||||||
|
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
There are two components to session management in Jetty: a session ID
|
There are two components to session management in Jetty: a session ID manager and a session manager.
|
||||||
manager and a session manager.
|
|
||||||
|
|
||||||
* The session ID manager ensures that session IDs are unique across all
|
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.
|
||||||
webapps hosted on a Jetty instance, and thus there can only be one
|
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.
|
||||||
session ID manager per Jetty instance.
|
|
||||||
* The session manager handles the session lifecycle
|
|
||||||
(create/update/invalidate/expire) on behalf of a web application, so
|
|
||||||
there is one session manager per web application instance.
|
|
||||||
|
|
||||||
These managers also cooperate and collaborate with the
|
These managers also cooperate and collaborate with the `org.eclipse.jetty.server.session.SessionHandler` to enable cross-context dispatch.
|
||||||
`org.eclipse.jetty.server.session.SessionHandler` to enable
|
|
||||||
cross-context dispatch.
|
|
||||||
|
|
||||||
==== The gcloud-sessions Module
|
==== The gcloud-sessions Module
|
||||||
|
|
||||||
When using the jetty distribution, to enable Cloud Datastore session
|
When using the jetty distribution, to enable Cloud Datastore session persistence, you will first need to enable the `gcloud-sessions` link:#startup-modules[module] for your link:#creating-jetty-base[base] using the `--add-to-start` or `--add-to-startd` argument to the link:#startup-overview[start.jar].
|
||||||
persistence, you will first need to enable the `gcloud-sessions`
|
|
||||||
link:#startup-modules[module] for your link:#creating-jetty-base[base]
|
|
||||||
using the --add-to-start or --add-to-startd argument to the
|
|
||||||
link:#startup-overview[start.jar].
|
|
||||||
|
|
||||||
As part of the module installation, the necessary jars will be
|
As part of the module installation, the necessary jars will be dynamically downloaded and installed to your `${jetty.base}/lib/gcloud` directory.
|
||||||
dynamically downloaded and installed to your `${jetty.base}/lib/gcloud`
|
If you need to up or downgrade the version of the jars, then you can delete the jars that were automatically installed and replace them.
|
||||||
directory. If you need to up or downgrade the version of the jars, then
|
Once you've done that, you will need to prevent jetty's startup checks from detecting the missing jars.
|
||||||
you can delete the jars that were automatically installed and replace
|
To do that, you can use `--skip-file-validation=glcoud-sessions` argument to start.jar on the command line, or place that line inside `${jetty.base}/start.ini` to ensure it is used for every start.
|
||||||
them. Once you've done that, you will need to prevent jetty's startup
|
|
||||||
checks from detecting the missing jars. To do that, you can use
|
|
||||||
`--skip-file-validation=glcoud-sessions` argument to start.jar on the
|
|
||||||
command line, or place that line inside `${jetty.base}/start.ini` to
|
|
||||||
ensure it is used for every start.
|
|
||||||
|
|
||||||
===== Configuring the GCloudSessionIdManager
|
===== Configuring the GCloudSessionIdManager
|
||||||
|
|
||||||
The gcloud-sessions module will have installed file called
|
The gcloud-sessions module will have installed file called `${jetty.home}/etc/jetty-gcloud-sessions.xml`.
|
||||||
`${jetty.home}/etc/jetty-gcloud-sessions.xml`. This file configures an
|
This file configures an instance of the `GCloudSessionIdManager` that will be shared across all webapps deployed on that server. It looks like this:
|
||||||
instance of the GCloudSessionIdManager that will be shared across all
|
|
||||||
webapps deployed on that server. It looks like this:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
include::{SRCDIR}/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-session-store.xml[]
|
include::{SRCDIR}/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-sessions.xml[]
|
||||||
----
|
----
|
||||||
|
|
||||||
You configure it by setting values for properties. The properties will
|
You configure it by setting values for properties.
|
||||||
either be inserted as commented out in your `start.ini`, or your
|
The properties will either be inserted as commented out in your `start.ini`, or your `start.d/gcloud-sessions.ini` file, depending on how you enabled the module.
|
||||||
`start.d/gcloud-sessions.ini` file, depending on how you enabled the
|
|
||||||
module.
|
|
||||||
|
|
||||||
The only property you always need to set is the name of the node in the
|
The only property you always need to set is the name of the node in the cluster:
|
||||||
cluster:
|
|
||||||
|
|
||||||
jetty.gcloudSession.workerName::
|
jetty.gcloudSession.workerName::
|
||||||
The name that uniquely identifies this node in the cluster. This value
|
The name that uniquely identifies this node in the cluster.
|
||||||
will also be used by the sticky load balancer to identify the node.
|
This value will also be used by the sticky load balancer to identify the node.
|
||||||
Don't forget to change the value of this property on *each* node on
|
Don't forget to change the value of this property on *each* node on which you enable gcloud datastore session clustering.
|
||||||
which you enable gcloud datastore session clustering.
|
|
||||||
|
|
||||||
Which other properties you need to set depends on the execution
|
Which other properties you need to set depends on the execution environment:
|
||||||
environment:
|
|
||||||
|
|
||||||
====== Running Within Google Infrastructure
|
====== Running Within Google Infrastructure
|
||||||
|
|
||||||
When you upload your webapp to run in Compute Engine, you do not need to
|
When you upload your webapp to run in Compute Engine, you do not need to set any other properties for Jetty.
|
||||||
set any other properties for jetty. If you follow the instructions in
|
If you follow the instructions in the https://cloud.google.com/datastore/docs/activate[Cloud Datastore documentation], all authorizations...etc. will be provided by the runtime environment.
|
||||||
the https://cloud.google.com/datastore/docs/activate[Cloud Datastore
|
|
||||||
documentation], all authorizations etc will be provided by the runtime
|
|
||||||
environment.
|
|
||||||
|
|
||||||
====== Running Externally to Google Infrastructure
|
====== Running Externally to Google Infrastructure
|
||||||
|
|
||||||
When your app is executing outside of Google, you can either contact a
|
When your app is executing outside of Google, you can either contact a remote Cloud Datastore instance, or a https://cloud.google.com/datastore/docs/tools/devserver[local test dev server] provided by the sdk.
|
||||||
remote Cloud Datastore instance, or a
|
The choice determines which properties you need to set:
|
||||||
https://cloud.google.com/datastore/docs/tools/devserver[local test dev
|
|
||||||
server] provided by the sdk. The choice determines which properties you
|
|
||||||
need to set:
|
|
||||||
|
|
||||||
Contacting an sdk dev server for testing:::
|
Contacting an sdk dev server for testing:::
|
||||||
In this case, you need to set up either some _System_ properties or
|
In this case, you need to set up either some _System_ properties or _environment variables_ - *NOT* Jetty properties!
|
||||||
_environment variables_ - NOT jetty properties!
|
|
||||||
+
|
|
||||||
DATASTORE_DATASET;;
|
DATASTORE_DATASET;;
|
||||||
This must be the name of your (test) project.
|
This must be the name of your (test) project.
|
||||||
DATASTORE_HOST;;
|
DATASTORE_HOST;;
|
||||||
This is the url of the dev server as described at
|
This is the url of the dev server as described https://cloud.google.com/datastore/docs/tools/devserver#setting_environment_variables[in Google's documentation].
|
||||||
https://cloud.google.com/datastore/docs/tools/devserver#setting_environment_variables.
|
An example may be "http://localhost:9999".
|
||||||
An example may be "http://localhost:9999"
|
|
||||||
Contacting a remote Cloud Datastore:::
|
Contacting a remote Cloud Datastore:::
|
||||||
In this case, you need to provide all of the authentication and
|
In this case, you need to provide all of the authentication and authorization information explicitly via jetty properties in the ini file:
|
||||||
authorization information explicitly via jetty properties in the ini
|
|
||||||
file:
|
|
||||||
+
|
|
||||||
jetty.gcloudSession.projectId;;
|
jetty.gcloudSession.projectId;;
|
||||||
This is the name of your project.
|
This is the name of your project.
|
||||||
jetty.gcloudSession.p12File;;
|
jetty.gcloudSession.p12File;;
|
||||||
This is the location of the p12 key file that is associated with
|
This is the location of the p12 key file that is associated with your project.
|
||||||
your project.
|
|
||||||
jetty.gcloudSession.serviceAccount;;
|
jetty.gcloudSession.serviceAccount;;
|
||||||
This is the email address that defines your service account for the
|
This is the email address that defines your service account for the Cloud Datastore.
|
||||||
Cloud Datastore.
|
|
||||||
jetty.gcloudSession.password;;
|
jetty.gcloudSession.password;;
|
||||||
This is the password associated with the p12 key file.
|
This is the password associated with the p12 key file.
|
||||||
|
|
||||||
===== Configuring the GCloudSessionManager
|
===== Configuring the GCloudSessionManager
|
||||||
|
|
||||||
As mentioned elsewhere, there should be one GCloudSessionManager per
|
As mentioned elsewhere, there should be one `GCloudSessionManager` per context (e.g. webapp).
|
||||||
context (ie webapp). It will need to reference the single
|
It will need to reference the single `GCloudSessionIdManager` from which it derives the Cloud Datastore configuration information.
|
||||||
GCloudSessionIdManager from which it derives the Cloud Datastore
|
|
||||||
configuration information.
|
|
||||||
|
|
||||||
The way you configure a GCloudSessionManager depends on whether you're
|
The way you configure a `GCloudSessionManager` depends on whether you're configuring from a context xml file, a `jetty-web.xml` file or code.
|
||||||
configuring from a context xml file or a `jetty-web.xml` file or code.
|
The basic difference is how you get a reference to the Jetty `org.eclipse.jetty.server.Server` instance.
|
||||||
The basic difference is how you get a reference to the Jetty
|
|
||||||
`org.eclipse.jetty.server.Server` instance.
|
|
||||||
|
|
||||||
From a context xml file, you reference the Server instance as a Ref:
|
From a context xml file, you reference the Server instance as a Ref:
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
<!-- Get a reference to the GCloudSessionIdManager -->
|
<!-- Get a reference to the GCloudSessionIdManager -->
|
||||||
<Ref id="Server">
|
<Ref id="Server">
|
||||||
<Call id="idMgr" name="getSessionIdManager"/>
|
<Call id="idMgr" name="getSessionIdManager"/>
|
||||||
|
@ -175,12 +128,10 @@ From a context xml file, you reference the Server instance as a Ref:
|
||||||
</Set>
|
</Set>
|
||||||
----
|
----
|
||||||
|
|
||||||
From a `WEB-INF/jetty-web.xml` file, you can reference the Server
|
From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance directly:
|
||||||
instance directly:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
||||||
<!-- Reference the server directly -->
|
<!-- Reference the server directly -->
|
||||||
<Get name="server">
|
<Get name="server">
|
||||||
<Get id="idMgr" name="sessionIdManager"/>
|
<Get id="idMgr" name="sessionIdManager"/>
|
||||||
|
@ -201,19 +152,17 @@ instance directly:
|
||||||
</Set>
|
</Set>
|
||||||
----
|
----
|
||||||
|
|
||||||
The GCloudSessionManager supports the following configuration setters:
|
The `GCloudSessionManager` supports the following configuration setters:
|
||||||
|
|
||||||
scavengeIntervalSec::
|
scavengeIntervalSec::
|
||||||
Time in seconds between runs of a scavenger task that looks for
|
Time in seconds between runs of a scavenger task that looks for expired old sessions to delete.
|
||||||
expired old sessions to delete. The default is 10 minutes. If set to
|
The default is 10 minutes.
|
||||||
0, no scavenging is done.
|
If set to 0, no scavenging is done.
|
||||||
staleIntervalSec::
|
staleIntervalSec::
|
||||||
The length of time a session can be in memory without being checked
|
The length of time a session can be in memory without being checked against the cluster.
|
||||||
against the cluster. A value of 0 indicates that the session is never
|
A value of 0 indicates that the session is never checked against the cluster - the current node is considered to be the master for the session.
|
||||||
checked against the cluster - the current node is considered to be the
|
|
||||||
master for the session.
|
|
||||||
maxQueryResults::
|
maxQueryResults::
|
||||||
The maximum number of results to return for a query to find expired
|
The maximum number of results to return for a query to find expired sessions.
|
||||||
sessions. For efficiency it is important to limit the size of the
|
For efficiency it is important to limit the size of the result.
|
||||||
result. The default is 100. If 0 or negative numbers are set, the
|
The default is 100.
|
||||||
default is used instead.
|
If 0 or negative numbers are set, the default is used instead.
|
||||||
|
|
|
@ -17,58 +17,33 @@
|
||||||
[[session-clustering-infinispan]]
|
[[session-clustering-infinispan]]
|
||||||
=== Session Clustering with Infinispan
|
=== Session Clustering with Infinispan
|
||||||
|
|
||||||
Jetty can support session clustering by persisting sessions to
|
Jetty can support session clustering by persisting sessions to http://www.infinispan.org[Infinispan].
|
||||||
http://www.infinispan.org[Infinispan]. Each Jetty instance locally
|
Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to Infinispan as the request exits the server.
|
||||||
caches sessions for which it has received requests, writing any changes
|
Sessions must obey the Serialization contract, and servlets must call the `Session.setAttribute()` method to ensure that changes are persisted.
|
||||||
to the session through to Infinispan as the request exits the server.
|
|
||||||
Sessions must obey the Serialization contract, and servlets must call
|
|
||||||
the Session.setAttribute() method to ensure that changes are persisted.
|
|
||||||
|
|
||||||
The persistent session mechanism works in conjunction with a load
|
The persistent session mechanism works in conjunction with a load balancer that supports stickiness.
|
||||||
balancer that supports stickiness. Stickiness can be based on various
|
Stickiness can be based on various data items, such as source IP address or characteristics of the session ID or a load-balancer specific mechanism.
|
||||||
data items, such as source IP address or characteristics of the session
|
For those load balancers that examine the session ID, the Jetty persistent session mechanism appends a node ID to the session ID, which can be used for routing.
|
||||||
ID or a load-balancer specific mechanism. For those load balancers that
|
|
||||||
examine the session ID, the Jetty persistent session mechanism appends a
|
|
||||||
node ID to the session ID, which can be used for routing.
|
|
||||||
|
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
There are two components to session management in Jetty: a session ID
|
There are two components to session management in Jetty: a session ID manager and a session manager.
|
||||||
manager and a session manager.
|
|
||||||
|
|
||||||
* The session ID manager ensures that session IDs are unique across all
|
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.
|
||||||
webapps hosted on a Jetty instance, and thus there can only be one
|
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.
|
||||||
session ID manager per Jetty instance.
|
|
||||||
* The session manager handles the session lifecycle
|
|
||||||
(create/update/invalidate/expire) on behalf of a web application, so
|
|
||||||
there is one session manager per web application instance.
|
|
||||||
|
|
||||||
These managers also cooperate and collaborate with the
|
These managers also cooperate and collaborate with the `org.eclipse.jetty.server.session.SessionHandler` to enable cross-context dispatch.
|
||||||
`org.eclipse.jetty.server.session.SessionHandler` to enable
|
|
||||||
cross-context dispatch.
|
|
||||||
|
|
||||||
==== The infinispan Module
|
==== The Infinispan Module
|
||||||
|
|
||||||
When using the jetty distribution, to enable Infinispan session
|
When using the jetty distribution, to enable Infinispan session persistence, you will first need to enable the Infinispan link:#startup-modules[module] for your link:#creating-jetty-base[base] using the `--add-to-start` or `--add-to-startd` argument to the link:#startup-overview[start.jar].
|
||||||
persistence, you will first need to enable the `infinispan`
|
|
||||||
link:#startup-modules[module] for your link:#creating-jetty-base[base]
|
|
||||||
using the --add-to-start or --add-to-startd argument to the
|
|
||||||
link:#startup-overview[start.jar].
|
|
||||||
|
|
||||||
As part of the module installation, the necessary infinispan jars will
|
As part of the module installation, the necessary Infinispan jars will be dynamically downloaded and installed to your `${jetty.base}/lib/infinispan` directory.
|
||||||
be dynamically downloaded and installed to your
|
If you need to up or downgrade the version of the Infinispan jars, then you can delete the jars that were automatically installed and replace them.
|
||||||
`${jetty.base}/lib/infinispan` directory. If you need to up or downgrade
|
Once you've done that, you will need to prevent Jetty's startup checks from detecting the missing jars.
|
||||||
the version of the infinispan jars, then you can delete the jars that
|
To do that, you can use `--skip-file-validation=infinispan` argument to start.jar on the command line, or place that line inside `${jetty.base}/start.ini` to ensure it is used for every start.
|
||||||
were automatically installed and replace them. Once you've done that,
|
|
||||||
you will need to prevent jetty's startup checks from detecting the
|
|
||||||
missing jars. To do that, you can use
|
|
||||||
`--skip-file-validation=infinispan` argument to start.jar on the command
|
|
||||||
line, or place that line inside `${jetty.base}/start.ini` to ensure it
|
|
||||||
is used for every start.
|
|
||||||
|
|
||||||
You will also find the following properties, either in your base's
|
You will also find the following properties, either in your base's `start.d/infinispan.ini` file or appended to your `start.ini`, depending on how you enabled the module:
|
||||||
`start.d/infinispan.ini` file or appended to your `start.ini`, depending
|
|
||||||
on how you enabled the module:
|
|
||||||
|
|
||||||
....
|
....
|
||||||
## Unique identifier for this node in the cluster
|
## Unique identifier for this node in the cluster
|
||||||
|
@ -76,61 +51,41 @@ jetty.infinispanSession.workerName=node1
|
||||||
....
|
....
|
||||||
|
|
||||||
jetty.infinispanSession.workerName::
|
jetty.infinispanSession.workerName::
|
||||||
The name that uniquely identifies this node in the cluster. This value
|
The name that uniquely identifies this node in the cluster.
|
||||||
will also be used by the sticky load balancer to identify the node.
|
This value will also be used by the sticky load balancer to identify the node.
|
||||||
Don't forget to change the value of this property on *each* node on
|
Don't forget to change the value of this property on *each* node on which you enable Infinispan session clustering.
|
||||||
which you enable infinispan session clustering.
|
|
||||||
|
|
||||||
These properties are applied to the InfinispanSessionIdManager described
|
These properties are applied to the `InfinispanSessionIdManager` described below.
|
||||||
below.
|
|
||||||
|
|
||||||
===== Configuring the InfinispanSessionIdManager
|
===== Configuring the InfinispanSessionIdManager
|
||||||
|
|
||||||
The infinispan module will have installed file called
|
The Infinispan module will have installed file called `$\{jetty.home}/etc/jetty-infinispan.xml`.
|
||||||
$\{jetty.home}/etc/jetty-infinispan.xml. This file configures an
|
This file configures an instance of the `InfinispanSessionIdManager` that will be shared across all webapps deployed on that server.
|
||||||
instance of the InfinispanSessionIdManager that will be shared across
|
It looks like this:
|
||||||
all webapps deployed on that server. It looks like this:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
include::{SRCDIR}/jetty-infinispan/src/main/config/etc/jetty-default-infinispan-store.xml[]
|
include::{SRCDIR}/jetty-infinispan/src/main/config/etc/jetty-infinispan.xml[]
|
||||||
----
|
----
|
||||||
|
|
||||||
As you can see, you configure the Infinispan
|
As you can see, you configure the Infinispan http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_the_cache_apis[Cache] instance that the `InfinispanSessionIdManager` should use in this file.
|
||||||
http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_the_cache_apis[Cache]
|
By default, the Infinispan http://infinispan.org/docs/7.1.x/getting_started/getting_started.html#_running_infinispan_on_a_single_node[Default cache] instance is used (e.g. on the local node).
|
||||||
instance that the InfinispanSessionIdManager should use in this file. By
|
You can instead use a custom Cache setup - the `jetty-infinispan.xml` file shows you how to configure a remote Cache (using the http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_using_hot_rod_server[hotrod java client]).
|
||||||
default, the infinispan
|
|
||||||
http://infinispan.org/docs/7.1.x/getting_started/getting_started.html#_running_infinispan_on_a_single_node[Default
|
|
||||||
cache] instance is used (ie on the local node). You can instead use a
|
|
||||||
custom Cache setup - the jetty-infinispan.xml file shows you how to
|
|
||||||
configure a remote Cache (using the
|
|
||||||
http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_using_hot_rod_server[hotrod
|
|
||||||
java client]).
|
|
||||||
|
|
||||||
The InfinispanSessionIdManager can be configured by calling setters:
|
The `InfinispanSessionIdManager` can be configured by calling setters:
|
||||||
|
|
||||||
idleExpiryMultiple::
|
idleExpiryMultiple::
|
||||||
Sessions that are not immortal, ie they have an expiry time, have
|
Sessions that are not immortal, e.g. they have an expiry time, have their ids stored into Infinispan with an http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_expiration[idle expiry timeout] equivalent to double the session's timeout.
|
||||||
their ids stored into Infinispan with an
|
This should be sufficient to ensure that a session id that is in-use by a session is never accidentally removed.
|
||||||
http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_expiration[idle
|
However, should you wish to, you can configure this to any integral value to effectively increase the http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_expiration[idle expiry] timeout.
|
||||||
expiry timeout] equivalent to double the session's timeout. This
|
|
||||||
should be sufficient to ensure that a session id that is in-use by a
|
|
||||||
session is never accidentally removed. However, should you wish to,
|
|
||||||
you can configure this to any integral value to effectively increase
|
|
||||||
the
|
|
||||||
http://infinispan.org/docs/7.1.x/user_guide/user_guide.html#_expiration[idle
|
|
||||||
expiry] timeout.
|
|
||||||
|
|
||||||
===== Configuring the InfinispanSessionManager
|
===== Configuring the InfinispanSessionManager
|
||||||
|
|
||||||
As mentioned elsewhere, there should be one InfinispanSessionManager per
|
As mentioned elsewhere, there should be one `InfinispanSessionManager` per context (e.g. webapp).
|
||||||
context (ie webapp). It will need to reference the single
|
It will need to reference the single `InfinispanSessionIdManager` configured previously for the Server.
|
||||||
InfinispanSessionIdManager configured previously for the Server.
|
|
||||||
|
|
||||||
The way you configure a InfinispanSessionManager depends on whether
|
The way you configure a `InfinispanSessionManager` depends on whether you're configuring from a context xml file, a `jetty-web.xml` file or code.
|
||||||
you're configuring from a context xml file or a `jetty-web.xml` file or
|
The basic difference is how you get a reference to the Jetty `org.eclipse.jetty.server.Server` instance.
|
||||||
code. The basic difference is how you get a reference to the Jetty
|
|
||||||
`org.eclipse.jetty.server.Server` instance.
|
|
||||||
|
|
||||||
From a context xml file, you reference the Server instance as a Ref:
|
From a context xml file, you reference the Server instance as a Ref:
|
||||||
|
|
||||||
|
@ -171,8 +126,7 @@ From a context xml file, you reference the Server instance as a Ref:
|
||||||
</Set>
|
</Set>
|
||||||
----
|
----
|
||||||
|
|
||||||
From a `WEB-INF/jetty-web.xml` file, you can reference the Server
|
From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance directly:
|
||||||
instance directly:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -213,25 +167,19 @@ instance directly:
|
||||||
The InfinispanSessionManager can be provided by calling setters:
|
The InfinispanSessionManager can be provided by calling setters:
|
||||||
|
|
||||||
scavengeInterval::
|
scavengeInterval::
|
||||||
Time in seconds between runs of a scavenger task that looks for
|
Time in seconds between runs of a scavenger task that looks for expired old sessions to delete.
|
||||||
expired old sessions to delete. The default is 10 minutes.
|
The default is 10 minutes.
|
||||||
staleIntervalSec::
|
staleIntervalSec::
|
||||||
The length of time a session can be in memory without being checked
|
The length of time a session can be in memory without being checked against the cluster.
|
||||||
against the cluster. A value of 0 indicates that the session is never
|
A value of 0 indicates that the session is never checked against the cluster - the current node is considered to be the master for the session.
|
||||||
checked against the cluster - the current node is considered to be the
|
|
||||||
master for the session.
|
|
||||||
|
|
||||||
===== Using HotRod
|
===== Using HotRod
|
||||||
|
|
||||||
If you're using the hotrod client - where serialization will be required
|
If you're using the hotrod client - where serialization will be required - you will need to ensure that the hotrod marshalling software works with Jetty classloading.
|
||||||
- you will need to ensure that the hotrod marshalling software works
|
To do this, firstly ensure that you have included the lines containing the `prependServerClass` to your context xml file as shown above.
|
||||||
with jetty classloading. To do this, firstly ensure that you have
|
|
||||||
included the lines containing the `prependServerClass` to your context
|
|
||||||
xml file as shown above.
|
|
||||||
|
|
||||||
Then, create the file
|
Then, create the file `${jetty.base}/resources/hotrod-client.properties`.
|
||||||
`${jetty.base}/resources/hotrod-client.properties`. Add the following
|
Add the following line to this file:
|
||||||
line to this file:
|
|
||||||
|
|
||||||
....
|
....
|
||||||
infinispan.client.hotrod.marshaller=org.eclipse.jetty.session.infinispan.WebAppMarshaller
|
infinispan.client.hotrod.marshaller=org.eclipse.jetty.session.infinispan.WebAppMarshaller
|
||||||
|
|
|
@ -17,57 +17,35 @@
|
||||||
[[session-clustering-jdbc]]
|
[[session-clustering-jdbc]]
|
||||||
=== Session Clustering with a Database
|
=== Session Clustering with a Database
|
||||||
|
|
||||||
Jetty can support session clustering by persisting sessions to a shared
|
Jetty can support session clustering by persisting sessions to a shared database.
|
||||||
database. Each Jetty instance locally caches sessions for which it has
|
Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the database as the request exits the server.
|
||||||
received requests, writing any changes to the session through to the
|
Sessions must obey the Serialization contract, and servlets must call the `Session.setAttribute()` method to ensure that changes are persisted.
|
||||||
database as the request exits the server. Sessions must obey the
|
|
||||||
Serialization contract, and servlets must call the
|
|
||||||
Session.setAttribute() method to ensure that changes are persisted.
|
|
||||||
|
|
||||||
The persistent session mechanism works in conjunction with a load
|
The persistent session mechanism works in conjunction with a load balancer that supports stickiness.
|
||||||
balancer that supports stickiness. Stickiness can be based on various
|
Stickiness can be based on various data items, such as source IP address or characteristics of the session ID or a load-balancer specific mechanism.
|
||||||
data items, such as source IP address or characteristics of the session
|
For those load balancers that examine the session ID, the Jetty persistent session mechanism appends a node ID to the session ID, which can be used for routing.
|
||||||
ID or a load-balancer specific mechanism. For those load balancers that
|
|
||||||
examine the session ID, the Jetty persistent session mechanism appends a
|
|
||||||
node ID to the session ID, which can be used for routing.
|
|
||||||
|
|
||||||
In this type of solution, the database can become both a bottleneck and
|
In this type of solution, the database can become both a bottleneck and a single point of failure.
|
||||||
a single point of failure. Jetty takes steps to reduce the load on the
|
Jetty takes steps to reduce the load on the database (discussed below), but in a heavily loaded environment you might need to investigate other optimization strategies such as local caching and database replication.
|
||||||
database (discussed below), but in a heavily loaded environment you
|
You should also consult your database vendor's documentation for information on how to ensure high availability and failover of your database.
|
||||||
might need to investigate other optimization strategies such as local
|
|
||||||
caching and database replication. You should also consult your database
|
|
||||||
vendor's documentation for information on how to ensure high
|
|
||||||
availability and failover of your database.
|
|
||||||
|
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
There are two components to session management in Jetty: a session ID
|
There are two components to session management in Jetty: a session ID manager and a session manager.
|
||||||
manager and a session manager.
|
|
||||||
|
|
||||||
* The session ID manager ensures that session IDs are unique across all
|
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.
|
||||||
webapps hosted on a Jetty instance, and thus there can only be one
|
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.
|
||||||
session ID manager per Jetty instance.
|
|
||||||
* The session manager handles the session lifecycle
|
|
||||||
(create/update/invalidate/expire) on behalf of a web application, so
|
|
||||||
there is one session manager per web application instance.
|
|
||||||
|
|
||||||
These managers also cooperate and collaborate with the
|
These managers also cooperate and collaborate with the `org.eclipse.jetty.server.session.SessionHandler` to enable cross-context dispatch.
|
||||||
`org.eclipse.jetty.server.session.SessionHandler` to enable
|
|
||||||
cross-context dispatch.
|
|
||||||
|
|
||||||
==== The jdbc-session Module
|
==== The jdbc-session Module
|
||||||
|
|
||||||
When using the jetty distribution, to enable jdbc session persistence,
|
When using the jetty distribution, to enable jdbc session persistence, you will first need to enable the jdbc-session link:#startup-modules[module] for your link:#creating-jetty-base[base] using the `--add-to-start` or `--add-to-startd` argument to the link:#startup-overview[start.jar].
|
||||||
you will first need to enable the jdbc-session
|
|
||||||
link:#startup-modules[module] for your link:#creating-jetty-base[base]
|
|
||||||
using the --add-to-start or --add-to-startd argument to the
|
|
||||||
link:#startup-overview[start.jar].
|
|
||||||
|
|
||||||
You will also find the following properties, either in your base's
|
You will also find the following properties, either in your base's start.d/jdbc-session.ini file or appended to your start.ini, depending on how you enabled the module:
|
||||||
start.d/jdbc-session.ini file or appended to your start.ini, depending
|
|
||||||
on how you enabled the module:
|
|
||||||
|
|
||||||
....
|
[source,java]
|
||||||
|
----
|
||||||
## Unique identifier for this node in the cluster
|
## Unique identifier for this node in the cluster
|
||||||
jetty.jdbcSession.workerName=node1
|
jetty.jdbcSession.workerName=node1
|
||||||
|
|
||||||
|
@ -75,53 +53,42 @@ jetty.jdbcSession.workerName=node1
|
||||||
#jetty.jdbcSession.datasource=sessions
|
#jetty.jdbcSession.datasource=sessions
|
||||||
jetty.jdbcSession.driverClass=org.apache.derby.jdbc.EmbeddedDriver
|
jetty.jdbcSession.driverClass=org.apache.derby.jdbc.EmbeddedDriver
|
||||||
jetty.jdbcSession.connectionURL=jdbc:derby:sessions;create=true
|
jetty.jdbcSession.connectionURL=jdbc:derby:sessions;create=true
|
||||||
....
|
----
|
||||||
|
|
||||||
jetty.jdbcSession.workerName::
|
jetty.jdbcSession.workerName::
|
||||||
The name that uniquely identifies this node in the cluster. This value
|
The name that uniquely identifies this node in the cluster.
|
||||||
will also be used by the sticky load balancer to identify the node.
|
This value will also be used by the sticky load balancer to identify the node.
|
||||||
Don't forget to change the value of this property on *each* node on
|
Don't forget to change the value of this property on *each* node on which you enable jdbc session clustering.
|
||||||
which you enable jdbc session clustering.
|
|
||||||
jetty.jdbcSession.scavenge::
|
jetty.jdbcSession.scavenge::
|
||||||
The time in seconds between sweeps of a task which scavenges old
|
The time in seconds between sweeps of a task which scavenges old expired sessions.
|
||||||
expired sessions. The default is 10 mins. We don't recommend you
|
The default is 10 minutess.
|
||||||
increase the frequency bcause doing so increases the load on the
|
Increasing the frequency is not recommended as doing so increases the load on the database with very little gain.
|
||||||
database with very little gain.
|
|
||||||
jetty.jdbcSession.datasource::
|
jetty.jdbcSession.datasource::
|
||||||
The name of a javax.sql.DataSource that gives access to the database
|
The name of a `javax.sql.DataSource` that gives access to the database that holds the session information.
|
||||||
that holds the session information. You should configure *either* this
|
You should configure *either* this or the jdbc driver information described next.
|
||||||
or the jdbc driver information described next.
|
|
||||||
jetty.jdbcSession.datasource and jetty.jdbcSession.connectionURL::
|
jetty.jdbcSession.datasource and jetty.jdbcSession.connectionURL::
|
||||||
This is the name of the jdbc driver class, and a jdbc connection url
|
This is the name of the jdbc driver class, and a jdbc connection url suitable for that driver.
|
||||||
suitable for that driver. You should configure *either* this or the
|
You should configure *either* this or the jdbc datasource name described above.
|
||||||
jdbc datasource name described above.
|
|
||||||
|
|
||||||
These properties are applied to the JDBCSessionIdManager described
|
These properties are applied to the `JDBCSessionIdManager` described below.
|
||||||
below.
|
|
||||||
|
|
||||||
===== Configuring the JDBCSessionIdManager
|
===== Configuring the JDBCSessionIdManager
|
||||||
|
|
||||||
The jdbc-session module will have installed file called
|
The jdbc-session module will have installed file called `$\{jetty.home}/etc/jetty-jdbc-sessions.xml`.
|
||||||
$\{jetty.home}/etc/jetty-jdbc-sessions.xml. This file configures an
|
This file configures an instance of the `JDBCSessionIdManager` that will be shared across all webapps deployed on that server.
|
||||||
instance of the JDBCSessionIdManager that will be shared across all
|
It looks like this:
|
||||||
webapps deployed on that server. It looks like this:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
include::{SRCDIR}/jetty-server/src/main/config/etc/jetty-jdbc-session-store.xml[]
|
include::{SRCDIR}/jetty-server/src/main/config/etc/jetty-jdbc-sessions.xml[]
|
||||||
----
|
----
|
||||||
|
|
||||||
As well as uncommenting and setting up appropriate values for the
|
As well as uncommenting and setting up appropriate values for the properties discussed above, you will also need to edit this file and uncomment *either* the data source or the driver info elements.
|
||||||
properties we discussed above, you will also need to edit this file and
|
|
||||||
uncomment *either* the datasource or the driver info elements.
|
|
||||||
|
|
||||||
As Jetty configuration files are direct mappings of XML to Java, it is
|
As Jetty configuration files are direct mappings of XML to Java, it is straight forward to do this in code:
|
||||||
straightforward to see how to do this in code, but here's an example
|
|
||||||
anyway:
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
...
|
...
|
||||||
JDBCSessionIdManager idMgr = new JDBCSessionIdManager(server);
|
JDBCSessionIdManager idMgr = new JDBCSessionIdManager(server);
|
||||||
|
@ -134,19 +101,18 @@ server.setSessionIdManager(idMgr);
|
||||||
|
|
||||||
====== Configuring the Database Schema
|
====== Configuring the Database Schema
|
||||||
|
|
||||||
You may find it necessary to change the names of the tables and columns
|
You may find it necessary to change the names of the tables and columns that the JDBC Session management uses to store the session information.
|
||||||
that the JDBC Session management uses to store the session information.
|
|
||||||
The defaults used are:
|
The defaults used are:
|
||||||
|
|
||||||
.Default Values for Session Id Table
|
.Default Values for Session Id Table
|
||||||
[cols=",",]
|
[options="header"]
|
||||||
|===========================
|
|===========================
|
||||||
|table name |JettySessionIds
|
|table name |JettySessionIds
|
||||||
|columns |id
|
|columns |id
|
||||||
|===========================
|
|===========================
|
||||||
|
|
||||||
.Default Values for Session Table
|
.Default Values for Session Table
|
||||||
[cols=",",]
|
[options="header"]
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|table name |JettySessions
|
|table name |JettySessions
|
||||||
|
|
||||||
|
@ -155,16 +121,11 @@ accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime,
|
||||||
expiryTime, maxInterval, map
|
expiryTime, maxInterval, map
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
To change these values, use the
|
To change these values, use the link:{JDURL}/org/eclipse/jetty/server/session/SessionIdTableSchema.html[org.eclipse.jetty.server.session.SessionIdTableSchema] and link:{JDURL}/org/eclipse/jetty/server/session/SessionTableSchema.html[org.eclipse.jetty.server.session.SessionTableSchema] classes.
|
||||||
link:{JDURL}/org/eclipse/jetty/server/session/SessionIdTableSchema.html[org.eclipse.jetty.server.session.SessionIdTableSchema]
|
These classes have getter/setter methods for the table name and all columns.
|
||||||
and
|
|
||||||
link:{JDURL}/org/eclipse/jetty/server/session/SessionTableSchema.html[org.eclipse.jetty.server.session.SessionTableSchema]
|
|
||||||
classes. These classes have getter/setter methods for the table name and
|
|
||||||
all columns.
|
|
||||||
|
|
||||||
Here's an example of changing the name of JettySessionsId table and its
|
Here's an example of changing the name of `JettySessionsId` table and its single column.
|
||||||
single column. This example will use java code, but as explained above,
|
This example will use java code, but as explained above, you may also do this via a Jetty xml configuration file:
|
||||||
you may also do this via a jetty xml configuration file:
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -176,10 +137,8 @@ idTableSchema.setIdColumn("theid");
|
||||||
idManager.setSessionIdTableSchema(idTableSchema);
|
idManager.setSessionIdTableSchema(idTableSchema);
|
||||||
----
|
----
|
||||||
|
|
||||||
In a similar fashion, you can change the names of the table and columns
|
In a similar fashion, you can change the names of the table and columns for the `JettySessions` table.
|
||||||
for the JettySessions table. *Note* that both the SessionIdTableSchema
|
*Note* that both the `SessionIdTableSchema` and the `SessionTableSchema` instances are set on the `JDBCSessionIdManager` class.
|
||||||
and the SessionTableSchema instances are set on the JDBCSessionIdManager
|
|
||||||
class.
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -203,14 +162,11 @@ idManager.setSessionTableSchema(sessionTableSchema);
|
||||||
|
|
||||||
===== Configuring the JDBCSessionManager
|
===== Configuring the JDBCSessionManager
|
||||||
|
|
||||||
As mentioned elsewhere, there should be one JDBCSessionManager per
|
As mentioned elsewhere, there should be one `JDBCSessionManager` per context (e.g. webapp).
|
||||||
context (ie webapp). It will need to reference the single
|
It will need to reference the single `JDBCSessionIdManager` configured previously for the Server.
|
||||||
JDBCSessionIdManager configured previously for the Server.
|
|
||||||
|
|
||||||
The way you configure a JDBCSessionManager depends on whether you're
|
The way you configure a `JDBCSessionManager` depends on whether you're configuring from a context xml file, a `jetty-web.xml` file or code.
|
||||||
configuring from a context xml file or a `jetty-web.xml` file or code.
|
The basic difference is how you get a reference to the Jetty `org.eclipse.jetty.server.Server` instance.
|
||||||
The basic difference is how you get a reference to the Jetty
|
|
||||||
`org.eclipse.jetty.server.Server` instance.
|
|
||||||
|
|
||||||
From a context xml file, you reference the Server instance as a Ref:
|
From a context xml file, you reference the Server instance as a Ref:
|
||||||
|
|
||||||
|
@ -232,8 +188,7 @@ From a context xml file, you reference the Server instance as a Ref:
|
||||||
</Set>
|
</Set>
|
||||||
----
|
----
|
||||||
|
|
||||||
From a `WEB-INF/jetty-web.xml` file, you can reference the Server
|
From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance directly:
|
||||||
instance directly:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,108 +17,72 @@
|
||||||
[[session-clustering-mongodb]]
|
[[session-clustering-mongodb]]
|
||||||
=== Session Clustering with MongoDB
|
=== Session Clustering with MongoDB
|
||||||
|
|
||||||
Jetty can support session clustering by persisting sessions into
|
Jetty can support session clustering by persisting sessions into http://www.mogodb.org[MongoDB].
|
||||||
http://www.mogodb.org[MongoDB]. Each Jetty instance locally caches
|
Each Jetty instance locally caches sessions for which it has received requests, writing any changes to the session through to the cluster as the request exits the server.
|
||||||
sessions for which it has received requests, writing any changes to the
|
Sessions must obey the Serialization contract, and servlets must call the `Session.setAttribute()` method to ensure that changes are persisted.
|
||||||
session through to the cluster as the request exits the server. Sessions
|
|
||||||
must obey the Serialization contract, and servlets must call the
|
|
||||||
Session.setAttribute() method to ensure that changes are persisted.
|
|
||||||
|
|
||||||
The session persistence mechanism works in conjunction with a load
|
The session persistence mechanism works in conjunction with a load balancer that supports stickiness.
|
||||||
balancer that supports stickiness. Stickiness can be based on various
|
Stickiness can be based on various data items, such as source IP address or characteristics of the session ID or a load-balancer specific mechanism.
|
||||||
data items, such as source IP address or characteristics of the session
|
For those load balancers that examine the session ID, the Jetty persistent session mechanism appends a node ID to the session ID, which can be used for routing.
|
||||||
ID or a load-balancer specific mechanism. For those load balancers that
|
|
||||||
examine the session ID, the Jetty persistent session mechanism appends a
|
|
||||||
node ID to the session ID, which can be used for routing.
|
|
||||||
|
|
||||||
In this type of solution, the traffic on the network needs to be
|
In this type of solution, the traffic on the network needs to be carefully watched and tends to be the bottleneck.
|
||||||
carefully watched and tends to be the bottleneck. You are probably
|
You are probably investigating this solution in order to scale to large amount of users and sessions, so careful attention should be paid to your usage scenario.
|
||||||
investigating this solution in order to scale to large amount of users
|
Applications with a heavy write profile to their sessions will consume more network bandwidth than profiles that are predominately read oriented.
|
||||||
and sessions, so careful attention should be paid to your usage
|
We recommend using this session manager with largely read based session scenarios.
|
||||||
scenario. Applications with a heavy write profile to their sessions will
|
|
||||||
consume more network bandwidth than profiles that are predominately read
|
|
||||||
oriented. We recommend using this session manager with largely read
|
|
||||||
based session scenarios.
|
|
||||||
|
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
There are two components to session management in Jetty: a session ID
|
There are two components to session management in Jetty: a session ID manager and a session manager.
|
||||||
manager and a session manager.
|
|
||||||
|
|
||||||
* The session ID manager ensures that session IDs are unique across all
|
* The session ID manager ensures that session IDs are unique across all webapps hosted on a Jetty instance, and thus there can only be one session ID manager per Jetty instance.
|
||||||
webapps hosted on a Jetty instance, and thus there should only be one
|
* The session manager handles the session lifecycle (create/update/invalidate/expire) on behalf of a web application, so there is one session manager per web application instance.
|
||||||
session ID manager per Jetty instance.
|
|
||||||
* The session manager handles the session lifecycle
|
|
||||||
(create/update/invalidate/expire) on behalf of a web application, so
|
|
||||||
there is one session manager per web application instance.
|
|
||||||
|
|
||||||
These managers also cooperate and collaborate with the
|
These managers also cooperate and collaborate with the `org.eclipse.jetty.server.session.SessionHandler` to enable cross-context dispatch.
|
||||||
`org.eclipse.jetty.server.session.SessionHandler` to enable
|
|
||||||
cross-context dispatch.
|
|
||||||
|
|
||||||
==== The nosql Module
|
==== The nosql Module
|
||||||
|
|
||||||
When using the jetty distribution, to enable the mongodb session
|
When using the jetty distribution, to enable the MongoDB session persistence mechanism, you will first need to enable the nosql link:#startup-modules[module] for your link:#creating-jetty-base[base] using the `--add-to-start` or `--add-to-startd` argument to the link:#startup-overview[start.jar].
|
||||||
persistence mechanism, you will first need to enable the nosql
|
This module will automatically download the `mongodb-java-driver` and install it to your base's `lib/nosql` directory.
|
||||||
link:#startup-modules[module] for your link:#creating-jetty-base[base]
|
|
||||||
using the --add-to-start or --add-to-startd argument to the
|
|
||||||
link:#startup-overview[start.jar]. This module will automatically
|
|
||||||
download the mongodb-java-driver and install it to your base's lib/nosql
|
|
||||||
directory.
|
|
||||||
|
|
||||||
As part of the module installation, the necessary mongo java driver jars
|
As part of the module installation, the necessary mongo java driver jars will be dynamically downloaded and installed to your `${jetty.base}/lib/nosql` directory.
|
||||||
will be dynamically downloaded and installed to your
|
If you need to up or downgrade the version of these jars, then you can delete the jars that were automatically installed and replace them.
|
||||||
`${jetty.base}/lib/nosql` directory. If you need to up or downgrade the
|
Once you've done that, you will need to prevent Jetty's startup checks from detecting the missing jars.
|
||||||
version of these jars, then you can delete the jars that were
|
To do that, you can use `--skip-file-validation=nosql` argument to start.jar on the command line, or place that line inside `${jetty.base}/start.ini` to ensure it is used for every start.
|
||||||
automatically installed and replace them. Once you've done that, you
|
|
||||||
will need to prevent jetty's startup checks from detecting the missing
|
|
||||||
jars. To do that, you can use `--skip-file-validation=nosql` argument to
|
|
||||||
start.jar on the command line, or place that line inside
|
|
||||||
`${jetty.base}/start.ini` to ensure it is used for every start.
|
|
||||||
|
|
||||||
You will also find the following properties, either in your base's
|
You will also find the following properties, either in your base's `start.d/nosql.ini` file or appended to your `start.ini`, depending on how you enabled the module:
|
||||||
start.d/nosql.ini file or appended to your start.ini, depending on how
|
|
||||||
you enabled the module:
|
|
||||||
|
|
||||||
....
|
[source,xml]
|
||||||
|
----
|
||||||
## Unique identifier for this node in the cluster
|
## Unique identifier for this node in the cluster
|
||||||
jetty.nosqlSession.workerName=node1
|
jetty.nosqlSession.workerName=node1
|
||||||
|
|
||||||
|
|
||||||
## Interval in seconds between scavenging expired sessions
|
## Interval in seconds between scavenging expired sessions
|
||||||
jetty.nosqlSession.scavenge=1800
|
jetty.nosqlSession.scavenge=1800
|
||||||
....
|
----
|
||||||
|
|
||||||
The `jetty.nosqlSession.workerName` is the unique name for this jetty
|
The `jetty.nosqlSession.workerName` is the unique name for this Jetty Server instance.
|
||||||
Server instance. It will be used by the sticky load balancer to uniquely
|
It will be used by the sticky load balancer to uniquely identify the node.
|
||||||
identify the node. You should change this value on *each* node to which
|
You should change this value on *each* node to which you install MongoDB session management.
|
||||||
you install mongodb session management.
|
|
||||||
|
|
||||||
The `jetty.nosqlSession.scavenge` property defines the time in seconds
|
The `jetty.nosqlSession.scavenge` property defines the time in seconds between runs of the scavenger: the scavenger is a task which runs periodically to clean out sessions that have expired but become stranded in the database for whatever reason.
|
||||||
between runs of the scavengeer: the scavenger is a task which runs
|
|
||||||
periodically to clean out sessions that have expired but become stranded
|
|
||||||
in the database for whatever reason.
|
|
||||||
|
|
||||||
These properties are substituted into the configuration of the
|
These properties are substituted into the configuration of the `MongoDBSessionIdManager` and `MongoSessionManager`.
|
||||||
MongoDBSessionIdManager and MongoSessionManager.
|
|
||||||
|
|
||||||
===== Configuring the MongoSessionIdManager
|
===== Configuring the MongoSessionIdManager
|
||||||
|
|
||||||
The nosql module will have installed file called
|
The nosql module will have installed file called `$\{jetty.home}/etc/jetty-nosql.xml`.
|
||||||
$\{jetty.home}/etc/jetty-nosql.xml. This file configures an instance of
|
This file configures an instance of the `MongoSessionIdManager` that will be shared across all webapps deployed on that server.
|
||||||
the MongoSessionIdManager that will be shared across all webapps
|
It looks like this:
|
||||||
deployed on that server. It looks like this:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
include::{SRCDIR}/jetty-nosql/src/main/config/etc/jetty-mongo-session-store.xml[]
|
include::{SRCDIR}/jetty-nosql/src/main/config/etc/jetty-nosql.xml[]
|
||||||
----
|
----
|
||||||
|
|
||||||
The MongoSessionIdManager needs access to a mongodb cluster, and the
|
The `MongoSessionIdManager` needs access to a MongoDB cluster, and the `jetty-nosql.xml` file assumes the defaults of localhost and default MongoDB port.
|
||||||
jetty-nosql.xml file assumes the defaults of localhost and default
|
If you need to configure something else, you will need to edit this file.
|
||||||
mongodb port. If you need to configure something else, you will need to
|
Here's an example of a more complex setup to use a remote MongoDB instance:
|
||||||
edit this file. Here's an example of a more complex setup to use a
|
|
||||||
remote mongodb instance:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -162,9 +126,7 @@ remote mongodb instance:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
As Jetty configuration files are direct mappings of XML to Java, it is
|
As Jetty configuration files are direct mappings of XML to Java, it is straight forward to do this in code:
|
||||||
straightforward to see how to do this in code, but here's an example
|
|
||||||
anyway:
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -178,71 +140,52 @@ anyway:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
The MongoSessionIdManager has slightly different options than some of
|
The MongoSessionIdManager has slightly different options than some of our more traditional session options.
|
||||||
our more traditional session options. The MongoDBSessionIdManager has
|
The `MongoDBSessionIdManager` has the same scavenge timers which govern the setting of a valid session to invalid after a certain period of inactivity.
|
||||||
the same scavenge timers which govern the setting of a valid session to
|
New to this session id manager is the extra purge setting which governs removal from the MongoDB cluster.
|
||||||
invalid after a certain period of inactivity. New to this session id
|
This can be configured through the 'purge' option. Purge is by default set to true and by default runs daily for each node on the cluster.
|
||||||
manager is the extra purge setting which governs removal from the
|
Also able to be configured is the age in which an invalid session will be retained which is set to 1 day by default.
|
||||||
mongodb cluster. This can be configured through the 'purge' option.
|
This means that invalid sessions will be removed after lingering in the MongoDB instance for a day.
|
||||||
Purge is by default set to true and by default runs daily for each node
|
There is also an option for purging valid sessions that have not been used recently.
|
||||||
on the cluster. Also able to be configured is the age in which an
|
The default time for this is 1 week. You can disable these behaviors by setting purge to false.
|
||||||
invalid session will be retained which is set to 1 day by default. This
|
|
||||||
means that invalid sessions will be removed after lingering in the
|
|
||||||
mongodb instance for a day. There is also an option for purging valid
|
|
||||||
sessions that have not been used recently. The default time for this is
|
|
||||||
1 week. You can disable these behaviors by setting purge to false.
|
|
||||||
|
|
||||||
scavengeDelay::
|
scavengeDelay::
|
||||||
How long to delay before periodically looking for sessions to
|
How long to delay before periodically looking for sessions to scavenge?
|
||||||
scavenge?
|
|
||||||
scavengePeriod::
|
scavengePeriod::
|
||||||
How much time after a scavenge has completed should you wait before
|
How much time after a scavenge has completed should you wait before doing it again?
|
||||||
doing it again?
|
|
||||||
scavengeBlockSize::
|
scavengeBlockSize::
|
||||||
Number of session ids to which to limit each scavenge query. If you
|
Number of session ids to which to limit each scavenge query.
|
||||||
have a very large number of sessions in memory then setting this to a
|
If you have a very large number of sessions in memory then setting this to a non 0 value may help speed up scavenging by breaking the scavenge into multiple, queries.
|
||||||
non 0 value may help speed up scavenging by breaking the scavenge into
|
The default is 0, which means that all session ids are considered in a single query.
|
||||||
multiple, queries. The default is 0, which means that all session ids
|
|
||||||
are considered in a single query.
|
|
||||||
purge (Boolean)::
|
purge (Boolean)::
|
||||||
Do you want to purge (delete) sessions that are invalid from the
|
Do you want to purge (delete) sessions that are invalid from the session store completely?
|
||||||
session store completely?
|
|
||||||
purgeDelay::
|
purgeDelay::
|
||||||
How often do you want to perform this purge operation?
|
How often do you want to perform this purge operation?
|
||||||
purgeInvalidAge::
|
purgeInvalidAge::
|
||||||
How old should an invalid session be before it is eligible to be
|
How old should an invalid session be before it is eligible to be purged?
|
||||||
purged?
|
|
||||||
purgeValidAge::
|
purgeValidAge::
|
||||||
How old should a valid session be before it is eligible to be marked
|
How old should a valid session be before it is eligible to be marked invalid and purged?
|
||||||
invalid and purged? Should this occur at all?
|
Should this occur at all?
|
||||||
purgeLimit::
|
purgeLimit::
|
||||||
Integer value that represents how many items to return from a purge
|
Integer value that represents how many items to return from a purge query.
|
||||||
query. The default is 0, which is unlimited. If you have a lot of old
|
The default is 0, which is unlimited.
|
||||||
expired orphaned sessions then setting this value may speed up the
|
If you have a lot of old expired orphaned sessions then setting this value may speed up the purge process.
|
||||||
purge process.
|
|
||||||
preserveOnStop::
|
preserveOnStop::
|
||||||
Whether or not to retain all sessions when the session manager stops.
|
Whether or not to retain all sessions when the session manager stops.
|
||||||
Default is `true`.
|
Default is `true`.
|
||||||
|
|
||||||
===== Configuring a MongoSessionManager
|
===== Configuring a MongoSessionManager
|
||||||
|
|
||||||
As mentioned elsewhere, there should be one MongoSessionManager per
|
As mentioned elsewhere, there should be one `MongoSessionManager` per context (e.g. webapp).
|
||||||
context (ie webapp). It will need to reference the single
|
It will need to reference the single `MongoSessionIdManager` configured previously for the Server.
|
||||||
MongoSessionIdManager configured previously for the Server.
|
|
||||||
|
|
||||||
The way you configure a
|
The way you configure a link:{JDURL}/org/eclipse/jetty/nosql/MongoSessionManager.html[org.eclipse.jetty.nosql.mongodb.MongoSessionManager] depends on whether you're configuring from a link:#deployable-descriptor-file[context xml] file or a link:#jetty-web-xml-config[jetty-web.xml] file or code.
|
||||||
link:{JDURL}/org/eclipse/jetty/nosql/MongoSessionManager.html[org.eclipse.jetty.nosql.mongodb.MongoSessionManager]
|
The basic difference is how you get a reference to the Jetty `org.eclipse.jetty.server.Server` instance.
|
||||||
depends on whether you're configuring from a
|
|
||||||
link:#deployable-descriptor-file[context xml] file or a
|
|
||||||
link:#jetty-web-xml-config[jetty-web.xml] file or code. The basic
|
|
||||||
difference is how you get a reference to the Jetty
|
|
||||||
`org.eclipse.jetty.server.Server` instance.
|
|
||||||
|
|
||||||
From a context xml file, you reference the Server instance as a Ref:
|
From a context xml file, you reference the Server instance as a Ref:
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
||||||
<Ref name="Server" id="Server">
|
<Ref name="Server" id="Server">
|
||||||
<Call id="mongoIdMgr" name="getSessionIdManager"/>
|
<Call id="mongoIdMgr" name="getSessionIdManager"/>
|
||||||
</Ref>
|
</Ref>
|
||||||
|
@ -258,15 +201,12 @@ From a context xml file, you reference the Server instance as a Ref:
|
||||||
</Arg>
|
</Arg>
|
||||||
</New>
|
</New>
|
||||||
</Set>
|
</Set>
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
From a `WEB-INF/jetty-web.xml` file, you can reference the Server
|
From a `WEB-INF/jetty-web.xml` file, you can reference the Server instance directly:
|
||||||
instance directly:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
||||||
<Get name="server">
|
<Get name="server">
|
||||||
<Get id="mongoIdMgr" name="sessionIdManager"/>
|
<Get id="mongoIdMgr" name="sessionIdManager"/>
|
||||||
</Get>
|
</Get>
|
||||||
|
@ -287,7 +227,6 @@ If you're embedding this in code:
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
|
||||||
//assuming you have already set up the MongoSessionIdManager as shown earlier
|
//assuming you have already set up the MongoSessionIdManager as shown earlier
|
||||||
//and have a reference to the Server instance:
|
//and have a reference to the Server instance:
|
||||||
|
|
||||||
|
@ -296,5 +235,4 @@ If you're embedding this in code:
|
||||||
MongoSessionManager mongoMgr = new MongoSessionManager();
|
MongoSessionManager mongoMgr = new MongoSessionManager();
|
||||||
mongoMgr.setSessionIdManager(server.getSessionIdManager());
|
mongoMgr.setSessionIdManager(server.getSessionIdManager());
|
||||||
wac.setSessionHandler(new SessionHandler(mongoMgr));
|
wac.setSessionHandler(new SessionHandler(mongoMgr));
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,9 +17,13 @@
|
||||||
[[setting-session-characteristics]]
|
[[setting-session-characteristics]]
|
||||||
=== Setting Session Characteristics
|
=== Setting Session Characteristics
|
||||||
|
|
||||||
To modify the session characteristics of a web application, you can use
|
Sessions are a concept within the Servlet api which allow requests to store and retrieve information across the time a user spends in an application.
|
||||||
the following parameters, applying them as in one of the example
|
Choosing the correct session manager implementation is an important consideration for every application as each can fit and perform optimally in different situations.
|
||||||
configurations:
|
If you need a simple in-memory session manager that can persist to disk then the `HashSessionManager` can be a good place to start.
|
||||||
|
If you need a session manager that can work in a clustered scenario with multiple instances of Jetty, then the JDBC session manager can be an excellent option.
|
||||||
|
Jetty also offers more niche session managers that leverage backends such as MongoDB, Inifinispan, or even Google's Cloud Data Store.
|
||||||
|
|
||||||
|
To modify the session characteristics of a web application, you can use the following parameters, applying them as in one of the example configurations:
|
||||||
|
|
||||||
[[using-init-parameters]]
|
[[using-init-parameters]]
|
||||||
==== Using Init Parameters
|
==== Using Init Parameters
|
||||||
|
@ -61,14 +65,12 @@ urls with calls to encodeURL(). False by default.
|
||||||
[[applying-init-parameters]]
|
[[applying-init-parameters]]
|
||||||
===== Applying Init Parameters
|
===== Applying Init Parameters
|
||||||
|
|
||||||
The following sections provide examples of how to apply the init
|
The following sections provide examples of how to apply the init parameters.
|
||||||
parameters.
|
|
||||||
|
|
||||||
[[context-parameter-example]]
|
[[context-parameter-example]]
|
||||||
====== Context Parameter Example
|
====== Context Parameter Example
|
||||||
|
|
||||||
You can set these parameters as context parameters in a web
|
You can set these parameters as context parameters in a web application's `WEB-INF/web.xml` file:
|
||||||
application's ` WEB-INF/web.xml` file:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -97,8 +99,7 @@ application's ` WEB-INF/web.xml` file:
|
||||||
[[web-application-examples]]
|
[[web-application-examples]]
|
||||||
====== Web Application Examples
|
====== Web Application Examples
|
||||||
|
|
||||||
You can configure init parameters on a web application, either in code,
|
You can configure init parameters on a web application, either in code, or in a Jetty context xml file equivalent:
|
||||||
or in a Jetty context xml file equivalent:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -125,8 +126,7 @@ or in a Jetty context xml file equivalent:
|
||||||
[[init-parameter-examples]]
|
[[init-parameter-examples]]
|
||||||
====== SessionManager Examples
|
====== SessionManager Examples
|
||||||
|
|
||||||
You can configure init parameters directly on a `SessionManager`
|
You can configure init parameters directly on a `SessionManager` instance, either in code or the equivalent in xml:
|
||||||
instance, either in code or the equivalent in xml:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -152,24 +152,16 @@ instance, either in code or the equivalent in xml:
|
||||||
|
|
||||||
==== Using Servlet 3.0 Session Configuration
|
==== Using Servlet 3.0 Session Configuration
|
||||||
|
|
||||||
With the advent of http://jcp.org/en/jsr/detail?id=315[Servlet
|
With the advent of http://jcp.org/en/jsr/detail?id=315[Servlet Specification 3.0] there are new APIs for configuring session handling characteristics.
|
||||||
Specification 3.0] there are new APIs for configuring session handling
|
What was achievable before only via Jetty-specific link:#session-init-params[init-parameters] can now be achieved in a container-agnostic manner either in code, or via `web.xml`.
|
||||||
characteristics. What was achievable before only via jetty-specific
|
|
||||||
link:#session-init-params[init-parameters] can now be achieved in a
|
|
||||||
container-agostic manner either in code, or via web.xml.
|
|
||||||
|
|
||||||
[[session-cookie-configuration]]
|
[[session-cookie-configuration]]
|
||||||
===== SessionCookieConfiguration
|
===== SessionCookieConfiguration
|
||||||
|
|
||||||
The
|
The http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html[javax.servlet.SessionCookieConfig] class can be used to set up session handling characteristics.
|
||||||
http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html[javax.servlet.SessionCookieConfig]
|
For full details, consult the http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html[javadoc].
|
||||||
class can be used to set up session handling characteristics. For full
|
|
||||||
details, consult the
|
|
||||||
http://docs.oracle.com/javaee/6/api/javax/servlet/SessionCookieConfig.html[javadoc].
|
|
||||||
|
|
||||||
Here's an example of how you use it: this is a ServletContextListener
|
Below is an example of this implementation: a `ServletContextListener` retrieves the `SessionCookieConfig` and sets up some new values when the context is being initialized:
|
||||||
that retrieves the SessionCookieConfig and sets up some new values for
|
|
||||||
it when the context is being initialized:
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -209,9 +201,7 @@ public class TestListener implements ServletContextListener
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
You can also use web.xml to configure the session handling
|
You can also use `web.xml` to configure the session handling characteristics instead: here's an example doing exactly the same as above instead of using code:
|
||||||
characteristics instead: here's an example, doing exactly the same as we
|
|
||||||
did above in code:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -240,14 +230,9 @@ did above in code:
|
||||||
[[session-tracking-modes]]
|
[[session-tracking-modes]]
|
||||||
===== SessionTrackingModes
|
===== SessionTrackingModes
|
||||||
|
|
||||||
In addition to the configuration of
|
In addition to the configuration of link:#session-cookie-configuration[session cookies], since Servlet 3.0 you can also use the http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html[javax.servlet.SessionTrackingMode] to configure session tracking.
|
||||||
link:#session-cookie-configuration[session cookies], since Servlet 3.0
|
|
||||||
you can also use the
|
|
||||||
http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html[javax.servlet.SessionTrackingMode]
|
|
||||||
to configure session tracking.
|
|
||||||
|
|
||||||
To determine what are the _default_ session tracking characteristics
|
To determine what are the _default_ session tracking characteristics used by the container, call:
|
||||||
used by the container, call:
|
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
|
@ -260,13 +245,12 @@ _default_ session tracking modes for Jetty are:
|
||||||
* http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html#COOKIE[SessionTrackingMode.COOKIE]
|
* http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html#COOKIE[SessionTrackingMode.COOKIE]
|
||||||
* http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html#URL[SessionTrackingMode.URL]
|
* http://docs.oracle.com/javaee/6/api/javax/servlet/SessionTrackingMode.html#URL[SessionTrackingMode.URL]
|
||||||
|
|
||||||
To see which session tracking modes are actually in effect for this
|
To see which session tracking modes are actually in effect for this Context, the following call returns a `java.util.Set` of `javax.servlet.SessionTrackingMode`:
|
||||||
Context, the following call returns a java.util.Set of
|
|
||||||
javax.servlet.SessionTrackingMode:
|
|
||||||
|
|
||||||
....
|
[source,java]
|
||||||
|
----
|
||||||
javax.servlet.SessionContext.getEffectiveSessionTrackingModes();
|
javax.servlet.SessionContext.getEffectiveSessionTrackingModes();
|
||||||
....
|
----
|
||||||
|
|
||||||
To change the session tracking modes, call:
|
To change the session tracking modes, call:
|
||||||
|
|
||||||
|
@ -275,7 +259,7 @@ To change the session tracking modes, call:
|
||||||
javax.servlet.SessionContext.setSessionTrackingModes(Set<SessionTrackingMode>);
|
javax.servlet.SessionContext.setSessionTrackingModes(Set<SessionTrackingMode>);
|
||||||
----
|
----
|
||||||
|
|
||||||
You may also set the tracking mode in web.xml, eg:
|
You may also set the tracking mode in `web.xml`, e.g.:
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
|
@ -17,21 +17,17 @@
|
||||||
[[using-persistent-sessions]]
|
[[using-persistent-sessions]]
|
||||||
=== Using Persistent Sessions
|
=== Using Persistent Sessions
|
||||||
|
|
||||||
It is sometimes useful to preserve existing Sessions across restarts of
|
It is sometimes useful to preserve existing Sessions across restarts of Jetty.
|
||||||
Jetty. The
|
The link:{JDURL}/org/eclipse/jetty/server/session/HashSessionManager.html[`HashSessionManager`] supports this feature.
|
||||||
link:{JDURL}/org/eclipse/jetty/server/session/HashSessionManager.html[`HashSessionManager`]
|
If you enable persistence, the `HashSessionManager` saves all existing, valid Sessions to disk before shutdown completes.
|
||||||
supports this feature. If you enable persistence, the
|
On restart, Jetty restores the saved Sessions.
|
||||||
`HashSessionManager` saves all existing, valid Sessions to disk before
|
|
||||||
shutdown completes. On restart, Jetty restores the saved Sessions.
|
|
||||||
|
|
||||||
[[enabling-persistence]]
|
[[enabling-persistence]]
|
||||||
==== Enabling Persistence
|
==== Enabling Persistence
|
||||||
|
|
||||||
A SessionManager does just what its name suggests–it manages the
|
A `SessionManager` does just what its name suggests – it manages the lifecycle and state of sessions on behalf of a webapp.
|
||||||
lifecycle and state of sessions on behalf of a webapp. Each webapp must
|
Each webapp must have its own unique `SessionManager` instance.
|
||||||
have its own unique SessionManager instance. Enabling persistence is as
|
Enabling persistence is as simple as configuring the `HashSessionManager` as the `SessionManager` for a webapp and telling it where on disk to store the sessions:
|
||||||
simple as configuring the `HashSessionManager` as the SessionManager for
|
|
||||||
a webapp and telling it where on disk to store the sessions:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -57,30 +53,25 @@ a webapp and telling it where on disk to store the sessions:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
____
|
The above uses an example of a xref:intro-jetty-configuration-contexts[context configuration file].
|
||||||
[TIP]
|
|
||||||
If you want to persist the sessions from multiple webapps:
|
|
||||||
1. Configure a separate HashSessionManager for each.
|
|
||||||
2. Assign to each a different value for 'storeDirectory'.
|
|
||||||
____
|
|
||||||
|
|
||||||
The above example uses a configuration file suitable for the
|
[TIP]
|
||||||
link:{JDURL}/org/eclipse/jetty/deploy/providers/ContextProvider.html[ContextProvider],
|
====
|
||||||
thus you might want to check out xref:using-context-provider[].
|
If you want to persist the sessions from multiple webapps:
|
||||||
|
|
||||||
|
1. Configure a separate `HashSessionManager` for each.
|
||||||
|
|
||||||
|
2. Assign to each a different value for `storeDirectory`.
|
||||||
|
====
|
||||||
|
|
||||||
[[delaying-session-load]]
|
[[delaying-session-load]]
|
||||||
==== Delaying Session Load
|
==== Delaying Session Load
|
||||||
|
|
||||||
You might need to ensure that the sessions are loaded AFTER the servlet
|
You might need to ensure that the sessions are loaded AFTER the servlet environment starts up (by default, Jetty eagerly loads sessions as part of the container startup, but before it initializes the servlet environment).
|
||||||
environment starts up (by default, Jetty eagerly loads sessions as part
|
For example, the Wicket web framework requires the servlet environment to be available when sessions are activated.
|
||||||
of the container startup, but before it initializes the servlet
|
|
||||||
environment). For example, the Wicket web framework requires the servlet
|
|
||||||
environment to be available when sessions are activated.
|
|
||||||
|
|
||||||
Using `SessionManager.setLazyLoad(true)`, Jetty loads sessions lazily
|
Using `SessionManager.setLazyLoad(true)`, Jetty loads sessions lazily either when it receives the first request for a session, or the session scavenger runs for the first time, whichever happens first.
|
||||||
either when it receives the first request for a session, or the session
|
Here's how the configuration looks in XML:
|
||||||
scavenger runs for the first time, whichever happens first. Here's how
|
|
||||||
the configuration looks in XML:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
@ -98,8 +89,7 @@ the configuration looks in XML:
|
||||||
[[enabling-persistence-for-jetty-maven-plugin]]
|
[[enabling-persistence-for-jetty-maven-plugin]]
|
||||||
==== Enabling Persistence for the Jetty Maven Plugin
|
==== Enabling Persistence for the Jetty Maven Plugin
|
||||||
|
|
||||||
To enable session persistence for the Jetty Maven plugin, set up the
|
To enable session persistence for the Jetty Maven plugin, set up the `HashSessionManager` in the configuration section like so:
|
||||||
HashSessionManager in the configuration section like so:
|
|
||||||
|
|
||||||
[source,xml]
|
[source,xml]
|
||||||
----
|
----
|
||||||
|
|
|
@ -55,7 +55,7 @@ Services::
|
||||||
==== Configuring Connectors
|
==== Configuring Connectors
|
||||||
|
|
||||||
A Jetty Server Connector is a network end point that accepts connections for one or more protocols which produce requests and/or messages for the Jetty server.
|
A Jetty Server Connector is a network end point that accepts connections for one or more protocols which produce requests and/or messages for the Jetty server.
|
||||||
In the standard Jetty server distribution, several provided configuration files add connectors to the server for various protocols and combinations of protocols: `http.ini`, `https.ini` and `jetty-spdy.xml`.
|
In the standard Jetty server distribution, several provided configuration files add connectors to the server for various protocols and combinations of protocols: `http.ini`, `https.ini` and `jetty-http2.xml`.
|
||||||
The configuration needed for connectors is typically:
|
The configuration needed for connectors is typically:
|
||||||
|
|
||||||
Port::
|
Port::
|
||||||
|
@ -67,10 +67,10 @@ Host::
|
||||||
Idle Timeout::
|
Idle Timeout::
|
||||||
The time in milliseconds that a connection can be idle before the connector takes action to close the connection.
|
The time in milliseconds that a connection can be idle before the connector takes action to close the connection.
|
||||||
HTTP Configuration::
|
HTTP Configuration::
|
||||||
Connector types that accept HTTP semantics (including HTTP, HTTPS and SPDY) are configured with a HttpConfiguration instance that contains common HTTP configuration that is independent of the specific wire protocol used.
|
Connector types that accept HTTP semantics (including HTTP, HTTPS and HTTP2) are configured with a `HttpConfiguration` instance that contains common HTTP configuration that is independent of the specific wire protocol used.
|
||||||
Because these values are often common to multiple connector types, the standard Jetty Server distribution creates a single HttpConfiguration in the `jetty.xml` file which is used via the XML Ref element in the specific connector files.
|
Because these values are often common to multiple connector types, the standard Jetty Server distribution creates a single `HttpConfiguration` in the `jetty.xml` file which is used via the XML Ref element in the specific connector files.
|
||||||
SSL Context Factory::
|
SSL Context Factory::
|
||||||
The TLS connector types (HTTPS and SPDY) configure an SSL Context Factory with the location of the server keystore and truststore for obtaining server certificates.
|
The TLS connector types (HTTPS and HTTP2) configure an SSL Context Factory with the location of the server keystore and truststore for obtaining server certificates.
|
||||||
|
|
||||||
|
|
||||||
____
|
____
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
<bundle-symbolic-name>${project.groupId}.alpn.tests</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.alpn.tests</bundle-symbolic-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>jdk8</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[1.8,1.9)</jdk>
|
||||||
|
</activation>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -43,11 +49,14 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
|
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar
|
||||||
|
</argLine>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
<bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>jdk8</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[1.8,1.9)</jdk>
|
||||||
|
</activation>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -43,11 +49,14 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
|
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar
|
||||||
|
</argLine>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -32,23 +32,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -29,6 +29,8 @@ import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.Condition;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.ArrayQueue;
|
import org.eclipse.jetty.util.ArrayQueue;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
@ -37,7 +39,6 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.thread.Locker;
|
import org.eclipse.jetty.util.thread.Locker;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/** ByteArrayEndPoint.
|
/** ByteArrayEndPoint.
|
||||||
*
|
*
|
||||||
|
@ -79,6 +80,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
};
|
};
|
||||||
|
|
||||||
private final Locker _locker = new Locker();
|
private final Locker _locker = new Locker();
|
||||||
|
private final Condition _hasOutput = _locker.newCondition();
|
||||||
private final Queue<ByteBuffer> _inQ = new ArrayQueue<>();
|
private final Queue<ByteBuffer> _inQ = new ArrayQueue<>();
|
||||||
private ByteBuffer _out;
|
private ByteBuffer _out;
|
||||||
private boolean _growOutput;
|
private boolean _growOutput;
|
||||||
|
@ -218,6 +220,7 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
_runFillable.run();
|
_runFillable.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
public void addInputAndExecute(ByteBuffer in)
|
public void addInputAndExecute(ByteBuffer in)
|
||||||
{
|
{
|
||||||
boolean fillable=false;
|
boolean fillable=false;
|
||||||
|
@ -258,9 +261,12 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
* @return Returns the out.
|
* @return Returns the out.
|
||||||
*/
|
*/
|
||||||
public ByteBuffer getOutput()
|
public ByteBuffer getOutput()
|
||||||
|
{
|
||||||
|
try(Locker.Lock lock = _locker.lock())
|
||||||
{
|
{
|
||||||
return _out;
|
return _out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -287,8 +293,36 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
*/
|
*/
|
||||||
public ByteBuffer takeOutput()
|
public ByteBuffer takeOutput()
|
||||||
{
|
{
|
||||||
ByteBuffer b=_out;
|
ByteBuffer b;
|
||||||
|
|
||||||
|
try(Locker.Lock lock = _locker.lock())
|
||||||
|
{
|
||||||
|
b=_out;
|
||||||
_out=BufferUtil.allocate(b.capacity());
|
_out=BufferUtil.allocate(b.capacity());
|
||||||
|
}
|
||||||
|
getWriteFlusher().completeWrite();
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/** Wait for some output
|
||||||
|
* @param time Time to wait
|
||||||
|
* @param unit Units for time to wait
|
||||||
|
* @return The buffer of output
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
public ByteBuffer waitForOutput(long time,TimeUnit unit) throws InterruptedException
|
||||||
|
{
|
||||||
|
ByteBuffer b;
|
||||||
|
|
||||||
|
try(Locker.Lock lock = _locker.lock())
|
||||||
|
{
|
||||||
|
if (BufferUtil.isEmpty(_out))
|
||||||
|
_hasOutput.await(time,unit);
|
||||||
|
|
||||||
|
b=_out;
|
||||||
|
_out=BufferUtil.allocate(b.capacity());
|
||||||
|
}
|
||||||
getWriteFlusher().completeWrite();
|
getWriteFlusher().completeWrite();
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
@ -318,8 +352,11 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
* @param out The out to set.
|
* @param out The out to set.
|
||||||
*/
|
*/
|
||||||
public void setOutput(ByteBuffer out)
|
public void setOutput(ByteBuffer out)
|
||||||
|
{
|
||||||
|
try(Locker.Lock lock = _locker.lock())
|
||||||
{
|
{
|
||||||
_out = out;
|
_out = out;
|
||||||
|
}
|
||||||
getWriteFlusher().completeWrite();
|
getWriteFlusher().completeWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,13 +421,15 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean flush(ByteBuffer... buffers) throws IOException
|
public boolean flush(ByteBuffer... buffers) throws IOException
|
||||||
|
{
|
||||||
|
boolean flushed=true;
|
||||||
|
try(Locker.Lock lock = _locker.lock())
|
||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
throw new IOException("CLOSED");
|
throw new IOException("CLOSED");
|
||||||
if (isOutputShutdown())
|
if (isOutputShutdown())
|
||||||
throw new IOException("OSHUT");
|
throw new IOException("OSHUT");
|
||||||
|
|
||||||
boolean flushed=true;
|
|
||||||
boolean idle=true;
|
boolean idle=true;
|
||||||
|
|
||||||
for (ByteBuffer b : buffers)
|
for (ByteBuffer b : buffers)
|
||||||
|
@ -419,7 +458,11 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!idle)
|
if (!idle)
|
||||||
|
{
|
||||||
notIdle();
|
notIdle();
|
||||||
|
_hasOutput.signalAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
return flushed;
|
return flushed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,8 +475,9 @@ public class ByteArrayEndPoint extends AbstractEndPoint
|
||||||
try(Locker.Lock lock = _locker.lock())
|
try(Locker.Lock lock = _locker.lock())
|
||||||
{
|
{
|
||||||
_inQ.clear();
|
_inQ.clear();
|
||||||
}
|
_hasOutput.signalAll();
|
||||||
BufferUtil.clear(_out);
|
BufferUtil.clear(_out);
|
||||||
|
}
|
||||||
super.reset();
|
super.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,8 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool.Bucket;
|
import org.eclipse.jetty.io.ByteBufferPool.Bucket;
|
||||||
import org.hamcrest.Matchers;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class ArrayByteBufferPoolTest
|
public class ArrayByteBufferPoolTest
|
||||||
|
|
|
@ -226,6 +226,7 @@ public class SelectChannelEndPointSslTest extends SelectChannelEndPointTest
|
||||||
filled=client.read(sslIn);
|
filled=client.read(sslIn);
|
||||||
Assert.assertEquals(-1,filled);
|
Assert.assertEquals(-1,filled);
|
||||||
|
|
||||||
|
Thread.sleep(100); // TODO This should not be needed
|
||||||
Assert.assertFalse(server.isOpen());
|
Assert.assertFalse(server.isOpen());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-plugin-plugin</artifactId>
|
<artifactId>maven-plugin-plugin</artifactId>
|
||||||
<version>3.4</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>exec-plugin-doc</id>
|
<id>exec-plugin-doc</id>
|
||||||
|
@ -96,9 +95,8 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
<version>2.1</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<dependencyLocationEnabled>false</dependencyLocationEnabled>
|
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
|
||||||
</configuration>
|
</configuration>
|
||||||
<reportSets>
|
<reportSets>
|
||||||
<reportSet>
|
<reportSet>
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-plugin-plugin</artifactId>
|
<artifactId>maven-plugin-plugin</artifactId>
|
||||||
<version>${pluginToolsVersion}</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>exec-plugin-doc</id>
|
<id>exec-plugin-doc</id>
|
||||||
|
@ -147,9 +146,8 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
<version>2.1</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<dependencyLocationEnabled>false</dependencyLocationEnabled>
|
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
|
||||||
</configuration>
|
</configuration>
|
||||||
<reportSets>
|
<reportSets>
|
||||||
<reportSet>
|
<reportSet>
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
<version>1.7</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>parse-version</id>
|
<id>parse-version</id>
|
||||||
|
|
|
@ -46,29 +46,6 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||||
<artifactId>jetty-osgi-project</artifactId>
|
<artifactId>jetty-osgi-project</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>jetty-osgi-boot-warurl</artifactId>
|
<artifactId>jetty-osgi-boot-warurl</artifactId>
|
||||||
|
@ -26,29 +25,6 @@
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -62,29 +62,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -56,29 +56,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -59,7 +59,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-eclipse-plugin</artifactId>
|
<artifactId>maven-eclipse-plugin</artifactId>
|
||||||
<version>2.8</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<manifest>prevent/overwriting/by/pointing/to/nonexisting/MANIFEST.MF</manifest>
|
<manifest>prevent/overwriting/by/pointing/to/nonexisting/MANIFEST.MF</manifest>
|
||||||
<pde>true</pde>
|
<pde>true</pde>
|
||||||
|
|
|
@ -53,29 +53,6 @@
|
||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
@ -86,7 +63,7 @@
|
||||||
<Bundle-Name>Jetty OSGi Test Context</Bundle-Name>
|
<Bundle-Name>Jetty OSGi Test Context</Bundle-Name>
|
||||||
<Bundle-Activator>com.acme.osgi.Activator</Bundle-Activator>
|
<Bundle-Activator>com.acme.osgi.Activator</Bundle-Activator>
|
||||||
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
||||||
<!-- disable the uses directive: jetty will accomodate pretty much any versions
|
<!-- disable the uses directive: jetty will accommodate pretty much any versions
|
||||||
of the packages it uses; no need to reflect some tight dependency determined at
|
of the packages it uses; no need to reflect some tight dependency determined at
|
||||||
compilation time. -->
|
compilation time. -->
|
||||||
<_nouses>true</_nouses>
|
<_nouses>true</_nouses>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||||
<artifactId>jetty-osgi-project</artifactId>
|
<artifactId>jetty-osgi-project</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>test-jetty-osgi-webapp</artifactId>
|
<artifactId>test-jetty-osgi-webapp</artifactId>
|
||||||
|
@ -31,12 +30,6 @@
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -46,29 +39,6 @@
|
||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>test-jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||||
<artifactId>jetty-osgi-project</artifactId>
|
<artifactId>jetty-osgi-project</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>test-jetty-osgi</artifactId>
|
<artifactId>test-jetty-osgi</artifactId>
|
||||||
|
@ -20,7 +19,6 @@
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Pax Exam Dependencies -->
|
<!-- Pax Exam Dependencies -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ops4j.pax.exam</groupId>
|
<groupId>org.ops4j.pax.exam</groupId>
|
||||||
<artifactId>pax-exam</artifactId>
|
<artifactId>pax-exam</artifactId>
|
||||||
|
@ -34,7 +32,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- use the forked container so we can pass it system properties eg for alpn -->
|
<!-- use the forked container so we can pass it system properties eg for alpn -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ops4j.pax.exam</groupId>
|
<groupId>org.ops4j.pax.exam</groupId>
|
||||||
|
@ -95,7 +92,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Jetty OSGi Deps -->
|
<!-- Jetty OSGi Deps -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||||
|
@ -334,7 +330,6 @@
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-plus</artifactId>
|
<artifactId>jetty-plus</artifactId>
|
||||||
|
@ -366,7 +361,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>test-mock-resources</artifactId>
|
<artifactId>test-mock-resources</artifactId>
|
||||||
|
@ -390,7 +384,14 @@
|
||||||
<artifactId>jetty-test-helper</artifactId>
|
<artifactId>jetty-test-helper</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>${slf4j-version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -401,19 +402,9 @@
|
||||||
<argLine>-Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar</argLine>
|
<argLine>-Dmortbay-alpn-boot=${settings.localRepository}/org/mortbay/jetty/alpn/alpn-boot/${alpn.version}/alpn-boot-${alpn.version}.jar</argLine>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>2.5.1</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.7</source>
|
|
||||||
<target>1.7</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.servicemix.tooling</groupId>
|
<groupId>org.apache.servicemix.tooling</groupId>
|
||||||
<artifactId>depends-maven-plugin</artifactId>
|
<artifactId>depends-maven-plugin</artifactId>
|
||||||
<version>1.2</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>generate-depends-file</id>
|
<id>generate-depends-file</id>
|
||||||
|
@ -454,4 +445,5 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.eclipse.jetty.client.HttpClient;
|
import org.eclipse.jetty.client.HttpClient;
|
||||||
|
@ -86,7 +87,6 @@ public class TestJettyOSGiBootWebAppAsService
|
||||||
return options.toArray(new Option[options.size()]);
|
return options.toArray(new Option[options.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static List<Option> configureJettyHomeAndPort(String jettySelectorFileName)
|
public static List<Option> configureJettyHomeAndPort(String jettySelectorFileName)
|
||||||
{
|
{
|
||||||
File etcFolder = new File("src/test/config/etc");
|
File etcFolder = new File("src/test/config/etc");
|
||||||
|
@ -126,8 +126,7 @@ public class TestJettyOSGiBootWebAppAsService
|
||||||
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
|
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Ignore
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testBundle() throws Exception
|
public void testBundle() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -154,5 +153,4 @@ public class TestJettyOSGiBootWebAppAsService
|
||||||
WebAppContext wac = (WebAppContext) bundleContext.getService(refs[0]);
|
WebAppContext wac = (WebAppContext) bundleContext.getService(refs[0]);
|
||||||
assertEquals("/acme", wac.getContextPath());
|
assertEquals("/acme", wac.getContextPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,14 @@ import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.http.HttpField;
|
||||||
|
import org.eclipse.jetty.http.HttpParser;
|
||||||
|
import org.eclipse.jetty.http.HttpVersion;
|
||||||
import org.eclipse.jetty.io.ByteArrayEndPoint;
|
import org.eclipse.jetty.io.ByteArrayEndPoint;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.io.Connection;
|
import org.eclipse.jetty.io.Connection;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
|
import org.eclipse.jetty.util.ByteArrayOutputStream2;
|
||||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
|
|
||||||
|
@ -76,7 +80,8 @@ public class LocalConnector extends AbstractConnector
|
||||||
* returned to the level it was before the requests.
|
* returned to the level it was before the requests.
|
||||||
* <p>
|
* <p>
|
||||||
* This methods waits until the connection is closed or
|
* This methods waits until the connection is closed or
|
||||||
* is idle for 1s before returning the responses.
|
* is idle for 5s before returning the responses.
|
||||||
|
* <p>Use {@link #getResponse(String)} for an alternative that does not wait for idle.
|
||||||
* @param requests the requests
|
* @param requests the requests
|
||||||
* @return the responses
|
* @return the responses
|
||||||
* @throws Exception if the requests fail
|
* @throws Exception if the requests fail
|
||||||
|
@ -92,6 +97,7 @@ public class LocalConnector extends AbstractConnector
|
||||||
* <p>
|
* <p>
|
||||||
* This methods waits until the connection is closed or
|
* This methods waits until the connection is closed or
|
||||||
* an idle period before returning the responses.
|
* an idle period before returning the responses.
|
||||||
|
* <p>Use {@link #getResponse(String)} for an alternative that does not wait for idle.
|
||||||
* @param requests the requests
|
* @param requests the requests
|
||||||
* @param idleFor The time the response stream must be idle for before returning
|
* @param idleFor The time the response stream must be idle for before returning
|
||||||
* @param units The units of idleFor
|
* @param units The units of idleFor
|
||||||
|
@ -109,7 +115,8 @@ public class LocalConnector extends AbstractConnector
|
||||||
* returned to the level it was before the requests.
|
* returned to the level it was before the requests.
|
||||||
* <p>
|
* <p>
|
||||||
* This methods waits until the connection is closed or
|
* This methods waits until the connection is closed or
|
||||||
* is idle for 1s before returning the responses.
|
* is idle for 5s before returning the responses.
|
||||||
|
* <p>Use {@link #getResponse(ByteBuffer)} for an alternative that does not wait for idle.
|
||||||
* @param requestsBuffer the requests
|
* @param requestsBuffer the requests
|
||||||
* @return the responses
|
* @return the responses
|
||||||
* @throws Exception if the requests fail
|
* @throws Exception if the requests fail
|
||||||
|
@ -147,7 +154,7 @@ public class LocalConnector extends AbstractConnector
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a request and return the EndPoint through which
|
* Execute a request and return the EndPoint through which
|
||||||
* responses can be received.
|
* multiple responses can be received or more input provided.
|
||||||
* @param rawRequest the request
|
* @param rawRequest the request
|
||||||
* @return the local endpoint
|
* @return the local endpoint
|
||||||
*/
|
*/
|
||||||
|
@ -181,9 +188,70 @@ public class LocalConnector extends AbstractConnector
|
||||||
connection.onOpen();
|
connection.onOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get a single response using a parser to search for the end of the message.
|
||||||
|
* @param requestsBuffer The request to send
|
||||||
|
* @return ByteBuffer containing response or null.
|
||||||
|
* @throws Exception If there is a problem
|
||||||
|
*/
|
||||||
|
public ByteBuffer getResponse(ByteBuffer requestsBuffer) throws Exception
|
||||||
|
{
|
||||||
|
return getResponse(requestsBuffer,false,10,TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a single response using a parser to search for the end of the message.
|
||||||
|
* @param requestsBuffer The request to send
|
||||||
|
* @param head True if the response is for a head request
|
||||||
|
* @param time The time to wait
|
||||||
|
* @param unit The units of the wait
|
||||||
|
* @return ByteBuffer containing response or null.
|
||||||
|
* @throws Exception If there is a problem
|
||||||
|
*/
|
||||||
|
public ByteBuffer getResponse(ByteBuffer requestsBuffer,boolean head, long time,TimeUnit unit) throws Exception
|
||||||
|
{
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("requests {}", BufferUtil.toUTF8String(requestsBuffer));
|
||||||
|
LocalEndPoint endp = executeRequest(requestsBuffer);
|
||||||
|
return endp.waitForResponse(head,time,unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get a single response using a parser to search for the end of the message.
|
||||||
|
* @param rawRequest The request to send
|
||||||
|
* @return ByteBuffer containing response or null.
|
||||||
|
* @throws Exception If there is a problem
|
||||||
|
*/
|
||||||
|
public String getResponse(String rawRequest) throws Exception
|
||||||
|
{
|
||||||
|
return getResponse(rawRequest,false,10,TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get a single response using a parser to search for the end of the message.
|
||||||
|
* @param rawRequest The request to send
|
||||||
|
* @param head True if the response is for a head request
|
||||||
|
* @param time The time to wait
|
||||||
|
* @param unit The units of the wait
|
||||||
|
* @return ByteBuffer containing response or null.
|
||||||
|
* @throws Exception If there is a problem
|
||||||
|
*/
|
||||||
|
public String getResponse(String rawRequest,boolean head, long time,TimeUnit unit) throws Exception
|
||||||
|
{
|
||||||
|
ByteBuffer requestsBuffer = BufferUtil.toBuffer(rawRequest, StandardCharsets.ISO_8859_1);
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("request {}", BufferUtil.toUTF8String(requestsBuffer));
|
||||||
|
LocalEndPoint endp = executeRequest(requestsBuffer);
|
||||||
|
|
||||||
|
return BufferUtil.toString(endp.waitForResponse(head,time,unit), StandardCharsets.ISO_8859_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Local EndPoint
|
||||||
|
*/
|
||||||
public class LocalEndPoint extends ByteArrayEndPoint
|
public class LocalEndPoint extends ByteArrayEndPoint
|
||||||
{
|
{
|
||||||
private final CountDownLatch _closed = new CountDownLatch(1);
|
private final CountDownLatch _closed = new CountDownLatch(1);
|
||||||
|
private ByteBuffer _responseData;
|
||||||
|
|
||||||
public LocalEndPoint()
|
public LocalEndPoint()
|
||||||
{
|
{
|
||||||
|
@ -253,5 +321,104 @@ public class LocalConnector extends AbstractConnector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Wait for a response using a parser to detect the end of message
|
||||||
|
* @param head
|
||||||
|
* @param time
|
||||||
|
* @param unit
|
||||||
|
* @return Buffer containing full response or null for EOF;
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public ByteBuffer waitForResponse(boolean head, long time,TimeUnit unit) throws Exception
|
||||||
|
{
|
||||||
|
HttpParser.ResponseHandler handler = new HttpParser.ResponseHandler()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void parsedHeader(HttpField field)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean messageComplete()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean headerComplete()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeaderCacheSize()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void earlyEOF()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean content(ByteBuffer item)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void badMessage(int status, String reason)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean startResponse(HttpVersion version, int status, String reason)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
HttpParser parser = new HttpParser(handler);
|
||||||
|
parser.setHeadResponse(head);
|
||||||
|
try(ByteArrayOutputStream2 bout = new ByteArrayOutputStream2();)
|
||||||
|
{
|
||||||
|
loop: while(true)
|
||||||
|
{
|
||||||
|
// read a chunk of response
|
||||||
|
ByteBuffer chunk = BufferUtil.hasContent(_responseData)
|
||||||
|
? _responseData : waitForOutput(time,unit);
|
||||||
|
_responseData=null;
|
||||||
|
|
||||||
|
// Parse the content of this chunk
|
||||||
|
while (BufferUtil.hasContent(chunk))
|
||||||
|
{
|
||||||
|
int pos=chunk.position();
|
||||||
|
boolean complete=parser.parseNext(chunk);
|
||||||
|
if (chunk.position()==pos)
|
||||||
|
{
|
||||||
|
// Nothing consumed
|
||||||
|
if (BufferUtil.isEmpty(chunk))
|
||||||
|
break;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all consumed bytes to the output stream
|
||||||
|
bout.write(chunk.array(),chunk.arrayOffset()+pos,chunk.position()-pos);
|
||||||
|
|
||||||
|
// If we are complete then break the outer loop
|
||||||
|
if (complete)
|
||||||
|
{
|
||||||
|
if (BufferUtil.hasContent(chunk))
|
||||||
|
_responseData=chunk;
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ByteBuffer.wrap(bout.getBuf(),0,bout.getCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,6 +223,7 @@ public class DumpHandler extends AbstractHandler
|
||||||
writer.flush();
|
writer.flush();
|
||||||
|
|
||||||
// commit now
|
// commit now
|
||||||
|
if (!Boolean.valueOf(request.getParameter("no-content-length")))
|
||||||
response.setContentLength(buf.size()+1000);
|
response.setContentLength(buf.size()+1000);
|
||||||
response.addHeader("Before-Flush",response.isCommitted()?"Committed???":"Not Committed");
|
response.addHeader("Before-Flush",response.isCommitted()?"Committed???":"Not Committed");
|
||||||
buf.writeTo(out);
|
buf.writeTo(out);
|
||||||
|
|
|
@ -330,6 +330,55 @@ public class HttpConnectionTest
|
||||||
assertTrue(postHeaders.equals(headHeaders));
|
assertTrue(postHeaders.equals(headHeaders));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHeadChunked() throws Exception
|
||||||
|
{
|
||||||
|
String responsePOST=connector.getResponse("POST /R1?no-content-length=true HTTP/1.1\r\n"+
|
||||||
|
"Host: localhost\r\n"+
|
||||||
|
"\r\n",false,1,TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
String responseHEAD=connector.getResponse("HEAD /R1?no-content-length=true HTTP/1.1\r\n"+
|
||||||
|
"Host: localhost\r\n"+
|
||||||
|
"\r\n",true,1,TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
String postLine;
|
||||||
|
boolean postDate=false;
|
||||||
|
Set<String> postHeaders = new HashSet<>();
|
||||||
|
try(BufferedReader in = new BufferedReader(new StringReader(responsePOST)))
|
||||||
|
{
|
||||||
|
postLine = in.readLine();
|
||||||
|
String line=in.readLine();
|
||||||
|
while (line!=null && line.length()>0)
|
||||||
|
{
|
||||||
|
if (line.startsWith("Date:"))
|
||||||
|
postDate=true;
|
||||||
|
else
|
||||||
|
postHeaders.add(line);
|
||||||
|
line=in.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String headLine;
|
||||||
|
boolean headDate=false;
|
||||||
|
Set<String> headHeaders = new HashSet<>();
|
||||||
|
try(BufferedReader in = new BufferedReader(new StringReader(responseHEAD)))
|
||||||
|
{
|
||||||
|
headLine = in.readLine();
|
||||||
|
String line=in.readLine();
|
||||||
|
while (line!=null && line.length()>0)
|
||||||
|
{
|
||||||
|
if (line.startsWith("Date:"))
|
||||||
|
headDate=true;
|
||||||
|
else
|
||||||
|
headHeaders.add(line);
|
||||||
|
line=in.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(postLine,equalTo(headLine));
|
||||||
|
assertThat(postDate,equalTo(headDate));
|
||||||
|
assertTrue(postHeaders.equals(headHeaders));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBadHostPort() throws Exception
|
public void testBadHostPort() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
|
@ -44,24 +45,26 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class LocalAsyncContextTest
|
public class LocalAsyncContextTest
|
||||||
{
|
{
|
||||||
protected Server _server = new Server();
|
protected Server _server;
|
||||||
protected SuspendHandler _handler = new SuspendHandler();
|
protected SuspendHandler _handler;
|
||||||
protected Connector _connector;
|
protected Connector _connector;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception
|
public void init() throws Exception
|
||||||
{
|
{
|
||||||
|
_server = new Server();
|
||||||
_connector = initConnector();
|
_connector = initConnector();
|
||||||
_server.setConnectors(new Connector[]{ _connector });
|
_server.setConnectors(new Connector[]{ _connector });
|
||||||
|
|
||||||
SessionHandler session = new SessionHandler();
|
SessionHandler session = new SessionHandler();
|
||||||
|
_handler = new SuspendHandler();
|
||||||
session.setHandler(_handler);
|
session.setHandler(_handler);
|
||||||
|
|
||||||
_server.setHandler(session);
|
_server.setHandler(session);
|
||||||
_server.start();
|
_server.start();
|
||||||
|
|
||||||
__completed.set(0);
|
__completed.set(null);
|
||||||
__completed1.set(0);
|
__completed1.set(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Connector initConnector()
|
protected Connector initConnector()
|
||||||
|
@ -86,8 +89,8 @@ public class LocalAsyncContextTest
|
||||||
_handler.setCompleteAfter(-1);
|
_handler.setCompleteAfter(-1);
|
||||||
response=process(null);
|
response=process(null);
|
||||||
check(response,"TIMEOUT");
|
check(response,"TIMEOUT");
|
||||||
spinAssertEquals(1,__completed::get);
|
spinAssertEquals(1,()->{return __completed.get()==null?0:1;});
|
||||||
spinAssertEquals(1,__completed1::get);
|
spinAssertEquals(1,()->{return __completed1.get()==null?0:1;});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -208,9 +211,6 @@ public class LocalAsyncContextTest
|
||||||
{
|
{
|
||||||
String response;
|
String response;
|
||||||
|
|
||||||
__completed.set(0);
|
|
||||||
__completed1.set(0);
|
|
||||||
|
|
||||||
_handler.setRead(0);
|
_handler.setRead(0);
|
||||||
_handler.setSuspendFor(1000);
|
_handler.setSuspendFor(1000);
|
||||||
_handler.setResumeAfter(100);
|
_handler.setResumeAfter(100);
|
||||||
|
@ -220,8 +220,8 @@ public class LocalAsyncContextTest
|
||||||
_handler.setCompleteAfter2(-1);
|
_handler.setCompleteAfter2(-1);
|
||||||
response=process(null);
|
response=process(null);
|
||||||
check(response,"STARTASYNC","DISPATCHED","startasync","STARTASYNC","DISPATCHED");
|
check(response,"STARTASYNC","DISPATCHED","startasync","STARTASYNC","DISPATCHED");
|
||||||
spinAssertEquals(1,__completed::get);
|
spinAssertEquals(1,()->{return __completed.get()==null?0:1;});
|
||||||
spinAssertEquals(0,__completed1::get);
|
spinAssertEquals(0,()->{return __completed1.get()==null?0:1;});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,22 +542,35 @@ public class LocalAsyncContextTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static AtomicInteger __completed = new AtomicInteger();
|
static AtomicReference<Throwable> __completed = new AtomicReference<>();
|
||||||
static AtomicInteger __completed1 = new AtomicInteger();
|
static AtomicReference<Throwable> __completed1 = new AtomicReference<>();
|
||||||
|
|
||||||
private static AsyncListener __asyncListener = new AsyncListener()
|
private static AsyncListener __asyncListener = new AsyncListener()
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(AsyncEvent event) throws IOException
|
public void onComplete(AsyncEvent event) throws IOException
|
||||||
{
|
{
|
||||||
__completed.incrementAndGet();
|
Throwable complete = new Throwable();
|
||||||
|
if (!__completed.compareAndSet(null,complete))
|
||||||
|
{
|
||||||
|
__completed.get().printStackTrace();
|
||||||
|
complete.printStackTrace();
|
||||||
|
__completed.set(null);
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(AsyncEvent event) throws IOException
|
public void onError(AsyncEvent event) throws IOException
|
||||||
{
|
{
|
||||||
__completed.incrementAndGet();
|
Throwable complete = new Throwable();
|
||||||
|
if (!__completed.compareAndSet(null,complete))
|
||||||
|
{
|
||||||
|
__completed.get().printStackTrace();
|
||||||
|
complete.printStackTrace();
|
||||||
|
__completed.set(null);
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -580,13 +593,29 @@ public class LocalAsyncContextTest
|
||||||
@Override
|
@Override
|
||||||
public void onComplete(AsyncEvent event) throws IOException
|
public void onComplete(AsyncEvent event) throws IOException
|
||||||
{
|
{
|
||||||
__completed1.incrementAndGet();
|
Throwable complete = new Throwable();
|
||||||
|
if (!__completed1.compareAndSet(null,complete))
|
||||||
|
{
|
||||||
|
__completed1.get().printStackTrace();
|
||||||
|
complete.printStackTrace();
|
||||||
|
__completed1.set(null);
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(AsyncEvent event) throws IOException
|
public void onError(AsyncEvent event) throws IOException
|
||||||
{
|
{
|
||||||
|
Throwable complete = new Throwable();
|
||||||
|
if (!__completed1.compareAndSet(null,complete))
|
||||||
|
{
|
||||||
|
__completed1.get().printStackTrace();
|
||||||
|
complete.printStackTrace();
|
||||||
|
__completed1.set(null);
|
||||||
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartAsync(AsyncEvent event) throws IOException
|
public void onStartAsync(AsyncEvent event) throws IOException
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,10 +22,12 @@ import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.Connection;
|
import org.eclipse.jetty.io.Connection;
|
||||||
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -92,6 +94,34 @@ public class LocalConnectorTest
|
||||||
assertThat(response,containsString("pathInfo=/R1"));
|
assertThat(response,containsString("pathInfo=/R1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneResponse_10() throws Exception
|
||||||
|
{
|
||||||
|
String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n\r\n");
|
||||||
|
assertThat(response,containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response,containsString("pathInfo=/R1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneResponse_10_keep_alive() throws Exception
|
||||||
|
{
|
||||||
|
String response=_connector.getResponse("GET /R1 HTTP/1.0\r\n" +
|
||||||
|
"Connection: keep-alive\r\n" +
|
||||||
|
"\r\n");
|
||||||
|
assertThat(response,containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response,containsString("pathInfo=/R1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneResponse_11() throws Exception
|
||||||
|
{
|
||||||
|
String response=_connector.getResponse("GET /R1 HTTP/1.1\r\n" +
|
||||||
|
"Host: localhost\r\n" +
|
||||||
|
"\r\n");
|
||||||
|
assertThat(response,containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response,containsString("pathInfo=/R1"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStopStart() throws Exception
|
public void testStopStart() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -125,6 +155,27 @@ public class LocalConnectorTest
|
||||||
assertThat(response,containsString("pathInfo=/R2"));
|
assertThat(response,containsString("pathInfo=/R2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTwoGETsParsed() throws Exception
|
||||||
|
{
|
||||||
|
LocalConnector.LocalEndPoint endp = _connector.executeRequest(
|
||||||
|
"GET /R1 HTTP/1.1\r\n"+
|
||||||
|
"Host: localhost\r\n"+
|
||||||
|
"\r\n"+
|
||||||
|
"GET /R2 HTTP/1.1\r\n"+
|
||||||
|
"Host: localhost\r\n"+
|
||||||
|
"\r\n");
|
||||||
|
|
||||||
|
String response = BufferUtil.toString(endp.waitForResponse(false,10,TimeUnit.SECONDS),StandardCharsets.ISO_8859_1);
|
||||||
|
assertThat(response,containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response,containsString("pathInfo=/R1"));
|
||||||
|
|
||||||
|
response = BufferUtil.toString(endp.waitForResponse(false,10,TimeUnit.SECONDS),StandardCharsets.ISO_8859_1);
|
||||||
|
assertThat(response,containsString("HTTP/1.1 200 OK"));
|
||||||
|
assertThat(response,containsString("pathInfo=/R2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManyGETs() throws Exception
|
public void testManyGETs() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<minimizeJar>true</minimizeJar>
|
<minimizeJar>true</minimizeJar>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
|
|
|
@ -125,7 +125,7 @@ public class SharedBlockingCallback
|
||||||
/**
|
/**
|
||||||
* A Closeable Callback.
|
* A Closeable Callback.
|
||||||
* Uses the auto close mechanism to check block has been called OK.
|
* Uses the auto close mechanism to check block has been called OK.
|
||||||
* <p>Implements {@link Callback.NonBlocking} because calls to this
|
* <p>Implements {@link Callback} because calls to this
|
||||||
* callback do not blocak, rather they wakeup the thread that is blocked
|
* callback do not blocak, rather they wakeup the thread that is blocked
|
||||||
* in {@link #block()}
|
* in {@link #block()}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,15 +18,12 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.thread;
|
package org.eclipse.jetty.util.thread;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>This is a lock designed to protect VERY short sections of
|
* Convenience Lock Wrapper.
|
||||||
* critical code. Threads attempting to take the lock will wait
|
*
|
||||||
* until the lock is available, thus it is important that
|
|
||||||
* the code protected by this lock is extremely simple and non
|
|
||||||
* blocking.</p>
|
|
||||||
* <pre>
|
* <pre>
|
||||||
* try(SpinLock.Lock lock = locker.lock())
|
* try(SpinLock.Lock lock = locker.lock())
|
||||||
* {
|
* {
|
||||||
|
@ -36,76 +33,35 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||||
*/
|
*/
|
||||||
public class Locker
|
public class Locker
|
||||||
{
|
{
|
||||||
private static final boolean SPIN = Boolean.getBoolean(Locker.class.getName() + ".spin");
|
|
||||||
private static final Lock LOCKED = new Lock();
|
private static final Lock LOCKED = new Lock();
|
||||||
|
|
||||||
private final boolean _spin;
|
|
||||||
private final ReentrantLock _lock = new ReentrantLock();
|
private final ReentrantLock _lock = new ReentrantLock();
|
||||||
private final AtomicReference<Thread> _spinLockState = new AtomicReference<>(null);
|
|
||||||
private final Lock _unlock = new UnLock();
|
private final Lock _unlock = new UnLock();
|
||||||
|
|
||||||
public Locker()
|
public Locker()
|
||||||
{
|
{
|
||||||
this(SPIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Locker(boolean spin)
|
|
||||||
{
|
|
||||||
this._spin = spin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lock lock()
|
public Lock lock()
|
||||||
{
|
{
|
||||||
if (_spin)
|
if (_lock.isHeldByCurrentThread())
|
||||||
spinLock();
|
throw new IllegalStateException("Locker is not reentrant");
|
||||||
else
|
_lock.lock();
|
||||||
concLock();
|
|
||||||
return _unlock;
|
return _unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Lock lockIfNotHeld ()
|
public Lock lockIfNotHeld ()
|
||||||
{
|
{
|
||||||
if (_spin)
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
if (_lock.isHeldByCurrentThread())
|
if (_lock.isHeldByCurrentThread())
|
||||||
return LOCKED;
|
return LOCKED;
|
||||||
_lock.lock();
|
_lock.lock();
|
||||||
return _unlock;
|
return _unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spinLock()
|
|
||||||
{
|
|
||||||
Thread current = Thread.currentThread();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Using test-and-test-and-set for better performance.
|
|
||||||
Thread locker = _spinLockState.get();
|
|
||||||
if (locker != null || !_spinLockState.compareAndSet(null, current))
|
|
||||||
{
|
|
||||||
if (locker == current)
|
|
||||||
throw new IllegalStateException("Locker is not reentrant");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void concLock()
|
|
||||||
{
|
|
||||||
if (_lock.isHeldByCurrentThread())
|
|
||||||
throw new IllegalStateException("Locker is not reentrant");
|
|
||||||
_lock.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLocked()
|
public boolean isLocked()
|
||||||
{
|
{
|
||||||
if (_spin)
|
|
||||||
return _spinLockState.get() != null;
|
|
||||||
else
|
|
||||||
return _lock.isLocked();
|
return _lock.isLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Lock implements AutoCloseable
|
public static class Lock implements AutoCloseable
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,16 +70,17 @@ public class Locker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class UnLock extends Lock
|
public class UnLock extends Lock
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
if (_spin)
|
|
||||||
_spinLockState.set(null);
|
|
||||||
else
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Condition newCondition()
|
||||||
|
{
|
||||||
|
return _lock.newCondition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,38 +18,24 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.thread;
|
package org.eclipse.jetty.util.thread;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.junit.runners.Parameterized;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
|
||||||
public class LockerTest
|
public class LockerTest
|
||||||
{
|
{
|
||||||
@Parameterized.Parameters
|
public LockerTest()
|
||||||
public static Collection<Object[]> parameters()
|
|
||||||
{
|
{
|
||||||
return Arrays.asList(new Object[]{true}, new Object[]{false});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean spin;
|
|
||||||
|
|
||||||
public LockerTest(boolean spin)
|
|
||||||
{
|
|
||||||
this.spin = spin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLocked()
|
public void testLocked()
|
||||||
{
|
{
|
||||||
Locker lock = new Locker(spin);
|
Locker lock = new Locker();
|
||||||
assertFalse(lock.isLocked());
|
assertFalse(lock.isLocked());
|
||||||
|
|
||||||
try(Locker.Lock l = lock.lock())
|
try(Locker.Lock l = lock.lock())
|
||||||
|
@ -67,7 +53,7 @@ public class LockerTest
|
||||||
@Test
|
@Test
|
||||||
public void testLockedException()
|
public void testLockedException()
|
||||||
{
|
{
|
||||||
Locker lock = new Locker(spin);
|
Locker lock = new Locker();
|
||||||
assertFalse(lock.isLocked());
|
assertFalse(lock.isLocked());
|
||||||
|
|
||||||
try(Locker.Lock l = lock.lock())
|
try(Locker.Lock l = lock.lock())
|
||||||
|
@ -90,7 +76,7 @@ public class LockerTest
|
||||||
@Test
|
@Test
|
||||||
public void testContend() throws Exception
|
public void testContend() throws Exception
|
||||||
{
|
{
|
||||||
final Locker lock = new Locker(spin);
|
final Locker lock = new Locker();
|
||||||
|
|
||||||
final CountDownLatch held0 = new CountDownLatch(1);
|
final CountDownLatch held0 = new CountDownLatch(1);
|
||||||
final CountDownLatch hold0 = new CountDownLatch(1);
|
final CountDownLatch hold0 = new CountDownLatch(1);
|
||||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.jetty.server.handler.ContextHandler;
|
||||||
import org.eclipse.jetty.util.log.StacklessLogging;
|
import org.eclipse.jetty.util.log.StacklessLogging;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.jsr356.EchoHandler;
|
import org.eclipse.jetty.websocket.jsr356.EchoHandler;
|
||||||
import org.eclipse.jetty.websocket.jsr356.endpoints.JsrEndpointEventDriver;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -91,7 +90,7 @@ public class MisbehavingClassTest
|
||||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||||
EndpointRuntimeOnOpen socket = new EndpointRuntimeOnOpen();
|
EndpointRuntimeOnOpen socket = new EndpointRuntimeOnOpen();
|
||||||
|
|
||||||
try (StacklessLogging logging = new StacklessLogging(EndpointRuntimeOnOpen.class,JsrEndpointEventDriver.class,WebSocketSession.class))
|
try (StacklessLogging logging = new StacklessLogging(EndpointRuntimeOnOpen.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
// expecting ArrayIndexOutOfBoundsException during onOpen
|
// expecting ArrayIndexOutOfBoundsException during onOpen
|
||||||
Session session = container.connectToServer(socket,serverUri);
|
Session session = container.connectToServer(socket,serverUri);
|
||||||
|
@ -112,7 +111,7 @@ public class MisbehavingClassTest
|
||||||
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
|
||||||
AnnotatedRuntimeOnOpen socket = new AnnotatedRuntimeOnOpen();
|
AnnotatedRuntimeOnOpen socket = new AnnotatedRuntimeOnOpen();
|
||||||
|
|
||||||
try (StacklessLogging logging = new StacklessLogging(AnnotatedRuntimeOnOpen.class,WebSocketSession.class))
|
try (StacklessLogging logging = new StacklessLogging(AnnotatedRuntimeOnOpen.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
// expecting ArrayIndexOutOfBoundsException during onOpen
|
// expecting ArrayIndexOutOfBoundsException during onOpen
|
||||||
Session session = container.connectToServer(socket,serverUri);
|
Session session = container.connectToServer(socket,serverUri);
|
||||||
|
|
|
@ -88,6 +88,7 @@ public class OnPartialTest
|
||||||
@SuppressWarnings("resource")
|
@SuppressWarnings("resource")
|
||||||
JsrSession session = new JsrSession(container,id,requestURI,driver,connection);
|
JsrSession session = new JsrSession(container,id,requestURI,driver,connection);
|
||||||
session.setPolicy(policy);
|
session.setPolicy(policy);
|
||||||
|
session.start();
|
||||||
session.open();
|
session.open();
|
||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ org.eclipse.jetty.LEVEL=WARN
|
||||||
# org.eclipse.jetty.websocket.LEVEL=WARN
|
# org.eclipse.jetty.websocket.LEVEL=WARN
|
||||||
# org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.common.io.LEVEL=DEBUG
|
||||||
|
|
||||||
|
# org.eclipse.jetty.websocket.common.WebSocketSession.LEVEL=DEBUG
|
||||||
|
# org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG
|
||||||
### Show state changes on BrowserDebugTool
|
### Show state changes on BrowserDebugTool
|
||||||
# -- LEAVE THIS AT DEBUG LEVEL --
|
# -- LEAVE THIS AT DEBUG LEVEL --
|
||||||
org.eclipse.jetty.websocket.jsr356.server.browser.LEVEL=DEBUG
|
org.eclipse.jetty.websocket.jsr356.server.browser.LEVEL=DEBUG
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<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">
|
<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">
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>jetty-project</artifactId>
|
<artifactId>jetty-project</artifactId>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
@ -35,21 +37,13 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>clirr-maven-plugin</artifactId>
|
<artifactId>clirr-maven-plugin</artifactId>
|
||||||
<version>2.5</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compare-api</id>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>clirr</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<minSeverity>info</minSeverity>
|
<minSeverity>info</minSeverity>
|
||||||
<comparisonVersion>9.1.0.v20131115</comparisonVersion>
|
<comparisonVersion>9.1.0.v20131115</comparisonVersion>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.eclipse.jetty.websocket.api;
|
package org.eclipse.jetty.websocket.api;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
@ -161,6 +162,13 @@ public interface RemoteEndpoint
|
||||||
*/
|
*/
|
||||||
void setBatchMode(BatchMode mode);
|
void setBatchMode(BatchMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the InetSocketAddress for the established connection.
|
||||||
|
*
|
||||||
|
* @return the InetSocketAddress for the established connection. (or null, if the connection is no longer established)
|
||||||
|
*/
|
||||||
|
InetSocketAddress getInetSocketAddress();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes messages that may have been batched by the implementation.
|
* Flushes messages that may have been batched by the implementation.
|
||||||
*
|
*
|
||||||
|
|
|
@ -88,7 +88,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.0</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
<execution>
|
<execution>
|
||||||
<id>artifact-jars</id>
|
<id>artifact-jars</id>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>jar</goal>
|
|
||||||
<goal>test-jar</goal>
|
<goal>test-jar</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.websocket.common;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.api.BatchMode;
|
||||||
|
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
|
||||||
|
import org.eclipse.jetty.websocket.api.extensions.OutgoingFrames;
|
||||||
|
|
||||||
|
public interface RemoteEndpointFactory
|
||||||
|
{
|
||||||
|
RemoteEndpoint newRemoteEndpoint(LogicalConnection connection, OutgoingFrames outgoingFrames, BatchMode batchMode);
|
||||||
|
}
|
|
@ -216,9 +216,15 @@ public class WebSocketRemoteEndpoint implements RemoteEndpoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the InetSocketAddress for the established connection.
|
||||||
|
*
|
||||||
|
* @return the InetSocketAddress for the established connection. (or null, if the connection is no longer established)
|
||||||
|
*/
|
||||||
public InetSocketAddress getInetSocketAddress()
|
public InetSocketAddress getInetSocketAddress()
|
||||||
{
|
{
|
||||||
|
if(connection == null)
|
||||||
|
return null;
|
||||||
return connection.getRemoteAddress();
|
return connection.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,11 @@ import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
|
@ -59,7 +61,7 @@ import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketSessionScope;
|
||||||
|
|
||||||
@ManagedObject("A Jetty WebSocket Session")
|
@ManagedObject("A Jetty WebSocket Session")
|
||||||
public class WebSocketSession extends ContainerLifeCycle implements Session, WebSocketSessionScope, IncomingFrames, Connection.Listener, ConnectionStateListener
|
public class WebSocketSession extends ContainerLifeCycle implements Session, RemoteEndpointFactory, WebSocketSessionScope, IncomingFrames, Connection.Listener, ConnectionStateListener
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(WebSocketSession.class);
|
private static final Logger LOG = Log.getLogger(WebSocketSession.class);
|
||||||
private static final Logger LOG_OPEN = Log.getLogger(WebSocketSession.class.getName() + "_OPEN");
|
private static final Logger LOG_OPEN = Log.getLogger(WebSocketSession.class.getName() + "_OPEN");
|
||||||
|
@ -70,9 +72,10 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private ExtensionFactory extensionFactory;
|
private ExtensionFactory extensionFactory;
|
||||||
|
private RemoteEndpointFactory remoteEndpointFactory;
|
||||||
private String protocolVersion;
|
private String protocolVersion;
|
||||||
private Map<String, String[]> parameterMap = new HashMap<>();
|
private Map<String, String[]> parameterMap = new HashMap<>();
|
||||||
private WebSocketRemoteEndpoint remote;
|
private RemoteEndpoint remote;
|
||||||
private IncomingFrames incomingHandler;
|
private IncomingFrames incomingHandler;
|
||||||
private OutgoingFrames outgoingHandler;
|
private OutgoingFrames outgoingHandler;
|
||||||
private WebSocketPolicy policy;
|
private WebSocketPolicy policy;
|
||||||
|
@ -141,6 +144,16 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
||||||
if(LOG.isDebugEnabled())
|
if(LOG.isDebugEnabled())
|
||||||
LOG.debug("starting - {}",this);
|
LOG.debug("starting - {}",this);
|
||||||
|
|
||||||
|
Iterator<RemoteEndpointFactory> iter = ServiceLoader.load(RemoteEndpointFactory.class).iterator();
|
||||||
|
if (iter.hasNext())
|
||||||
|
remoteEndpointFactory = iter.next();
|
||||||
|
|
||||||
|
if (remoteEndpointFactory == null)
|
||||||
|
remoteEndpointFactory = this;
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled())
|
||||||
|
LOG.debug("Using RemoteEndpointFactory: {}", remoteEndpointFactory);
|
||||||
|
|
||||||
super.doStart();
|
super.doStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +470,11 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WebSocketRemoteEndpoint newRemoteEndpoint(LogicalConnection connection, OutgoingFrames outgoingFrames, BatchMode batchMode)
|
||||||
|
{
|
||||||
|
return new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open/Activate the session
|
* Open/Activate the session
|
||||||
*/
|
*/
|
||||||
|
@ -477,7 +495,7 @@ public class WebSocketSession extends ContainerLifeCycle implements Session, Web
|
||||||
connection.getIOState().onConnected();
|
connection.getIOState().onConnected();
|
||||||
|
|
||||||
// Connect remote
|
// Connect remote
|
||||||
remote = new WebSocketRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
remote = remoteEndpointFactory.newRemoteEndpoint(connection,outgoingHandler,getBatchMode());
|
||||||
if(LOG_OPEN.isDebugEnabled())
|
if(LOG_OPEN.isDebugEnabled())
|
||||||
LOG_OPEN.debug("[{}] {}.open() remote={}",policy.getBehavior(),this.getClass().getSimpleName(),remote);
|
LOG_OPEN.debug("[{}] {}.open() remote={}",policy.getBehavior(),this.getClass().getSimpleName(),remote);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
import org.eclipse.jetty.websocket.common.frames.BinaryFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.PingFrame;
|
import org.eclipse.jetty.websocket.common.frames.PingFrame;
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.io.CloseableLocalWebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession;
|
import org.eclipse.jetty.websocket.common.io.LocalWebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
|
@ -67,12 +68,12 @@ public class EventDriverTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAdapter_ConnectClose() throws IOException
|
public void testAdapter_ConnectClose() throws Exception
|
||||||
{
|
{
|
||||||
AdapterConnectCloseSocket socket = new AdapterConnectCloseSocket();
|
AdapterConnectCloseSocket socket = new AdapterConnectCloseSocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.open();
|
conn.open();
|
||||||
driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame());
|
driver.incomingFrame(new CloseInfo(StatusCode.NORMAL).asFrame());
|
||||||
|
@ -84,12 +85,12 @@ public class EventDriverTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAnnotated_ByteArray() throws IOException
|
public void testAnnotated_ByteArray() throws Exception
|
||||||
{
|
{
|
||||||
AnnotatedBinaryArraySocket socket = new AnnotatedBinaryArraySocket();
|
AnnotatedBinaryArraySocket socket = new AnnotatedBinaryArraySocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.open();
|
conn.open();
|
||||||
driver.incomingFrame(makeBinaryFrame("Hello World",true));
|
driver.incomingFrame(makeBinaryFrame("Hello World",true));
|
||||||
|
@ -103,12 +104,12 @@ public class EventDriverTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAnnotated_Error() throws IOException
|
public void testAnnotated_Error() throws Exception
|
||||||
{
|
{
|
||||||
AnnotatedTextSocket socket = new AnnotatedTextSocket();
|
AnnotatedTextSocket socket = new AnnotatedTextSocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.open();
|
conn.open();
|
||||||
driver.incomingError(new WebSocketException("oof"));
|
driver.incomingError(new WebSocketException("oof"));
|
||||||
|
@ -122,12 +123,12 @@ public class EventDriverTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAnnotated_Frames() throws IOException
|
public void testAnnotated_Frames() throws Exception
|
||||||
{
|
{
|
||||||
AnnotatedFramesSocket socket = new AnnotatedFramesSocket();
|
AnnotatedFramesSocket socket = new AnnotatedFramesSocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.open();
|
conn.open();
|
||||||
driver.incomingFrame(new PingFrame().setPayload("PING"));
|
driver.incomingFrame(new PingFrame().setPayload("PING"));
|
||||||
|
@ -151,7 +152,7 @@ public class EventDriverTest
|
||||||
AnnotatedBinaryStreamSocket socket = new AnnotatedBinaryStreamSocket();
|
AnnotatedBinaryStreamSocket socket = new AnnotatedBinaryStreamSocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.open();
|
conn.open();
|
||||||
driver.incomingFrame(makeBinaryFrame("Hello World",true));
|
driver.incomingFrame(makeBinaryFrame("Hello World",true));
|
||||||
|
@ -170,7 +171,7 @@ public class EventDriverTest
|
||||||
ListenerBasicSocket socket = new ListenerBasicSocket();
|
ListenerBasicSocket socket = new ListenerBasicSocket();
|
||||||
EventDriver driver = wrap(socket);
|
EventDriver driver = wrap(socket);
|
||||||
|
|
||||||
try (LocalWebSocketSession conn = new LocalWebSocketSession(container,testname,driver))
|
try (LocalWebSocketSession conn = new CloseableLocalWebSocketSession(container,testname,driver))
|
||||||
{
|
{
|
||||||
conn.start();
|
conn.start();
|
||||||
conn.open();
|
conn.open();
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.websocket.common.io;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.websocket.common.events.EventDriver;
|
||||||
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
|
import org.junit.rules.TestName;
|
||||||
|
|
||||||
|
public class CloseableLocalWebSocketSession extends LocalWebSocketSession implements AutoCloseable
|
||||||
|
{
|
||||||
|
public CloseableLocalWebSocketSession(WebSocketContainerScope containerScope, TestName testname, EventDriver driver)
|
||||||
|
{
|
||||||
|
super(containerScope, testname, driver);
|
||||||
|
// LifeCycle start
|
||||||
|
try
|
||||||
|
{
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
// WebSocketSession.close();
|
||||||
|
super.close();
|
||||||
|
|
||||||
|
// LifeCycle Stop
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,13 +61,14 @@ public class MessageOutputStreamTest
|
||||||
private LocalWebSocketSession session;
|
private LocalWebSocketSession session;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void closeSession()
|
public void closeSession() throws Exception
|
||||||
{
|
{
|
||||||
session.close();
|
session.close();
|
||||||
|
session.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupSession()
|
public void setupSession() throws Exception
|
||||||
{
|
{
|
||||||
policy = WebSocketPolicy.newServerPolicy();
|
policy = WebSocketPolicy.newServerPolicy();
|
||||||
policy.setInputBufferSize(1024);
|
policy.setInputBufferSize(1024);
|
||||||
|
@ -91,6 +92,8 @@ public class MessageOutputStreamTest
|
||||||
session.setPolicy(policy);
|
session.setPolicy(policy);
|
||||||
// talk to our remote socket
|
// talk to our remote socket
|
||||||
session.setOutgoingHandler(socketPipe);
|
session.setOutgoingHandler(socketPipe);
|
||||||
|
// start session
|
||||||
|
session.start();
|
||||||
// open connection
|
// open connection
|
||||||
session.open();
|
session.open();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,13 +59,14 @@ public class MessageWriterTest
|
||||||
private LocalWebSocketSession session;
|
private LocalWebSocketSession session;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void closeSession()
|
public void closeSession() throws Exception
|
||||||
{
|
{
|
||||||
session.close();
|
session.close();
|
||||||
|
session.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setupSession()
|
public void setupSession() throws Exception
|
||||||
{
|
{
|
||||||
policy = WebSocketPolicy.newServerPolicy();
|
policy = WebSocketPolicy.newServerPolicy();
|
||||||
policy.setInputBufferSize(1024);
|
policy.setInputBufferSize(1024);
|
||||||
|
@ -89,6 +90,8 @@ public class MessageWriterTest
|
||||||
session.setPolicy(policy);
|
session.setPolicy(policy);
|
||||||
// talk to our remote socket
|
// talk to our remote socket
|
||||||
session.setOutgoingHandler(socketPipe);
|
session.setOutgoingHandler(socketPipe);
|
||||||
|
// start session
|
||||||
|
session.start();
|
||||||
// open connection
|
// open connection
|
||||||
session.open();
|
session.open();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server;
|
package org.eclipse.jetty.websocket.server;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.Assert.*;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -38,7 +39,6 @@ import org.eclipse.jetty.websocket.common.CloseInfo;
|
||||||
import org.eclipse.jetty.websocket.common.OpCode;
|
import org.eclipse.jetty.websocket.common.OpCode;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
import org.eclipse.jetty.websocket.common.WebSocketSession;
|
||||||
import org.eclipse.jetty.websocket.common.events.AbstractEventDriver;
|
|
||||||
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
||||||
import org.eclipse.jetty.websocket.common.test.IBlockheadClient;
|
import org.eclipse.jetty.websocket.common.test.IBlockheadClient;
|
||||||
|
@ -257,7 +257,7 @@ public class WebSocketCloseTest
|
||||||
{
|
{
|
||||||
client.setProtocols("fastfail");
|
client.setProtocols("fastfail");
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
client.setTimeout(1,TimeUnit.SECONDS);
|
||||||
try (StacklessLogging scope = new StacklessLogging(AbstractEventDriver.class,WebSocketSession.class))
|
try (StacklessLogging scope = new StacklessLogging(FastFailSocket.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.connect();
|
client.connect();
|
||||||
client.sendStandardRequest();
|
client.sendStandardRequest();
|
||||||
|
|
|
@ -39,11 +39,7 @@ public class AnnotatedRuntimeOnConnectSocket
|
||||||
public void onWebSocketConnect(Session sess)
|
public void onWebSocketConnect(Session sess)
|
||||||
{
|
{
|
||||||
// Intentional runtime exception.
|
// Intentional runtime exception.
|
||||||
int[] arr = new int[5];
|
throw new RuntimeException("Intentional Exception from onWebSocketConnect");
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
arr[i] = 222;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnWebSocketClose
|
@OnWebSocketClose
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class ListenerRuntimeOnConnectSocket extends WebSocketAdapter
|
||||||
{
|
{
|
||||||
super.onWebSocketConnect(sess);
|
super.onWebSocketConnect(sess);
|
||||||
|
|
||||||
throw new ArrayIndexOutOfBoundsException("Intentional Exception");
|
throw new RuntimeException("Intentional Exception from onWebSocketConnect");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.server.misbehaving;
|
package org.eclipse.jetty.websocket.server.misbehaving;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.eclipse.jetty.toolchain.test.EventQueue;
|
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
|
@ -64,12 +67,12 @@ public class MisbehavingClassTest
|
||||||
@Test
|
@Test
|
||||||
public void testListenerRuntimeOnConnect() throws Exception
|
public void testListenerRuntimeOnConnect() throws Exception
|
||||||
{
|
{
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
|
try (IBlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
StacklessLogging scope = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("listener-runtime-connect");
|
client.setProtocols("listener-runtime-connect");
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
client.setTimeout(1,TimeUnit.SECONDS);
|
||||||
try (StacklessLogging scope = new StacklessLogging(ListenerRuntimeOnConnectSocket.class, WebSocketSession.class))
|
|
||||||
{
|
|
||||||
ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect;
|
ListenerRuntimeOnConnectSocket socket = badSocketsServlet.listenerRuntimeConnect;
|
||||||
socket.reset();
|
socket.reset();
|
||||||
|
|
||||||
|
@ -92,20 +95,19 @@ public class MisbehavingClassTest
|
||||||
// Validate errors
|
// Validate errors
|
||||||
assertThat("socket.onErrors",socket.errors.size(),is(1));
|
assertThat("socket.onErrors",socket.errors.size(),is(1));
|
||||||
Throwable cause = socket.errors.pop();
|
Throwable cause = socket.errors.pop();
|
||||||
assertThat("Error type",cause,instanceOf(ArrayIndexOutOfBoundsException.class));
|
assertThat("Error type",cause,instanceOf(RuntimeException.class));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAnnotatedRuntimeOnConnect() throws Exception
|
public void testAnnotatedRuntimeOnConnect() throws Exception
|
||||||
{
|
{
|
||||||
try (IBlockheadClient client = new BlockheadClient(server.getServerUri()))
|
try (IBlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class))
|
||||||
{
|
{
|
||||||
client.setProtocols("annotated-runtime-connect");
|
client.setProtocols("annotated-runtime-connect");
|
||||||
client.setTimeout(1,TimeUnit.SECONDS);
|
client.setTimeout(1,TimeUnit.SECONDS);
|
||||||
try (StacklessLogging scope = new StacklessLogging(AnnotatedRuntimeOnConnectSocket.class, WebSocketSession.class))
|
|
||||||
{
|
|
||||||
AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect;
|
AnnotatedRuntimeOnConnectSocket socket = badSocketsServlet.annotatedRuntimeConnect;
|
||||||
socket.reset();
|
socket.reset();
|
||||||
|
|
||||||
|
@ -128,8 +130,7 @@ public class MisbehavingClassTest
|
||||||
// Validate errors
|
// Validate errors
|
||||||
assertThat("socket.onErrors",socket.errors.size(),is(1));
|
assertThat("socket.onErrors",socket.errors.size(),is(1));
|
||||||
Throwable cause = socket.errors.pop();
|
Throwable cause = socket.errors.pop();
|
||||||
assertThat("Error type",cause,instanceOf(ArrayIndexOutOfBoundsException.class));
|
assertThat("Error type",cause,instanceOf(RuntimeException.class));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set
|
||||||
|
|
||||||
|
export PATH=$M3/bin:$PATH
|
||||||
|
|
||||||
|
mvn clean install -DskipTests
|
||||||
|
|
||||||
|
cd $MODULE
|
||||||
|
|
||||||
|
let count=0
|
||||||
|
|
||||||
|
while mvn $OPTS test -Dtest=$TESTNAME 2>&1 > target/lastbuild.log
|
||||||
|
do
|
||||||
|
now=`date`
|
||||||
|
echo "Test Run $count - $now"
|
||||||
|
let count=$count+1
|
||||||
|
done
|
|
@ -5,7 +5,6 @@
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-project</artifactId>
|
<artifactId>jetty-project</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>tests-parent</artifactId>
|
<artifactId>tests-parent</artifactId>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>tests-parent</artifactId>
|
<artifactId>tests-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>test-continuation</artifactId>
|
<artifactId>test-continuation</artifactId>
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
<bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.client.http</bundle-symbolic-name>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>jdk8</id>
|
||||||
|
<activation>
|
||||||
|
<jdk>[1.8,1.9)</jdk>
|
||||||
|
</activation>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -44,9 +50,17 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar</argLine>
|
<argLine>-Xbootclasspath/p:${project.build.directory}/alpn/alpn-boot-${alpn.version}.jar
|
||||||
|
</argLine>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
|
|
@ -82,7 +82,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-failsafe-plugin</artifactId>
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
<version>2.17</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
|
@ -95,7 +94,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
<version>1.7</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>start-jetty</id>
|
<id>start-jetty</id>
|
||||||
|
|
|
@ -37,12 +37,6 @@
|
||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>tests-parent</artifactId>
|
<artifactId>tests-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
@ -110,7 +109,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>appassembler-maven-plugin</artifactId>
|
<artifactId>appassembler-maven-plugin</artifactId>
|
||||||
<version>1.7</version>
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<platforms>
|
<platforms>
|
||||||
<platform>unix</platform>
|
<platform>unix</platform>
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>tests-parent</artifactId>
|
<artifactId>tests-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>test-webapps-parent</artifactId>
|
<artifactId>test-webapps-parent</artifactId>
|
||||||
<name>Jetty Tests :: WebApps :: Parent</name>
|
<name>Jetty Tests :: WebApps :: Parent</name>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>test-webapps-parent</artifactId>
|
<artifactId>test-webapps-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -81,7 +81,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>2.2-beta-3</version>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
|
@ -92,18 +91,11 @@
|
||||||
<descriptors>
|
<descriptors>
|
||||||
<descriptor>src/main/assembly/config.xml</descriptor>
|
<descriptor>src/main/assembly/config.xml</descriptor>
|
||||||
</descriptors>
|
</descriptors>
|
||||||
<!-- filters> <filter>src/filters/filter.properties</filter>
|
<!-- filters> <filter>src/filters/filter.properties</filter> </filters -->
|
||||||
</filters -->
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<groupId>org.eclipse.jetty.tests</groupId>
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
<artifactId>test-webapps-parent</artifactId>
|
<artifactId>test-webapps-parent</artifactId>
|
||||||
<version>9.4.0-SNAPSHOT</version>
|
<version>9.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -13,29 +13,6 @@
|
||||||
</properties>
|
</properties>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<verbose>false</verbose>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>artifact-jar</id>
|
|
||||||
<goals>
|
|
||||||
<goal>jar</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
|
|
@ -62,7 +62,6 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.felix</groupId>
|
<groupId>org.apache.felix</groupId>
|
||||||
<artifactId>maven-bundle-plugin</artifactId>
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
@ -93,7 +92,6 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
|
@ -141,24 +139,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
|
||||||
<version>2.2-beta-3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>single</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>${basedir}/src/main/assembly/config.xml</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin -->
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
|
@ -192,6 +172,7 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.transaction</groupId>
|
<groupId>javax.transaction</groupId>
|
||||||
|
|
Loading…
Reference in New Issue