blob: d6ac6e8a65529adb14848b0507e7335a2d483b07 [file] [log] [blame]
/*
* 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");
}
}
}