Merge branch 'jetty-12.1.x' into experiment/jetty-12.1.x/delayedDispatch
This commit is contained in:
commit
cac0d62f51
|
@ -15,6 +15,9 @@ package org.eclipse.jetty.docs.programming;
|
|||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.VirtualThreadPool;
|
||||
|
@ -26,9 +29,26 @@ public class ArchitectureDocs
|
|||
{
|
||||
// tag::queuedVirtual[]
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
|
||||
// Simple, unlimited, virtual thread Executor.
|
||||
threadPool.setVirtualThreadsExecutor(Executors.newVirtualThreadPerTaskExecutor());
|
||||
|
||||
// Configurable, bounded, virtual thread executor (preferred).
|
||||
VirtualThreadPool virtualExecutor = new VirtualThreadPool();
|
||||
virtualExecutor.setMaxThreads(128);
|
||||
threadPool.setVirtualThreadsExecutor(virtualExecutor);
|
||||
|
||||
// For server-side usage.
|
||||
Server server = new Server(threadPool);
|
||||
|
||||
// Simple client-side usage.
|
||||
HttpClient client = new HttpClient();
|
||||
client.setExecutor(threadPool);
|
||||
|
||||
// Client-side usage with explicit HttpClientTransport.
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setExecutor(threadPool);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
// end::queuedVirtual[]
|
||||
}
|
||||
|
||||
|
@ -38,8 +58,21 @@ public class ArchitectureDocs
|
|||
VirtualThreadPool threadPool = new VirtualThreadPool();
|
||||
// Limit the max number of current virtual threads.
|
||||
threadPool.setMaxThreads(200);
|
||||
// Track, with details, virtual threads usage.
|
||||
threadPool.setTracking(true);
|
||||
threadPool.setDetailedDump(true);
|
||||
|
||||
// For server-side usage.
|
||||
Server server = new Server(threadPool);
|
||||
|
||||
// Simple client-side usage.
|
||||
HttpClient client = new HttpClient();
|
||||
client.setExecutor(threadPool);
|
||||
|
||||
// Client-side usage with explicit HttpClientTransport.
|
||||
ClientConnector clientConnector = new ClientConnector();
|
||||
clientConnector.setExecutor(threadPool);
|
||||
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
|
||||
// end::virtualVirtual[]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -714,7 +714,6 @@ See also the xref:server/index.adoc#threadpool[section about configuring the thr
|
|||
The `threadpool-all-virtual` module allows you to configure the server-wide thread pool, similarly to what you can do with the <<threadpool,`threadpool`>> Jetty module, so that all threads are virtual threads, introduced as an official feature since Java 21.
|
||||
|
||||
CAUTION: Only use this module if you are using Java 21 or later.
|
||||
If you are using Java 19 or Java 20, use the <<threadpool-virtual-preview,`threadpool-virtual-preview`>> Jetty module instead.
|
||||
|
||||
The module properties to configure the thread pool are:
|
||||
|
||||
|
@ -724,17 +723,7 @@ include::{jetty-home}/modules/threadpool-all-virtual.mod[tags=documentation]
|
|||
|
||||
The property `jetty.threadpool.maxThreads` limits, using a `Semaphore`, the number of current virtual threads in use.
|
||||
|
||||
Limiting the number of current virtual threads helps to limit resource usage in applications, especially in case of load spikes.
|
||||
When an unlimited number of virtual threads is allowed, the server might be brought down due to resource (typically memory) exhaustion.
|
||||
|
||||
[CAUTION]
|
||||
====
|
||||
Even when using virtual threads, Jetty uses non-blocking I/O, and dedicates a thread to each `java.nio.channels.Selector` to perform the `Selector.select()` operation.
|
||||
|
||||
Currently (up to Java 22), calling `Selector.select()` from a virtual thread pins the carrier thread.
|
||||
|
||||
When using the `threadpool-all-virtual` Jetty module, if you have `N` selectors, then `N` carrier threads will be pinned by the virtual threads calling `Selector.select()`, possibly making your system less efficient, and at worst locking up the entire system if there are no carrier threads available to run virtual threads.
|
||||
====
|
||||
Please refer to the xref:programming-guide:arch/threads.adoc#thread-pool-virtual-threads[virtual threads section] of the Jetty Threading Architecture for more information about virtual threads and their pitfalls.
|
||||
|
||||
[[threadpool-virtual]]
|
||||
== Module `threadpool-virtual`
|
||||
|
|
|
@ -269,6 +269,35 @@ Defaulting the number of reserved threads to zero ensures that the <<execution-s
|
|||
include::code:example$src/main/java/org/eclipse/jetty/docs/programming/ArchitectureDocs.java[tags=virtualVirtual]
|
||||
----
|
||||
|
||||
Despite the name, `VirtualThreadPool` does not pool virtual threads, but allows you to impose a limit on the maximum number of current virtual threads, in order to limit resource consumption.
|
||||
Despite the name, `VirtualThreadPool` does not pool virtual threads, but allows you to impose a limit on the maximum number of current virtual threads, using a `Semaphore`.
|
||||
|
||||
Furthermore, you can configure it to track virtual threads so that a xref:troubleshooting/component-dump.adoc[Jetty component dump] will show all virtual threads, including those that are unmounted.
|
||||
Limiting the number of current virtual threads helps to limit resource usage in applications, especially in case of load spikes.
|
||||
When an unlimited number of virtual threads is allowed, the server might be brought down due to resource (typically memory) exhaustion.
|
||||
|
||||
Furthermore, you can configure it to track virtual threads so that a xref:troubleshooting/component-dump.adoc[Jetty component dump] will show all virtual threads currently in use, including those that are unmounted.
|
||||
|
||||
[[thread-pool-virtual-threads-pinning]]
|
||||
==== Virtual Threads Pinning
|
||||
|
||||
Even when using virtual threads, Jetty uses non-blocking I/O, and dedicates a thread to each `java.nio.channels.Selector` to perform the `Selector.select()` operation.
|
||||
|
||||
Currently (up to Java 22), calling `Selector.select()` from a virtual thread *pins* the carrier thread.
|
||||
|
||||
If you configure a server-side `Connector`, or Jetty's `HttpClient` with `N` selectors, then `N` carrier threads will be pinned by the virtual threads calling `Selector.select()`.
|
||||
|
||||
If you have less than `N` CPU cores in your system, then by default all carriers will be pinned in the `Selector.select()` call, leaving no carrier to execute virtual threads, and therefore completely locking up your system, which will become completely unresponsive.
|
||||
|
||||
If you have more than `N` CPU cores in your system, then by default your system may be less efficient, since the carrier threads may be pinned in the `Selector.select()` call, and therefore not available to run virtual threads.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
The number of CPU cores of your system determines, by default, the number of carrier threads.
|
||||
The number of carrier threads may be explicitly configured by setting the system property `-Djdk.virtualThreadScheduler.parallelism=N`, where `N` is your desired number of carrier threads.
|
||||
|
||||
Selector threads used by Jetty pin carrier threads.
|
||||
|
||||
Choose the number of selectors wisely when using virtual threads: the number of selectors must always be less than the number of carrier threads, to leave some of the carrier threads free to run virtual threads.
|
||||
|
||||
As an extreme example, if your system only has `1` CPU core, then `1` selector is enough to pin the only carrier thread, and your system will eventually lock up.
|
||||
In this case, you must explicitly configure the number of carrier threads by setting the system property `-Djdk.virtualThreadScheduler.parallelism=2` (or to a larger value).
|
||||
====
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.eclipse.jetty.client.Origin;
|
|||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -42,7 +41,7 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran
|
|||
|
||||
public HttpClientTransportOverHTTP()
|
||||
{
|
||||
this(Math.max(1, ProcessorUtils.availableProcessors() / 2));
|
||||
this(1);
|
||||
}
|
||||
|
||||
public HttpClientTransportOverHTTP(int selectors)
|
||||
|
|
|
@ -422,6 +422,11 @@ public class HttpParser
|
|||
return _state;
|
||||
}
|
||||
|
||||
public boolean hasContent()
|
||||
{
|
||||
return _endOfContent != EndOfContent.NO_CONTENT;
|
||||
}
|
||||
|
||||
public boolean inContentState()
|
||||
{
|
||||
return _state.ordinal() >= State.CONTENT.ordinal() && _state.ordinal() < State.END.ordinal();
|
||||
|
|
|
@ -385,6 +385,15 @@ public class HttpConnection extends AbstractMetaDataConnection implements Runnab
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("HANDLE {} {}", request, this);
|
||||
|
||||
// If the buffer is empty and no body is expected, then release the buffer
|
||||
if (isRequestBufferEmpty() && !_parser.hasContent())
|
||||
{
|
||||
// try parsing now to the end of the message
|
||||
parseRequestBuffer();
|
||||
if (_parser.isComplete())
|
||||
releaseRequestBuffer();
|
||||
}
|
||||
|
||||
// Handle the request by running the task.
|
||||
_handling.set(true);
|
||||
Runnable onRequest = _onRequest;
|
||||
|
@ -411,7 +420,15 @@ public class HttpConnection extends AbstractMetaDataConnection implements Runnab
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("upgraded {} -> {}", this, getEndPoint().getConnection());
|
||||
releaseRequestBuffer();
|
||||
if (_requestBuffer != null)
|
||||
releaseRequestBuffer();
|
||||
break;
|
||||
}
|
||||
|
||||
// If we have already released the request buffer, then use fill interest before allocating another
|
||||
if (_requestBuffer == null)
|
||||
{
|
||||
fillInterested();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,7 +292,7 @@ public abstract class IteratingCallback implements Callback
|
|||
{
|
||||
ExceptionUtil.callAndThen(cause, this::onAborted, this::onFailure);
|
||||
}
|
||||
|
||||
|
||||
private void doOnAbortedOnFailureOnCompleted(Throwable cause)
|
||||
{
|
||||
ExceptionUtil.callAndThen(cause, this::doOnAbortedOnFailure, _onCompleted);
|
||||
|
@ -423,6 +423,7 @@ public abstract class IteratingCallback implements Callback
|
|||
{
|
||||
// we won the race against the callback, so the callback has to process and we can break processing
|
||||
_state = State.PENDING;
|
||||
_reprocess = false;
|
||||
if (_aborted)
|
||||
{
|
||||
onAbortedOnFailureIfNotPendingDoCompleted = _failure;
|
||||
|
@ -482,6 +483,7 @@ public abstract class IteratingCallback implements Callback
|
|||
}
|
||||
callOnSuccess = true;
|
||||
_state = State.PROCESSING;
|
||||
_reprocess = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -818,6 +820,14 @@ public abstract class IteratingCallback implements Callback
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean isPending()
|
||||
{
|
||||
try (AutoLock ignored = _lock.lock())
|
||||
{
|
||||
return _state == State.PENDING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this callback is idle, and {@link #iterate()} needs to be called
|
||||
*/
|
||||
|
|
|
@ -33,7 +33,9 @@ import org.junit.jupiter.api.Test;
|
|||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
@ -63,6 +65,45 @@ public class IteratingCallbackTest
|
|||
scheduler.stop();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testIterateWhileProcessingLoopCount(boolean succeededWinsRace)
|
||||
{
|
||||
var icb = new IteratingCallback()
|
||||
{
|
||||
int counter = 0;
|
||||
|
||||
@Override
|
||||
protected Action process()
|
||||
{
|
||||
int counter = this.counter++;
|
||||
if (counter == 0)
|
||||
{
|
||||
iterate();
|
||||
if (succeededWinsRace)
|
||||
{
|
||||
succeeded();
|
||||
}
|
||||
else
|
||||
{
|
||||
new Thread(() ->
|
||||
{
|
||||
await().atMost(5, TimeUnit.SECONDS).until(this::isPending, is(true));
|
||||
succeeded();
|
||||
}).start();
|
||||
}
|
||||
return Action.SCHEDULED;
|
||||
}
|
||||
return Action.IDLE;
|
||||
}
|
||||
};
|
||||
|
||||
icb.iterate();
|
||||
|
||||
await().atMost(10, TimeUnit.SECONDS).until(icb::isIdle, is(true));
|
||||
assertEquals(2, icb.counter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonWaitingProcess() throws Exception
|
||||
{
|
||||
|
|
|
@ -76,20 +76,20 @@ public class Response implements HttpServletResponse
|
|||
* String used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code HttpOnly} attribute.
|
||||
**/
|
||||
private static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
|
||||
protected static final String HTTP_ONLY_COMMENT = "__HTTP_ONLY__";
|
||||
/**
|
||||
* String used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code Partitioned} attribute.
|
||||
**/
|
||||
private static final String PARTITIONED_COMMENT = "__PARTITIONED__";
|
||||
protected static final String PARTITIONED_COMMENT = "__PARTITIONED__";
|
||||
/**
|
||||
* The strings used in the {@code Comment} attribute of {@link Cookie}
|
||||
* to support the {@code SameSite} attribute.
|
||||
**/
|
||||
private static final String SAME_SITE_COMMENT = "__SAME_SITE_";
|
||||
private static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__";
|
||||
private static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__";
|
||||
private static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__";
|
||||
protected static final String SAME_SITE_COMMENT = "__SAME_SITE_";
|
||||
protected static final String SAME_SITE_NONE_COMMENT = SAME_SITE_COMMENT + "NONE__";
|
||||
protected static final String SAME_SITE_LAX_COMMENT = SAME_SITE_COMMENT + "LAX__";
|
||||
protected static final String SAME_SITE_STRICT_COMMENT = SAME_SITE_COMMENT + "STRICT__";
|
||||
|
||||
public enum OutputType
|
||||
{
|
||||
|
@ -1465,7 +1465,7 @@ public class Response implements HttpServletResponse
|
|||
return (HttpServletResponse)servletResponse;
|
||||
}
|
||||
|
||||
private static class HttpFieldsSupplier implements Supplier<HttpFields>
|
||||
protected static class HttpFieldsSupplier implements Supplier<HttpFields>
|
||||
{
|
||||
private final Supplier<Map<String, String>> _supplier;
|
||||
|
||||
|
@ -1494,7 +1494,7 @@ public class Response implements HttpServletResponse
|
|||
}
|
||||
}
|
||||
|
||||
private static class HttpCookieFacade implements HttpCookie
|
||||
protected static class HttpCookieFacade implements HttpCookie
|
||||
{
|
||||
private final Cookie _cookie;
|
||||
private final String _comment;
|
||||
|
@ -1622,12 +1622,12 @@ public class Response implements HttpServletResponse
|
|||
return comment != null && comment.contains(HTTP_ONLY_COMMENT);
|
||||
}
|
||||
|
||||
private static boolean isPartitionedInComment(String comment)
|
||||
protected static boolean isPartitionedInComment(String comment)
|
||||
{
|
||||
return comment != null && comment.contains(PARTITIONED_COMMENT);
|
||||
}
|
||||
|
||||
private static SameSite getSameSiteFromComment(String comment)
|
||||
protected static SameSite getSameSiteFromComment(String comment)
|
||||
{
|
||||
if (comment == null)
|
||||
return null;
|
||||
|
@ -1640,7 +1640,7 @@ public class Response implements HttpServletResponse
|
|||
return null;
|
||||
}
|
||||
|
||||
private static String getCommentWithoutAttributes(String comment)
|
||||
protected static String getCommentWithoutAttributes(String comment)
|
||||
{
|
||||
if (comment == null)
|
||||
return null;
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.eclipse.jetty.session.SessionConfig;
|
|||
import org.eclipse.jetty.session.SessionIdManager;
|
||||
import org.eclipse.jetty.session.SessionManager;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -613,7 +614,8 @@ public class SessionHandler extends ScopedHandler implements SessionConfig.Mutab
|
|||
* CookieConfig
|
||||
*
|
||||
* Implementation of the jakarta.servlet.SessionCookieConfig.
|
||||
* SameSite configuration can be achieved by using setComment
|
||||
* SameSite configuration can be achieved by using setComment.
|
||||
* Partitioned configuration can be achieved by using setComment.
|
||||
*
|
||||
* @see HttpCookie
|
||||
*/
|
||||
|
@ -671,7 +673,19 @@ public class SessionHandler extends ScopedHandler implements SessionConfig.Mutab
|
|||
public void setComment(String comment)
|
||||
{
|
||||
checkAvailable();
|
||||
_sessionManager.setSessionComment(comment);
|
||||
|
||||
if (!StringUtil.isEmpty(comment))
|
||||
{
|
||||
HttpCookie.SameSite sameSite = Response.HttpCookieFacade.getSameSiteFromComment(comment);
|
||||
if (sameSite != null)
|
||||
_sessionManager.setSameSite(sameSite);
|
||||
|
||||
boolean partitioned = Response.HttpCookieFacade.isPartitionedInComment(comment);
|
||||
if (partitioned)
|
||||
_sessionManager.setPartitioned(partitioned);
|
||||
|
||||
_sessionManager.setSessionComment(Response.HttpCookieFacade.getCommentWithoutAttributes(comment));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -168,7 +168,7 @@ public class SessionHandlerTest
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSessionCookie() throws Exception
|
||||
public void testSessionCookieConfig() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
MockSessionIdManager idMgr = new MockSessionIdManager(server);
|
||||
|
@ -190,12 +190,51 @@ public class SessionHandlerTest
|
|||
sessionCookieConfig.setSecure(false);
|
||||
sessionCookieConfig.setPath("/foo");
|
||||
sessionCookieConfig.setMaxAge(99);
|
||||
|
||||
//test setting SameSite and Partitioned the old way in the comment
|
||||
sessionCookieConfig.setComment(Response.PARTITIONED_COMMENT + " " + Response.SAME_SITE_STRICT_COMMENT);
|
||||
|
||||
//for < ee10, SameSite cannot be set on the SessionCookieConfig, only on the SessionManager, or
|
||||
//a default value on the context attribute org.eclipse.jetty.cookie.sameSiteDefault
|
||||
HttpCookie cookie = mgr.getSessionManager().getSessionCookie(session, false);
|
||||
assertEquals("SPECIAL", cookie.getName());
|
||||
assertEquals("universe", cookie.getDomain());
|
||||
assertEquals("/foo", cookie.getPath());
|
||||
assertFalse(cookie.isHttpOnly());
|
||||
assertFalse(cookie.isSecure());
|
||||
assertTrue(cookie.isPartitioned());
|
||||
assertEquals(99, cookie.getMaxAge());
|
||||
assertEquals(HttpCookie.SameSite.STRICT, cookie.getSameSite());
|
||||
|
||||
String cookieStr = HttpCookieUtils.getRFC6265SetCookie(cookie);
|
||||
assertThat(cookieStr, containsString("; Partitioned; SameSite=Strict"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSessionCookieViaSetters() throws Exception
|
||||
{
|
||||
Server server = new Server();
|
||||
MockSessionIdManager idMgr = new MockSessionIdManager(server);
|
||||
idMgr.setWorkerName("node1");
|
||||
SessionHandler mgr = new SessionHandler();
|
||||
MockSessionCache cache = new MockSessionCache(mgr.getSessionManager());
|
||||
cache.setSessionDataStore(new NullSessionDataStore());
|
||||
mgr.setSessionCache(cache);
|
||||
mgr.setSessionIdManager(idMgr);
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
ManagedSession session = new ManagedSession(mgr.getSessionManager(), new SessionData("123", "_foo", "0.0.0.0", now, now, now, 30));
|
||||
session.setExtendedId("123.node1");
|
||||
|
||||
//test setting up session cookie via setters on SessionHandler
|
||||
mgr.setSessionCookie("SPECIAL");
|
||||
mgr.setSessionDomain("universe");
|
||||
mgr.setHttpOnly(false);
|
||||
mgr.setSecureCookies(false);
|
||||
mgr.setSessionPath("/foo");
|
||||
mgr.setMaxCookieAge(99);
|
||||
mgr.setSameSite(HttpCookie.SameSite.STRICT);
|
||||
mgr.setPartitioned(true);
|
||||
|
||||
|
||||
HttpCookie cookie = mgr.getSessionManager().getSessionCookie(session, false);
|
||||
assertEquals("SPECIAL", cookie.getName());
|
||||
assertEquals("universe", cookie.getDomain());
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
<modules>
|
||||
<module>jetty-testers</module>
|
||||
<module>jetty-jmh</module>
|
||||
<module>jetty-test-common</module>
|
||||
<module>jetty-test-multipart</module>
|
||||
<module>jetty-test-session-common</module>
|
||||
<module>jetty-test-common</module>
|
||||
<module>test-cross-context-dispatch</module>
|
||||
<module>test-distribution</module>
|
||||
<module>test-integration</module>
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
<modules>
|
||||
<module>test-distribution-common</module>
|
||||
<module>test-ee11-distribution</module>
|
||||
<module>test-ee10-distribution</module>
|
||||
<module>test-ee9-distribution</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -15,9 +15,21 @@
|
|||
<bundle-symbolic-name>${project.groupId}.tests.distribution.common</bundle-symbolic-name>
|
||||
<!-- <junit.jupiter.execution.parallel.enabled>false</junit.jupiter.execution.parallel.enabled>-->
|
||||
<junit.jupiter.execution.parallel.config.fixed.parallelism>2</junit.jupiter.execution.parallel.config.fixed.parallelism>
|
||||
<testcontainers-keycloak.version>3.4.0</testcontainers-keycloak.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.dasniko</groupId>
|
||||
<artifactId>testcontainers-keycloak</artifactId>
|
||||
<version>${testcontainers-keycloak.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit4-mock</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
|
@ -54,6 +66,10 @@
|
|||
<groupId>org.apache.maven.resolver</groupId>
|
||||
<artifactId>maven-resolver-util</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15to18</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-xml</artifactId>
|
||||
|
@ -64,6 +80,10 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ethereum</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
|
@ -138,6 +158,12 @@
|
|||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-infinispan-common</artifactId>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.smallrye</groupId>
|
||||
<artifactId>jandex</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
@ -155,6 +181,41 @@
|
|||
<artifactId>jetty-util-ajax</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||
<artifactId>jetty-ee10-test-log4j2-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||
<artifactId>jetty-ee10-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
||||
<artifactId>jetty-ee11-test-log4j2-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
||||
<artifactId>jetty-ee11-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
||||
<artifactId>jetty-ee9-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.http2</groupId>
|
||||
<artifactId>jetty-http2-client</artifactId>
|
||||
|
@ -244,17 +305,6 @@
|
|||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.ee11.tests.distribution;
|
||||
package org.eclipse.jetty.tests.distribution;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -19,16 +19,21 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -43,8 +48,17 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DisableUrlCacheTest.class);
|
||||
|
||||
@Test
|
||||
public void testReloadWebAppWithLog4j2() throws Exception
|
||||
public static Stream<Arguments> tests()
|
||||
{
|
||||
return Stream.of(
|
||||
Arguments.of("ee10", "Started oeje10w.WebAppContext@"),
|
||||
Arguments.of("ee11", "Started oeje11w.WebAppContext@")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("tests")
|
||||
public void testReloadWebAppWithLog4j2(String env, String logToSearch) throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
|
@ -55,7 +69,7 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
.build();
|
||||
|
||||
String[] setupArgs = {
|
||||
"--add-modules=http,ee11-webapp,ee11-deploy,disable-urlcache"
|
||||
"--add-modules=http," + toEnvironment("webapp", env) + "," + toEnvironment("deploy", env) + ",disable-urlcache"
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run setupRun = distribution.start(setupArgs))
|
||||
|
@ -63,7 +77,7 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
assertTrue(setupRun.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, setupRun.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee11:jetty-ee11-test-log4j2-webapp:war:" + jettyVersion);
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-log4j2-webapp:war:" + jettyVersion);
|
||||
Path testWebApp = distribution.getJettyBase().resolve("webapps/test.war");
|
||||
|
||||
Files.copy(webApp, testWebApp);
|
||||
|
@ -75,16 +89,15 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
FS.ensureEmpty(resourcesDir);
|
||||
|
||||
Path webappsDir = distribution.getJettyBase().resolve("webapps");
|
||||
String warXml = """
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
|
||||
<Configure class="org.eclipse.jetty.ee11.webapp.WebAppContext">
|
||||
<Set name="contextPath">/test</Set>
|
||||
<Set name="war"><Property name="jetty.webapps"/>/test.war</Set>
|
||||
<Set name="tempDirectory"><Property name="jetty.base"/>/work/test</Set>
|
||||
<Set name="tempDirectoryPersistent">false</Set>
|
||||
</Configure>
|
||||
""";
|
||||
String warXml =
|
||||
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" +
|
||||
"<!DOCTYPE Configure PUBLIC \"-//Jetty//Configure//EN\" \"https://jetty.org/configure_10_0.dtd\">" +
|
||||
"<Configure class=\"org.eclipse.jetty." + env + ".webapp.WebAppContext\">" +
|
||||
" <Set name=\"contextPath\">/test</Set>" +
|
||||
" <Set name=\"war\"><Property name=\"jetty.webapps\"/>/test.war</Set>" +
|
||||
" <Set name=\"tempDirectory\"><Property name=\"jetty.base\"/>/work/test</Set>" +
|
||||
" <Set name=\"tempDirectoryPersistent\">false</Set>" +
|
||||
"</Configure>";
|
||||
Path warXmlPath = webappsDir.resolve("test.xml");
|
||||
Files.writeString(warXmlPath, warXml, StandardCharsets.UTF_8);
|
||||
|
||||
|
@ -92,10 +105,11 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
String loggingConfig = """
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
org.eclipse.jetty.deploy.LEVEL=DEBUG
|
||||
org.eclipse.jetty.ee11.webapp.LEVEL=DEBUG
|
||||
org.eclipse.jetty.ee11.webapp.WebAppClassLoader.LEVEL=INFO
|
||||
org.eclipse.jetty.ee11.servlet.LEVEL=DEBUG
|
||||
org.eclipse.jetty.eexx.webapp.LEVEL=DEBUG
|
||||
org.eclipse.jetty.eexx.webapp.WebAppClassLoader.LEVEL=INFO
|
||||
org.eclipse.jetty.exx.servlet.LEVEL=DEBUG
|
||||
""";
|
||||
loggingConfig = loggingConfig.replace("eexx", env);
|
||||
Files.writeString(loggingFile, loggingConfig, StandardCharsets.UTF_8);
|
||||
|
||||
|
||||
|
@ -121,7 +135,7 @@ public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
|||
touch(warXmlPath);
|
||||
|
||||
// Wait for reload to start context
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oeje11w.WebAppContext@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertTrue(run2.awaitConsoleLogsFor(logToSearch, START_TIMEOUT, TimeUnit.SECONDS));
|
||||
// wait for deployer node to complete so context is Started not Starting
|
||||
assertTrue(run2.awaitConsoleLogsFor("Executing Node Node[started]", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 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.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import dasniko.testcontainers.keycloak.KeycloakContainer;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.keycloak.admin.client.CreatedResponseUtil;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class OpenIdTests extends AbstractJettyHomeTest
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(OpenIdTests.class);
|
||||
|
||||
private static final KeycloakContainer KEYCLOAK_CONTAINER = new KeycloakContainer();
|
||||
|
||||
private static final String clientId = "jetty-api";
|
||||
private static final String clientSecret = "JettyRocks!";
|
||||
|
||||
private static final String userName = "jetty";
|
||||
private static final String password = "JettyRocks!Really";
|
||||
|
||||
private static final String firstName = "John";
|
||||
private static final String lastName = "Doe";
|
||||
private static final String email = "jetty@jetty.org";
|
||||
|
||||
private static String userId;
|
||||
|
||||
@BeforeAll
|
||||
public static void startKeycloak()
|
||||
{
|
||||
KEYCLOAK_CONTAINER.start();
|
||||
// init keycloak
|
||||
try (Keycloak keycloak = KEYCLOAK_CONTAINER.getKeycloakAdminClient())
|
||||
{
|
||||
RealmRepresentation jettyRealm = new RealmRepresentation();
|
||||
jettyRealm.setId("jetty");
|
||||
jettyRealm.setRealm("jetty");
|
||||
jettyRealm.setEnabled(true);
|
||||
keycloak.realms().create(jettyRealm);
|
||||
|
||||
ClientRepresentation clientRepresentation = new ClientRepresentation();
|
||||
clientRepresentation.setClientId(clientId);
|
||||
clientRepresentation.setSecret(clientSecret);
|
||||
clientRepresentation.setRedirectUris(List.of("http://localhost:*"));
|
||||
clientRepresentation.setEnabled(true);
|
||||
clientRepresentation.setPublicClient(Boolean.TRUE);
|
||||
keycloak.realm("jetty").clients().create(clientRepresentation);
|
||||
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setEnabled(true);
|
||||
user.setFirstName(firstName);
|
||||
user.setLastName(lastName);
|
||||
user.setUsername(userName);
|
||||
user.setEmail(email);
|
||||
|
||||
userId = CreatedResponseUtil.getCreatedId(keycloak.realm("jetty").users().create(user));
|
||||
|
||||
CredentialRepresentation passwordCred = new CredentialRepresentation();
|
||||
passwordCred.setTemporary(false);
|
||||
passwordCred.setType(CredentialRepresentation.PASSWORD);
|
||||
passwordCred.setValue(password);
|
||||
|
||||
// Set password credential
|
||||
keycloak.realm("jetty").users().get(userId).resetPassword(passwordCred);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void stopKeycloak()
|
||||
{
|
||||
if (KEYCLOAK_CONTAINER.isRunning())
|
||||
{
|
||||
KEYCLOAK_CONTAINER.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static Stream<Arguments> tests()
|
||||
{
|
||||
return Stream.of(
|
||||
Arguments.of("ee9", "ee9-openid"),
|
||||
Arguments.of("ee10", "openid"),
|
||||
Arguments.of("ee11", "openid")
|
||||
);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("tests")
|
||||
public void testOpenID(String env, String openIdModule) throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.build();
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=http," + toEnvironment("webapp", env) + "," + toEnvironment("deploy", env) + "," + openIdModule
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty." + env + ":jetty-" + env + "-test-openid-webapp:war:" + jettyVersion);
|
||||
distribution.installWar(webApp, "test");
|
||||
String openIdProvider = KEYCLOAK_CONTAINER.getAuthServerUrl() + "/realms/jetty";
|
||||
LOGGER.info("openIdProvider: {}", openIdProvider);
|
||||
|
||||
int port = Tester.freePort();
|
||||
String[] args2 = {
|
||||
"jetty.http.port=" + port,
|
||||
"jetty.ssl.port=" + port,
|
||||
"jetty.openid.provider=" + openIdProvider,
|
||||
"jetty.openid.clientId=" + clientId,
|
||||
"jetty.openid.clientSecret=" + clientSecret,
|
||||
//"jetty.server.dumpAfterStart=true",
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
String uri = "http://localhost:" + port + "/test";
|
||||
// Initially not authenticated
|
||||
startHttpClient();
|
||||
ContentResponse contentResponse = client.GET(uri + "/");
|
||||
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||
assertThat(contentResponse.getContentAsString(), containsString("not authenticated"));
|
||||
|
||||
// Request to login is success
|
||||
contentResponse = client.GET(uri + "/login");
|
||||
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||
// need to extract form
|
||||
String html = contentResponse.getContentAsString();
|
||||
// need this attribute <form ***** action="***"
|
||||
String postUrl = html.substring(html.indexOf("action=\"")).substring(0, html.substring(html.indexOf("action=\"")).indexOf("\"", 9)).substring(8);
|
||||
Fields fields = new Fields();
|
||||
fields.put("username", userName);
|
||||
fields.add("password", password);
|
||||
contentResponse = client.FORM(postUrl, fields);
|
||||
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||
assertThat(contentResponse.getContentAsString(), containsString("success"));
|
||||
|
||||
// Now authenticated we can get info
|
||||
String content = client.GET(uri + "/").getContentAsString();
|
||||
assertThat(content, containsString("userId: " + userId));
|
||||
assertThat(content, containsString("name: " + firstName + " " + lastName));
|
||||
assertThat(content, containsString("email: " + email));
|
||||
|
||||
// Request to admin page gives 403 as we do not have admin role
|
||||
contentResponse = client.GET(uri + "/admin");
|
||||
assertThat(contentResponse.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||
|
||||
// We are no longer authenticated after logging out
|
||||
contentResponse = client.GET(uri + "/logout");
|
||||
assertThat(contentResponse.getStatus(), is(HttpStatus.OK_200));
|
||||
content = contentResponse.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,3 +6,6 @@ org.testcontainers.LEVEL=INFO
|
|||
#org.testcontainers.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.LEVEL=DEBUG
|
||||
#org.eclipse.jetty.tests.distribution.LEVEL=DEBUG
|
||||
# uncomment to get output of forked jetty process in the logs
|
||||
#org.eclipse.jetty.tests.testers.ProcessWrapper.LEVEL=DEBUG
|
||||
com.gargoylesoftware.htmlunit.LEVEL=ERROR
|
|
@ -1,81 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution</artifactId>
|
||||
<version>12.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-ee10-distribution</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Tests :: Distribution :: EE10</name>
|
||||
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.ee10.distribution</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
<type>zip</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-ethereum</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-openid</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||
<artifactId>jetty-ee10-servlet</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee10</groupId>
|
||||
<artifactId>jetty-ee10-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-test-common</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-testers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution-common</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,143 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 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.ee10.tests.distribution;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.FileTime;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Isolated
|
||||
public class DisableUrlCacheTest extends AbstractJettyHomeTest
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DisableUrlCacheTest.class);
|
||||
|
||||
@Test
|
||||
public void testReloadWebAppWithLog4j2() throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.jvmArgs(List.of("-Dorg.eclipse.jetty.deploy.LEVEL=DEBUG"))
|
||||
.build();
|
||||
|
||||
String[] setupArgs = {
|
||||
"--add-modules=http,ee10-webapp,ee10-deploy,disable-urlcache"
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run setupRun = distribution.start(setupArgs))
|
||||
{
|
||||
assertTrue(setupRun.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, setupRun.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee10:jetty-ee10-test-log4j2-webapp:war:" + jettyVersion);
|
||||
Path testWebApp = distribution.getJettyBase().resolve("webapps/test.war");
|
||||
|
||||
Files.copy(webApp, testWebApp);
|
||||
|
||||
Path tempDir = distribution.getJettyBase().resolve("work");
|
||||
FS.ensureEmpty(tempDir);
|
||||
|
||||
Path resourcesDir = distribution.getJettyBase().resolve("resources");
|
||||
FS.ensureEmpty(resourcesDir);
|
||||
|
||||
Path webappsDir = distribution.getJettyBase().resolve("webapps");
|
||||
String warXml = """
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
|
||||
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext">
|
||||
<Set name="contextPath">/test</Set>
|
||||
<Set name="war"><Property name="jetty.webapps"/>/test.war</Set>
|
||||
<Set name="tempDirectory"><Property name="jetty.base"/>/work/test</Set>
|
||||
<Set name="tempDirectoryPersistent">false</Set>
|
||||
</Configure>
|
||||
""";
|
||||
Path warXmlPath = webappsDir.resolve("test.xml");
|
||||
Files.writeString(warXmlPath, warXml, StandardCharsets.UTF_8);
|
||||
|
||||
Path loggingFile = resourcesDir.resolve("jetty-logging.properties");
|
||||
String loggingConfig = """
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
org.eclipse.jetty.deploy.LEVEL=DEBUG
|
||||
org.eclipse.jetty.ee10.webapp.LEVEL=DEBUG
|
||||
org.eclipse.jetty.ee10.webapp.WebAppClassLoader.LEVEL=INFO
|
||||
org.eclipse.jetty.ee10.servlet.LEVEL=DEBUG
|
||||
""";
|
||||
Files.writeString(loggingFile, loggingConfig, StandardCharsets.UTF_8);
|
||||
|
||||
|
||||
int port = Tester.freePort();
|
||||
String[] runArgs = {
|
||||
"jetty.http.port=" + port,
|
||||
"jetty.deploy.scanInterval=1"
|
||||
//"jetty.server.dumpAfterStart=true",
|
||||
};
|
||||
try (JettyHomeTester.Run run2 = distribution.start(runArgs))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
startHttpClient(false);
|
||||
|
||||
// Test webapp is there
|
||||
ContentResponse response = client.GET("http://localhost:" + port + "/test/log/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
String content = response.getContentAsString();
|
||||
assertThat(content, containsString("GET at LogServlet"));
|
||||
|
||||
// Trigger a hot-reload
|
||||
run2.getLogs().clear();
|
||||
touch(warXmlPath);
|
||||
|
||||
// Wait for reload to start context
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oeje10w.WebAppContext@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
// wait for deployer node to complete so context is Started not Starting
|
||||
assertTrue(run2.awaitConsoleLogsFor("Executing Node Node[started]", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
|
||||
// Is webapp still there?
|
||||
response = client.GET("http://localhost:" + port + "/test/log/");
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, response.getStatus(), is(HttpStatus.OK_200));
|
||||
assertThat(content, containsString("GET at LogServlet"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void touch(Path path) throws IOException
|
||||
{
|
||||
LOG.info("Touch: {}", path);
|
||||
FileTime now = FileTime.fromMillis(System.currentTimeMillis() + 2000);
|
||||
Files.setLastModifiedTime(path, now);
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 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.ee10.tests.distribution;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Isolated
|
||||
public class OpenIdTests extends AbstractJettyHomeTest
|
||||
{
|
||||
@Test
|
||||
public void testOpenID() throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.build();
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=http,ee10-webapp,ee10-deploy,openid"
|
||||
};
|
||||
|
||||
String clientId = "clientId123";
|
||||
String clientSecret = "clientSecret456";
|
||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee10:jetty-ee10-test-openid-webapp:war:" + jettyVersion);
|
||||
distribution.installWar(webApp, "test");
|
||||
|
||||
int port = Tester.freePort();
|
||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
||||
openIdProvider.start();
|
||||
String[] args2 = {
|
||||
"jetty.http.port=" + port,
|
||||
"jetty.ssl.port=" + port,
|
||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
||||
"jetty.openid.clientId=" + clientId,
|
||||
"jetty.openid.clientSecret=" + clientSecret,
|
||||
//"jetty.server.dumpAfterStart=true",
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
startHttpClient(false);
|
||||
String uri = "http://localhost:" + port + "/test";
|
||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
||||
|
||||
// Initially not authenticated
|
||||
ContentResponse response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
String content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
|
||||
// Request to login is success
|
||||
response = client.GET(uri + "/login");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("success"));
|
||||
|
||||
// Now authenticated we can get info
|
||||
response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("userId: 123456789"));
|
||||
assertThat(content, containsString("name: Alice"));
|
||||
assertThat(content, containsString("email: Alice@example.com"));
|
||||
|
||||
// Request to admin page gives 403 as we do not have admin role
|
||||
response = client.GET(uri + "/admin");
|
||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||
|
||||
// We are no longer authenticated after logging out
|
||||
response = client.GET(uri + "/logout");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
openIdProvider.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution</artifactId>
|
||||
<version>12.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-ee11-distribution</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Tests :: Distribution :: EE11</name>
|
||||
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.ee11.distribution</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
<type>zip</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-openid</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
||||
<artifactId>jetty-ee11-servlet</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee11</groupId>
|
||||
<artifactId>jetty-ee11-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-test-common</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-testers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution-common</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution-common</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,119 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 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.ee11.tests.distribution;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Isolated
|
||||
public class OpenIdTests extends AbstractJettyHomeTest
|
||||
{
|
||||
@Test
|
||||
public void testOpenID() throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.build();
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=http,ee11-webapp,ee11-deploy,openid"
|
||||
};
|
||||
|
||||
String clientId = "clientId123";
|
||||
String clientSecret = "clientSecret456";
|
||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee11:jetty-ee11-test-openid-webapp:war:" + jettyVersion);
|
||||
distribution.installWar(webApp, "test");
|
||||
|
||||
int port = Tester.freePort();
|
||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
||||
openIdProvider.start();
|
||||
String[] args2 = {
|
||||
"jetty.http.port=" + port,
|
||||
"jetty.ssl.port=" + port,
|
||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
||||
"jetty.openid.clientId=" + clientId,
|
||||
"jetty.openid.clientSecret=" + clientSecret,
|
||||
//"jetty.server.dumpAfterStart=true",
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
startHttpClient(false);
|
||||
String uri = "http://localhost:" + port + "/test";
|
||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
||||
|
||||
// Initially not authenticated
|
||||
ContentResponse response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
String content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
|
||||
// Request to login is success
|
||||
response = client.GET(uri + "/login");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("success"));
|
||||
|
||||
// Now authenticated we can get info
|
||||
response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("userId: 123456789"));
|
||||
assertThat(content, containsString("name: Alice"));
|
||||
assertThat(content, containsString("email: Alice@example.com"));
|
||||
|
||||
// Request to admin page gives 403 as we do not have admin role
|
||||
response = client.GET(uri + "/admin");
|
||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||
|
||||
// We are no longer authenticated after logging out
|
||||
response = client.GET(uri + "/logout");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
openIdProvider.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution</artifactId>
|
||||
<version>12.1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>test-ee9-distribution</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Tests :: Distribution :: EE9</name>
|
||||
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.ee9.distribution</bundle-symbolic-name>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-home</artifactId>
|
||||
<type>zip</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-client</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-slf4j-impl</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
||||
<artifactId>jetty-ee9-openid</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
||||
<artifactId>jetty-ee9-servlet</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.ee9</groupId>
|
||||
<artifactId>jetty-ee9-test-openid-webapp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>war</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-test-common</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>jetty-testers</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.tests</groupId>
|
||||
<artifactId>test-distribution-common</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -1,120 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 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.ee9.tests.distribution;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.tests.OpenIdProvider;
|
||||
import org.eclipse.jetty.tests.distribution.AbstractJettyHomeTest;
|
||||
import org.eclipse.jetty.tests.testers.JettyHomeTester;
|
||||
import org.eclipse.jetty.tests.testers.Tester;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.Isolated;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Isolated
|
||||
public class OpenIdTests extends AbstractJettyHomeTest
|
||||
{
|
||||
@Test
|
||||
public void testOpenID() throws Exception
|
||||
{
|
||||
Path jettyBase = newTestJettyBaseDirectory();
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
JettyHomeTester distribution = JettyHomeTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.jettyBase(jettyBase)
|
||||
.build();
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=http,ee9-webapp,ee9-deploy,ee9-openid"
|
||||
};
|
||||
|
||||
String clientId = "clientId123";
|
||||
String clientSecret = "clientSecret456";
|
||||
OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret);
|
||||
try (JettyHomeTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(START_TIMEOUT, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
|
||||
Path webApp = distribution.resolveArtifact("org.eclipse.jetty.ee9:jetty-ee9-test-openid-webapp:war:" + jettyVersion);
|
||||
distribution.installWar(webApp, "test");
|
||||
|
||||
int port = Tester.freePort();
|
||||
openIdProvider.addRedirectUri("http://localhost:" + port + "/test/j_security_check");
|
||||
openIdProvider.start();
|
||||
String[] args2 = {
|
||||
"jetty.http.port=" + port,
|
||||
"jetty.ssl.port=" + port,
|
||||
"jetty.openid.provider=" + openIdProvider.getProvider(),
|
||||
"jetty.openid.clientId=" + clientId,
|
||||
"jetty.openid.clientSecret=" + clientSecret,
|
||||
//"jetty.server.dumpAfterStart=true",
|
||||
};
|
||||
|
||||
try (JettyHomeTester.Run run2 = distribution.start(args2))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started oejs.Server@", START_TIMEOUT, TimeUnit.SECONDS));
|
||||
startHttpClient(false);
|
||||
String uri = "http://localhost:" + port + "/test";
|
||||
openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice"));
|
||||
|
||||
// Initially not authenticated
|
||||
ContentResponse response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
String content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
|
||||
// Request to login is success
|
||||
response = client.GET(uri + "/login");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("success"));
|
||||
|
||||
// Now authenticated we can get info
|
||||
response = client.GET(uri + "/");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("userId: 123456789"));
|
||||
assertThat(content, containsString("name: Alice"));
|
||||
assertThat(content, containsString("email: Alice@example.com"));
|
||||
|
||||
// Request to admin page gives 403 as we do not have admin role
|
||||
response = client.GET(uri + "/admin");
|
||||
assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403));
|
||||
|
||||
// We are no longer authenticated after logging out
|
||||
response = client.GET(uri + "/logout");
|
||||
assertThat(response.getStatus(), is(HttpStatus.OK_200));
|
||||
content = response.getContentAsString();
|
||||
assertThat(content, containsString("not authenticated"));
|
||||
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
openIdProvider.stop();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue