You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2017/02/17 13:59:08 UTC
cxf git commit: Support for the constructor injection into the
singleton resources starting from Application.getClasses
Repository: cxf
Updated Branches:
refs/heads/master 19a4d72a3 -> 64e17b906
Support for the constructor injection into the singleton resources starting from Application.getClasses
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/64e17b90
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/64e17b90
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/64e17b90
Branch: refs/heads/master
Commit: 64e17b90635e7acd6f0836ab2bb8f6ede026ecff
Parents: 19a4d72
Author: Sergey Beryozkin <sb...@gmail.com>
Authored: Fri Feb 17 13:58:53 2017 +0000
Committer: Sergey Beryozkin <sb...@gmail.com>
Committed: Fri Feb 17 13:58:53 2017 +0000
----------------------------------------------------------------------
.../cxf/cdi/JAXRSCdiResourceExtension.java | 6 +-
.../cxf/jaxrs/JAXRSServerFactoryBean.java | 22 +--
.../cxf/jaxrs/impl/RuntimeDelegateImpl.java | 2 +-
.../lifecycle/SingletonResourceProvider.java | 36 ++++-
.../jaxrs/servlet/CXFNonSpringJaxrsServlet.java | 22 ++-
.../apache/cxf/jaxrs/utils/ResourceUtils.java | 33 +++--
.../cxf/jaxrs/model/ClassResourceInfoTest.java | 2 +-
.../cxf/jaxrs/utils/ResourceUtilsTest.java | 6 +-
.../cxf/systest/jaxrs/sse/BookStore2.java | 136 +++++++++++++++++++
.../cxf/systest/jaxrs/sse/SseApplication.java | 38 ++++++
.../test/resources/jaxrs_sse/WEB-INF/web.xml | 8 +-
11 files changed, 265 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
----------------------------------------------------------------------
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 51c4f2f..8ec1781 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
@@ -187,7 +187,8 @@ public class JAXRSCdiResourceExtension implements Extension {
private JAXRSServerFactoryBean createFactoryInstance(final Application application, final List< ? > services,
final List< ? > providers, final List< ? extends Feature > features) {
- final JAXRSServerFactoryBean instance = ResourceUtils.createApplication(application, false, false, bus);
+ final JAXRSServerFactoryBean instance =
+ ResourceUtils.createApplication(application, false, false, false, bus);
instance.setServiceBeans(new ArrayList<>(services));
instance.setProviders(providers);
instance.setProviders(loadExternalProviders());
@@ -203,7 +204,8 @@ public class JAXRSCdiResourceExtension implements Extension {
*/
private JAXRSServerFactoryBean createFactoryInstance(final Application application, final BeanManager beanManager) {
- final JAXRSServerFactoryBean instance = ResourceUtils.createApplication(application, false, false, bus);
+ final JAXRSServerFactoryBean instance =
+ ResourceUtils.createApplication(application, false, false, false, bus);
final ClassifiedClasses classified = classes2singletons(application, beanManager);
instance.setProviders(classified.getProviders());
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
index 123642f..3aff010 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServerFactoryBean.java
@@ -44,6 +44,7 @@ import org.apache.cxf.jaxrs.ext.ResourceComparator;
import org.apache.cxf.jaxrs.impl.RequestPreprocessor;
import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider;
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.jaxrs.model.ApplicationInfo;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
@@ -159,7 +160,6 @@ public class JAXRSServerFactoryBean extends AbstractJAXRSFactoryBean {
checkResources(true);
if (serviceFactory.getService() == null) {
serviceFactory.create();
- updateClassResourceProviders();
}
Endpoint ep = createEndpoint();
@@ -196,6 +196,7 @@ public class JAXRSServerFactoryBean extends AbstractJAXRSFactoryBean {
applyBusFeatures(getBus());
applyFeatures();
+ updateClassResourceProviders(ep);
injectContexts(factory);
factory.applyDynamicFeatures(getServiceFactory().getClassResourceInfo());
@@ -427,17 +428,18 @@ public class JAXRSServerFactoryBean extends AbstractJAXRSFactoryBean {
}
}
- protected void updateClassResourceProviders() {
+ protected void updateClassResourceProviders(Endpoint ep) {
for (ClassResourceInfo cri : serviceFactory.getClassResourceInfo()) {
- if (cri.getResourceProvider() != null) {
- continue;
+ if (cri.getResourceProvider() == null) {
+ ResourceProvider rp = resourceProviders.get(cri.getResourceClass());
+ if (rp != null) {
+ cri.setResourceProvider(rp);
+ } else {
+ setDefaultResourceProvider(cri);
+ }
}
-
- ResourceProvider rp = resourceProviders.get(cri.getResourceClass());
- if (rp != null) {
- cri.setResourceProvider(rp);
- } else {
- setDefaultResourceProvider(cri);
+ if (cri.getResourceProvider() instanceof SingletonResourceProvider) {
+ ((SingletonResourceProvider)cri.getResourceProvider()).init(ep);
}
}
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RuntimeDelegateImpl.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RuntimeDelegateImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RuntimeDelegateImpl.java
index 612578c..3dcc399 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RuntimeDelegateImpl.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RuntimeDelegateImpl.java
@@ -110,7 +110,7 @@ public class RuntimeDelegateImpl extends RuntimeDelegate {
&& !JAXRSServerFactoryBean.class.isAssignableFrom(endpointType))) {
throw new IllegalArgumentException();
}
- JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, false);
+ JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, false, false, false, null);
if (JAXRSServerFactoryBean.class.isAssignableFrom(endpointType)) {
return endpointType.cast(bean);
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/SingletonResourceProvider.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/SingletonResourceProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/SingletonResourceProvider.java
index 519b4fc..a188359 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/SingletonResourceProvider.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/lifecycle/SingletonResourceProvider.java
@@ -19,10 +19,17 @@
package org.apache.cxf.jaxrs.lifecycle;
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+
import org.apache.cxf.common.util.ClassHelper;
+import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxrs.utils.InjectionUtils;
import org.apache.cxf.jaxrs.utils.ResourceUtils;
+import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.factory.ServiceConstructionException;
/**
* The default singleton resource provider which returns
@@ -30,19 +37,38 @@ import org.apache.cxf.message.Message;
*/
public class SingletonResourceProvider implements ResourceProvider {
private Object resourceInstance;
-
+ private boolean callPostConstruct;
+
public SingletonResourceProvider(Object o, boolean callPostConstruct) {
resourceInstance = o;
- if (callPostConstruct) {
- InjectionUtils.invokeLifeCycleMethod(o,
- ResourceUtils.findPostConstructMethod(ClassHelper.getRealClass(o)));
- }
+ this.callPostConstruct = callPostConstruct;
}
public SingletonResourceProvider(Object o) {
this(o, false);
}
+ public void init(Endpoint ep) {
+ if (resourceInstance instanceof Constructor) {
+ Constructor<?> c = (Constructor<?>)resourceInstance;
+ Message m = new MessageImpl();
+ ExchangeImpl exchange = new ExchangeImpl();
+ exchange.put(Endpoint.class, ep);
+ m.setExchange(exchange);
+ Object[] values =
+ ResourceUtils.createConstructorArguments(c, m, false, Collections.emptyMap());
+ try {
+ resourceInstance = values.length > 0 ? c.newInstance(values) : c.newInstance(new Object[]{});
+ } catch (Exception ex) {
+ throw new ServiceConstructionException(ex);
+ }
+ }
+ if (callPostConstruct) {
+ InjectionUtils.invokeLifeCycleMethod(resourceInstance,
+ ResourceUtils.findPostConstructMethod(ClassHelper.getRealClass(resourceInstance)));
+ }
+ }
+
/**
* {@inheritDoc}
*/
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
index 1ad1fe9..a90ef65 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/servlet/CXFNonSpringJaxrsServlet.java
@@ -415,7 +415,11 @@ public class CXFNonSpringJaxrsServlet extends CXFNonSpringServlet {
return map;
}
-
+ protected boolean isResourceLifecycleASingleton(ServletConfig servletConfig) {
+ String scope = servletConfig.getInitParameter(SERVICE_SCOPE_PARAM);
+ return SERVICE_SCOPE_SINGLETON.equals(scope);
+ }
+
protected Object createSingletonInstance(Class<?> cls, Map<String, List<String>> props, ServletConfig sc)
throws ServletException {
Constructor<?> c = ResourceUtils.findResourceConstructor(cls, false);
@@ -500,9 +504,12 @@ public class CXFNonSpringJaxrsServlet extends CXFNonSpringServlet {
for (String cName : classNames) {
ApplicationInfo providerApp = createApplicationInfo(cName, servletConfig);
- JAXRSServerFactoryBean bean = ResourceUtils.createApplication(providerApp.getProvider(),
+ JAXRSServerFactoryBean bean = ResourceUtils.createApplication(
+ providerApp.getProvider(),
ignoreApplicationPath,
- getStaticSubResolutionValue(servletConfig));
+ getStaticSubResolutionValue(servletConfig),
+ isResourceLifecycleASingleton(servletConfig),
+ getBus());
String splitChar = getParameterSplitChar(servletConfig);
setAllInterceptors(bean, servletConfig, splitChar);
setInvoker(bean, servletConfig);
@@ -523,9 +530,12 @@ public class CXFNonSpringJaxrsServlet extends CXFNonSpringServlet {
protected void createServerFromApplication(ServletConfig servletConfig)
throws ServletException {
- JAXRSServerFactoryBean bean = ResourceUtils.createApplication(getApplication(),
- isIgnoreApplicationPath(servletConfig),
- getStaticSubResolutionValue(servletConfig));
+ JAXRSServerFactoryBean bean = ResourceUtils.createApplication(
+ getApplication(),
+ isIgnoreApplicationPath(servletConfig),
+ getStaticSubResolutionValue(servletConfig),
+ isResourceLifecycleASingleton(servletConfig),
+ getBus());
bean.setBus(getBus());
bean.setApplication(getApplication());
bean.create();
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
index 6fffea3..999a492 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java
@@ -100,6 +100,7 @@ import org.apache.cxf.jaxrs.model.UserOperation;
import org.apache.cxf.jaxrs.model.UserResource;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.staxutils.StaxUtils;
@@ -124,7 +125,7 @@ public final class ResourceUtils {
SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.ContainerRequestFilter");
SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.ContainerResponseFilter");
SERVER_PROVIDER_CLASS_NAMES.add("javax.ws.rs.container.DynamicFeature");
- SERVER_PROVIDER_CLASS_NAMES.add("org.apache.cxf.jaxrs.ext.ContextResolver");
+ SERVER_PROVIDER_CLASS_NAMES.add("org.apache.cxf.jaxrs.ext.ContextProvider");
}
@@ -779,12 +780,15 @@ public final class ResourceUtils {
Message m,
boolean perRequest,
Map<Class<?>, Object> contextValues) {
+ if (m == null) {
+ m = new MessageImpl();
+ }
Class<?>[] params = c.getParameterTypes();
Annotation[][] anns = c.getParameterAnnotations();
Type[] genericTypes = c.getGenericParameterTypes();
@SuppressWarnings("unchecked")
- MultivaluedMap<String, String> templateValues = m == null ? null
- : (MultivaluedMap<String, String>)m.get(URITemplate.TEMPLATE_PARAMETERS);
+ MultivaluedMap<String, String> templateValues =
+ (MultivaluedMap<String, String>)m.get(URITemplate.TEMPLATE_PARAMETERS);
Object[] values = new Object[params.length];
for (int i = 0; i < params.length; i++) {
if (AnnotationUtils.getAnnotation(anns[i], Context.class) != null) {
@@ -808,18 +812,13 @@ public final class ResourceUtils {
}
return values;
}
- public static JAXRSServerFactoryBean createApplication(Application app, boolean ignoreAppPath) {
- return createApplication(app, ignoreAppPath, false);
- }
-
- public static JAXRSServerFactoryBean createApplication(Application app, boolean ignoreAppPath,
- boolean staticSubresourceResolution) {
- return createApplication(app, ignoreAppPath, staticSubresourceResolution, null);
- }
-
+
@SuppressWarnings("unchecked")
- public static JAXRSServerFactoryBean createApplication(Application app, boolean ignoreAppPath,
- boolean staticSubresourceResolution, Bus bus) {
+ public static JAXRSServerFactoryBean createApplication(Application app,
+ boolean ignoreAppPath,
+ boolean staticSubresourceResolution,
+ boolean useSingletonResourceProvider,
+ Bus bus) {
Set<Object> singletons = app.getSingletons();
verifySingletons(singletons);
@@ -839,7 +838,11 @@ public final class ResourceUtils {
features.add(createFeatureInstance((Class<? extends Feature>) cls));
} else {
resourceClasses.add(cls);
- map.put(cls, new PerRequestResourceProvider(cls));
+ if (useSingletonResourceProvider) {
+ map.put(cls, new SingletonResourceProvider(createProviderInstance(cls)));
+ } else {
+ map.put(cls, new PerRequestResourceProvider(cls));
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java
index 251f7f2..a0b839f 100644
--- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/model/ClassResourceInfoTest.java
@@ -249,7 +249,7 @@ public class ClassResourceInfoTest extends Assert {
@Test
public void testNameBindings() {
Application app = new TestApplication();
- JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, true, true);
+ JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, true, true, false, null);
ClassResourceInfo cri = bean.getServiceFactory().getClassResourceInfo().get(0);
Set<String> names = cri.getNameBindings();
assertEquals(Collections.singleton(CustomNameBinding.class.getName()), names);
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/ResourceUtilsTest.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/ResourceUtilsTest.java b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/ResourceUtilsTest.java
index f4f908e..4edc5bd 100644
--- a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/ResourceUtilsTest.java
+++ b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/ResourceUtilsTest.java
@@ -164,13 +164,15 @@ public class ResourceUtilsTest extends Assert {
@Test
public void shouldCreateApplicationWhichInheritsApplicationPath() throws Exception {
- JAXRSServerFactoryBean application = ResourceUtils.createApplication(new SuperApplication(), false);
+ JAXRSServerFactoryBean application = ResourceUtils.createApplication(
+ new SuperApplication(), false, false, false, null);
assertEquals("/base", application.getAddress());
}
@Test
public void shouldCreateApplicationWhichOverridesApplicationPath() throws Exception {
- JAXRSServerFactoryBean application = ResourceUtils.createApplication(new CustomApplication(), false);
+ JAXRSServerFactoryBean application = ResourceUtils.createApplication(
+ new CustomApplication(), false, false, false, null);
assertEquals("/custom", application.getAddress());
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/BookStore2.java
----------------------------------------------------------------------
diff --git a/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/BookStore2.java b/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/BookStore2.java
new file mode 100644
index 0000000..68603f9
--- /dev/null
+++ b/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/BookStore2.java
@@ -0,0 +1,136 @@
+/**
+ * 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.systest.jaxrs.sse;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+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.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.sse.OutboundSseEvent;
+import javax.ws.rs.sse.OutboundSseEvent.Builder;
+import javax.ws.rs.sse.Sse;
+import javax.ws.rs.sse.SseBroadcaster;
+import javax.ws.rs.sse.SseEventSink;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/api/bookstore")
+public class BookStore2 {
+ private static final Logger LOG = LoggerFactory.getLogger(BookStore2.class);
+
+ private final CountDownLatch latch = new CountDownLatch(2);
+ private Sse sse;
+ private SseBroadcaster broadcaster;
+
+ public BookStore2(@Context Sse sse) {
+ this.sse = sse;
+ this.broadcaster = sse.newBroadcaster();
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public Collection<Book> books() {
+ return Arrays.asList(
+ new Book("New Book #1", 1),
+ new Book("New Book #2", 2)
+ );
+ }
+
+ @GET
+ @Path("sse/{id}")
+ @Produces(MediaType.SERVER_SENT_EVENTS)
+ public void forBook(@Context SseEventSink sink, @PathParam("id") final String id,
+ @HeaderParam(HttpHeaders.LAST_EVENT_ID_HEADER) @DefaultValue("0") final String lastEventId) {
+
+ new Thread() {
+ public void run() {
+ try {
+ final Integer id = Integer.valueOf(lastEventId);
+ final Builder builder = sse.newEventBuilder();
+
+ sink.onNext(createStatsEvent(builder.name("book"), id + 1));
+ Thread.sleep(200);
+ sink.onNext(createStatsEvent(builder.name("book"), id + 2));
+ Thread.sleep(200);
+ sink.onNext(createStatsEvent(builder.name("book"), id + 3));
+ Thread.sleep(200);
+ sink.onNext(createStatsEvent(builder.name("book"), id + 4));
+ Thread.sleep(200);
+ sink.close();
+ } catch (final InterruptedException | IOException ex) {
+ LOG.error("Communication error", ex);
+ }
+ }
+ }.start();
+ }
+
+ @GET
+ @Path("broadcast/sse")
+ @Produces(MediaType.SERVER_SENT_EVENTS)
+ public void broadcast(@Context SseEventSink sink) {
+ try {
+ broadcaster.subscribe(sink);
+ } finally {
+ latch.countDown();
+ }
+ }
+
+ @POST
+ @Path("broadcast/close")
+ public void stop() {
+ try {
+ // Await a least 2 clients to be broadcasted over
+ if (!latch.await(10, TimeUnit.SECONDS)) {
+ LOG.warn("Not enough clients have been connected, closing broadcaster anyway");
+ }
+
+ final Builder builder = sse.newEventBuilder();
+ broadcaster.broadcast(createStatsEvent(builder.name("book"), 1000));
+ broadcaster.broadcast(createStatsEvent(builder.name("book"), 2000));
+
+ } catch (final InterruptedException ex) {
+ LOG.error("Wait has been interrupted", ex);
+ }
+
+ if (broadcaster != null) {
+ broadcaster.close();
+ }
+ }
+
+ private static OutboundSseEvent createStatsEvent(final OutboundSseEvent.Builder builder, final int eventId) {
+ return builder
+ .id(Integer.toString(eventId))
+ .data(Book.class, new Book("New Book #" + eventId, eventId))
+ .mediaType(MediaType.APPLICATION_JSON_TYPE)
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/SseApplication.java
----------------------------------------------------------------------
diff --git a/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/SseApplication.java b/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/SseApplication.java
new file mode 100644
index 0000000..a4a4049
--- /dev/null
+++ b/systests/rs-sse/src/test/java/org/apache/cxf/systest/jaxrs/sse/SseApplication.java
@@ -0,0 +1,38 @@
+/**
+ * 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.systest.jaxrs.sse;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
+
+public class SseApplication extends Application {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return Collections.singleton(BookStore2.class);
+ }
+
+ @Override
+ public Set<Object> getSingletons() {
+ return Collections.singleton(new JacksonJsonProvider());
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/64e17b90/systests/rs-sse/src/test/resources/jaxrs_sse/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/systests/rs-sse/src/test/resources/jaxrs_sse/WEB-INF/web.xml b/systests/rs-sse/src/test/resources/jaxrs_sse/WEB-INF/web.xml
index d446f8ec..64746acb 100644
--- a/systests/rs-sse/src/test/resources/jaxrs_sse/WEB-INF/web.xml
+++ b/systests/rs-sse/src/test/resources/jaxrs_sse/WEB-INF/web.xml
@@ -12,12 +12,12 @@
<param-value>http://cxf.apache.org/transports/http/sse</param-value>
</init-param>
<init-param>
- <param-name>jaxrs.serviceClasses</param-name>
- <param-value>org.apache.cxf.systest.jaxrs.sse.BookStore</param-value>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.apache.cxf.systest.jaxrs.sse.SseApplication</param-value>
</init-param>
<init-param>
- <param-name>jaxrs.providers</param-name>
- <param-value>com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider</param-value>
+ <param-name>jaxrs.scope</param-name>
+ <param-value>singleton</param-value>
</init-param>
</servlet>