Skip to content

Commit

Permalink
Support for @ApplicationPath in SE
Browse files Browse the repository at this point in the history
Signed-off-by: jansupol <[email protected]>
  • Loading branch information
jansupol committed Sep 19, 2021
1 parent 34cb077 commit 747153e
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,9 @@ public static HttpServer createHttpServer(final URI uri,
// Map the path to the processor.
final ServerConfiguration config = server.getServerConfiguration();
if (handler != null) {
final String path = uri.getPath().replaceAll("/{2,}", "/");
final String appPath = handler.getApplicationHandler().getConfiguration().getApplicationPath();
final String uriPath = appPath == null ? uri.getPath() : uri.getPath() + "/" + appPath;
final String path = uriPath.replaceAll("/{2,}", "/");

final String contextPath = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
config.addHttpHandler(handler, HttpHandlerRegistration.bulder().contextPath(contextPath).build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,19 @@ public final void configure(final HttpsParameters httpsParameters) {
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_SCHEME_UNKNOWN(uri));
}

final String path = uri.getPath();
if (path == null) {
final String _path = uri.getPath();
if (_path == null) {
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_NULL(uri));
} else if (path.isEmpty()) {
} else if (_path.isEmpty()) {
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_EMPTY(uri));
} else if (path.charAt(0) != '/') {
} else if (_path.charAt(0) != '/') {
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_START(uri));
}

final String appPath = handler.getApplicationHandler().getConfiguration().getApplicationPath();
final String uriPath = appPath == null ? _path : _path + "/" + appPath;
final String path = uriPath.replaceAll("/{2,}", "/");

