Skip to content
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

Updates to move to latest Jersey and Jetty; refs GitHub #68 #374

Merged
merged 1 commit into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -1346,24 +1346,31 @@ project(':wres-tasker') {
// Easy byte[] to hex conversion
implementation 'commons-codec:commons-codec:1.17.1'

//Jakarta servlet
implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0'

// Server library to run a web server:
implementation 'org.eclipse.jetty:jetty-server:11.0.24'
implementation 'org.eclipse.jetty:jetty-server:12.0.16'

// Servlet library is now tied to ee10.
implementation 'org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.16'
implementation 'org.eclipse.jetty.ee10:jetty-ee10-servlets:12.0.16'

// Support HTTP/2
implementation 'org.eclipse.jetty.http2:http2-server:11.0.24'
implementation 'org.eclipse.jetty.http2:jetty-http2-server:12.0.16'

// Support ALPN
implementation 'org.eclipse.jetty:jetty-alpn-java-server:11.0.24'
implementation 'org.eclipse.jetty:jetty-alpn-java-server:12.0.16'

// Servlet container library to run a web application with:
implementation 'org.eclipse.jetty:jetty-webapp:11.0.24'
implementation 'org.eclipse.jetty.ee10:jetty-ee10-webapp:12.0.16'

// Needed at compile-time to reference ServletContainer.class and
// DefaultServlet.class
implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.1.8'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.1.9'

// To handle multipart post
implementation 'org.glassfish.jersey.media:jersey-media-multipart:3.1.8'
implementation 'org.glassfish.jersey.media:jersey-media-multipart:3.1.9'

// To temporarily cache/store-in-RAM job metadata when redis unavailable
implementation('com.github.ben-manes.caffeine:caffeine:3.1.8') {
Expand Down Expand Up @@ -1408,11 +1415,11 @@ project(':wres-tasker') {
exclude group: 'edu.washington.cs.types.checker', module: 'checker-framework'
}

runtimeOnly 'org.glassfish.jersey.core:jersey-server:3.1.8'
runtimeOnly 'org.glassfish.jersey.core:jersey-server:3.1.9'

// Needed to prevent "java.lang.IllegalStateException: InjectionManagerFactory not found."
// Thanks, https://luohuahuang.org/2017/11/13/jersey-illegalstateexception-injectionmanagerfactory/
runtimeOnly 'org.glassfish.jersey.inject:jersey-hk2:3.1.8'
runtimeOnly 'org.glassfish.jersey.inject:jersey-hk2:3.1.9'

testImplementation 'junit:junit:4.13.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.11.3'
Expand Down Expand Up @@ -1884,15 +1891,22 @@ dependencies {
// For Java 9+ compatibility:
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:3.0.1'

//Jakarta servlet
implementation 'jakarta.servlet:jakarta.servlet-api:6.0.0'

//Jetty servlet stuff now tied to ee10, with the move to Jetty 12.
implementation 'org.eclipse.jetty.ee10:jetty-ee10-servlet:12.0.16'
implementation 'org.eclipse.jetty.ee10:jetty-ee10-servlets:12.0.16'

// Servlet container library to run a web application with:
implementation 'org.eclipse.jetty:jetty-webapp:11.0.24'

// Needed at compile-time to reference ServletContainer.class and
// DefaultServlet.class
implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.1.8'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:3.1.9'

// Jetty server
implementation 'org.eclipse.jetty:jetty-server:11.0.24'
implementation 'org.eclipse.jetty:jetty-server:12.0.16'

implementation('com.github.ben-manes.caffeine:caffeine:3.1.8') {
// Not used at runtime, bloat
Expand Down Expand Up @@ -1924,18 +1938,19 @@ dependencies {
// JCIP annotations
compileOnly group: 'net.jcip', name: 'jcip-annotations', version: '1.0'

runtimeOnly 'org.glassfish.jersey.containers:jersey-container-servlet:3.1.8'
runtimeOnly 'org.glassfish.jersey.core:jersey-server:3.1.8'
runtimeOnly 'org.glassfish.jersey.containers:jersey-container-servlet:3.1.9'
runtimeOnly 'org.glassfish.jersey.core:jersey-server:3.1.9'
// currently locked at this version, check this ticket for more information
// https://vlab.***REMOVED***/redmine/issues/124200
runtimeOnly 'org.glassfish.jersey.containers:jersey-container-jetty-http:3.1.3'
runtimeOnly 'org.glassfish.jersey.inject:jersey-hk2:3.1.8'
runtimeOnly 'org.glassfish.jersey.containers:jersey-container-jetty-http:3.1.9'
runtimeOnly 'org.glassfish.jersey.inject:jersey-hk2:3.1.9'

// Support HTTP/2
implementation 'org.eclipse.jetty.http2:http2-server:11.0.24'
//implementation 'org.eclipse.jetty.http2:http2-server:11.0.24'
implementation 'org.eclipse.jetty.http2:jetty-http2-server:12.0.16'

// Support ALPN
implementation 'org.eclipse.jetty:jetty-alpn-java-server:11.0.24'
implementation 'org.eclipse.jetty:jetty-alpn-java-server:12.0.16'

runtimeOnly('ch.qos.logback:logback-classic:1.5.12') {
// Not used at runtime, bloat
Expand Down
59 changes: 26 additions & 33 deletions src/wres/server/WebServer.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
package wres.server;

import jakarta.servlet.Servlet;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.ShutdownHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* Runs the core application as a long-running instance or web server that accepts evaluation requests
*/
Expand All @@ -43,25 +39,6 @@ public class WebServer
*/
private static final int MAX_SERVER_THREADS = 20;


/**
* Ensure that the X-Frame-Options header element is included in the response.
* If not already set, then it will be set to DENY. If it is already set when this
* is called, then it will be left unchanged (there is no check for DENY).
*/
private static final HttpChannel.Listener HTTP_CHANNEL_LISTENER = new HttpChannel.Listener()
{
@Override
public void onResponseBegin( Request request )
{
if ( request.getResponse().getHeader( "X-Frame-Options" ) == null )
{
request.getResponse().addHeader( "X-Frame-Options", "DENY" );
}
}
};


/**
* Get the port that is passed in from args, if not present then use default port
* @param args args potentially containing the port
Expand Down Expand Up @@ -104,8 +81,23 @@ public static void main( String[] args ) throws Exception
dynamicHolder.setServlet( servlet );

// Static handler:
ResourceHandler resourceHandler = new ResourceHandler();
Resource resource = Resource.newClassPathResource( "html" );
ResourceHandler resourceHandler = new ResourceHandler()
{
@Override
public boolean handle( Request request,
Response response,
Callback callback )
throws Exception
{
response.getHeaders()
.add( "X-Frame-Options", "DENY" );
response.getHeaders()
.add( "strict-transport-security", "max-age=31536000; includeSubDomains; preload;" );
return super.handle( request, response, callback );
}
};
ResourceFactory resourceFactory = ResourceFactory.root();
Resource resource = resourceFactory.newClassLoaderResource( "html", false );
resourceHandler.setBaseResource( resource );

// Have to chain/wrap the handler this way to get both static/dynamic:
Expand Down Expand Up @@ -156,13 +148,12 @@ public static void main( String[] args ) throws Exception
// by other processes running locally, e.g. a shim or a UI.
serverConnector.setHost( "127.0.0.1" );
serverConnector.setPort( port );
serverConnector.addBean( HTTP_CHANNEL_LISTENER );
serverConnector.setAcceptedSendBufferSize( 0 );
serverConnector.setAcceptedSendBufferSize( -1 );
ServerConnector[] serverConnectors = { serverConnector };
jettyServer.setConnectors( serverConnectors );

jettyServer.start();
jettyServer.dump( System.err ); // NOSONAR
jettyServer.dump( System.err ); // NOSONAR
String helpMessage =
String.format( "Server started. Visit localhost:%d/evaluation for usage instructions", port );
LOGGER.info( helpMessage );
Expand All @@ -182,3 +173,5 @@ public static void main( String[] args ) throws Exception
}
}
}


72 changes: 41 additions & 31 deletions wres-tasker/src/wres/tasker/Tasker.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
package wres.tasker;

import java.io.IOException;
import java.security.Security;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.Slf4jRequestLogWriter;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.servlet.FilterHolder;
import org.eclipse.jetty.ee10.servlets.HeaderFilter;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
Expand Down Expand Up @@ -101,30 +115,6 @@ public class Tasker
*/
static final int MAX_SERVER_THREADS = 100;


/**
* Ensure that the X-Frame-Options header element is included in the response.
* If not already set, then it will be set to DENY. If it is already set when this
* is called, then it will be left unchanged (there is no check for DENY).
*/
private static final HttpChannel.Listener HTTP_CHANNEL_LISTENER = new HttpChannel.Listener()
{
@Override
public void onResponseBegin( Request request )
{
if ( request.getResponse().getHeader( "X-Frame-Options" ) == null )
{
request.getResponse().addHeader( "X-Frame-Options", "DENY" );
}
if ( request.getResponse()
.getHeader( "strict-transport-security" ) == null )
{
request.getResponse()
.addHeader( "strict-transport-security", "max-age=31536000; includeSubDomains; preload;" );
}
}
};

/**
* Tasker receives requests for wres runs and passes them along to queue.
* Actual work is done in WresJob restlet class, Tasker sets up a server.
Expand Down Expand Up @@ -155,6 +145,8 @@ public static void main( String[] args )
//Set up the ServlentContextHandler and add the ContextFilter for X-Frame-Options for all requests.
ServletContextHandler context = new ServletContextHandler( ServletContextHandler.NO_SESSIONS );
context.setContextPath( "/" );

//The servlet holder is declared.
ServletHolder dynamicHolder = context.addServlet( ServletContainer.class,
"/*" );

Expand All @@ -168,11 +160,30 @@ public static void main( String[] args )
dynamicHolder.setInitParameter( "jersey.config.server.provider.classnames",
MultiPartFeature.class.getCanonicalName() );

// Static handler:
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setBaseResource( Resource.newClassPathResource( "html" ) );
//Static handler for index.html. This also impacts the dynamic resources
//by being chained in setHandler, below.
ResourceHandler resourceHandler = new ResourceHandler()
{
@Override
public boolean handle( Request request,
Response response,
Callback callback )
throws Exception
{
response.getHeaders()
.add( "X-Frame-Options", "DENY" );
response.getHeaders()
.add( "strict-transport-security", "max-age=31536000; includeSubDomains; preload;" );
return super.handle( request, response, callback );
}
};

ResourceFactory resourceFactory = ResourceFactory.root();
Resource resource = resourceFactory.newClassLoaderResource( "html", false );
resourceHandler.setBaseResource( resource );

// Have to chain/wrap the handler this way to get both static/dynamic:
// Have to chain/wrap the handler this way to get both static/dynamic.
// This applies the handle method, above, to dynamic and static resources.
resourceHandler.setHandler( context );

// Fix the max server threads for better stack memory predictability,
Expand Down Expand Up @@ -212,7 +223,6 @@ public static void main( String[] args )
httpTwo ) )
{
serverConnector.setPort( Tasker.SERVER_PORT );
serverConnector.addBean( HTTP_CHANNEL_LISTENER );
ServerConnector[] serverConnectors = { serverConnector };
jettyServer.setConnectors( serverConnectors );

Expand Down
Loading