diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml
index 43d7fd0fe03..070c76aa25a 100644
--- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/etc/sessions/gcloud/session-store.xml
@@ -14,7 +14,9 @@
-
+
+
+
diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod
index 9ee2a31f749..90856809b16 100644
--- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config-template/modules/session-store-gcloud.mod
@@ -33,6 +33,8 @@ etc/sessions/gcloud/session-store.xml
#jetty.session.gcloud.maxRetries=5
#jetty.session.gcloud.backoffMs=1000
#jetty.session.gcloud.namespace=
+#jetty.session.gcloud.host=
+#jetty.session.gcloud.projectId=
#jetty.session.gcloud.model.kind=GCloudSession
#jetty.session.gcloud.model.id=id
#jetty.session.gcloud.model.contextPath=contextPath
diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
index d120ff593ac..fd5fb1a8716 100644
--- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java
@@ -67,6 +67,8 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
protected EntityDataModel _model;
protected boolean _modelProvided;
private String _namespace = DEFAULT_NAMESPACE;
+ private String _host;
+ private String _projectId;
/**
* EntityDataModel
@@ -455,15 +457,49 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
return _maxRetries;
}
+ public void setHost(String host)
+ {
+ _host = host;
+ }
+
+ @ManagedAttribute(value = "gcloud host", readonly = true)
+ public String getHost()
+ {
+ return _host;
+ }
+
+ public void setProjectId(String projectId)
+ {
+ _projectId = projectId;
+ }
+
+ @ManagedAttribute(value = "gcloud project Id", readonly = true)
+ public String getProjectId()
+ {
+ return _projectId;
+ }
+
@Override
protected void doStart() throws Exception
{
if (!_dsProvided)
{
- if (!StringUtil.isBlank(getNamespace()))
- _datastore = DatastoreOptions.newBuilder().setNamespace(getNamespace()).build().getService();
+ boolean blankCustomnamespace = StringUtil.isBlank(getNamespace());
+ boolean blankCustomHost = StringUtil.isBlank(getHost());
+ boolean blankCustomProjectId = StringUtil.isBlank(getProjectId());
+ if (blankCustomnamespace && blankCustomHost && blankCustomProjectId)
+ _datastore = DatastoreOptions.getDefaultInstance().getService();
else
- _datastore = DatastoreOptions.getDefaultInstance().getService();
+ {
+ DatastoreOptions.Builder builder = DatastoreOptions.newBuilder();
+ if (!blankCustomnamespace)
+ builder.setNamespace(getNamespace());
+ if (!blankCustomHost)
+ builder.setHost(getHost());
+ if (!blankCustomProjectId)
+ builder.setProjectId(getProjectId());
+ _datastore = builder.build().getService();
+ }
}
if (_model == null)
diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java
index 716e18f9102..6875a334a4e 100644
--- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java
@@ -26,6 +26,8 @@ public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFacto
private int _maxRetries = GCloudSessionDataStore.DEFAULT_MAX_RETRIES;
private int _backoffMs = GCloudSessionDataStore.DEFAULT_BACKOFF_MS;
private GCloudSessionDataStore.EntityDataModel _model;
+ private String _host;
+ private String _projectId;
public GCloudSessionDataStore.EntityDataModel getEntityDataModel()
{
@@ -73,6 +75,26 @@ public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFacto
_namespace = namespace;
}
+ public void setHost(String host)
+ {
+ _host = host;
+ }
+
+ public String getHost()
+ {
+ return _host;
+ }
+
+ public void setProjectId(String projectId)
+ {
+ _projectId = projectId;
+ }
+
+ public String getProjectId()
+ {
+ return _projectId;
+ }
+
@Override
public SessionDataStore getSessionDataStore(SessionHandler handler) throws Exception
{
@@ -83,6 +105,8 @@ public class GCloudSessionDataStoreFactory extends AbstractSessionDataStoreFacto
ds.setNamespace(getNamespace());
ds.setSavePeriodSec(getSavePeriodSec());
ds.setEntityDataModel(getEntityDataModel());
+ ds.setHost(getHost());
+ ds.setProjectId(getProjectId());
return ds;
}
}
diff --git a/jetty-home/src/main/resources/modules/hawtio.mod b/jetty-home/src/main/resources/modules/hawtio.mod
index 2181a65259f..050c6265449 100644
--- a/jetty-home/src/main/resources/modules/hawtio.mod
+++ b/jetty-home/src/main/resources/modules/hawtio.mod
@@ -17,7 +17,7 @@ etc/hawtio.xml
[files]
etc/hawtio/
lib/hawtio/
-maven://io.hawt/hawtio-default/1.4.16|lib/hawtio/hawtio.war
+maven://io.hawt/hawtio-default/${hawtio.version}/war|lib/hawtio/hawtio.war
basehome:modules/hawtio/hawtio.xml|etc/hawtio.xml
[license]
@@ -26,6 +26,9 @@ http://hawt.io/
http://github.com/hawtio/hawtio
http://www.apache.org/licenses/LICENSE-2.0.html
+[ini]
+hawtio.version?=2.13.5
+
[ini-template]
## Hawt.io configuration
-Dhawtio.authenticationEnabled?=false
diff --git a/jetty-home/src/main/resources/modules/jminix.mod b/jetty-home/src/main/resources/modules/jminix.mod
index a52f9d5e50d..c3d6f7f71bb 100644
--- a/jetty-home/src/main/resources/modules/jminix.mod
+++ b/jetty-home/src/main/resources/modules/jminix.mod
@@ -9,8 +9,7 @@ Deploys the Jminix JMX Console within the server.
[depend]
stats
jmx
-jcl-api
-jcl-impl
+commons-logging
[xml]
etc/jminix.xml
diff --git a/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml b/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml
index 7fa442548a0..ebce2c69276 100644
--- a/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml
+++ b/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod
index e627553096a..cfa1a035495 100644
--- a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod
+++ b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod
@@ -29,4 +29,3 @@ http://www.apache.org/licenses/LICENSE-2.0.html
#jetty.session.infinispan.idleTimeout.seconds=0
#jetty.session.gracePeriod.seconds=3600
#jetty.session.savePeriod.seconds=0
-
diff --git a/pom.xml b/pom.xml
index 317cfa956c0..30de5fe3b53 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,6 +68,7 @@
false
5.5
2.2
+ 10.3.6
@@ -79,7 +80,7 @@
false
0
1.15.1
- 2.7.0
+ 2.7.0
@@ -1137,6 +1138,11 @@
pom
import
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ ${mariadb.version}
+
net.java.dev.jna
jna
diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml
index 107ba0f26e5..304f6da8356 100644
--- a/tests/test-distribution/pom.xml
+++ b/tests/test-distribution/pom.xml
@@ -12,6 +12,7 @@
${project.groupId}.tests.distribution
-1
+ 10
@@ -180,6 +181,21 @@
testcontainers
test
+
+ org.testcontainers
+ mariadb
+ test
+
+
+ org.testcontainers
+ gcloud
+ test
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ test
+
@@ -192,7 +208,10 @@
${settings.localRepository}
${project.version}
${hazelcast.version}
+ ${mariadb.docker.version}
$(distribution.debug.port}
+ ${home.start.timeout}
+ ${mariadb.version}
diff --git a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/JettyHomeTester.java b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/JettyHomeTester.java
index ebbb5b43d0e..16ce3a2fbab 100644
--- a/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/JettyHomeTester.java
+++ b/tests/test-distribution/src/main/java/org/eclipse/jetty/tests/distribution/JettyHomeTester.java
@@ -180,6 +180,7 @@ public class JettyHomeTester
ProcessBuilder pbCmd = new ProcessBuilder(commands);
pbCmd.directory(jettyBaseDir);
+ pbCmd.environment().putAll(config.env);
Process process = pbCmd.start();
return new Run(config, process);
@@ -393,6 +394,7 @@ public class JettyHomeTester
private String jettyVersion;
private String mavenLocalRepository = System.getProperty("mavenRepoPath", System.getProperty("user.home") + "/.m2/repository");
private List jvmArgs = new ArrayList<>();
+ private Map env = new HashMap<>();
public Path getJettyBase()
{
@@ -419,6 +421,11 @@ public class JettyHomeTester
return Collections.unmodifiableList(jvmArgs);
}
+ public Map getEnv()
+ {
+ return Collections.unmodifiableMap(env);
+ }
+
@Override
public String toString()
{
@@ -765,6 +772,16 @@ public class JettyHomeTester
return this;
}
+ /**
+ * @param env the env to add
+ * @return this Builder
+ */
+ public Builder env(Map env)
+ {
+ config.env = env;
+ return this;
+ }
+
/**
* @return an empty instance of Builder
*/
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractJettyHomeTest.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractJettyHomeTest.java
index 37468835f65..7f33ce80b3b 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractJettyHomeTest.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/AbstractJettyHomeTest.java
@@ -19,6 +19,7 @@ import java.nio.file.Path;
import java.util.function.Supplier;
import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.toolchain.test.FS;
@@ -68,4 +69,24 @@ public class AbstractJettyHomeTest
if (client != null)
client.stop();
}
+
+ protected class ResponseDetails implements Supplier
+ {
+ private final ContentResponse response;
+
+ public ResponseDetails(ContentResponse response)
+ {
+ this.response = response;
+ }
+
+ @Override
+ public String get()
+ {
+ StringBuilder ret = new StringBuilder();
+ ret.append(response.toString()).append(System.lineSeparator());
+ ret.append(response.getHeaders().toString()).append(System.lineSeparator());
+ ret.append(response.getContentAsString()).append(System.lineSeparator());
+ return ret.toString();
+ }
+ }
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
index ec5a06826bb..d1e0cde2501 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java
@@ -296,24 +296,4 @@ public class DemoModulesTests extends AbstractJettyHomeTest
}
}
}
-
- private class ResponseDetails implements Supplier
- {
- private final ContentResponse response;
-
- public ResponseDetails(ContentResponse response)
- {
- this.response = response;
- }
-
- @Override
- public String get()
- {
- StringBuilder ret = new StringBuilder();
- ret.append(response.toString()).append(System.lineSeparator());
- ret.append(response.getHeaders().toString()).append(System.lineSeparator());
- ret.append(response.getContentAsString()).append(System.lineSeparator());
- return ret.toString();
- }
- }
}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/ThirdPartyModulesTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/ThirdPartyModulesTests.java
new file mode 100644
index 00000000000..5c92ac5017e
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/ThirdPartyModulesTests.java
@@ -0,0 +1,181 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution;
+
+import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ThirdPartyModulesTests extends AbstractJettyHomeTest
+{
+ @Test
+ public void testHawtio() throws Exception
+ {
+ Path jettyBase = newTestJettyBaseDirectory();
+ String jettyVersion = System.getProperty("jettyVersion");
+ JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .jettyBase(jettyBase)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ int httpPort = distribution.freePort();
+
+ String[] argsConfig = {
+ "--approve-all-licenses",
+ "--add-modules=hawtio,http"
+ };
+
+ try (JettyHomeTester.Run runConfig = distribution.start(argsConfig))
+ {
+ assertTrue(runConfig.awaitFor(2, TimeUnit.MINUTES));
+ assertEquals(0, runConfig.getExitValue());
+
+ String[] argsStart = {
+ "jetty.http.port=" + httpPort
+ };
+
+ try (JettyHomeTester.Run runStart = distribution.start(argsStart))
+ {
+ assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + httpPort + "/hawtio");
+ assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response));
+ assertThat(response.getContentAsString(), containsString("Hawtio"));
+ }
+ }
+ }
+
+ @Test
+ public void testJAMon() throws Exception
+ {
+ Path jettyBase = newTestJettyBaseDirectory();
+ String jettyVersion = System.getProperty("jettyVersion");
+ JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .jettyBase(jettyBase)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ int httpPort = distribution.freePort();
+
+ String[] argsConfig = {
+ "--approve-all-licenses",
+ "--add-modules=jamon,http"
+ };
+
+ try (JettyHomeTester.Run runConfig = distribution.start(argsConfig))
+ {
+ assertTrue(runConfig.awaitFor(2, TimeUnit.MINUTES));
+ assertEquals(0, runConfig.getExitValue());
+
+ String[] argsStart = {
+ "jetty.http.port=" + httpPort
+ };
+
+ try (JettyHomeTester.Run runStart = distribution.start(argsStart))
+ {
+ assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + httpPort + "/jamon");
+ assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response));
+ assertThat(response.getContentAsString(), containsString("JAMon"));
+ }
+ }
+ }
+
+ @Test
+ public void testjminix() throws Exception
+ {
+ Path jettyBase = newTestJettyBaseDirectory();
+ String jettyVersion = System.getProperty("jettyVersion");
+ JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .jettyBase(jettyBase)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ int httpPort = distribution.freePort();
+
+ String[] argsConfig = {
+ "--approve-all-licenses",
+ "--add-modules=jminix,http,logging-jcl-capture"
+ };
+
+ try (JettyHomeTester.Run runConfig = distribution.start(argsConfig))
+ {
+ assertTrue(runConfig.awaitFor(2, TimeUnit.MINUTES));
+ assertEquals(0, runConfig.getExitValue());
+
+ String[] argsStart = {
+ "jetty.http.port=" + httpPort
+ };
+
+ try (JettyHomeTester.Run runStart = distribution.start(argsStart))
+ {
+ assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
+ }
+ }
+ }
+
+ @Test
+ public void testjolokia() throws Exception
+ {
+ Path jettyBase = newTestJettyBaseDirectory();
+ String jettyVersion = System.getProperty("jettyVersion");
+ JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .jettyBase(jettyBase)
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+
+ int httpPort = distribution.freePort();
+
+ String[] argsConfig = {
+ "--approve-all-licenses",
+ "--add-modules=jolokia,http"
+ };
+
+ try (JettyHomeTester.Run runConfig = distribution.start(argsConfig))
+ {
+ assertTrue(runConfig.awaitFor(2, TimeUnit.MINUTES));
+ assertEquals(0, runConfig.getExitValue());
+
+ String[] argsStart = {
+ "jetty.http.port=" + httpPort
+ };
+
+ try (JettyHomeTester.Run runStart = distribution.start(argsStart))
+ {
+ assertTrue(runStart.awaitConsoleLogsFor("Started Server@", 20, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + httpPort + "/jolokia");
+ assertEquals(HttpStatus.OK_200, response.getStatus(), new ResponseDetails(response));
+ assertThat(response.getContentAsString(), containsString("\"agentType\":\"servlet\""));
+ }
+ }
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java
new file mode 100644
index 00000000000..c35171cd5fa
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java
@@ -0,0 +1,136 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
+import org.eclipse.jetty.tests.distribution.JettyHomeTester;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public abstract class AbstractSessionDistributionTests extends AbstractJettyHomeTest
+{
+
+ private String jettyVersion = System.getProperty("jettyVersion");
+
+ protected JettyHomeTester jettyHomeTester;
+
+ private static final int START_TIMEOUT = Integer.getInteger("home.start.timeout", 10);
+
+ @BeforeEach
+ public void prepareJettyHomeTester() throws Exception
+ {
+
+ jettyHomeTester = JettyHomeTester.Builder.newInstance()
+ .jettyVersion(jettyVersion)
+ .env(env())
+ .mavenLocalRepository(System.getProperty("mavenRepoPath"))
+ .build();
+ }
+
+ @Test
+ public void stopRestartWebappTestSessionContentSaved() throws Exception
+ {
+ startExternalSessionStorage();
+
+ List args = new ArrayList<>(Arrays.asList(
+ "--create-startd",
+ "--approve-all-licenses",
+ "--add-module=resources,server,http,webapp,deploy,jmx,servlet,servlets," + getFirstStartExtraModules()
+ ));
+ args.addAll(getFirstStartExtraArgs());
+ String[] argsStart = args.toArray(new String[0]);
+
+ try (JettyHomeTester.Run run1 = jettyHomeTester.start(argsStart))
+ {
+ assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
+ assertEquals(0, run1.getExitValue());
+
+ File war = jettyHomeTester.resolveArtifact("org.eclipse.jetty.tests:test-simple-session-webapp:war:" + jettyVersion);
+ jettyHomeTester.installWarFile(war, "test");
+
+ int port = jettyHomeTester.freePort();
+ args = new ArrayList<>(Collections.singletonList("jetty.http.port=" + port));
+ args.addAll(getSecondStartExtraArgs());
+ argsStart = args.toArray(new String[0]);
+
+ try (JettyHomeTester.Run run2 = jettyHomeTester.start(argsStart))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started Server@", START_TIMEOUT, TimeUnit.SECONDS));
+
+ startHttpClient();
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/session?action=CREATE");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("SESSION CREATED"));
+
+ response = client.GET("http://localhost:" + port + "/test/session?action=READ");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
+ }
+
+ Path logFile = jettyHomeTester.getJettyBase().resolve("resources").resolve("jetty-logging.properties");
+ Files.deleteIfExists(logFile);
+ try (BufferedWriter writer = Files.newBufferedWriter(logFile, StandardCharsets.UTF_8, StandardOpenOption.CREATE))
+ {
+ writer.write("org.eclipse.jetty.server.session.LEVEL=DEBUG");
+ }
+
+ try (JettyHomeTester.Run run2 = jettyHomeTester.start(argsStart))
+ {
+ assertTrue(run2.awaitConsoleLogsFor("Started Server@", START_TIMEOUT, TimeUnit.SECONDS));
+
+ ContentResponse response = client.GET("http://localhost:" + port + "/test/session?action=READ");
+ assertEquals(HttpStatus.OK_200, response.getStatus());
+ assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
+ }
+ }
+
+ stopExternalSessionStorage();
+ }
+
+ public Map env()
+ {
+ return Collections.emptyMap();
+ }
+
+ public abstract List getFirstStartExtraArgs();
+
+ public abstract String getFirstStartExtraModules();
+
+ public abstract List getSecondStartExtraArgs();
+
+ public abstract void startExternalSessionStorage() throws Exception;
+
+ public abstract void stopExternalSessionStorage() throws Exception;
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionDistributionTests.java
new file mode 100644
index 00000000000..025bee15b69
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionDistributionTests.java
@@ -0,0 +1,55 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public class FileSessionDistributionTests extends AbstractSessionDistributionTests
+{
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ // no op
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ // no op
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-file";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionWithMemcacheDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionWithMemcacheDistributionTests.java
new file mode 100644
index 00000000000..70973d96415
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionWithMemcacheDistributionTests.java
@@ -0,0 +1,89 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+
+/**
+ *
+ */
+public class FileSessionWithMemcacheDistributionTests extends AbstractSessionDistributionTests
+{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FileSessionWithMemcacheDistributionTests.class);
+ private static final Logger MEMCACHED_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.memcached");
+
+ private GenericContainer memcached;
+
+ private String host;
+ private int port;
+
+ @Override
+ @BeforeEach
+ public void prepareJettyHomeTester() throws Exception
+ {
+ memcached =
+ new GenericContainer("memcached:" + System.getProperty("memcached.docker.version", "1.6.6"))
+ .withLogConsumer(new Slf4jLogConsumer(MEMCACHED_LOG));
+ memcached.start();
+ this.host = memcached.getContainerIpAddress();
+ this.port = memcached.getMappedPort(11211);
+ super.prepareJettyHomeTester();
+ }
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ // no op
+ }
+
+ @Override
+ public Map env()
+ {
+ return Map.of("MEMCACHE_PORT_11211_TCP_ADDR", host, "MEMCACHE_PORT_11211_TCP_PORT", Integer.toString(port));
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ memcached.stop();
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Collections.singletonList("session-data-cache=xmemcached");
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-file,session-store-cache";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Collections.singletonList("session-data-cache=xmemcached");
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/GCloudSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/GCloudSessionDistributionTests.java
new file mode 100644
index 00000000000..a7c4b1117a7
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/GCloudSessionDistributionTests.java
@@ -0,0 +1,111 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.DatastoreEmulatorContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ *
+ */
+public class GCloudSessionDistributionTests extends AbstractSessionDistributionTests
+{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GCloudSessionDistributionTests.class);
+ private static final Logger GCLOUD_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.gcloudLogs");
+
+ public DatastoreEmulatorContainer emulator =
+ new CustomDatastoreEmulatorContainer(DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:316.0.0-emulators"))
+ .withLogConsumer(new Slf4jLogConsumer(GCLOUD_LOG));
+
+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk");
+
+ private static final String CMD = "gcloud beta emulators datastore start --project test-project --host-port 0.0.0.0:8081 --consistency=1.0";
+ private static final int HTTP_PORT = 8081;
+
+ String host;
+
+ public static class CustomDatastoreEmulatorContainer extends DatastoreEmulatorContainer
+ {
+ public CustomDatastoreEmulatorContainer(DockerImageName dockerImageName)
+ {
+ super(dockerImageName);
+
+ dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
+
+ withExposedPorts(HTTP_PORT);
+ setWaitStrategy(Wait.forHttp("/").forStatusCode(200));
+ withCommand("/bin/sh", "-c", CMD);
+ }
+ }
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ emulator.start();
+
+ //work out if we're running locally or not: if not local, then the host passed to
+ //DatastoreOptions must be prefixed with a scheme
+ String endPoint = emulator.getEmulatorEndpoint();
+ InetAddress hostAddr = InetAddress.getByName(new URL("http://" + endPoint).getHost());
+ LOGGER.info("endPoint: {} ,hostAddr.isAnyLocalAddress(): {},hostAddr.isLoopbackAddress(): {}",
+ endPoint,
+ hostAddr.isAnyLocalAddress(),
+ hostAddr.isLoopbackAddress());
+ if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress())
+ host = endPoint;
+ else
+ host = "http://" + endPoint;
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ emulator.stop();
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.gcloud.host=" + host,
+ "jetty.session.gcloud.projectId=foobar"
+ );
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-gcloud";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.gcloud.host=" + host,
+ "jetty.session.gcloud.projectId=foobar"
+ );
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HazelcastSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
similarity index 65%
rename from tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HazelcastSessionDistributionTests.java
rename to tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
index 6fe937dd474..338391e766f 100644
--- a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/HazelcastSessionDistributionTests.java
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java
@@ -11,7 +11,7 @@
// ========================================================================
//
-package org.eclipse.jetty.tests.distribution;
+package org.eclipse.jetty.tests.distribution.session;
import java.io.File;
import java.io.OutputStream;
@@ -21,6 +21,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -28,8 +29,8 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.tests.distribution.JettyHomeTester;
import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.BindMode;
@@ -42,90 +43,67 @@ import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-public class HazelcastSessionDistributionTests extends AbstractJettyHomeTest
+/**
+ * This simulate the onlyClient option which means the JVM running Jetty is only an Hazelcast client and not part
+ * of the cluster
+ */
+public class HazelcastSessionDistributionTests extends AbstractSessionDistributionTests
{
- private static final Logger HAZELCAST_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.HazelcastLogs");
+ private static final Logger HAZELCAST_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.HazelcastLogs");
private static final Logger LOGGER = LoggerFactory.getLogger(HazelcastSessionDistributionTests.class);
+ private GenericContainer hazelcast = new GenericContainer("hazelcast/hazelcast:" + System.getProperty("hazelcast.version", "4.1"))
+ .withExposedPorts(5701)
+ .waitingFor(Wait.forListeningPort())
+ .withLogConsumer(new Slf4jLogConsumer(HAZELCAST_LOG));
- /**
- * This simulate the onlyClient option which means the JVM running Jetty is only an Hazelcast client and not part
- * of the cluster
- */
- @Test
- public void testHazelcastRemoteOnlyClient() throws Exception
+ private Path hazelcastJettyPath;
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
{
- try (GenericContainer hazelcast =
- new GenericContainer("hazelcast/hazelcast:" + System.getProperty("hazelcast.version", "4.1"))
- .withExposedPorts(5701)
- .waitingFor(Wait.forListeningPort())
- .withLogConsumer(new Slf4jLogConsumer(HAZELCAST_LOG)))
- {
- hazelcast.start();
- String hazelcastHost = hazelcast.getContainerIpAddress();
- int hazelcastPort = hazelcast.getMappedPort(5701);
+ hazelcast.start();
- LOGGER.info("hazelcast started on {}:{}", hazelcastHost, hazelcastPort);
+ String hazelcastHost = hazelcast.getContainerIpAddress();
+ int hazelcastPort = hazelcast.getMappedPort(5701);
- Map tokenValues = new HashMap<>();
- tokenValues.put("hazelcast_ip", hazelcastHost);
- tokenValues.put("hazelcast_port", Integer.toString(hazelcastPort));
- Path hazelcastJettyPath = Paths.get("target/hazelcast-client.xml");
- transformFileWithHostAndPort(Paths.get("src/test/resources/hazelcast-client.xml"),
- hazelcastJettyPath,
- tokenValues);
+ LOGGER.info("hazelcast started on {}:{}", hazelcastHost, hazelcastPort);
- String jettyVersion = System.getProperty("jettyVersion");
- JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
- .jettyVersion(jettyVersion)
- .mavenLocalRepository(System.getProperty("mavenRepoPath"))
- .build();
+ Map tokenValues = new HashMap<>();
+ tokenValues.put("hazelcast_ip", hazelcastHost);
+ tokenValues.put("hazelcast_port", Integer.toString(hazelcastPort));
+ this.hazelcastJettyPath = Paths.get("target/hazelcast-client.xml");
+ transformFileWithHostAndPort(Paths.get("src/test/resources/hazelcast-client.xml"),
+ hazelcastJettyPath,
+ tokenValues);
+ }
- String[] args1 = {
- "--create-startd",
- "--approve-all-licenses",
- "--add-to-start=resources,server,http,webapp,deploy,jmx,servlet,servlets,session-store-hazelcast-remote"
- };
- try (JettyHomeTester.Run run1 = distribution.start(args1))
- {
- assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
- assertEquals(0, run1.getExitValue());
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ hazelcast.stop();
+ }
- File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-session-webapp:war:" + jettyVersion);
- distribution.installWarFile(war, "test");
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Collections.emptyList();
+ }
- int port = distribution.freePort();
- String[] argsStart = {
- "jetty.http.port=" + port,
- "jetty.session.hazelcast.configurationLocation=" + hazelcastJettyPath.toAbsolutePath(),
- "jetty.session.hazelcast.onlyClient=true"
- };
- try (JettyHomeTester.Run run2 = distribution.start(argsStart))
- {
- assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-hazelcast-remote";
+ }
- startHttpClient();
- ContentResponse response = client.GET("http://localhost:" + port + "/test/session?action=CREATE");
- assertEquals(HttpStatus.OK_200, response.getStatus());
- assertThat(response.getContentAsString(), containsString("SESSION CREATED"));
-
- response = client.GET("http://localhost:" + port + "/test/session?action=READ");
- assertEquals(HttpStatus.OK_200, response.getStatus());
- assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
- }
-
- try (JettyHomeTester.Run run2 = distribution.start(argsStart))
- {
- assertTrue(run2.awaitConsoleLogsFor("Started Server@", 10, TimeUnit.SECONDS));
-
- ContentResponse response = client.GET("http://localhost:" + port + "/test/session?action=READ");
- assertEquals(HttpStatus.OK_200, response.getStatus());
- assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
- }
- }
-
- }
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.hazelcast.configurationLocation=" + hazelcastJettyPath.toAbsolutePath(),
+ "jetty.session.hazelcast.onlyClient=true"
+ );
}
@Disabled("not working see https://github.com/hazelcast/hazelcast/issues/18508")
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/InfinispanSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/InfinispanSessionDistributionTests.java
new file mode 100644
index 00000000000..917c181b972
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/InfinispanSessionDistributionTests.java
@@ -0,0 +1,116 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.jetty.util.IO;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.configuration.Configuration;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+
+/**
+ *
+ */
+public class InfinispanSessionDistributionTests extends AbstractSessionDistributionTests
+{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(InfinispanSessionDistributionTests.class);
+ private static final Logger INFINISPAN_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.infinispan");
+
+ private GenericContainer infinispan;
+
+ private String host;
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ String infinispanVersion = System.getProperty("infinispan.docker.image.version", "9.4.8.Final");
+ infinispan =
+ new GenericContainer(System.getProperty("infinispan.docker.image.name", "jboss/infinispan-server") +
+ ":" + infinispanVersion)
+ //.withEnv("APP_USER", "theuser")
+ //.withEnv("APP_PASS", "foobar")
+ .withEnv("MGMT_USER", "admin")
+ .withEnv("MGMT_PASS", "admin")
+ .withCommand("standalone")
+ .waitingFor(new LogMessageWaitStrategy()
+ .withRegEx(".*Infinispan Server.*started in.*\\s"))
+ .withExposedPorts(4712, 4713, 8088, 8089, 8443, 9990, 9993, 11211, 11222, 11223, 11224)
+ .withLogConsumer(new Slf4jLogConsumer(INFINISPAN_LOG));
+ infinispan.start();
+ String host = infinispan.getContainerIpAddress();
+ int port = infinispan.getMappedPort(11222);
+
+ Path resourcesDirectory = Path.of(jettyHomeTester.getJettyBase().toString(), "resources/");
+ if (Files.exists(resourcesDirectory))
+ {
+ IO.delete(resourcesDirectory.toFile());
+ }
+ Files.createDirectories(resourcesDirectory);
+ Properties properties = new Properties();
+ properties.put("infinispan.client.hotrod.server_list", host + ":" + port);
+ //properties.put("jetty.session.infinispan.clientIntelligence", "BASIC");
+
+ Path hotrod = Path.of(resourcesDirectory.toString(), "hotrod-client.properties");
+ Files.deleteIfExists(hotrod);
+ Files.createFile(hotrod);
+ try (Writer writer = Files.newBufferedWriter(hotrod))
+ {
+ properties.store(writer, null);
+ }
+
+ Configuration configuration = new ConfigurationBuilder().withProperties(properties)
+ .addServer().host(host).port(port).build();
+
+ RemoteCacheManager remoteCacheManager = new RemoteCacheManager(configuration);
+ remoteCacheManager.administration().getOrCreateCache("sessions", (String)null);
+
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ infinispan.stop();
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Arrays.asList();
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-infinispan-remote";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Arrays.asList();
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/JDBCSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/JDBCSessionDistributionTests.java
new file mode 100644
index 00000000000..580a34317c3
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/JDBCSessionDistributionTests.java
@@ -0,0 +1,107 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.MariaDBContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+
+/**
+ *
+ */
+public class JDBCSessionDistributionTests extends AbstractSessionDistributionTests
+{
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JDBCSessionDistributionTests.class);
+
+ private static final String MARIA_DB_USER = "beer";
+ private static final String MARIA_DB_PASSWORD = "pacific_ale";
+ private String jdbcUrl;
+ private String driverClassName;
+
+ private MariaDBContainer mariaDBContainer = new MariaDBContainer("mariadb:" + System.getProperty("mariadb.docker.version", "10.3.6"))
+ .withUsername(MARIA_DB_USER)
+ .withPassword(MARIA_DB_PASSWORD)
+ .withDatabaseName("sessions");
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ mariaDBContainer.start();
+ jdbcUrl = mariaDBContainer.getJdbcUrl() + "?user=" + MARIA_DB_USER +
+ "&password=" + MARIA_DB_PASSWORD;
+ driverClassName = mariaDBContainer.getDriverClassName();
+
+ // prepare mariadb driver mod file
+ String mariaDBVersion = System.getProperty("mariadb.version");
+ StringBuilder modFileContent = new StringBuilder();
+ modFileContent.append("[lib]").append(System.lineSeparator());
+ modFileContent.append("lib/mariadb-java-client-" + mariaDBVersion + ".jar").append(System.lineSeparator());
+ modFileContent.append("[files]").append(System.lineSeparator());
+ modFileContent.append("maven://org.mariadb.jdbc/mariadb-java-client/" + mariaDBVersion +
+ "|lib/mariadb-java-client-" + mariaDBVersion + ".jar")
+ .append(System.lineSeparator());
+
+ Path modulesDirectory = Path.of(jettyHomeTester.getJettyBase().toString(), "modules");
+ if (Files.notExists(modulesDirectory))
+ {
+ Files.createDirectories(modulesDirectory);
+ }
+ Path mariaDbModPath = Path.of(modulesDirectory.toString(), "mariadb-driver.mod");
+ Files.deleteIfExists(mariaDbModPath);
+ Files.createFile(mariaDbModPath);
+ LOGGER.info("create file modfile: {} with content {} ", mariaDbModPath, modFileContent);
+ Files.writeString(mariaDbModPath, modFileContent);
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ mariaDBContainer.stop();
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.jdbc.driverUrl=" + jdbcUrl,
+ "db-connection-type=driver",
+ "jetty.session.jdbc.driverClass=" + driverClassName
+ );
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-jdbc,mariadb-driver";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.jdbc.driverUrl=" + jdbcUrl,
+ "db-connection-type=driver",
+ "jetty.session.jdbc.driverClass=" + driverClassName
+ );
+ }
+
+}
diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/MongodbSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/MongodbSessionDistributionTests.java
new file mode 100644
index 00000000000..80558f61d3c
--- /dev/null
+++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/session/MongodbSessionDistributionTests.java
@@ -0,0 +1,79 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.tests.distribution.session;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
+
+/**
+ *
+ */
+public class MongodbSessionDistributionTests extends AbstractSessionDistributionTests
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(MongodbSessionDistributionTests.class);
+
+ private static final Logger MONGO_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.mongo");
+
+ final String imageName = "mongo:" + System.getProperty("mongo.docker.version", "2.2.7");
+ final GenericContainer mongoDBContainer =
+ new GenericContainer(imageName)
+ .withLogConsumer(new Slf4jLogConsumer(MONGO_LOG))
+ .waitingFor(new LogMessageWaitStrategy()
+ .withRegEx(".*waiting for connections.*"));
+ private String host;
+ private int port;
+
+ @Override
+ public void startExternalSessionStorage() throws Exception
+ {
+ mongoDBContainer.start();
+ host = mongoDBContainer.getHost();
+ port = mongoDBContainer.getMappedPort(27017);
+ }
+
+ @Override
+ public void stopExternalSessionStorage() throws Exception
+ {
+ mongoDBContainer.stop();
+ }
+
+ @Override
+ public List getFirstStartExtraArgs()
+ {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public String getFirstStartExtraModules()
+ {
+ return "session-store-mongo";
+ }
+
+ @Override
+ public List getSecondStartExtraArgs()
+ {
+ return Arrays.asList(
+ "jetty.session.mongo.host=" + host,
+ "jetty.session.mongo.port=" + port
+ );
+ }
+
+}
diff --git a/tests/test-loginservice/pom.xml b/tests/test-loginservice/pom.xml
index 959214680b5..a53fd881972 100644
--- a/tests/test-loginservice/pom.xml
+++ b/tests/test-loginservice/pom.xml
@@ -65,7 +65,7 @@
org.mariadb.jdbc
mariadb-java-client
- ${maria.version}
+ ${mariadb.version}
test
diff --git a/tests/test-sessions/test-jdbc-sessions/pom.xml b/tests/test-sessions/test-jdbc-sessions/pom.xml
index a38fab2cf2d..cb114b0ef0b 100644
--- a/tests/test-sessions/test-jdbc-sessions/pom.xml
+++ b/tests/test-sessions/test-jdbc-sessions/pom.xml
@@ -10,7 +10,6 @@
Jetty Tests :: Sessions :: JDBC
${project.groupId}.sessions.jdbc
- 10.3.6
@@ -91,7 +90,6 @@
org.mariadb.jdbc
mariadb-java-client
- ${maria.version}
test