diff --git a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java index 8c03feebfee..fa7e56547a0 100644 --- a/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java +++ b/microprofile/fault-tolerance/src/main/java/io/helidon/microprofile/faulttolerance/FaultToleranceExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021 Oracle and/or its affiliates. + * Copyright (c) 2018, 2024 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. @@ -27,6 +27,7 @@ import javax.annotation.Priority; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Destroyed; import javax.enterprise.context.Initialized; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AfterDeploymentValidation; @@ -210,6 +211,16 @@ private void registerFaultToleranceMethods(BeanManager bm, AnnotatedType type } } + /** + * Clean up method states, to make sure we honor different config if CDI is shut down and restarted, + * such as when running tests. + * + * @param event ignored event + */ + void cleanUp(@Observes @Priority(LIBRARY_BEFORE + 15) @Destroyed(ApplicationScoped.class) Object event) { + MethodInvoker.clearMethodStatesMap(); + } + /** * Registers metrics for all FT methods and init executors. * diff --git a/tests/integration/mp-gh-8478/pom.xml b/tests/integration/mp-gh-8478/pom.xml new file mode 100644 index 00000000000..7fdf39b7c2f --- /dev/null +++ b/tests/integration/mp-gh-8478/pom.xml @@ -0,0 +1,62 @@ + + + + + io.helidon.tests.integration + helidon-tests-integration + 2.6.6-SNAPSHOT + + 4.0.0 + + helidon-tests-integration-mp-gh-8478 + Helidon Tests Integration MP GH 8478 + Reproducer for Github issue #8478 - Fault tolerance config fails in HelidonTest + + + + io.helidon.microprofile.server + helidon-microprofile-server + + + io.helidon.microprofile + helidon-microprofile-fault-tolerance + + + io.helidon.microprofile.metrics + helidon-microprofile-metrics + + + org.junit.jupiter + junit-jupiter-api + test + + + org.hamcrest + hamcrest-all + test + + + io.helidon.microprofile.tests + helidon-microprofile-tests-junit5 + test + + + \ No newline at end of file diff --git a/tests/integration/mp-gh-8478/src/main/java/io/helidon/tests/integration/gh8478/Gh8478Resource.java b/tests/integration/mp-gh-8478/src/main/java/io/helidon/tests/integration/gh8478/Gh8478Resource.java new file mode 100644 index 00000000000..927cfe7eec2 --- /dev/null +++ b/tests/integration/mp-gh-8478/src/main/java/io/helidon/tests/integration/gh8478/Gh8478Resource.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 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.integration.gh8478; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Logger; + +import javax.ws.rs.ForbiddenException; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.eclipse.microprofile.faulttolerance.Retry; +import org.eclipse.microprofile.faulttolerance.Timeout; + +@Path("/greet") +@Retry +@Timeout +public class Gh8478Resource { + private static final Logger LOGGER = Logger.getLogger(Gh8478Resource.class.getName()); + + static final AtomicInteger COUNTER = new AtomicInteger(); + + @GET + @Produces(MediaType.TEXT_PLAIN) + public String getDefaultMessage() throws InterruptedException { + COUNTER.incrementAndGet(); + + LOGGER.info("Attempt #" + COUNTER.get() + " before sleep."); + Thread.sleep(100); + if (COUNTER.get() == 3) { + LOGGER.info("Attempt #" + COUNTER.get() + " returning response."); + return "Hello World!"; + } + + LOGGER.info("Attempt #" + COUNTER.get() + " throwing exception."); + throw new ForbiddenException("Intentional exception"); + } +} diff --git a/tests/integration/mp-gh-8478/src/main/resources/META-INF/beans.xml b/tests/integration/mp-gh-8478/src/main/resources/META-INF/beans.xml new file mode 100644 index 00000000000..1fc0bb124af --- /dev/null +++ b/tests/integration/mp-gh-8478/src/main/resources/META-INF/beans.xml @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/tests/integration/mp-gh-8478/src/main/resources/application.yaml b/tests/integration/mp-gh-8478/src/main/resources/application.yaml new file mode 100644 index 00000000000..eb57790080c --- /dev/null +++ b/tests/integration/mp-gh-8478/src/main/resources/application.yaml @@ -0,0 +1,24 @@ +# +# Copyright (c) 2024 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: + port: 8080 + host: 0.0.0.0 + +io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/enabled: true +io.helidon.tests.integration.gh8478.Gh8478Resource/Timeout/enabled: true +io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/maxRetries: 3 +io.helidon.tests.integration.gh8478.Gh8478Resource/Timeout/value: 5000 diff --git a/tests/integration/mp-gh-8478/src/main/resources/logging.properties b/tests/integration/mp-gh-8478/src/main/resources/logging.properties new file mode 100644 index 00000000000..cb327be85a2 --- /dev/null +++ b/tests/integration/mp-gh-8478/src/main/resources/logging.properties @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 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. +# + +handlers=io.helidon.common.HelidonConsoleHandler +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 + +.level=WARNING + +io.helidon.level=INFO diff --git a/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478Test.java b/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478Test.java new file mode 100644 index 00000000000..0a55dcc3600 --- /dev/null +++ b/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478Test.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 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.integration.gh8478; + +import io.helidon.microprofile.tests.junit5.AddConfig; +import io.helidon.microprofile.tests.junit5.HelidonTest; + +import javax.inject.Inject; +import javax.ws.rs.ForbiddenException; +import javax.ws.rs.client.WebTarget; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +@HelidonTest +@AddConfig(key ="io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/enabled", value = "true") +@AddConfig(key ="io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/maxRetries", value = "1") +@AddConfig(key ="io.helidon.tests.integration.gh8478.Gh8478Resource/Timeout/enabled", value = "true") +@AddConfig(key ="io.helidon.tests.integration.gh8478.Gh8478Resource/Timeout/value", value = "10000") +class Gh8478Test { + @Inject + private WebTarget target; + + @BeforeEach + void setUp() { + Gh8478Resource.COUNTER.set(0); + } + + @Test + void test() { + assertThrows(ForbiddenException.class, () -> target + .path("/greet") + .request() + .get(String.class)); + } +} diff --git a/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478YamlTest.java b/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478YamlTest.java new file mode 100644 index 00000000000..137310c9e7e --- /dev/null +++ b/tests/integration/mp-gh-8478/src/test/java/io/helidon/tests/integration/gh8478/Gh8478YamlTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 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.integration.gh8478; + +import io.helidon.microprofile.tests.junit5.HelidonTest; + +import javax.inject.Inject; +import javax.ws.rs.client.WebTarget; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@HelidonTest +class Gh8478YamlTest { + @Inject + private WebTarget target; + + @BeforeEach + void setUp() { + Gh8478Resource.COUNTER.set(0); + } + + @Test + void test() { + String response = target + .path("/greet") + .request() + .get(String.class); + + assertThat(response, is("Hello World!")); + } +} diff --git a/tests/integration/mp-gh-8478/src/test/resources/application.yaml b/tests/integration/mp-gh-8478/src/test/resources/application.yaml new file mode 100644 index 00000000000..21177c8fd3e --- /dev/null +++ b/tests/integration/mp-gh-8478/src/test/resources/application.yaml @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 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. +# + +config_ordinal: 500 +io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/enabled: true +io.helidon.tests.integration.gh8478.Gh8478Resource/Timeout/enabled: false +io.helidon.tests.integration.gh8478.Gh8478Resource/Retry/maxRetries: 3 diff --git a/tests/integration/pom.xml b/tests/integration/pom.xml index f1a62afc094..1d76aa4f8a9 100644 --- a/tests/integration/pom.xml +++ b/tests/integration/pom.xml @@ -50,6 +50,7 @@ mp-gh-3974 mp-gh-4123 mp-gh-4654 + mp-gh-8478 kafka jms config