mirror of
https://github.com/jlengrand/helidon.git
synced 2026-03-10 08:21:17 +00:00
Request scope propagation for non-async calls in FT (#2495)
* New test for issue 2480. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Swithed to new test framework for MP. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Use a wrapped supplier to propagate request scope even for synchronous calls as some FT primitives (like Retry) use executors and may run code in a different thread. Updated new test that fails without this change and passes with it. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Renamed variable. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Fixed copyright problems. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Dropped fixed port in config. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Remove redundant main class. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>
This commit is contained in:
committed by
GitHub
parent
7425747cc5
commit
e7b9b8b8d3
@@ -577,11 +577,11 @@ class MethodInvoker implements FtSupplier<Object> {
|
||||
return () -> {
|
||||
invocationStartNanos = System.nanoTime();
|
||||
|
||||
// Wrap supplier with request context setup
|
||||
FtSupplier wrappedSupplier = requestContextSupplier(supplier);
|
||||
|
||||
CompletableFuture<Object> resultFuture = new CompletableFuture<>();
|
||||
if (introspector.isAsynchronous()) {
|
||||
// Wrap supplier with request context setup
|
||||
FtSupplier wrappedSupplier = requestContextSupplier(supplier);
|
||||
|
||||
// Invoke supplier in new thread and propagate ccl for config
|
||||
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
|
||||
Single<Object> single = Async.create().invoke(() -> {
|
||||
@@ -634,7 +634,7 @@ class MethodInvoker implements FtSupplier<Object> {
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
resultFuture.complete(supplier.get());
|
||||
resultFuture.complete(wrappedSupplier.get());
|
||||
return resultFuture;
|
||||
} catch (Throwable t) {
|
||||
resultFuture.completeExceptionally(t);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class HelloBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs in Hystrix thread.
|
||||
* Runs in FT thread.
|
||||
*
|
||||
* @return Hello string.
|
||||
*/
|
||||
@@ -68,7 +68,7 @@ public class HelloBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs in Hystrix thread via FT async thread.
|
||||
* Runs via FT async thread.
|
||||
*
|
||||
* @return Hello string.
|
||||
*/
|
||||
|
||||
@@ -40,5 +40,6 @@
|
||||
<module>context-propagation</module>
|
||||
<module>mp-synthetic-app</module>
|
||||
<module>mp-compression</module>
|
||||
<module>request-scope</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
69
tests/functional/request-scope/pom.xml
Normal file
69
tests/functional/request-scope/pom.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2020 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.
|
||||
-->
|
||||
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>helidon-tests-functional-project</artifactId>
|
||||
<groupId>io.helidon.tests.functional</groupId>
|
||||
<version>2.1.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>helidon-tests-functional-request-scope</artifactId>
|
||||
<name>Helidon Functional Test: Request Scope and Fault Tolerance</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.helidon.microprofile.bundles</groupId>
|
||||
<artifactId>helidon-microprofile-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.helidon.config</groupId>
|
||||
<artifactId>helidon-config-yaml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.helidon.microprofile</groupId>
|
||||
<artifactId>helidon-microprofile-fault-tolerance</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.helidon.microprofile.metrics</groupId>
|
||||
<artifactId>helidon-microprofile-metrics</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
<artifactId>hamcrest-all</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.helidon.microprofile.tests</groupId>
|
||||
<artifactId>helidon-microprofile-tests-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
public class IllegalTenantException extends Exception {
|
||||
|
||||
public IllegalTenantException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
@RequestScoped
|
||||
@Path("/test")
|
||||
public class MultiTenantService {
|
||||
|
||||
@Inject
|
||||
SomeService someService;
|
||||
|
||||
@GET
|
||||
public String getTenantResource() {
|
||||
try {
|
||||
return someService.test();
|
||||
} catch (IllegalTenantException e) {
|
||||
return "Expected";
|
||||
} catch (Exception e) {
|
||||
// This path implies a CDI exception related to request scope
|
||||
// See https://github.com/oracle/helidon/issues/2480
|
||||
throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@RequestScoped
|
||||
@TestQualifier
|
||||
public class RequestTestQualifier {
|
||||
|
||||
@Inject
|
||||
TenantContext tenantContext;
|
||||
|
||||
public String test() throws Exception {
|
||||
String tenantId = tenantContext.getTenantId();
|
||||
System.out.println("Tenant Context: " + tenantId);
|
||||
if (tenantId == null) {
|
||||
throw new IllegalTenantException("No tenant context");
|
||||
}
|
||||
return tenantId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.eclipse.microprofile.faulttolerance.Retry;
|
||||
|
||||
@ApplicationScoped
|
||||
public class SomeService {
|
||||
|
||||
@Inject
|
||||
@TestQualifier
|
||||
RequestTestQualifier requestTestQualifier;
|
||||
|
||||
@Retry
|
||||
public String test() throws Exception {
|
||||
return requestTestQualifier.test();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.ws.rs.core.Context;
|
||||
|
||||
import io.helidon.webserver.ServerRequest;
|
||||
|
||||
@RequestScoped
|
||||
public class TenantContext {
|
||||
|
||||
@Context
|
||||
private ServerRequest request;
|
||||
|
||||
public String getTenantId() {
|
||||
return request.headers().value("x-tenant-id").orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.ElementType.TYPE;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Qualifier
|
||||
@Retention(RUNTIME)
|
||||
@Target({TYPE, METHOD, FIELD, PARAMETER})
|
||||
public @interface TestQualifier {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Copyright (c) 2020 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.
|
||||
|
||||
-->
|
||||
|
||||
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
|
||||
version="2.0"
|
||||
bean-discovery-mode="annotated">
|
||||
</beans>
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright (c) 2020 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.
|
||||
#
|
||||
|
||||
server.host=0.0.0.0
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.tests.functional.requestscope;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.client.WebTarget;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import io.helidon.microprofile.tests.junit5.HelidonTest;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
@HelidonTest
|
||||
class TenantTest {
|
||||
|
||||
@Inject
|
||||
private WebTarget baseTarget;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Response r = baseTarget.path("test")
|
||||
.request()
|
||||
.get();
|
||||
assertThat(r.getStatus(), is(HttpResponseStatus.OK.code()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright (c) 2020 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.
|
||||
#
|
||||
|
||||
# Example Logging Configuration File
|
||||
# For more information see $JAVA_HOME/jre/lib/logging.properties
|
||||
|
||||
# Send messages to the console
|
||||
handlers=io.helidon.common.HelidonConsoleHandler
|
||||
|
||||
# HelidonConsoleHandler uses a SimpleFormatter subclass that replaces "!thread!" with the current thread
|
||||
java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$s %3$s !thread!: %5$s%6$s%n
|
||||
|
||||
# Global logging level. Can be overridden by specific loggers
|
||||
.level=INFO
|
||||
|
||||
# Component specific log levels
|
||||
AUDIT.level=FINEST
|
||||
Reference in New Issue
Block a user