diff --git a/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsCdiExtension.java b/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsCdiExtension.java index 4e2fc9307..27a6f0c14 100644 --- a/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsCdiExtension.java +++ b/microprofile/server/src/main/java/io/helidon/microprofile/server/JaxRsCdiExtension.java @@ -34,8 +34,7 @@ import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Initialized; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.Extension; -import javax.enterprise.inject.spi.ProcessAnnotatedType; -import javax.enterprise.inject.spi.WithAnnotations; +import javax.enterprise.inject.spi.ProcessManagedBean; import javax.ws.rs.Path; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Application; @@ -64,30 +63,34 @@ public class JaxRsCdiExtension implements Extension { private final Set> providers = new HashSet<>(); private final AtomicBoolean setInStone = new AtomicBoolean(false); - private void collectApplications(@Observes ProcessAnnotatedType applicationType) { - applications.add(applicationType.getAnnotatedType().getJavaClass()); + private void collectApplications(@Observes ProcessManagedBean processManagedBean) { + applications.add(processManagedBean.getAnnotatedBeanClass().getJavaClass()); } - private void collectResourceClasses(@Observes @WithAnnotations(Path.class) ProcessAnnotatedType resourceType) { - Class resourceClass = resourceType.getAnnotatedType().getJavaClass(); - if (resourceClass.isInterface()) { - // we are only interested in classes - interface is most likely a REST client API - return; + private void collectResourceClasses(@Observes ProcessManagedBean processManagedBean) { + if (processManagedBean.getAnnotated().isAnnotationPresent(Path.class)) { + Class resourceClass = processManagedBean.getAnnotatedBeanClass().getJavaClass(); + if (resourceClass.isInterface()) { + // we are only interested in classes - interface is most likely a REST client API + return; + } + LOGGER.finest(() -> "Discovered resource class " + resourceClass.getName()); + resources.add(resourceClass); } - LOGGER.finest(() -> "Discovered resource class " + resourceClass.getName()); - resources.add(resourceClass); } - private void collectProviderClasses(@Observes @WithAnnotations(Provider.class) ProcessAnnotatedType providerType) { - Class providerClass = providerType.getAnnotatedType().getJavaClass(); - if (providerClass.isInterface()) { - // we are only interested in classes - LOGGER.finest(() -> "Discovered @Provider interface " + providerClass - .getName() + ", ignored as we only support classes"); - return; + private void collectProviderClasses(@Observes ProcessManagedBean processManagedBean) { + if (processManagedBean.getAnnotated().isAnnotationPresent(Provider.class)) { + Class providerClass = processManagedBean.getAnnotatedBeanClass().getJavaClass(); + if (providerClass.isInterface()) { + // we are only interested in classes + LOGGER.finest(() -> "Discovered @Provider interface " + providerClass + .getName() + ", ignored as we only support classes"); + return; + } + LOGGER.finest(() -> "Discovered @Provider class " + providerClass.getName()); + providers.add(providerClass); } - LOGGER.finest(() -> "Discovered @Provider class " + providerClass.getName()); - providers.add(providerClass); } // once application scoped starts, we do not allow modification of applications diff --git a/tests/apps/bookstore/bookstore-mp/pom.xml b/tests/apps/bookstore/bookstore-mp/pom.xml index ffafa7f75..ae98b7965 100644 --- a/tests/apps/bookstore/bookstore-mp/pom.xml +++ b/tests/apps/bookstore/bookstore-mp/pom.xml @@ -70,6 +70,11 @@ junit-jupiter-api test + + io.helidon.microprofile.tests + helidon-microprofile-tests-junit5 + test + diff --git a/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoCdiExtension.java b/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoCdiExtension.java new file mode 100644 index 000000000..097580244 --- /dev/null +++ b/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoCdiExtension.java @@ -0,0 +1,37 @@ +/* + * 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.apps.bookstore.mp; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.ProcessAnnotatedType; +import javax.enterprise.inject.spi.WithAnnotations; +import javax.ws.rs.Path; + +/** + * A CDI extension to dynamically veto the resource class {@link VetoedResource}. + * After this class is vetoed, it shall not be part of the application. + */ +public class VetoCdiExtension implements Extension { + + private void vetoResourceClass(@Observes @WithAnnotations(Path.class) ProcessAnnotatedType resourceType) { + Class resourceClass = resourceType.getAnnotatedType().getJavaClass(); + if (resourceClass == VetoedResource.class) { + resourceType.veto(); + } + } +} diff --git a/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/BookApplication.java b/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoedResource.java similarity index 52% rename from tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/BookApplication.java rename to tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoedResource.java index 94d06dbb8..eb43f53bd 100644 --- a/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/BookApplication.java +++ b/tests/apps/bookstore/bookstore-mp/src/main/java/io/helidon/tests/apps/bookstore/mp/VetoedResource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019 Oracle and/or its affiliates. All rights reserved. + * 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. @@ -16,18 +16,24 @@ package io.helidon.tests.apps.bookstore.mp; -import java.util.Set; +import javax.enterprise.context.RequestScoped; +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; -import javax.enterprise.context.ApplicationScoped; -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; +/** + * This resource class will be dynamically vetoed by {@link VetoCdiExtension} and + * should not be part of the application after startup. + */ +@Path("/vetoed") +@RequestScoped +public class VetoedResource { -@ApplicationScoped -@ApplicationPath("/") -public class BookApplication extends Application { - - @Override - public Set> getClasses() { - return Set.of(BookResource.class); + @GET + @Produces(MediaType.TEXT_PLAIN) + public Response get() { + return Response.ok().build(); } } diff --git a/tests/apps/bookstore/bookstore-mp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/tests/apps/bookstore/bookstore-mp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 000000000..c1d56cfce --- /dev/null +++ b/tests/apps/bookstore/bookstore-mp/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1,17 @@ +# +# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. +# +# 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. +# + +io.helidon.tests.apps.bookstore.mp.VetoCdiExtension \ No newline at end of file diff --git a/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/BookResourceTest.java b/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/BookResourceTest.java index 3fc9dc192..1709136aa 100644 --- a/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/BookResourceTest.java +++ b/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/BookResourceTest.java @@ -16,50 +16,40 @@ package io.helidon.tests.apps.bookstore.mp; -import io.helidon.tests.apps.bookstore.common.Book; - -import javax.enterprise.inject.se.SeContainer; -import javax.enterprise.inject.spi.CDI; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import javax.inject.Inject; import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.Response; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.stream.Collectors; -import io.helidon.microprofile.server.Server; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; +import io.helidon.microprofile.tests.junit5.HelidonTest; +import io.helidon.tests.apps.bookstore.common.Book; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +@HelidonTest class BookResourceTest { - private static Server server; - - private static Client client = ClientBuilder.newClient(); - - @BeforeAll - public static void startTheServer() { - server = Main.startServer(); - } + @Inject + private WebTarget webTarget; @Test void testBooks() { assertBookStoreSize(0); - Response res = client.target(getConnectionString("/books")) + Response res = webTarget.path("/books") .request() .post(Entity.json(getBookAsJson())); assertEquals(Response.Status.OK.getStatusCode(), res.getStatus()); assertBookStoreSize(1); - res = client.target(getConnectionString("/books/123456")) + res = webTarget.path("/books/123456") .request() .get(); assertEquals(Response.Status.OK.getStatusCode(), res.getStatus()); @@ -67,14 +57,14 @@ class BookResourceTest { assertBookStoreSize(1); - res = client.target(getConnectionString("/books/123456")) + res = webTarget.path("/books/123456") .request() .put(Entity.json(getBookAsJson())); assertEquals(Response.Status.OK.getStatusCode(), res.getStatus()); assertBookStoreSize(1); - res = client.target(getConnectionString("/books/123456")) + res = webTarget.path("/books/123456") .request() .delete(); assertEquals(Response.Status.OK.getStatusCode(), res.getStatus()); @@ -82,16 +72,6 @@ class BookResourceTest { assertBookStoreSize(0); } - @AfterAll - static void destroyClass() { - CDI current = CDI.current(); - ((SeContainer) current).close(); - } - - private String getConnectionString(String path) { - return "http://localhost:" + server.port() + path; - } - private String getBookAsJson() { InputStream is = getClass().getClassLoader().getResourceAsStream("book.json"); if (is != null) { @@ -102,8 +82,7 @@ class BookResourceTest { } private void assertBookStoreSize(int size) { - Book[] jsonArray = client - .target(getConnectionString("/books")) + Book[] jsonArray = webTarget.path("/books") .request() .get(Book[].class); assertEquals(size, jsonArray.length); diff --git a/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/VetoedResourceTest.java b/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/VetoedResourceTest.java new file mode 100644 index 000000000..a7f28d697 --- /dev/null +++ b/tests/apps/bookstore/bookstore-mp/src/test/java/io/helidon/tests/apps/bookstore/mp/VetoedResourceTest.java @@ -0,0 +1,42 @@ +/* + * 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.apps.bookstore.mp; + +import javax.inject.Inject; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; +import io.helidon.microprofile.tests.junit5.HelidonTest; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Test that the resource class {@link VetoedResource} is not part + * of the application after it has been vetoed by {@link VetoCdiExtension}. + */ +@HelidonTest +class VetoedResourceTest { + + @Inject + private WebTarget webTarget; + + @Test + void testVetoed() { + Response res = webTarget.path("/vetoed").request().get(); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), res.getStatus()); + } +}