final int port = (uri.getPort() == -1)
? (isHttp ? Container.DEFAULT_HTTP_PORT : Container.DEFAULT_HTTPS_PORT)
: uri.getPort();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -51,6 +51,7 @@
class JerseyServerHandler extends ChannelInboundHandlerAdapter {

private final URI baseUri;
private final String applicationPath;
private final NettyInputStream nettyInputStream = new NettyInputStream();
private final NettyHttpContainer container;
private final ResourceConfig resourceConfig;
Expand All @@ -65,9 +66,20 @@ class JerseyServerHandler extends ChannelInboundHandlerAdapter {
* @param container Netty container implementation.
*/
public JerseyServerHandler(URI baseUri, NettyHttpContainer container, ResourceConfig resourceConfig) {
this(baseUri, null, container, resourceConfig);
}

/**
* Constructor.
*
* @param baseUri base {@link URI} of the container (includes context path, if any).
* @param container Netty container implementation.
*/
public JerseyServerHandler(URI baseUri, String applicationPath, NettyHttpContainer container, ResourceConfig resourceConfig) {
this.baseUri = baseUri;
this.container = container;
this.resourceConfig = resourceConfig;
this.applicationPath = applicationPath;
}

@Override
Expand Down Expand Up @@ -145,7 +157,11 @@ public void run() {
private ContainerRequest createContainerRequest(ChannelHandlerContext ctx, HttpRequest req) {

String s = req.uri().startsWith("/") ? req.uri().substring(1) : req.uri();
URI requestUri = URI.create(baseUri + ContainerUtils.encodeUnsafeCharacters(s));
final String baseUriStr = baseUri.toString();
final String base = applicationPath == null || applicationPath.isEmpty()
? baseUriStr
: baseUriStr.substring(0, baseUriStr.length() - applicationPath.length() - 1);
final URI requestUri = URI.create(base + ContainerUtils.encodeUnsafeCharacters(s));

ContainerRequest requestContext = new ContainerRequest(
baseUri, requestUri, req.method().name(), getSecurityContext(ctx),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -44,6 +44,7 @@
class JerseyServerInitializer extends ChannelInitializer<SocketChannel> {

private final URI baseUri;
private final String applicationPath;
private final SslContext sslCtx;
private final NettyHttpContainer container;
private final boolean http2;
Expand Down Expand Up @@ -72,7 +73,14 @@ public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContaine
*/
public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContainer container, ResourceConfig resourceConfig,
boolean http2) {
this.baseUri = baseUri;
applicationPath = container.getApplicationHandler().getConfiguration().getApplicationPath();
final String uriPath = applicationPath == null
? baseUri.toString()
: baseUri.toString() + "/" + applicationPath + "/";
final int doubleSlash = uriPath.indexOf("/") + 2;
final String path = uriPath.substring(0, doubleSlash) + uriPath.substring(doubleSlash).replaceAll("/{2,}", "/");

this.baseUri = URI.create(path);
this.sslCtx = sslCtx;
this.container = container;
this.resourceConfig = resourceConfig;
Expand All @@ -96,7 +104,7 @@ public void initChannel(SocketChannel ch) {
}
p.addLast(new HttpServerCodec());
p.addLast(new ChunkedWriteHandler());
p.addLast(new JerseyServerHandler(baseUri, container, resourceConfig));
p.addLast(new JerseyServerHandler(baseUri, applicationPath, container, resourceConfig));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public static final class Builder implements SeBootstrap.Configuration.Builder {
private final Map<String, Object> properties = new HashMap<>();

private Builder() {
this.properties.put(SeBootstrap.Configuration.PROTOCOL, "http");
this.properties.put(SeBootstrap.Configuration.PROTOCOL, "HTTP"); // upper case mandated by javadoc
this.properties.put(SeBootstrap.Configuration.HOST, "localhost");
this.properties.put(SeBootstrap.Configuration.PORT, -1); // Auto-select port 80 for HTTP or 443 for HTTPS
this.properties.put(SeBootstrap.Configuration.ROOT_PATH, "/");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.RuntimeType;
import jakarta.ws.rs.core.Application;
Expand Down Expand Up @@ -57,6 +59,7 @@
import org.glassfish.jersey.server.internal.scanning.FilesScanner;
import org.glassfish.jersey.server.internal.scanning.PackageNamesScanner;
import org.glassfish.jersey.server.model.Resource;
import org.glassfish.jersey.uri.UriComponent;


/**
Expand Down Expand Up @@ -997,6 +1000,32 @@ public final Application getApplication() {
return _getApplication();
}

/**
* Returns encoded value of {@link ApplicationPath} annotation of the Application corresponding
* with this ResourceConfig or {@code null} when the annotation is not present.
*
* @return Returns encoded value of {@link ApplicationPath} annotation of the Application
* corresponding with this ResourceConfig.
*/
public final String getApplicationPath() {
final Application application;
if (ResourceConfig.class.isInstance(_getApplication())) {
final Application unwrap = unwrapCustomRootApplication((ResourceConfig) _getApplication());
application = unwrap != null ? unwrap : _getApplication();
} else {
application = _getApplication();
}
final ApplicationPath appPath = application.getClass().getAnnotation(ApplicationPath.class);
final String value;
if (appPath != null && !appPath.value().isEmpty() && !appPath.value().trim().equals("/")) {
final String val = appPath.value().trim();
value = UriComponent.encode(val.startsWith("/") ? val.substring(1) : val, UriComponent.Type.PATH);
} else {
value = null;
}
return value;
}

/**
* Allows overriding the {@link #getApplication()} method functionality in {@link WrappingResourceConfig}.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -13,15 +13,13 @@
import java.util.HashSet;
import java.util.Set;

import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

/**
* JAX-RS application.
*
* @author Jonathan Benoit
*/
@ApplicationPath("/*")
public class MyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -35,7 +35,7 @@ protected Application configure() {
*/
@Test
public void testDefaultMethods() {
final WebTarget defaultMethodTarget = target("default-method");
final WebTarget defaultMethodTarget = target("j8").path("default-method");

// test default method with no @Path annotation
String response = defaultMethodTarget.request().get(String.class);
Expand All @@ -51,7 +51,7 @@ public void testDefaultMethods() {
*/
@Test
public void testImplementingClass() throws Exception {
final String response = target("default-method").path("class").request().get(String.class);
final String response = target("j8").path("default-method").path("class").request().get(String.class);
assertEquals("class", response);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -36,7 +36,7 @@ protected Application configure() {
*/
@Test
public void testLambdas() {
final WebTarget target = target("lambdas/{p}");
final WebTarget target = target("j8").path("lambdas/{p}");

// test default method with no @Path annotation
String response = target.resolveTemplate("p", "test").request().get(String.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -45,7 +45,7 @@ protected URI getBaseUri() {

@Test
public void testManagedClientSimple() throws Exception {
final WebTarget resource = target().path("client");
final WebTarget resource = target("app").path("client");
Response response;

response = resource.path("animals").request(MediaType.TEXT_PLAIN).get();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -125,7 +125,7 @@ protected URI getBaseUri() {
@Test
public void testItemsStore() throws Exception {
final List<String> items = Collections.unmodifiableList(Arrays.asList("foo", "bar", "baz"));
final WebTarget itemsTarget = target("items");
final WebTarget itemsTarget = target("resources").path("items");
final CountDownLatch latch = new CountDownLatch(items.size() * MAX_LISTENERS * 2); // countdown on all events
final List<Queue<Integer>> indexQueues = new ArrayList<>(MAX_LISTENERS);
final SseEventSource[] sources = new SseEventSource[MAX_LISTENERS];
Expand Down Expand Up @@ -193,7 +193,7 @@ public void testItemsStore() throws Exception {
*/
@Test
public void testEventSourceReconnect() throws Exception {
final WebTarget itemsTarget = target("items");
final WebTarget itemsTarget = target("resources").path("items");
final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2); // countdown only on new item events
final List<Queue<String>> receivedQueues = new ArrayList<>(MAX_LISTENERS);
final SseEventSource[] sources = new SseEventSource[MAX_LISTENERS];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0, which is available at
Expand Down Expand Up @@ -101,7 +101,7 @@ public void testItemsStore() throws Exception {
"foo",
"bar",
"baz"));
final WebTarget itemsTarget = target("items");
final WebTarget itemsTarget = target("resources").path("items");
final CountDownLatch latch = new CountDownLatch(items.size() * MAX_LISTENERS * 2); // countdown on all events
final List<Queue<Integer>> indexQueues = new ArrayList<>(MAX_LISTENERS);
final EventSource[] sources = new EventSource[MAX_LISTENERS];
Expand Down Expand Up @@ -174,9 +174,8 @@ public void testItemsStore() throws Exception {
* @throws Exception in case of a test failure.
*/
@Test
@Ignore //TODO - remove after jacartification
public void testEventSourceReconnect() throws Exception {
final WebTarget itemsTarget = target("items");
final WebTarget itemsTarget = target("resources").path("items");
final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2); // countdown only on new item events
final List<Queue<String>> receivedQueues = new ArrayList<>(MAX_LISTENERS);
final EventSource[] sources = new EventSource[MAX_LISTENERS];
Expand Down
Loading

0 comments on commit 747153e

Please sign in to comment.