Skip to content

Commit 2493265

Browse files
committed
Support for @ApplicationPath in SE
Signed-off-by: jansupol <jan.supol@oracle.com>
1 parent 34cb077 commit 2493265

File tree

18 files changed

+548
-47
lines changed

18 files changed

+548
-47
lines changed

containers/grizzly2-http/src/main/java/org/glassfish/jersey/grizzly2/httpserver/GrizzlyHttpServerFactory.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.IOException;
2020
import java.net.URI;
2121

22+
import jakarta.ws.rs.ApplicationPath;
2223
import jakarta.ws.rs.ProcessingException;
2324

2425
import org.glassfish.jersey.grizzly2.httpserver.internal.LocalizationMessages;
@@ -252,7 +253,9 @@ public static HttpServer createHttpServer(final URI uri,
252253
// Map the path to the processor.
253254
final ServerConfiguration config = server.getServerConfiguration();
254255
if (handler != null) {
255-
final String path = uri.getPath().replaceAll("/{2,}", "/");
256+
final String appPath = handler.getApplicationHandler().getConfiguration().getApplicationPath();
257+
final String uriPath = appPath == null ? uri.getPath() : uri.getPath() + "/" + appPath;
258+
final String path = uriPath.replaceAll("/{2,}", "/");
256259

257260
final String contextPath = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
258261
config.addHttpHandler(handler, HttpHandlerRegistration.bulder().contextPath(contextPath).build());

containers/jdk-http/src/main/java/org/glassfish/jersey/jdkhttp/JdkHttpServerFactory.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.concurrent.Executors;
2424
import java.util.logging.Logger;
2525

26+
import jakarta.ws.rs.ApplicationPath;
2627
import jakarta.ws.rs.ProcessingException;
2728

2829
import javax.net.ssl.SSLContext;
@@ -228,15 +229,19 @@ public final void configure(final HttpsParameters httpsParameters) {
228229
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_SCHEME_UNKNOWN(uri));
229230
}
230231

231-
final String path = uri.getPath();
232-
if (path == null) {
232+
final String _path = uri.getPath();
233+
if (_path == null) {
233234
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_NULL(uri));
234-
} else if (path.isEmpty()) {
235+
} else if (_path.isEmpty()) {
235236
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_EMPTY(uri));
236-
} else if (path.charAt(0) != '/') {
237+
} else if (_path.charAt(0) != '/') {
237238
throw new IllegalArgumentException(LocalizationMessages.ERROR_CONTAINER_URI_PATH_START(uri));
238239
}
239240

241+
final String appPath = handler.getApplicationHandler().getConfiguration().getApplicationPath();
242+
final String uriPath = appPath == null ? _path : _path + "/" + appPath;
243+
final String path = uriPath.replaceAll("/{2,}", "/");
244+
240245
final int port = (uri.getPort() == -1)
241246
? (isHttp ? Container.DEFAULT_HTTP_PORT : Container.DEFAULT_HTTPS_PORT)
242247
: uri.getPort();

containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerHandler.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -51,6 +51,7 @@
5151
class JerseyServerHandler extends ChannelInboundHandlerAdapter {
5252

5353
private final URI baseUri;
54+
private final String applicationPath;
5455
private final NettyInputStream nettyInputStream = new NettyInputStream();
5556
private final NettyHttpContainer container;
5657
private final ResourceConfig resourceConfig;
@@ -65,9 +66,20 @@ class JerseyServerHandler extends ChannelInboundHandlerAdapter {
6566
* @param container Netty container implementation.
6667
*/
6768
public JerseyServerHandler(URI baseUri, NettyHttpContainer container, ResourceConfig resourceConfig) {
69+
this(baseUri, null, container, resourceConfig);
70+
}
71+
72+
/**
73+
* Constructor.
74+
*
75+
* @param baseUri base {@link URI} of the container (includes context path, if any).
76+
* @param container Netty container implementation.
77+
*/
78+
public JerseyServerHandler(URI baseUri, String applicationPath, NettyHttpContainer container, ResourceConfig resourceConfig) {
6879
this.baseUri = baseUri;
6980
this.container = container;
7081
this.resourceConfig = resourceConfig;
82+
this.applicationPath = applicationPath;
7183
}
7284

7385
@Override
@@ -145,7 +157,11 @@ public void run() {
145157
private ContainerRequest createContainerRequest(ChannelHandlerContext ctx, HttpRequest req) {
146158

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

150166
ContainerRequest requestContext = new ContainerRequest(
151167
baseUri, requestUri, req.method().name(), getSecurityContext(ctx),

containers/netty-http/src/main/java/org/glassfish/jersey/netty/httpserver/JerseyServerInitializer.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -44,6 +44,7 @@
4444
class JerseyServerInitializer extends ChannelInitializer<SocketChannel> {
4545

4646
private final URI baseUri;
47+
private final String applicationPath;
4748
private final SslContext sslCtx;
4849
private final NettyHttpContainer container;
4950
private final boolean http2;
@@ -72,7 +73,14 @@ public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContaine
7273
*/
7374
public JerseyServerInitializer(URI baseUri, SslContext sslCtx, NettyHttpContainer container, ResourceConfig resourceConfig,
7475
boolean http2) {
75-
this.baseUri = baseUri;
76+
applicationPath = container.getApplicationHandler().getConfiguration().getApplicationPath();
77+
final String uriPath = applicationPath == null
78+
? baseUri.toString()
79+
: baseUri.toString() + "/" + applicationPath + "/";
80+
final int doubleSlash = uriPath.indexOf("/") + 2;
81+
final String path = uriPath.substring(0, doubleSlash) + uriPath.substring(doubleSlash).replaceAll("/{2,}", "/");
82+
83+
this.baseUri = URI.create(path);
7684
this.sslCtx = sslCtx;
7785
this.container = container;
7886
this.resourceConfig = resourceConfig;
@@ -96,7 +104,7 @@ public void initChannel(SocketChannel ch) {
96104
}
97105
p.addLast(new HttpServerCodec());
98106
p.addLast(new ChunkedWriteHandler());
99-
p.addLast(new JerseyServerHandler(baseUri, container, resourceConfig));
107+
p.addLast(new JerseyServerHandler(baseUri, applicationPath, container, resourceConfig));
100108
}
101109
}
102110

core-server/src/main/java/org/glassfish/jersey/server/JerseySeBootstrapConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public static final class Builder implements SeBootstrap.Configuration.Builder {
136136
private final Map<String, Object> properties = new HashMap<>();
137137

138138
private Builder() {
139-
this.properties.put(SeBootstrap.Configuration.PROTOCOL, "http");
139+
this.properties.put(SeBootstrap.Configuration.PROTOCOL, "HTTP"); // upper case mandated by javadoc
140140
this.properties.put(SeBootstrap.Configuration.HOST, "localhost");
141141
this.properties.put(SeBootstrap.Configuration.PORT, -1); // Auto-select port 80 for HTTP or 443 for HTTPS
142142
this.properties.put(SeBootstrap.Configuration.ROOT_PATH, "/");

core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java

+25
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
import java.util.HashSet;
2626
import java.util.IdentityHashMap;
2727
import java.util.Map;
28+
import java.util.Optional;
2829
import java.util.Set;
2930
import java.util.logging.Level;
3031
import java.util.logging.Logger;
3132
import java.util.stream.Collectors;
3233

34+
import jakarta.ws.rs.ApplicationPath;
3335
import jakarta.ws.rs.Path;
3436
import jakarta.ws.rs.RuntimeType;
3537
import jakarta.ws.rs.core.Application;
@@ -57,6 +59,7 @@
5759
import org.glassfish.jersey.server.internal.scanning.FilesScanner;
5860
import org.glassfish.jersey.server.internal.scanning.PackageNamesScanner;
5961
import org.glassfish.jersey.server.model.Resource;
62+
import org.glassfish.jersey.uri.UriComponent;
6063

6164

6265
/**
@@ -997,6 +1000,28 @@ public final Application getApplication() {
9971000
return _getApplication();
9981001
}
9991002

1003+
/**
1004+
* Returns encoded value of {@link ApplicationPath} annotation of the Application corresponding
1005+
* with this ResourceConfig or {@code null} when the annotation is not present.
1006+
*
1007+
* @return Returns encoded value of {@link ApplicationPath} annotation of the Application
1008+
* corresponding with this ResourceConfig.
1009+
*/
1010+
public final String getApplicationPath() {
1011+
final Application application;
1012+
if (ResourceConfig.class.isInstance(_getApplication())) {
1013+
final Application unwrap = unwrapCustomRootApplication((ResourceConfig) _getApplication());
1014+
application = unwrap != null ? unwrap : _getApplication();
1015+
} else {
1016+
application = _getApplication();
1017+
}
1018+
final ApplicationPath appPath = application.getClass().getAnnotation(ApplicationPath.class);
1019+
final String value = appPath != null && !appPath.value().isEmpty() && !appPath.value().trim().equals("/")
1020+
? UriComponent.encode(appPath.value(), UriComponent.Type.PATH)
1021+
: null;
1022+
return value;
1023+
}
1024+
10001025
/**
10011026
* Allows overriding the {@link #getApplication()} method functionality in {@link WrappingResourceConfig}.
10021027
*

examples/cdi-webapp/src/main/java/org/glassfish/jersey/examples/cdi/resources/MyApplication.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -13,15 +13,13 @@
1313
import java.util.HashSet;
1414
import java.util.Set;
1515

16-
import jakarta.ws.rs.ApplicationPath;
1716
import jakarta.ws.rs.core.Application;
1817

1918
/**
2019
* JAX-RS application.
2120
*
2221
* @author Jonathan Benoit
2322
*/
24-
@ApplicationPath("/*")
2523
public class MyApplication extends Application {
2624
@Override
2725
public Set<Class<?>> getClasses() {

examples/java8-webapp/src/test/java/org/glassfish/jersey/examples/java8/DefaultMethodResourceTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -35,7 +35,7 @@ protected Application configure() {
3535
*/
3636
@Test
3737
public void testDefaultMethods() {
38-
final WebTarget defaultMethodTarget = target("default-method");
38+
final WebTarget defaultMethodTarget = target("j8").path("default-method");
3939

4040
// test default method with no @Path annotation
4141
String response = defaultMethodTarget.request().get(String.class);
@@ -51,7 +51,7 @@ public void testDefaultMethods() {
5151
*/
5252
@Test
5353
public void testImplementingClass() throws Exception {
54-
final String response = target("default-method").path("class").request().get(String.class);
54+
final String response = target("j8").path("default-method").path("class").request().get(String.class);
5555
assertEquals("class", response);
5656
}
5757
}

examples/java8-webapp/src/test/java/org/glassfish/jersey/examples/java8/LambdaResourceTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -36,7 +36,7 @@ protected Application configure() {
3636
*/
3737
@Test
3838
public void testLambdas() {
39-
final WebTarget target = target("lambdas/{p}");
39+
final WebTarget target = target("j8").path("lambdas/{p}");
4040

4141
// test default method with no @Path annotation
4242
String response = target.resolveTemplate("p", "test").request().get(String.class);

examples/managed-client-simple-webapp/src/test/java/org/glassfish/jersey/examples/managedclientsimple/ManagedClientSimpleTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -45,7 +45,7 @@ protected URI getBaseUri() {
4545

4646
@Test
4747
public void testManagedClientSimple() throws Exception {
48-
final WebTarget resource = target().path("client");
48+
final WebTarget resource = target("app").path("client");
4949
Response response;
5050

5151
response = resource.path("animals").request(MediaType.TEXT_PLAIN).get();

examples/sse-item-store-jaxrs-webapp/src/test/java/org/glassfish/jersey/examples/sseitemstore/jaxrs/JaxrsItemStoreResourceTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -125,7 +125,7 @@ protected URI getBaseUri() {
125125
@Test
126126
public void testItemsStore() throws Exception {
127127
final List<String> items = Collections.unmodifiableList(Arrays.asList("foo", "bar", "baz"));
128-
final WebTarget itemsTarget = target("items");
128+
final WebTarget itemsTarget = target("resources").path("items");
129129
final CountDownLatch latch = new CountDownLatch(items.size() * MAX_LISTENERS * 2); // countdown on all events
130130
final List<Queue<Integer>> indexQueues = new ArrayList<>(MAX_LISTENERS);
131131
final SseEventSource[] sources = new SseEventSource[MAX_LISTENERS];
@@ -193,7 +193,7 @@ public void testItemsStore() throws Exception {
193193
*/
194194
@Test
195195
public void testEventSourceReconnect() throws Exception {
196-
final WebTarget itemsTarget = target("items");
196+
final WebTarget itemsTarget = target("resources").path("items");
197197
final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2); // countdown only on new item events
198198
final List<Queue<String>> receivedQueues = new ArrayList<>(MAX_LISTENERS);
199199
final SseEventSource[] sources = new SseEventSource[MAX_LISTENERS];

examples/sse-item-store-jersey-webapp/src/test/java/org/glassfish/jersey/examples/sseitemstore/jersey/JerseyItemStoreResourceTest.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -101,7 +101,7 @@ public void testItemsStore() throws Exception {
101101
"foo",
102102
"bar",
103103
"baz"));
104-
final WebTarget itemsTarget = target("items");
104+
final WebTarget itemsTarget = target("resources").path("items");
105105
final CountDownLatch latch = new CountDownLatch(items.size() * MAX_LISTENERS * 2); // countdown on all events
106106
final List<Queue<Integer>> indexQueues = new ArrayList<>(MAX_LISTENERS);
107107
final EventSource[] sources = new EventSource[MAX_LISTENERS];
@@ -174,9 +174,8 @@ public void testItemsStore() throws Exception {
174174
* @throws Exception in case of a test failure.
175175
*/
176176
@Test
177-
@Ignore //TODO - remove after jacartification
178177
public void testEventSourceReconnect() throws Exception {
179-
final WebTarget itemsTarget = target("items");
178+
final WebTarget itemsTarget = target("resources").path("items");
180179
final CountDownLatch latch = new CountDownLatch(MAX_ITEMS * MAX_LISTENERS * 2); // countdown only on new item events
181180
final List<Queue<String>> receivedQueues = new ArrayList<>(MAX_LISTENERS);
182181
final EventSource[] sources = new EventSource[MAX_LISTENERS];

0 commit comments

Comments
 (0)