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<String> 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<String, String> env() + { + return Collections.emptyMap(); + } + + public abstract List<String> getFirstStartExtraArgs(); + + public abstract String getFirstStartExtraModules(); + + public abstract List<String> 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<String> getFirstStartExtraArgs() + { + return Collections.emptyList(); + } + + @Override + public String getFirstStartExtraModules() + { + return "session-store-file"; + } + + @Override + public List<String> 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<String, String> 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<String> getFirstStartExtraArgs() + { + return Collections.singletonList("session-data-cache=xmemcached"); + } + + @Override + public String getFirstStartExtraModules() + { + return "session-store-file,session-store-cache"; + } + + @Override + public List<String> 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<String> 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<String> 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<String, String> 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<String, String> 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<String> 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<String> 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<String> getFirstStartExtraArgs() + { + return Arrays.asList(); + } + + @Override + public String getFirstStartExtraModules() + { + return "session-store-infinispan-remote"; + } + + @Override + public List<String> 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<String> 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<String> 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<String> getFirstStartExtraArgs() + { + return Collections.emptyList(); + } + + @Override + public String getFirstStartExtraModules() + { + return "session-store-mongo"; + } + + @Override + public List<String> 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 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>${maria.version}</version> + <version>${mariadb.version}</version> <scope>test</scope> </dependency> <dependency> 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 @@ <name>Jetty Tests :: Sessions :: JDBC</name> <properties> <bundle-symbolic-name>${project.groupId}.sessions.jdbc</bundle-symbolic-name> - <mariadb.docker.version>10.3.6</mariadb.docker.version> </properties> <build> <plugins> @@ -91,7 +90,6 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>${maria.version}</version> <scope>test</scope> </dependency> </dependencies>