diff --git a/bom/pom.xml b/bom/pom.xml index c6ac49a178..8394f55a66 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -1,7 +1,7 @@ + 3.1.7.Final test org.glassfish.jersey.ext.cdi jersey-cdi1x - ${project.version} org.glassfish.jersey.ext.cdi jersey-cdi-inject - ${project.version} + + + org.glassfish.jersey.media + jersey-media-sse org.glassfish.jersey.containers diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java index cc8223ba26..29e11d81f8 100644 --- a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java @@ -19,13 +19,11 @@ import org.glassfish.jersey.internal.PropertiesDelegate; import org.glassfish.jersey.servlet.WebConfig; -import javax.enterprise.inject.spi.BeanManager; import javax.inject.Inject; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ResourceContext; import javax.ws.rs.container.ResourceInfo; import javax.ws.rs.core.Application; @@ -58,10 +56,10 @@ public class ParentInject implements ParentChecker { protected HttpHeaders injectHttpHeaders; @Context - ParamConverterProvider contextParamConverterProvider; + protected ParamConverterProvider contextParamConverterProvider; @Inject - ParamConverterProvider injectParamConverterProvider; + protected ParamConverterProvider injectParamConverterProvider; @Context protected PropertiesDelegate contextPropertiesDelegate; diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/SseAplication.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/SseAplication.java new file mode 100644 index 0000000000..df402b134c --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/SseAplication.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import org.glassfish.jersey.server.ServerProperties; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseBroadcaster; +import javax.ws.rs.sse.SseEventSink; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class SseAplication extends Application { + + @Path(InjectionChecker.ROOT) + @ApplicationScoped + public static class ApplicationScopedResource { + @Context + Sse contextSse; + + @Inject + Sse injectSse; + + private static SseBroadcaster contextSseBroadcaster; + private static SseBroadcaster injectSseBroadcaster; + + @GET + @Path("register/{x}") + @Produces(MediaType.SERVER_SENT_EVENTS) + public void register(@PathParam("x") String inject, @Context SseEventSink eventSink) { + if (inject.contains("context")) { + contextSseBroadcaster = contextSse.newBroadcaster(); + contextSseBroadcaster.register(eventSink); + eventSink.send(contextSse.newEvent(inject)); + } else { + injectSseBroadcaster = injectSse.newBroadcaster(); + injectSseBroadcaster.register(eventSink); + eventSink.send(injectSse.newEvent(inject)); + } + } + + @POST + @Path("broadcast/{x}") + @Consumes(MediaType.MULTIPART_FORM_DATA) + public void broadcast(@PathParam("x") String inject, String event) { + if (inject.contains("context")) { + if (contextSseBroadcaster == null) { + throw new IllegalStateException("contextSseBroadcaster is null"); + } else if (contextSse == null) { + throw new IllegalStateException("contextSse is null"); + } + contextSseBroadcaster.broadcast(contextSse.newEvent(event)); + contextSseBroadcaster.close(); + } else { + if (injectSseBroadcaster == null) { + throw new IllegalStateException("injectSseBroadcaster is null"); + } else if (injectSse == null) { + throw new IllegalStateException("injectSse is null"); + } + injectSseBroadcaster.broadcast(injectSse.newEvent(event)); + injectSseBroadcaster.close(); + } + } + } + + @Override + public Set> getClasses() { + return Collections.singleton(ApplicationScopedResource.class); + } + + @Override + public Map getProperties() { + Map props = new HashMap<>(1); + props.put(ServerProperties.WADL_FEATURE_DISABLE, true); + return props; + } +} diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/SseTest.java b/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/SseTest.java new file mode 100644 index 0000000000..331cf3b512 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/SseTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory; +import org.glassfish.jersey.servlet.ServletProperties; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.ServletDeploymentContext; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.jboss.weld.environment.se.Weld; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.sse.SseEventSource; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class SseTest extends JerseyTest { + private Weld weld; + + @Before + public void setup() { + Assume.assumeTrue(Hk2InjectionManagerFactory.isImmediateStrategy()); + } + + @Override + public void setUp() throws Exception { + if (Hk2InjectionManagerFactory.isImmediateStrategy()) { + weld = new Weld(); + weld.initialize(); + super.setUp(); + } + } + + @Override + public void tearDown() throws Exception { + if (Hk2InjectionManagerFactory.isImmediateStrategy()) { + weld.shutdown(); + super.tearDown(); + } + } + + @Override + protected Application configure() { + return new SseAplication(); + } + + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return new GrizzlyWebTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment() { + return ServletDeploymentContext.builder(configure()) + .initParam(ServletProperties.JAXRS_APPLICATION_CLASS, SseAplication.class.getName()) + .build(); + } + + @Test + public void testContextSse() throws InterruptedException { + testSse("contexted"); + } + + @Test + public void testInjectSse() throws InterruptedException { + testSse("injected"); + } + + private void testSse(String injectType) throws InterruptedException { + final String entity = "Everyone !!!"; + final CountDownLatch broadcastLatch = new CountDownLatch(2); + final CountDownLatch registerLatch = new CountDownLatch(1); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + final WebTarget target = target(InjectionChecker.ROOT).path("register").path(injectType); + try (SseEventSource source = SseEventSource.target(target).build()) { + source.register(inboundSseEvent -> { + try { + byteArrayOutputStream.write(inboundSseEvent.readData(String.class).getBytes()); + registerLatch.countDown(); + broadcastLatch.countDown(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + source.open(); + registerLatch.await(5000, TimeUnit.MILLISECONDS); + Assert.assertEquals(0, registerLatch.getCount()); + + try (Response response = target(InjectionChecker.ROOT).path("broadcast").path(injectType) + .request() + .post(Entity.entity(entity, MediaType.MULTIPART_FORM_DATA_TYPE))) { + String readEntity = response.readEntity(String.class); + // System.out.println(readEntity); + Assert.assertEquals(readEntity, response.getStatus(), Response.Status.NO_CONTENT.getStatusCode()); + + } + broadcastLatch.await(5000, TimeUnit.MILLISECONDS); + } + Assert.assertTrue(byteArrayOutputStream.toString().contains(entity)); + Assert.assertEquals(0, broadcastLatch.getCount()); + } +}