Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into 3.x
Browse files Browse the repository at this point in the history
Signed-off-by: Maxim Nesen <[email protected]>
  • Loading branch information
senivam committed Aug 2, 2022
2 parents 66ee890 + da45922 commit 3619462
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCa
final AtomicBoolean callbackInvoked = new AtomicBoolean(false);
final Throwable failure;
try {
final CompletableFuture<ClientResponse> responseFuture =
new CompletableFuture<ClientResponse>().whenComplete(
final CompletableFuture<ClientResponse> responseFuture = new CompletableFuture<ClientResponse>();
responseFuture.whenComplete(
(clientResponse, throwable) -> {
if (throwable != null && throwable instanceof CancellationException) {
// take care of future cancellation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,31 @@ public static HttpServer createHttpServer(final URI uri,
true);
}

/**
* Create new {@link HttpServer} instance.
*
* @param uri uri on which the {@link ApplicationHandler} will be deployed. Only first path
* segment will be used as context path, the rest will be ignored.
* @param config web application configuration.
* @param secure used for call {@link NetworkListener#setSecure(boolean)}.
* @param sslEngineConfigurator Ssl settings to be passed to {@link NetworkListener#setSSLEngineConfig}.
* @param parentContext DI provider specific context with application's registered bindings.
* @param start if set to false, server will not get started, this allows end users to set
* additional properties on the underlying listener.
* @return newly created {@code HttpServer}.
* @throws ProcessingException in case of any failure when creating a new {@code HttpServer} instance.
* @see GrizzlyHttpContainer
* @since 2.37
*/
public static HttpServer createHttpServer(final URI uri,
final ResourceConfig config,
final boolean secure,
final SSLEngineConfigurator sslEngineConfigurator,
final Object parentContext,
final boolean start) {
return createHttpServer(uri, new GrizzlyHttpContainer(config, parentContext), secure, sslEngineConfigurator, start);
}

/**
* Create new {@link HttpServer} instance.
*
Expand All @@ -209,6 +234,27 @@ public static HttpServer createHttpServer(final URI uri,
return createHttpServer(uri, new GrizzlyHttpContainer(config, parentContext), false, null, true);
}

/**
* Create new {@link HttpServer} instance.
*
* @param uri uri on which the {@link ApplicationHandler} will be deployed. Only first path
* segment will be used as context path, the rest will be ignored.
* @param config web application configuration.
* @param parentContext DI provider specific context with application's registered bindings.
* @param start if set to false, server will not get started, this allows end users to set
* additional properties on the underlying listener.
* @return newly created {@code HttpServer}.
* @throws ProcessingException in case of any failure when creating a new {@code HttpServer} instance.
* @see GrizzlyHttpContainer
* @since 2.37
*/
public static HttpServer createHttpServer(final URI uri,
final ResourceConfig config,
final Object parentContext,
final boolean start) {
return createHttpServer(uri, new GrizzlyHttpContainer(config, parentContext), false, null, start);
}

/**
* Create new {@link HttpServer} instance.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2022 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 @@ -85,6 +85,7 @@ public class ResourceMethodInvoker implements Endpoint, ResourceInfo {
private final Type invocableResponseType;
private final boolean canUseInvocableResponseType;
private final boolean isCompletionStageResponseType;
private final boolean isCompletionStageResponseResponseType; // CompletionStage<Response>
private final Type completionStageResponseType;
private final ResourceMethodDispatcher dispatcher;
private final Method resourceMethod;
Expand Down Expand Up @@ -313,6 +314,8 @@ protected void configure() {
&& CompletionStage.class.isAssignableFrom((Class<?>) ((ParameterizedType) invocableResponseType).getRawType());
this.completionStageResponseType =
isCompletionStageResponseType ? ((ParameterizedType) invocableResponseType).getActualTypeArguments()[0] : null;
this.isCompletionStageResponseResponseType = Class.class.isInstance(completionStageResponseType)
&& Response.class.isAssignableFrom((Class<?>) completionStageResponseType);
}

private <T> void addNameBoundProviders(
Expand Down Expand Up @@ -465,7 +468,7 @@ private Response invoke(final RequestProcessingContext context, final Object res
if (canUseInvocableResponseType
&& response.hasEntity()
&& !(response.getEntityType() instanceof ParameterizedType)) {
response.setEntityType(unwrapInvocableResponseType(context.request()));
response.setEntityType(unwrapInvocableResponseType(context.request(), response.getEntityType()));
}

return response;
Expand All @@ -484,10 +487,10 @@ private Response invoke(final RequestProcessingContext context, final Object res
return jaxrsResponse;
}

private Type unwrapInvocableResponseType(ContainerRequest request) {
private Type unwrapInvocableResponseType(ContainerRequest request, Type entityType) {
if (isCompletionStageResponseType
&& request.resolveProperty(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.TRUE)) {
return completionStageResponseType;
&& request.resolveProperty(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.FALSE)) {
return isCompletionStageResponseResponseType ? entityType : completionStageResponseType;
}
return invocableResponseType;
}
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
<artifactId>jersey-media-json-processing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-gson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2022 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 @@ -65,7 +65,8 @@ public class CompletionStageTest extends JerseyTest {

@Override
protected Application configure() {
return new ResourceConfig(CompletionStageResource.class, DataBeanWriter.class);
return new ResourceConfig(CompletionStageResource.class, DataBeanWriter.class)
.property(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.TRUE);
}

@Test
Expand Down Expand Up @@ -105,6 +106,14 @@ public void testGetCompletedAsync() {
assertThat(response.readEntity(String.class), is(ENTITY));
}

@Test
public void testGetCompletedAsyncResponse() {
Response response = target("cs/completedAsyncResponse").request().get();

assertThat(response.getStatus(), is(200));
assertThat(response.readEntity(List.class).get(0), is(ENTITY));
}

@Test
public void testGetException400Async() {
Response response = target("cs/exception400Async").request().get();
Expand Down Expand Up @@ -214,6 +223,14 @@ public CompletionStage<String> getCompletedAsync() {
return cs;
}

@GET
@Path("/completedAsyncResponse")
public CompletionStage<Response> getCompletedAsyncResponse() {
CompletableFuture<Response> cs = new CompletableFuture<>();
delaySubmit(() -> cs.complete(Response.ok().entity(Collections.singletonList(ENTITY)).build()));
return cs;
}

@GET
@Path("/exception400Async")
public CompletionStage<String> getException400Async() {
Expand Down

0 comments on commit 3619462

Please sign in to comment.