This is an automated email from the ASF dual-hosted git repository. rzo1 pushed a commit to branch TOMEE-4342 in repository https://gitbox.apache.org/repos/asf/tomee.git
commit b53eb903944e86eff6fb303b9e121b9889414f0b Author: Richard Zowalla <r...@apache.org> AuthorDate: Sat May 25 21:48:32 2024 +0200 TOMEE-4342 - ApplicationComposer should inject declared custom resources into tests --- .../testing/SingleApplicationComposerBase.java | 40 +++++++++++ container/openejb-junit5/pom.xml | 20 ++++++ .../SingleAppComposerResourceInjectionTest.java | 72 +++++++++++++++++++ .../apache/openejb/junit5/app/MyResourceApp.java | 80 ++++++++++++++++++++++ 4 files changed, 212 insertions(+) diff --git a/container/openejb-core/src/main/java/org/apache/openejb/testing/SingleApplicationComposerBase.java b/container/openejb-core/src/main/java/org/apache/openejb/testing/SingleApplicationComposerBase.java index c54577da8a..b945fcd86d 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/testing/SingleApplicationComposerBase.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/testing/SingleApplicationComposerBase.java @@ -16,13 +16,17 @@ */ package org.apache.openejb.testing; +import jakarta.annotation.Resource; import org.apache.openejb.core.ThreadContext; +import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.spi.ContainerSystem; import org.apache.openejb.util.JavaSecurityManagers; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.inject.OWBInjector; import org.apache.xbean.finder.AnnotationFinder; import org.apache.xbean.finder.archive.FileArchive; +import javax.naming.Context; import java.lang.reflect.Field; import java.util.Iterator; import java.util.concurrent.atomic.AtomicReference; @@ -145,6 +149,31 @@ public class SingleApplicationComposerBase { f.setAccessible(true); } f.set(target, app); + } else if (f.isAnnotationPresent(Resource.class)) { + //TOMEE-4342 + try { + if (!f.isAccessible()) { + f.setAccessible(true); + } + + final Resource r = f.getAnnotation(Resource.class); + final Context jndiContext = SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext(); + String jndiRef = r.lookup(); + if (jndiRef.isEmpty()) { + jndiRef = getJndiRef(r.name()); + if(jndiRef.isEmpty()){ + // last resort: field name + jndiRef = getJndiRef(f.getName()); + } + } + + final Object o = jndiContext.lookup(jndiRef); + if(o != null && f.getType().isAssignableFrom(o.getClass())) { + f.set(target, o); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } } } final Class<?> superclass = aClass.getSuperclass(); @@ -153,6 +182,17 @@ public class SingleApplicationComposerBase { } } + private String getJndiRef(String name) { + if (!name.isEmpty()) { + if (name.startsWith("java:") || name.startsWith("comp/env")) { + return name; + } else { + return "java:comp/env/" + name; + } + } + return name; + } + public boolean isStarted() { return started; } diff --git a/container/openejb-junit5/pom.xml b/container/openejb-junit5/pom.xml index 5a0ad0d4b4..63cfdb3534 100644 --- a/container/openejb-junit5/pom.xml +++ b/container/openejb-junit5/pom.xml @@ -87,6 +87,7 @@ <excludes> <exclude>org/apache/openejb/junit5/SingleAppComposerTest</exclude> <exclude>org/apache/openejb/junit5/SingleAppComposerJVMTest</exclude> + <exclude>org/apache/openejb/junit5/SingleAppComposerResourceInjectionTest</exclude> </excludes> </configuration> </execution> @@ -111,6 +112,25 @@ </argLine> </configuration> </execution> + <execution> + <id>per-jvm-with-resource-tests</id> + <phase>test</phase> + <goals> + <goal>test</goal> + </goals> + <configuration> + <forkCount>1</forkCount> + <reuseForks>true</reuseForks> + <includes> + <include>org/apache/openejb/junit5/SingleAppComposerResourceInjectionTest</include> + </includes> + <argLine> + ${jacocoArgLine} + -enableassertions + -Dtomee.application-composer.application=org.apache.openejb.junit5.app.MyResourceApp + </argLine> + </configuration> + </execution> </executions> </plugin> </plugins> diff --git a/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/SingleAppComposerResourceInjectionTest.java b/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/SingleAppComposerResourceInjectionTest.java new file mode 100644 index 0000000000..aeb88532ef --- /dev/null +++ b/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/SingleAppComposerResourceInjectionTest.java @@ -0,0 +1,72 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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 org.apache.openejb.junit5; + +import jakarta.annotation.Resource; +import jakarta.inject.Inject; +import org.apache.openejb.junit5.app.MyResourceApp; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@RunWithApplicationComposer(mode = ExtensionMode.PER_JVM) +public class SingleAppComposerResourceInjectionTest { + + @Resource + private MyResourceApp.MyResource myResource; + + @Resource(name = "myResource") + private MyResourceApp.MyResource myResource2; + + @Resource(name = "java:comp/env/myResource") + private MyResourceApp.MyResource myResource3; + + @Inject + private MyResourceApp.MyService service; + + @Inject + private MyResourceApp app; + + @Test + public void testInject() { + // In App.. + assertNotNull(app, "app must not be null"); + assertNotNull(app.getResource(), "app#myResource must not be null"); + assertEquals("value1", app.getResource().getAttr1(), "app#attr1 should equal 'value1'"); + assertEquals("value2", app.getResource().getAttr2(), "app#attr2 should equal 'value2'"); + + // In Service. + assertNotNull(service, "service must not be null"); + assertNotNull(service.getResource(), "service#myResource must not be null"); + assertEquals("value1", service.getResource().getAttr1(), "service#resource#attr1 should equal 'value1'"); + assertEquals("value2", service.getResource().getAttr2(), "service#resource#attr2 should equal 'value2'"); + + // In Test -> TOMEE-4342 + assertNotNull(myResource, "'myResource' in test must not be null"); + assertEquals("value1", myResource.getAttr1(), "myResource#attr1 should equal 'value1'"); + assertEquals("value2", myResource.getAttr2(), "myResource#attr2 should equal 'value2'"); + + assertNotNull(myResource2, "'myResource3' in test must not be null"); + assertEquals("value1", myResource3.getAttr1(), "myResource2#attr1 should equal 'value1'"); + assertEquals("value2", myResource3.getAttr2(), "myResource2#attr2 should equal 'value2'"); + + assertNotNull(myResource3, "'myResource3' in test must not be null"); + assertEquals("value1", myResource3.getAttr1(), "myResource#attr1 should equal 'value1'"); + assertEquals("value2", myResource3.getAttr2(), "myResource#attr2 should equal 'value2'"); + } +} diff --git a/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/app/MyResourceApp.java b/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/app/MyResourceApp.java new file mode 100644 index 0000000000..9b13cf03fc --- /dev/null +++ b/container/openejb-junit5/src/test/java/org/apache/openejb/junit5/app/MyResourceApp.java @@ -0,0 +1,80 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.openejb.junit5.app; + +import jakarta.annotation.Resource; +import org.apache.openejb.jee.EjbJar; +import org.apache.openejb.testing.Application; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.Configuration; +import org.apache.openejb.testing.Module; + +import java.util.Properties; + +@Application +public class MyResourceApp { + + @Module + @Classes(cdi = true, value = {MyResourceApp.class, MyService.class}) + public EjbJar modules() { + return new EjbJar(); + } + + @Configuration + public Properties config() { + final Properties p = new Properties(); + p.put("myResource", "new://Resource?class-name=org.apache.openejb.junit5.app.MyResourceApp$MyResource" + + "&constructor=attr1, attr2"); + p.put("myResource.attr1", "value1"); + p.put("myResource.attr2", "value2"); + return p; + } + + @Resource(name = "myResource") + private MyResource resource; + + public MyResource getResource() { + return resource; + } + + public static class MyService { + @Resource(name = "myResource") + private MyResource resource; + + public MyResource getResource() { + return resource; + } + } + public static class MyResource { + + private final String attr1; + private final String attr2; + + public MyResource(String attr1, String attr2) { + this.attr1 = attr1; + this.attr2 = attr2; + } + + public String getAttr1() { + return attr1; + } + + public String getAttr2() { + return attr2; + } + } +}