Skip to content

Commit

Permalink
Upgraded Jersey and Jetty (#2405)
Browse files Browse the repository at this point in the history
  • Loading branch information
breiler authored Dec 30, 2023
1 parent 9a4fa9f commit 78fee70
Show file tree
Hide file tree
Showing 17 changed files with 504 additions and 149 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
<changelist>-SNAPSHOT</changelist>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>9.4.41.v20210516</jetty.version>
<jersey.version>2.29.1</jersey.version>
<jetty.version>12.0.3</jetty.version>
<jersey.version>3.1.5</jersey.version>
<gluegen.version>2.5.0</gluegen.version>
<jogl.version>2.5.0</jogl.version>
<miglayout.version>3.7.4</miglayout.version>
Expand Down
37 changes: 28 additions & 9 deletions ugs-pendant/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,24 @@
<version>${commons-lang3.version}</version>
</dependency>

<!-- Javax APIS -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty.version}</version>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.0.0</version>
</dependency>

<!-- Jersey + Jetty Server -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
Expand Down Expand Up @@ -73,6 +75,23 @@
<artifactId>jersey-media-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey.version}</version>
</dependency>

<!-- For WebSocket -->
<dependency>
<groupId>org.eclipse.jetty.ee10.websocket</groupId>
<artifactId>jetty-ee10-websocket-jakarta-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee10</groupId>
<artifactId>jetty-ee10-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
</dependencies>

<profiles>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016-2019 Will Winder
Copyright 2016-2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
Expand All @@ -21,24 +21,16 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.BackendAPI;

