| /* |
| * 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.felix.http.itest; |
| |
| import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; |
| import static javax.servlet.http.HttpServletResponse.SC_OK; |
| import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.concurrent.CountDownLatch; |
| import java.util.concurrent.TimeUnit; |
| |
| import javax.servlet.Servlet; |
| import javax.servlet.ServletContextEvent; |
| import javax.servlet.ServletContextListener; |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletRequestEvent; |
| import javax.servlet.ServletRequestListener; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| import javax.servlet.http.HttpSessionAttributeListener; |
| import javax.servlet.http.HttpSessionBindingEvent; |
| import javax.servlet.http.HttpSessionEvent; |
| import javax.servlet.http.HttpSessionListener; |
| |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.ops4j.pax.exam.junit.PaxExam; |
| import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; |
| import org.ops4j.pax.exam.spi.reactors.PerMethod; |
| import org.osgi.framework.ServiceRegistration; |
| import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; |
| |
| /** |
| * Test cases for all supported event listeners. |
| * |
| * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| @RunWith(PaxExam.class) |
| @ExamReactorStrategy(PerMethod.class) |
| public class EventListenerTest extends BaseIntegrationTest |
| { |
| private Dictionary<String, Object> getListenerProps() |
| { |
| final Dictionary<String, Object> props = new Hashtable<String, Object>(); |
| props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true"); |
| |
| return props; |
| } |
| |
| private Dictionary<String, Object> getServletProps(final String pattern) |
| { |
| final Dictionary<String, Object> props = new Hashtable<String, Object>(); |
| props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, pattern); |
| |
| return props; |
| } |
| |
| /** |
| * Tests that {@link HttpSessionListener}s are called whenever a session is created or destroyed. |
| */ |
| @Test |
| public void testHttpSessionListenerOldWhiteboardOk() throws Exception |
| { |
| final CountDownLatch createdLatch = new CountDownLatch(1); |
| final CountDownLatch destroyedLatch = new CountDownLatch(1); |
| |
| HttpSessionListener listener = new HttpSessionListener() |
| { |
| @Override |
| public void sessionDestroyed(HttpSessionEvent se) |
| { |
| destroyedLatch.countDown(); |
| } |
| |
| @Override |
| public void sessionCreated(HttpSessionEvent se) |
| { |
| createdLatch.countDown(); |
| } |
| }; |
| |
| ServiceRegistration<HttpSessionListener> reg = m_context.registerService(HttpSessionListener.class, listener, null); |
| |
| register("/session", new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| HttpSession session = req.getSession(); |
| session.setMaxInactiveInterval(2); |
| |
| resp.setStatus(SC_OK); |
| resp.flushBuffer(); |
| } |
| }); |
| |
| try |
| { |
| assertContent(SC_OK, null, createURL("/session")); |
| |
| // Session should been created... |
| assertTrue(createdLatch.await(50, TimeUnit.SECONDS)); |
| |
| assertContent(SC_OK, null, createURL("/session")); |
| |
| // Session should timeout automatically... |
| assertTrue(destroyedLatch.await(50, TimeUnit.SECONDS)); |
| } |
| finally |
| { |
| reg.unregister(); |
| } |
| } |
| |
| /** |
| * Tests that {@link HttpSessionAttributeListener}s are called whenever a session attribute is added, changed or removed. |
| */ |
| @Test |
| public void testHttpSessionAttributeListenerOldWhiteboardOk() throws Exception |
| { |
| final CountDownLatch addedLatch = new CountDownLatch(1); |
| final CountDownLatch removedLatch = new CountDownLatch(1); |
| final CountDownLatch replacedLatch = new CountDownLatch(1); |
| |
| HttpSessionAttributeListener listener = new HttpSessionAttributeListener() |
| { |
| @Override |
| public void attributeAdded(HttpSessionBindingEvent event) |
| { |
| addedLatch.countDown(); |
| } |
| |
| @Override |
| public void attributeRemoved(HttpSessionBindingEvent event) |
| { |
| removedLatch.countDown(); |
| } |
| |
| @Override |
| public void attributeReplaced(HttpSessionBindingEvent event) |
| { |
| replacedLatch.countDown(); |
| } |
| }; |
| |
| ServiceRegistration<HttpSessionAttributeListener> reg = m_context.registerService(HttpSessionAttributeListener.class, listener, null); |
| |
| register("/session", new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| try |
| { |
| HttpSession session = req.getSession(); |
| |
| session.setAttribute("foo", "bar"); |
| |
| assertTrue(addedLatch.await(5, TimeUnit.SECONDS)); |
| |
| session.setAttribute("foo", "qux"); |
| |
| assertTrue(replacedLatch.await(5, TimeUnit.SECONDS)); |
| |
| session.removeAttribute("foo"); |
| |
| assertTrue(removedLatch.await(5, TimeUnit.SECONDS)); |
| |
| resp.setStatus(SC_OK); |
| } |
| catch (AssertionError ae) |
| { |
| resp.sendError(SC_INTERNAL_SERVER_ERROR, ae.getMessage()); |
| throw ae; |
| } |
| catch (InterruptedException e) |
| { |
| resp.sendError(SC_SERVICE_UNAVAILABLE, e.getMessage()); |
| } |
| finally |
| { |
| resp.flushBuffer(); |
| } |
| } |
| }); |
| |
| try |
| { |
| assertContent(SC_OK, null, createURL("/session")); |
| } |
| finally |
| { |
| reg.unregister(); |
| } |
| } |
| |
| /** |
| * Tests that {@link HttpSessionListener}s are called whenever a session is created or destroyed. |
| */ |
| @Test |
| public void testHttpSessionListenerOk() throws Exception |
| { |
| final CountDownLatch createdLatch = new CountDownLatch(1); |
| final CountDownLatch destroyedLatch = new CountDownLatch(1); |
| |
| HttpSessionListener listener = new HttpSessionListener() |
| { |
| @Override |
| public void sessionDestroyed(HttpSessionEvent se) |
| { |
| destroyedLatch.countDown(); |
| } |
| |
| @Override |
| public void sessionCreated(HttpSessionEvent se) |
| { |
| createdLatch.countDown(); |
| } |
| }; |
| |
| ServiceRegistration<HttpSessionListener> reg = m_context.registerService(HttpSessionListener.class, listener, getListenerProps()); |
| ServiceRegistration<Servlet> regS = m_context.registerService(Servlet.class, |
| new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| HttpSession session = req.getSession(); |
| session.setMaxInactiveInterval(2); |
| |
| resp.setStatus(SC_OK); |
| resp.flushBuffer(); |
| } |
| }, getServletProps("/session")); |
| |
| try |
| { |
| assertContent(SC_OK, null, createURL("/session")); |
| |
| // Session should been created... |
| assertTrue(createdLatch.await(50, TimeUnit.SECONDS)); |
| |
| assertContent(SC_OK, null, createURL("/session")); |
| |
| // Session should timeout automatically... |
| assertTrue(destroyedLatch.await(50, TimeUnit.SECONDS)); |
| } |
| finally |
| { |
| reg.unregister(); |
| regS.unregister(); |
| } |
| } |
| |
| /** |
| * Tests that {@link HttpSessionAttributeListener}s are called whenever a session attribute is added, changed or removed. |
| */ |
| @Test |
| public void testHttpSessionAttributeListenerOk() throws Exception |
| { |
| final CountDownLatch addedLatch = new CountDownLatch(1); |
| final CountDownLatch removedLatch = new CountDownLatch(1); |
| final CountDownLatch replacedLatch = new CountDownLatch(1); |
| |
| HttpSessionAttributeListener listener = new HttpSessionAttributeListener() |
| { |
| @Override |
| public void attributeAdded(HttpSessionBindingEvent event) |
| { |
| addedLatch.countDown(); |
| } |
| |
| @Override |
| public void attributeRemoved(HttpSessionBindingEvent event) |
| { |
| removedLatch.countDown(); |
| } |
| |
| @Override |
| public void attributeReplaced(HttpSessionBindingEvent event) |
| { |
| replacedLatch.countDown(); |
| } |
| }; |
| |
| ServiceRegistration<HttpSessionAttributeListener> reg = m_context.registerService(HttpSessionAttributeListener.class, listener, getListenerProps()); |
| |
| ServiceRegistration<Servlet> regS = m_context.registerService(Servlet.class, |
| new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| try |
| { |
| HttpSession session = req.getSession(); |
| |
| session.setAttribute("foo", "bar"); |
| |
| assertTrue(addedLatch.await(5, TimeUnit.SECONDS)); |
| |
| session.setAttribute("foo", "qux"); |
| |
| assertTrue(replacedLatch.await(5, TimeUnit.SECONDS)); |
| |
| session.removeAttribute("foo"); |
| |
| assertTrue(removedLatch.await(5, TimeUnit.SECONDS)); |
| |
| resp.setStatus(SC_OK); |
| } |
| catch (AssertionError ae) |
| { |
| resp.sendError(SC_INTERNAL_SERVER_ERROR, ae.getMessage()); |
| throw ae; |
| } |
| catch (InterruptedException e) |
| { |
| resp.sendError(SC_SERVICE_UNAVAILABLE, e.getMessage()); |
| } |
| finally |
| { |
| resp.flushBuffer(); |
| } |
| } |
| }, getServletProps("/session")); |
| |
| try |
| { |
| assertContent(SC_OK, null, createURL("/session")); |
| } |
| finally |
| { |
| reg.unregister(); |
| } |
| } |
| |
| /** |
| * Tests {@link ServletContextListener}s |
| */ |
| @Test |
| public void testServletContextListener() throws Exception |
| { |
| final CountDownLatch initLatch = new CountDownLatch(1); |
| final CountDownLatch destroyLatch = new CountDownLatch(1); |
| |
| final ServletContextListener listener = new ServletContextListener() |
| { |
| |
| @Override |
| public void contextInitialized(final ServletContextEvent sce) |
| { |
| initLatch.countDown(); |
| } |
| |
| @Override |
| public void contextDestroyed(final ServletContextEvent sce) |
| { |
| destroyLatch.countDown(); |
| } |
| }; |
| |
| // register with default context |
| final ServiceRegistration<ServletContextListener> reg = m_context.registerService(ServletContextListener.class, listener, getListenerProps()); |
| |
| try |
| { |
| assertTrue(initLatch.await(5, TimeUnit.SECONDS)); |
| } |
| finally |
| { |
| reg.unregister(); |
| } |
| assertTrue(destroyLatch.await(5, TimeUnit.SECONDS)); |
| } |
| |
| /** |
| * Tests {@link ServletRequestListener}s |
| */ |
| @Test |
| public void testServletRequestListener() throws Exception |
| { |
| final List<String> list = new ArrayList<>(); |
| |
| final ServletRequestListener listener = new ServletRequestListener() |
| { |
| |
| @Override |
| public void requestDestroyed(ServletRequestEvent arg0) |
| { |
| list.add("DESTROY"); |
| } |
| |
| @Override |
| public void requestInitialized(ServletRequestEvent arg0) |
| { |
| list.add("INIT"); |
| } |
| }; |
| |
| // register with default context |
| final ServiceRegistration<ServletRequestListener> reg1 = m_context.registerService(ServletRequestListener.class, listener, getListenerProps()); |
| // register proprietary listener |
| final ServiceRegistration<ServletRequestListener> reg2 = m_context.registerService(ServletRequestListener.class, listener, null); |
| |
| // register test servlet with default context |
| ServiceRegistration<Servlet> regS = m_context.registerService(Servlet.class, |
| new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| resp.setStatus(SC_OK); |
| resp.flushBuffer(); |
| } |
| }, getServletProps("/test")); |
| |
| try |
| { |
| assertEquals(0, list.size()); |
| assertContent(SC_OK, null, createURL("/test")); |
| assertEquals(2, list.size()); |
| assertEquals("INIT", list.get(0)); |
| assertEquals("DESTROY", list.get(1)); |
| } |
| finally |
| { |
| reg1.unregister(); |
| reg2.unregister(); |
| regS.unregister(); |
| } |
| } |
| |
| /** |
| * Tests {@link ServletRequestListener}s |
| */ |
| @Test |
| public void testServletRequestListenerWithHttpAdmin() throws Exception |
| { |
| final List<String> list = new ArrayList<>(); |
| |
| final ServletRequestListener listener = new ServletRequestListener() |
| { |
| |
| @Override |
| public void requestDestroyed(ServletRequestEvent arg0) |
| { |
| list.add("DESTROY"); |
| } |
| |
| @Override |
| public void requestInitialized(ServletRequestEvent arg0) |
| { |
| list.add("INIT"); |
| } |
| }; |
| |
| // register with all contexts |
| final Dictionary<String, Object> props = new Hashtable<String, Object>(); |
| props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER, "true"); |
| props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)"); |
| final ServiceRegistration<ServletRequestListener> reg = m_context.registerService(ServletRequestListener.class, listener, props); |
| // register proprietary listener |
| final ServiceRegistration<ServletRequestListener> reg2 = m_context.registerService(ServletRequestListener.class, listener, null); |
| |
| // register test servlet with http service |
| getHttpService().registerServlet("/test", new TestServlet() |
| { |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException |
| { |
| resp.setStatus(SC_OK); |
| resp.flushBuffer(); |
| } |
| }, null, null); |
| |
| try |
| { |
| assertEquals(0, list.size()); |
| assertContent(SC_OK, null, createURL("/test")); |
| assertEquals(4, list.size()); |
| assertEquals("INIT", list.get(0)); |
| assertEquals("INIT", list.get(1)); |
| assertEquals("DESTROY", list.get(2)); |
| assertEquals("DESTROY", list.get(3)); |
| } |
| finally |
| { |
| reg.unregister(); |
| reg2.unregister(); |
| getHttpService().unregister("/test"); |
| } |
| } |
| } |