-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix demo-spec webapp failures #10178
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,8 +83,8 @@ public void onStartup(Set<Class<?>> classes, ServletContext context) | |
if (context.getAttribute("org.example.Foo") != null) | ||
throw new IllegalStateException("FooInitializer on Startup already called"); | ||
|
||
context.setAttribute("org.example.Foo", new ArrayList<Class>(classes)); | ||
ServletRegistration.Dynamic reg = context.addServlet("AnnotationTest", "org.example.AnnotationTest"); | ||
context.setAttribute("org.example.Foo", new ArrayList<>(classes)); | ||
ServletRegistration.Dynamic reg = context.addServlet("AnnotationTest", "org.example.test.AnnotationTest"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should refer to the class, rather than the name of the class? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
context.setAttribute("org.example.AnnotationTest.complete", (reg == null)); | ||
context.addListener(new FooListener()); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// | ||
// ======================================================================== | ||
// 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.demos; | ||
|
||
import java.io.IOException; | ||
import java.net.URI; | ||
import java.nio.file.FileSystem; | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.StandardCopyOption; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.Map; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.TimeoutException; | ||
import java.util.stream.Stream; | ||
|
||
import org.eclipse.jetty.client.ContentResponse; | ||
import org.eclipse.jetty.client.HttpClient; | ||
import org.eclipse.jetty.ee10.webapp.WebAppContext; | ||
import org.eclipse.jetty.http.HttpStatus; | ||
import org.eclipse.jetty.security.HashLoginService; | ||
import org.eclipse.jetty.security.SecurityHandler; | ||
import org.eclipse.jetty.server.Server; | ||
import org.eclipse.jetty.server.ServerConnector; | ||
import org.eclipse.jetty.toolchain.test.FS; | ||
import org.eclipse.jetty.toolchain.test.IO; | ||
import org.eclipse.jetty.toolchain.test.MavenPaths; | ||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; | ||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; | ||
import org.eclipse.jetty.util.component.LifeCycle; | ||
import org.eclipse.jetty.util.resource.Resource; | ||
import org.eclipse.jetty.util.resource.ResourceFactory; | ||
import org.example.MockDataSource; | ||
import org.example.MockUserTransaction; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.containsString; | ||
import static org.hamcrest.Matchers.is; | ||
import static org.hamcrest.Matchers.not; | ||
import static org.junit.jupiter.api.Assertions.fail; | ||
|
||
@ExtendWith(WorkDirExtension.class) | ||
public class SpecWebAppTest | ||
{ | ||
private Server server; | ||
private HttpClient client; | ||
|
||
@BeforeEach | ||
public void setup(WorkDir workDir) throws Exception | ||
{ | ||
server = new Server(); | ||
|
||
ServerConnector connector = new ServerConnector(server); | ||
connector.setPort(0); | ||
server.addConnector(connector); | ||
|
||
Path webappDir = prepareWebAppDir(workDir); | ||
|
||
WebAppContext webapp = new WebAppContext(); | ||
ResourceFactory resourceFactory = ResourceFactory.of(webapp); | ||
webapp.setContextPath("/"); | ||
webapp.setWarResource(resourceFactory.newResource(webappDir)); | ||
webapp.setAttribute( | ||
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", | ||
".*/jakarta.servlet-api-[^/]*\\.jar$|.*/[^/]*taglibs.*\\.jar$"); | ||
|
||
HashLoginService hashLoginService = new HashLoginService(); | ||
hashLoginService.setName("Test Realm"); | ||
Path realmFile = MavenPaths.findTestResourceFile("ee10-demo-realm.properties"); | ||
Resource realmResource = ResourceFactory.of(server).newResource(realmFile); | ||
hashLoginService.setConfig(realmResource); | ||
SecurityHandler securityHandler = webapp.getSecurityHandler(); | ||
securityHandler.setLoginService(hashLoginService); | ||
|
||
new org.eclipse.jetty.ee10.plus.jndi.Resource(webapp, "jdbc/mydatasource", new MockDataSource()); | ||
new org.eclipse.jetty.ee10.plus.jndi.Transaction("ee10", new MockUserTransaction()); | ||
|
||
server.setHandler(webapp); | ||
server.start(); | ||
|
||
client = new HttpClient(); | ||
client.start(); | ||
} | ||
|
||
private Path prepareWebAppDir(WorkDir workDir) throws IOException | ||
{ | ||
Path webappDir = workDir.getEmptyPathDir(); | ||
Path srcWebapp = MavenPaths.projectBase().resolve("src/main/webapp"); | ||
IO.copyDir(srcWebapp, webappDir); | ||
|
||
Path webappClassesDir = webappDir.resolve("WEB-INF/classes"); | ||
FS.ensureDirExists(webappClassesDir); | ||
Path classesDir = MavenPaths.projectBase().resolve("target/classes"); | ||
IO.copyDir(classesDir, webappClassesDir); | ||
|
||
Path libDir = webappDir.resolve("WEB-INF/lib"); | ||
FS.ensureDirExists(libDir); | ||
copyDependency("jetty-ee10-demo-container-initializer", libDir); | ||
copyDependency("jetty-ee10-demo-web-fragment", libDir); | ||
|
||
return webappDir; | ||
} | ||
|
||
private void copyDependency(String depName, Path libDir) throws IOException | ||
{ | ||
Path depPath = MavenPaths.projectBase().resolve("../" + depName).normalize(); | ||
if (!Files.isDirectory(depPath)) | ||
fail("Dependency not found: " + depPath); | ||
Path outputJar = libDir.resolve(depName + ".jar"); | ||
Map<String, String> env = new HashMap<>(); | ||
env.put("create", "true"); | ||
|
||
URI uri = URI.create("jar:" + outputJar.toUri().toASCIIString()); | ||
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) | ||
{ | ||
Path root = fs.getPath("/"); | ||
copyContents(depPath.resolve("target/classes"), root); | ||
copyContents(depPath.resolve("src/main/resources"), root); | ||
} | ||
} | ||
|
||
public void copyContents(Path srcPath, Path destPath) throws IOException | ||
{ | ||
try (Stream<Path> srcStream = Files.walk(srcPath)) | ||
{ | ||
Iterator<Path> iter = srcStream | ||
.filter(Files::isRegularFile) | ||
.iterator(); | ||
while (iter.hasNext()) | ||
{ | ||
Path path = iter.next(); | ||
URI relativeSrc = srcPath.toUri().relativize(path.toUri()); | ||
Path destFile = destPath.resolve(relativeSrc.toASCIIString()); | ||
System.err.printf("Copy %s (%s) -> %s%n", path, relativeSrc, destFile); | ||
if (!Files.exists(destFile.getParent())) | ||
Files.createDirectories(destFile.getParent()); | ||
Files.copy(path, destFile, StandardCopyOption.REPLACE_EXISTING); | ||
} | ||
} | ||
} | ||
|
||
@AfterEach | ||
public void teardown() | ||
{ | ||
LifeCycle.stop(client); | ||
LifeCycle.stop(server); | ||
} | ||
|
||
@Test | ||
public void testNoFailures() throws InterruptedException, ExecutionException, TimeoutException | ||
{ | ||
ContentResponse response = client.newRequest(server.getURI().resolve("/test/")) | ||
.followRedirects(false) | ||
.send(); | ||
|
||
assertThat("response status", response.getStatus(), is(HttpStatus.OK_200)); | ||
// Look for 0 entries that fail. | ||
assertThat("response", response.getContentAsString(), not(containsString(">FAIL<"))); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# | ||
# This file defines users passwords and roles for a HashUserRealm | ||
# | ||
# The format is | ||
# <username>: <password>[,<rolename> ...] | ||
# | ||
# Passwords may be clear text, obfuscated or checksummed. The class | ||
# org.eclipse.util.Password should be used to generate obfuscated | ||
# passwords or password checksums | ||
# | ||
# If DIGEST Authentication is used, the password must be in a recoverable | ||
# format, either plain text or OBF:. | ||
# | ||
jetty: MD5:164c88b302622e17050af52c89945d44,user | ||
admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin,user | ||
other: OBF:1xmk1w261u9r1w1c1xmq,user | ||
plain: plain,user | ||
user: password,user | ||
|
||
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password | ||
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
## Jetty Logging using jetty-slf4j-impl | ||
org.eclipse.jetty.LEVEL=INFO | ||
#org.eclipse.jetty.STACKS=true | ||
org.eclipse.jetty.ee10.annotations.LEVEL=DEBUG | ||
#org.eclipse.jetty.STACKS=false | ||
#org.eclipse.jetty.io.LEVEL=DEBUG | ||
#org.eclipse.jetty.io.ssl.LEVEL=DEBUG | ||
#org.eclipse.jetty.server.LEVEL=DEBUG | ||
#org.eclipse.jetty.ee10.servlets.LEVEL=DEBUG | ||
#org.eclipse.jetty.alpn.LEVEL=DEBUG | ||
#org.eclipse.jetty.jmx.LEVEL=DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the bug that caused all of the varying failures.