/**
* A factory for accessing the backend in injected resources
* A provider for accessing the backend in injected resources
*/
public class BackendAPIFactory {
private static BackendAPIFactory instance;
private BackendAPI backendAPI;

public static BackendAPIFactory getInstance() {
if (instance == null) {
instance = new BackendAPIFactory();
}
return instance;
}
public class BackendProvider {
private static BackendAPI backendAPI;

public void register(BackendAPI backendAPI) {
this.backendAPI = backendAPI;
public static void register(BackendAPI backendAPI) {
BackendProvider.backendAPI = backendAPI;
}

public BackendAPI getBackendAPI() {
public static BackendAPI getBackendAPI() {
return backendAPI;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016-2019 Will Winder
Copyright 2016-2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
Expand All @@ -20,11 +20,11 @@ This file is part of Universal Gcode Sender (UGS).

import com.willwinder.universalgcodesender.pendantui.v1.model.PendantError;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> {
public class ExceptionMapper implements jakarta.ws.rs.ext.ExceptionMapper<Exception> {

@Override
public Response toResponse(Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2016-2019 Will Winder
Copyright 2016-2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
Expand All @@ -22,24 +22,27 @@ This file is part of Universal Gcode Sender (UGS).
import com.willwinder.universalgcodesender.model.BackendAPI;
import com.willwinder.universalgcodesender.model.UGSEvent;
import com.willwinder.universalgcodesender.model.events.SettingChangedEvent;
import com.willwinder.universalgcodesender.pendantui.html.StaticConfig;
import com.willwinder.universalgcodesender.pendantui.v1.AppV1Config;
import com.willwinder.universalgcodesender.pendantui.v1.ws.EventsSocket;
import com.willwinder.universalgcodesender.services.JogService;
import jakarta.ws.rs.core.UriBuilder;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.glassfish.jersey.jetty.JettyHttpContainerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;

import java.io.ByteArrayOutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.net.URI;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
Expand All @@ -51,55 +54,37 @@ This file is part of Universal Gcode Sender (UGS).
* @author bobj
*/
public class PendantUI implements UGSEventListener {
private BackendAPI backendAPI;
private Server server = null;
private int port = 8080;
public static final String WEBSOCKET_CONTEXT_PATH = "/ws/v1";
public static final String API_CONTEXT_PATH = "/api/v1";
private static final Logger LOG = Logger.getLogger(PendantUI.class.getSimpleName());
private final JogService jogService;
private final BackendAPI backendAPI;
private int port = 8080;
private Server server;

public PendantUI(BackendAPI backendAPI) {
this.backendAPI = backendAPI;
backendAPI.addUGSEventListener(this);
BackendAPIFactory.getInstance().register(backendAPI);
jogService = new JogService(backendAPI);
BackendProvider.register(backendAPI);
}

public Resource getBaseResource(String directory) {
try {
URL res = getClass().getResource(directory);
return Resource.newResource(res);
} catch (Exception e) {
throw new RuntimeException(e);
}
}


/**
* Launches the local web server.
*
* @return the url for the pendant interface
*/
public List<PendantURLBean> start() {
int port = backendAPI.getSettings().getPendantPort();
server = new Server(port);
port = backendAPI.getSettings().getPendantPort();
URI baseUri = UriBuilder.fromUri("http://localhost/").port(port).build();

ResourceHandler staticResourceHandler = new ResourceHandler();
staticResourceHandler.setDirectoriesListed(true);
staticResourceHandler.setWelcomeFiles(new String[]{"index.html"});
staticResourceHandler.setBaseResource(getBaseResource("/resources/ugs-pendant"));
server = JettyHttpContainerFactory.createServer(baseUri, false);
ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
server.setHandler(contextHandlerCollection);

ContextHandler staticResourceHandlerContext = new ContextHandler();
staticResourceHandlerContext.setContextPath("/");
staticResourceHandlerContext.setHandler(staticResourceHandler);

// Create a servlet servletContextHandler
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
servletContextHandler.setContextPath("/api");
ServletHolder servletHolder = servletContextHandler.addServlet(ServletContainer.class, "/*");
servletHolder.setInitOrder(1);
servletHolder.setInitParameter("javax.ws.rs.Application", AppConfig.class.getCanonicalName());

HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]{servletContextHandler, staticResourceHandlerContext, new DefaultHandler()});
server.setHandler(handlers);
contextHandlerCollection.addHandler(createResourceConfigHandler(new StaticConfig(), ""));
contextHandlerCollection.addHandler(createResourceConfigHandler(new AppV1Config(backendAPI, jogService), API_CONTEXT_PATH));
contextHandlerCollection.addHandler(createWebSocketHandler(WEBSOCKET_CONTEXT_PATH));

try {
server.start();
Expand All @@ -110,6 +95,25 @@ public List<PendantURLBean> start() {
return getUrlList();
}

private ServletContextHandler createResourceConfigHandler(ResourceConfig config, String path) {
ServletContainer servletContainer = new ServletContainer(config);
ServletHolder servletHolder = new ServletHolder(servletContainer);
ServletContextHandler servletContextHandler = new ServletContextHandler();
servletContextHandler.setContextPath(path);
servletContextHandler.addServlet(servletHolder, "/*");
return servletContextHandler;
}

private ServletContextHandler createWebSocketHandler(String contextPath) {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath(contextPath);
JakartaWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> {
wsContainer.setDefaultMaxTextMessageBufferSize(65535);
wsContainer.addEndpoint(EventsSocket.class);
});
return context;
}

/**
* Unfortunately, this is not as simple as it seems... since you can have multiple addresses and some of those may not be available via wireless
*
Expand All @@ -131,8 +135,7 @@ public List<PendantURLBean> getUrlList() {
while (addressEnum.hasMoreElements()) {
InetAddress addr = addressEnum.nextElement();
String hostAddress = addr.getHostAddress();
if (!hostAddress.contains(":") &&
!hostAddress.equals("127.0.0.1")) {
if (!hostAddress.contains(":") && !hostAddress.equals("127.0.0.1")) {
String url = "http://" + hostAddress + ":" + port;
ByteArrayOutputStream bout = QRCode.from(url).to(ImageType.PNG).stream();
out.add(new PendantURLBean(url, bout.toByteArray()));
Expand Down Expand Up @@ -162,10 +165,6 @@ public BackendAPI getBackendAPI() {
return backendAPI;
}

public void setBackendAPI(BackendAPI backendAPI) {
this.backendAPI = backendAPI;
}

@Override
public void UGSEvent(UGSEvent evt) {
if (evt instanceof SettingChangedEvent) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
Copyright 2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.pendantui.html;

import org.glassfish.jersey.server.ResourceConfig;

public class StaticConfig extends ResourceConfig {
public StaticConfig() {
register(StaticResource.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2023 Will Winder
This file is part of Universal Gcode Sender (UGS).
UGS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
UGS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with UGS. If not, see <http://www.gnu.org/licenses/>.
*/
package com.willwinder.universalgcodesender.pendantui.html;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;
import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;

import java.io.InputStream;
import java.util.Objects;

@Path("/")
public class StaticResource {

public static final String RESOURCES_PATH = "/resources/ugs-pendant/%s";

private static String getMimeType(String path) {
String mimeType = "application/octet-stream";
if (path.endsWith(".js")) {
mimeType = "text/javascript";
} else if (path.endsWith(".html")) {
mimeType = "text/html";
} else if (path.endsWith(".css")) {
mimeType = "text/css";
}
return mimeType;
}

@GET
public Response getIndex() throws Exception {
return getStaticResource("");
}

@GET
@Path("{path:.*\\.(jpg|gif|html|js|css|ico)$}")
public Response getStaticResource(@PathParam("path") String path) throws Exception {
if (path.equalsIgnoreCase("")) {
path = "index.html";
}

InputStream resource = StaticResource.class.getResourceAsStream(String.format(RESOURCES_PATH, path));
String mimeType = getMimeType(path);
return Objects.isNull(resource) ? Response.status(NOT_FOUND).build() :
Response.ok().entity(resource).header(HttpHeaders.CONTENT_TYPE, mimeType).build();
}
}
Loading

0 comments on commit 78fee70

Please sign in to comment.