Skip to content

Commit

Permalink
Merge pull request #27685 from mkouba/cp-thread-context-provider-buil…
Browse files Browse the repository at this point in the history
…d-item

SmallRye CP - introduce ThreadContextProviderBuildItem
  • Loading branch information
mkouba authored Sep 6, 2022
2 parents 90ae8fb + be0322e commit 6ba12ab
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 4 deletions.
5 changes: 5 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,11 @@
<artifactId>quarkus-smallrye-context-propagation-deployment</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation-spi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-streams-operators</artifactId>
Expand Down
4 changes: 4 additions & 0 deletions extensions/arc/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx-http-dev-console-spi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ public class ArcConfig {
@ConfigItem
public Optional<List<String>> ignoredSplitPackages;

/**
* Context propagation configuration.
*/
@ConfigItem
public ArcContextPropagationConfig contextPropagation;

public final boolean isRemoveUnusedBeansFieldValid() {
return ALLOWED_REMOVE_UNUSED_BEANS_VALUES.contains(removeUnusedBeans.toLowerCase());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.arc.deployment;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;

@ConfigGroup
public class ArcContextPropagationConfig {

/**
* If set to true and SmallRye Context Propagation extension is present then enable the context propagation for CDI
* contexts.
*/
@ConfigItem(defaultValue = "true")
public boolean enabled;

}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.arc.runtime.LaunchModeProducer;
import io.quarkus.arc.runtime.LoggerProducer;
import io.quarkus.arc.runtime.context.ArcContextProvider;
import io.quarkus.arc.runtime.test.PreloadedTestApplicationClassPredicate;
import io.quarkus.bootstrap.BootstrapDebug;
import io.quarkus.deployment.Capabilities;
Expand Down Expand Up @@ -114,6 +115,7 @@
import io.quarkus.runtime.annotations.QuarkusMain;
import io.quarkus.runtime.test.TestApplicationClassPredicate;
import io.quarkus.runtime.util.HashUtil;
import io.quarkus.smallrye.context.deployment.spi.ThreadContextProviderBuildItem;

/**
* This class contains build steps that trigger various phases of the bean processing.
Expand Down Expand Up @@ -813,6 +815,13 @@ void validateAsyncObserverExceptionHandlers(ValidationPhaseBuildItem validationP
}
}

@BuildStep
void registerContextPropagation(ArcConfig config, BuildProducer<ThreadContextProviderBuildItem> threadContextProvider) {
if (config.contextPropagation.enabled) {
threadContextProvider.produce(new ThreadContextProviderBuildItem(ArcContextProvider.class));
}
}

private void registerListInjectionPointsBeans(BeanRegistrationPhaseBuildItem beanRegistrationPhase,
List<InjectionPointInfo> injectionPoints, BuildProducer<ReflectiveMethodBuildItem> reflectiveMethods,
BuildProducer<ReflectiveFieldBuildItem> reflectiveFields,
Expand Down

This file was deleted.

4 changes: 4 additions & 0 deletions extensions/smallrye-context-propagation/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-context-propagation</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.ShutdownContextBuildItem;
import io.quarkus.deployment.util.ServiceUtil;
import io.quarkus.smallrye.context.deployment.spi.ThreadContextProviderBuildItem;
import io.quarkus.smallrye.context.runtime.SmallRyeContextPropagationProvider;
import io.quarkus.smallrye.context.runtime.SmallRyeContextPropagationRecorder;
import io.smallrye.context.SmallRyeManagedExecutor;
Expand All @@ -59,12 +60,15 @@ void registerBean(BuildProducer<AdditionalBeanBuildItem> additionalBeans) {

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void buildStatic(SmallRyeContextPropagationRecorder recorder)
void buildStatic(SmallRyeContextPropagationRecorder recorder, List<ThreadContextProviderBuildItem> threadContextProviders)
throws ClassNotFoundException, IOException {
List<ThreadContextProvider> discoveredProviders = new ArrayList<>();
List<ContextManagerExtension> discoveredExtensions = new ArrayList<>();
for (Class<?> provider : ServiceUtil.classesNamedIn(Thread.currentThread().getContextClassLoader(),
"META-INF/services/" + ThreadContextProvider.class.getName())) {
List<Class<?>> providers = threadContextProviders.stream().map(ThreadContextProviderBuildItem::getProvider)
.collect(Collectors.toCollection(ArrayList::new));
ServiceUtil.classesNamedIn(Thread.currentThread().getContextClassLoader(),
"META-INF/services/" + ThreadContextProvider.class.getName()).forEach(providers::add);
for (Class<?> provider : providers) {
try {
discoveredProviders.add((ThreadContextProvider) provider.getDeclaredConstructor().newInstance());
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.quarkus.smallrye.context.deployment.test.cdi;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.fail;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ContextNotActiveException;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

import org.eclipse.microprofile.context.ManagedExecutor;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.ManagedContext;
import io.quarkus.test.QuarkusUnitTest;

public class ContextProviderDisabledTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().overrideConfigKey("quarkus.arc.context-propagation.enabled",
"false");

@Inject
ManagedExecutor all;

@Inject
MyRequestBean bean;

@Test
public void testPropagationDisabled() throws InterruptedException, ExecutionException, TimeoutException {
ManagedContext requestContext = Arc.container().requestContext();

requestContext.activate();
assertEquals("FOO", bean.getId());
try {
assertEquals("OK",
all.completedFuture("OK").thenApplyAsync(text -> {
// Assertion error would result in an ExecutionException thrown from the CompletableFuture.get()
assertFalse(requestContext.isActive());
try {
bean.getId();
fail();
} catch (ContextNotActiveException expected) {
}
return text;
}).toCompletableFuture().get(5, TimeUnit.SECONDS));
} finally {
requestContext.terminate();
}
}

@RequestScoped
public static class MyRequestBean {

String id;

@PostConstruct
void init() {
id = "FOO";
}

public String getId() {
return id;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.quarkus.smallrye.context.deployment.test.cdi;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

import org.eclipse.microprofile.context.ManagedExecutor;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.ManagedContext;
import io.quarkus.test.QuarkusUnitTest;

public class ContextProviderEnabledTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest().overrideConfigKey("quarkus.arc.context-propagation.enabled",
"true");

@Inject
ManagedExecutor all;

@Inject
MyRequestBean bean;

@Test
public void testPropagationEnabled() throws InterruptedException, ExecutionException, TimeoutException {
ManagedContext requestContext = Arc.container().requestContext();

requestContext.activate();
assertEquals("FOO", bean.getId());
try {
assertEquals("OK",
all.completedFuture("OK").thenApplyAsync(text -> {
// Assertion error would result in an ExecutionException thrown from the CompletableFuture.get()
assertTrue(requestContext.isActive());
assertEquals("FOO", bean.getId());
return text;
}).toCompletableFuture().get(5, TimeUnit.SECONDS));
;
} finally {
requestContext.terminate();
}
}

@RequestScoped
public static class MyRequestBean {

String id;

@PostConstruct
void init() {
id = "FOO";
}

public String getId() {
return id;
}

}

}
1 change: 1 addition & 0 deletions extensions/smallrye-context-propagation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
<modules>
<module>deployment</module>
<module>runtime</module>
<module>spi</module>
</modules>
</project>
27 changes: 27 additions & 0 deletions extensions/smallrye-context-propagation/spi/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-smallrye-context-propagation-parent</artifactId>
<groupId>io.quarkus</groupId>
<version>999-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>quarkus-smallrye-context-propagation-spi</artifactId>
<name>Quarkus - SmallRye Context Propagation - SPI</name>

<dependencies>
<dependency>
<groupId>org.eclipse.microprofile.context-propagation</groupId>
<artifactId>microprofile-context-propagation-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.smallrye.context.deployment.spi;

import org.eclipse.microprofile.context.spi.ThreadContextProvider;

import io.quarkus.builder.item.MultiBuildItem;

/**
* This build item can be used to register a {@link ThreadContextProvider}.
*/
public final class ThreadContextProviderBuildItem extends MultiBuildItem {

private final Class<? extends ThreadContextProvider> provider;

public ThreadContextProviderBuildItem(Class<? extends ThreadContextProvider> provider) {
this.provider = provider;
}

public Class<? extends ThreadContextProvider> getProvider() {
return provider;
}

}

0 comments on commit 6ba12ab

Please sign in to comment.