You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2021/04/15 12:18:11 UTC

[cxf] 01/02: CXF-7921: JAXRS CDI extension ignores interfaces annotations (#777)

This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.4.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 63d01f5b8487c7b4596a50e430394eb3a36d1529
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Wed Apr 14 20:22:03 2021 -0400

    CXF-7921: JAXRS CDI extension ignores interfaces annotations (#777)
    
    (cherry picked from commit e173fd47157bad61631a2e87415732d524e05c74)
---
 .../apache/cxf/cdi/JAXRSCdiResourceExtension.java  | 30 +++++++++++--
 .../cxf/cdi/JAXRSCdiResourceExtensionTest.java     |  4 +-
 .../systests/cdi/base/AbstractCdiMultiAppTest.java |  7 +++
 .../cxf/systests/cdi/base/contract/BookStore.java  | 36 ++++++++++++++++
 .../systests/cdi/base/contract/BookStoreImpl.java  | 50 ++++++++++++++++++++++
 .../systest/jaxrs/BookStoreCustomApplication.java  |  3 +-
 .../systest/jaxrs/BookStoreCustomApplication.java  |  3 +-
 7 files changed, 125 insertions(+), 8 deletions(-)

diff --git a/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
index b5d72c4..02263d3 100644
--- a/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
+++ b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
@@ -18,6 +18,7 @@
  */
 package org.apache.cxf.cdi;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,12 +29,14 @@ import java.util.List;
 import java.util.Objects;
 import java.util.ServiceLoader;
 import java.util.Set;
+import java.util.stream.Stream;
 
 import javax.enterprise.context.Dependent;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.event.Observes;
 import javax.enterprise.inject.spi.AfterBeanDiscovery;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Annotated;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
@@ -188,12 +191,13 @@ public class JAXRSCdiResourceExtension implements Extension {
     }
 
     @SuppressWarnings("unchecked")
-    public <T> void collect(@Observes final ProcessBean< T > event) {
-        if (event.getAnnotated().isAnnotationPresent(ApplicationPath.class)) {
+    public <T> void collect(@Observes final ProcessBean< T > event, final BeanManager beanManager) {
+        final Annotated annotated = event.getAnnotated();
+        if (isAnnotationPresent(beanManager, annotated, ApplicationPath.class)) {
             applicationBeans.add(event.getBean());
-        } else if (event.getAnnotated().isAnnotationPresent(Path.class)) {
+        } else if (isAnnotationPresent(beanManager, annotated, Path.class)) {
             serviceBeans.add(event.getBean());
-        } else if (event.getAnnotated().isAnnotationPresent(Provider.class)) {
+        } else if (isAnnotationPresent(beanManager, annotated, Provider.class)) {
             providerBeans.add(event.getBean());
         } else if (event.getBean().getTypes().contains(javax.ws.rs.core.Feature.class)) {
             providerBeans.add(event.getBean());
@@ -574,4 +578,22 @@ public class JAXRSCdiResourceExtension implements Extension {
         }
         return Collections.unmodifiableSet(customContextClasses);
     }
+    
+    @SuppressWarnings("unchecked")
+    private static boolean isAnnotationPresent(final BeanManager beanManager, final Annotated annotated, 
+            final Class<? extends Annotation> annotationType) {
+
+        if (annotated.isAnnotationPresent(annotationType)) {
+            return true;
+        }
+        
+        final Stream<AnnotatedType<?>> annotatedTypes = annotated
+            .getTypeClosure()
+            .stream()
+            .filter(Class.class::isInstance)
+            .map(Class.class::cast)
+            .map(cls -> (AnnotatedType<?>)beanManager.createAnnotatedType(cls));
+        
+        return annotatedTypes.anyMatch(at -> at.isAnnotationPresent(annotationType));
+    }
 }
diff --git a/integration/cdi/src/test/java/org/apache/cxf/cdi/JAXRSCdiResourceExtensionTest.java b/integration/cdi/src/test/java/org/apache/cxf/cdi/JAXRSCdiResourceExtensionTest.java
index d7517c5..28b3ce2 100644
--- a/integration/cdi/src/test/java/org/apache/cxf/cdi/JAXRSCdiResourceExtensionTest.java
+++ b/integration/cdi/src/test/java/org/apache/cxf/cdi/JAXRSCdiResourceExtensionTest.java
@@ -67,7 +67,7 @@ public class JAXRSCdiResourceExtensionTest {
         Class cls = Bus.class;
         when(busBean.getBeanClass()).thenReturn(cls);
         when(busBean.getName()).thenReturn(CdiBusBean.CXF);
-        extension.collect(processBean);
+        extension.collect(processBean, beanManager);
 
         extension.injectBus(event, beanManager);
 
@@ -79,7 +79,7 @@ public class JAXRSCdiResourceExtensionTest {
         when(processBean.getBean()).thenReturn(busBean);
         when(processBean.getAnnotated()).thenReturn(annotated);
         when(annotated.isAnnotationPresent(Path.class)).thenReturn(true);
-        extension.collect(processBean);
+        extension.collect(processBean, beanManager);
 
         extension.injectBus(event, beanManager);
 
diff --git a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/AbstractCdiMultiAppTest.java b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/AbstractCdiMultiAppTest.java
index 1f8e2cf..d79ef9c 100644
--- a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/AbstractCdiMultiAppTest.java
+++ b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/AbstractCdiMultiAppTest.java
@@ -81,6 +81,13 @@ public abstract class AbstractCdiMultiAppTest extends AbstractCdiSingleAppTest {
     }
     
     @Test
+    public void testResponseHasBeenReceivedWhenQueringContractBookstore() {
+        Response r = createWebClient("/rest/v2/bookstore/contract/books").get();
+        assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
+        assertThat(r.getHeaderString("X-Logged"), equalTo("true"));
+    }
+    
+    @Test
     public void testResponseHasBeenReceivedWhenQueringMethodWithNameBinding() {
         Response r = createWebClient("/rest/v2/bookstore/books").get();
         assertEquals(Response.Status.OK.getStatusCode(), r.getStatus());
diff --git a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStore.java b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStore.java
new file mode 100644
index 0000000..17daab4
--- /dev/null
+++ b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStore.java
@@ -0,0 +1,36 @@
+/**
+ * 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.cxf.systests.cdi.base.contract;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+@Path("/bookstore/contract")
+public interface BookStore {
+    @GET
+    @Path("/books")
+    @NotNull @Valid
+    @Produces(MediaType.APPLICATION_JSON)
+    Response getBooks();
+}
diff --git a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStoreImpl.java b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStoreImpl.java
new file mode 100644
index 0000000..6700416
--- /dev/null
+++ b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/contract/BookStoreImpl.java
@@ -0,0 +1,50 @@
+/**
+ * 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.cxf.systests.cdi.base.contract;
+
+import javax.inject.Inject;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.cxf.systests.cdi.base.BookStoreService;
+import org.apache.cxf.systests.cdi.base.bindings.Logged;
+
+@Logged
+public class BookStoreImpl implements BookStore {
+    private BookStoreService service;
+    private UriInfo uriInfo;
+
+    public BookStoreImpl() {
+    }
+
+    @Inject
+    public BookStoreImpl(BookStoreService service, UriInfo uriInfo) {
+        this.service = service;
+        this.uriInfo = uriInfo;
+    }
+
+    @Override
+    public Response getBooks() {
+        return Response
+          .ok()
+          .entity(service.all())
+          .contentLocation(uriInfo.getAbsolutePath())
+          .build();
+    }
+}
diff --git a/systests/cdi/cdi-owb/cdi-multiple-apps-owb/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java b/systests/cdi/cdi-owb/cdi-multiple-apps-owb/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
index aeb3083..49c7534 100644
--- a/systests/cdi/cdi-owb/cdi-multiple-apps-owb/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
+++ b/systests/cdi/cdi-owb/cdi-multiple-apps-owb/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
@@ -35,6 +35,7 @@ import org.apache.cxf.systests.cdi.base.BookStoreByIds;
 import org.apache.cxf.systests.cdi.base.CustomScopedBookStore;
 import org.apache.cxf.systests.cdi.base.RequestScopedBookStore;
 import org.apache.cxf.systests.cdi.base.bindings.LoggingFilter;
+import org.apache.cxf.systests.cdi.base.contract.BookStoreImpl;
 
 @ApplicationPath("/v2")
 public class BookStoreCustomApplication extends Application {
@@ -51,6 +52,6 @@ public class BookStoreCustomApplication extends Application {
     @Override
     public Set<Class<?>> getClasses() {
         return new LinkedHashSet<>(Arrays.asList(BookStore.class, BookStoreByIds.class, 
-             CustomScopedBookStore.class, RequestScopedBookStore.class));
+             CustomScopedBookStore.class, RequestScopedBookStore.class, BookStoreImpl.class));
     }
 }
diff --git a/systests/cdi/cdi-weld/cdi-multiple-apps-weld/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java b/systests/cdi/cdi-weld/cdi-multiple-apps-weld/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
index b6d82f2..4c1f529 100644
--- a/systests/cdi/cdi-weld/cdi-multiple-apps-weld/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
+++ b/systests/cdi/cdi-weld/cdi-multiple-apps-weld/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java
@@ -34,6 +34,7 @@ import org.apache.cxf.systests.cdi.base.BookStore;
 import org.apache.cxf.systests.cdi.base.CustomScopedBookStore;
 import org.apache.cxf.systests.cdi.base.RequestScopedBookStore;
 import org.apache.cxf.systests.cdi.base.bindings.LoggingFilter;
+import org.apache.cxf.systests.cdi.base.contract.BookStoreImpl;
 
 @ApplicationPath("/v2")
 public class BookStoreCustomApplication extends Application {
@@ -50,6 +51,6 @@ public class BookStoreCustomApplication extends Application {
     @Override
     public Set<Class<?>> getClasses() {
         return new LinkedHashSet<>(Arrays.asList(BookStore.class, RequestScopedBookStore.class, 
-            CustomScopedBookStore.class));
+            CustomScopedBookStore.class, BookStoreImpl.class));
     }
 }