Skip to content

Commit

Permalink
Jersey JAX-RS client context propagation #3762
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Kec <[email protected]>
  • Loading branch information
danielkec committed Feb 21, 2022
1 parent 1f37bc9 commit ce160df
Show file tree
Hide file tree
Showing 7 changed files with 402 additions and 2 deletions.
19 changes: 18 additions & 1 deletion jersey/client/pom.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2019, 2021 Oracle and/or its affiliates.
Copyright (c) 2019, 2022 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -50,11 +50,28 @@
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-context</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package io.helidon.jersey.client;

import jakarta.annotation.Priority;
import jakarta.ws.rs.Priorities;
import jakarta.ws.rs.client.ClientBuilder;

/**
* Listen to the Jersey's client builder being invoked and register Helidon executor provider.
*/
// Lowest priority gets invoked first and first registered provider wins,
// user's custom ClientBuilderListeners needs to be able to override this
@Priority(Priorities.USER + 100)
public class ClientBuilderListener implements org.glassfish.jersey.client.spi.ClientBuilderListener {

private static final String USE_CONTEXT_AWARE_EXEC_PROVIDER = "io.helidon.jersey.client.useContextAwareExecutorProvider";
private static Boolean useProvider;

@Override
public void onNewBuilder(ClientBuilder builder) {
if (useContextAwareProvider()) {
builder.register(ExecutorProvider.class);
builder.register(ScheduledExecutorProvider.class);
}
}

private boolean useContextAwareProvider() {
if (useProvider == null) {
useProvider = Boolean.parseBoolean(System.getProperty(USE_CONTEXT_AWARE_EXEC_PROVIDER, "true"));
}
return useProvider;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package io.helidon.jersey.client;

import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger;

import io.helidon.common.context.Contexts;

import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.glassfish.jersey.client.ClientAsyncExecutor;
import org.glassfish.jersey.client.internal.LocalizationMessages;
import org.glassfish.jersey.internal.util.collection.LazyValue;
import org.glassfish.jersey.internal.util.collection.Value;
import org.glassfish.jersey.internal.util.collection.Values;
import org.glassfish.jersey.spi.ThreadPoolExecutorProvider;

/**
* Wraps default executor to enable Helidon context propagation for Jersey async calls.
*/
@ClientAsyncExecutor
public class ExecutorProvider extends ThreadPoolExecutorProvider {

static final String THREAD_NAME_PREFIX = "helidon-client-async-executor";
private static final Logger LOGGER = Logger.getLogger(ExecutorProvider.class.getName());
private final LazyValue<Integer> asyncThreadPoolSize;

/**
* Create new instance of the context aware executor provider.
* @param poolSize Maximum pool size
*/
@Inject
public ExecutorProvider(@Named("ClientAsyncThreadPoolSize") final Optional<Integer> poolSize) {
super(THREAD_NAME_PREFIX);

this.asyncThreadPoolSize = Values.lazy((Value<Integer>) () -> {
if (poolSize.filter(i -> i > 0).isEmpty()) {
LOGGER.config(LocalizationMessages.IGNORED_ASYNC_THREADPOOL_SIZE(poolSize.orElse(0)));
// using default
return Integer.MAX_VALUE;
} else {
LOGGER.config(LocalizationMessages.USING_FIXED_ASYNC_THREADPOOL(poolSize.get()));
return poolSize.get();
}
});
}

@Override
protected int getMaximumPoolSize() {
return asyncThreadPoolSize.get();
}

@Override
protected int getCorePoolSize() {
// Mimicking the Executors.newCachedThreadPool and newFixedThreadPool configuration values.
final int maximumPoolSize = getMaximumPoolSize();
if (maximumPoolSize != Integer.MAX_VALUE) {
return maximumPoolSize;
} else {
return 0;
}
}

@Override
public ExecutorService getExecutorService() {
return Contexts.wrap(super.getExecutorService());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package io.helidon.jersey.client;

import java.util.concurrent.ScheduledExecutorService;

import io.helidon.common.context.Contexts;

import org.glassfish.jersey.client.ClientBackgroundScheduler;
import org.glassfish.jersey.spi.ScheduledThreadPoolExecutorProvider;

/**
* Wraps default executor to enable Helidon context propagation for Jersey async calls.
*/
@ClientBackgroundScheduler
public class ScheduledExecutorProvider extends ScheduledThreadPoolExecutorProvider {

/**
* Creates a new instance.
*/
public ScheduledExecutorProvider() {
super("helidon-client-background-scheduler");
}

@Override
protected int getCorePoolSize() {
return 1;
}

@Override
public ScheduledExecutorService getExecutorService() {
return Contexts.wrap(super.getExecutorService());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

/**
* Jersey JAX-RS client with context propagation support.
*/
package io.helidon.jersey.client;
9 changes: 8 additions & 1 deletion jersey/client/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates.
* Copyright (c) 2018, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,4 +21,11 @@
requires transitive jakarta.ws.rs;
requires transitive jersey.common;
requires transitive jersey.client;
requires java.logging;
requires jakarta.inject;
requires jakarta.annotation;
requires io.helidon.common.context;

provides org.glassfish.jersey.client.spi.ClientBuilderListener
with io.helidon.jersey.client.ClientBuilderListener;
}
Loading

0 comments on commit ce160df

Please sign in to comment.