Author: julien(a)jboss.com
Date: 2008-02-27 17:06:45 -0500 (Wed, 27 Feb 2008)
New Revision: 10139
Added:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/EventPhaseSessionImpl.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventPhaseSession.java
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletController.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletRequestHandler.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventControllerContext.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/impl/event/EventControllerContextImpl.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PageUpdateResponse.java
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PortletResponse.java
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/EventControllerContextSupport.java
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerContextSupport.java
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerTestCase.java
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/PortalServlet.java
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/jsp/PageEventControllerContext.java
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/tck/TCKRendererContext.java
Log:
JBPORTAL-1926 : Portlet event loop detection
Added:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/EventPhaseSessionImpl.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/EventPhaseSessionImpl.java
(rev 0)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/EventPhaseSessionImpl.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -0,0 +1,103 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2008, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.portlet.controller;
+
+import org.jboss.portal.portlet.controller.event.EventPhaseSession;
+import org.jboss.portal.portlet.controller.event.Event;
+import org.apache.log4j.Logger;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 630 $
+ */
+class EventPhaseSessionImpl implements EventPhaseSession
+{
+
+ /** . */
+ private final Logger log;
+
+ /** . */
+ LinkedList<Event> producedEventHistory;
+
+ /** . */
+ LinkedList<Event> consumedEventHistory;
+
+ /** . */
+ LinkedList<Event> producedEvents;
+
+ /** . */
+ LinkedList<Event> toConsumeEvents;
+
+ /** . */
+ boolean interruped;
+
+ EventPhaseSessionImpl(Logger log)
+ {
+ this.log = log;
+ this.producedEventHistory = new LinkedList<Event>();
+ this.consumedEventHistory = new LinkedList<Event>();
+ this.producedEvents = new LinkedList<Event>();
+ this.toConsumeEvents = new LinkedList<Event>();
+ this.interruped = false;
+ }
+
+ public Iterator<Event> browseProducedEventHistory()
+ {
+ return this.producedEventHistory.iterator();
+ }
+
+
+ public Iterator<Event> browseConsumedEventHistory()
+ {
+ return this.consumedEventHistory.iterator();
+ }
+
+ public void queueEvent(Event event)
+ {
+ if (interruped)
+ {
+ throw new IllegalStateException("The event phase is interruped");
+ }
+ if (event == null)
+ {
+ throw new IllegalArgumentException("No null event accepted");
+ }
+
+ //
+ log.trace("Queued event " + event + " in the session");
+
+ //
+ this.toConsumeEvents.addLast(event);
+ }
+
+ public void interrupt()
+ {
+ log.trace("Event delivery interruped");
+
+ //
+ this.interruped = true;
+ }
+}
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletController.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletController.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletController.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -30,8 +30,12 @@
import org.jboss.portal.portlet.controller.response.ControllerResponse;
/**
- * The portlet controller which handles the page state management and the interactions
between the action phase and the
- * event phase. It really only does that and not more.
+ * <p>The portlet controller which handles the page state management and the
interactions between the action phase and the
+ * event phase. It really only does that and not more.</p>
+ *
+ * <p>The event distribution is based on a fifo policy.</p>
+ *
+ *
* <p/>
* 1/ introduce EventRequest so the portal can send events directly to a portlet
* <p/>
@@ -51,10 +55,18 @@
/** . */
private boolean distributeNonProduceableEvents;
+ /** . */
+ private int producedEventThreshold;
+
+ /** . */
+ private int consumedEventThreshold;
+
public PortletController()
{
distributeNonConsumableEvents = true;
distributeNonProduceableEvents = true;
+ producedEventThreshold = 32;
+ consumedEventThreshold = 64;
}
/**
@@ -91,6 +103,40 @@
this.distributeNonProduceableEvents = distributeNonProduceableEvents;
}
+ /**
+ * The option configures the maximum number of events that can be produced during one
interaction.
+ * A negative value means that there is no limit to the number of events that can be
produced
+ * during one interaction.
+ *
+ * @return the maximum number of produced events
+ */
+ public int getProducedEventThreshold()
+ {
+ return producedEventThreshold;
+ }
+
+ public void setProducedEventThreshold(int producedEventThreshold)
+ {
+ this.producedEventThreshold = producedEventThreshold;
+ }
+
+ /**
+ * The option configures the maximum number of events that can be consumed during one
interaction.
+ * A negative value means that there is no limit to the number of events that can be
consumed
+ * during one interaction.
+ *
+ * @return the maximum number of consumed events
+ */
+ public int getConsumedEventThreshold()
+ {
+ return consumedEventThreshold;
+ }
+
+ public void setConsumedEventThreshold(int consumedEventThreshold)
+ {
+ this.consumedEventThreshold = consumedEventThreshold;
+ }
+
public ControllerResponse process(PortletControllerContext controllerContext,
ControllerRequest controllerRequest) throws PortletInvokerException
{
if (controllerContext == null)
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletRequestHandler.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletRequestHandler.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/PortletRequestHandler.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -49,7 +49,6 @@
import org.jboss.portal.portlet.spi.PortletInvocationContext;
import javax.servlet.http.Cookie;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -106,100 +105,140 @@
EventControllerContext eventCC = context.getEventControllerContext();
UpdateNavigationalStateResponse stateResponse =
(UpdateNavigationalStateResponse)response;
- // Create event list and feed it with the events that may have been produced
- LinkedList<Event> srcEventQueue = new LinkedList<Event>();
+ //
+ EventPhaseSessionImpl session = new EventPhaseSessionImpl(log);
+
+ // Feed session it with the events that may have been produced
for (UpdateNavigationalStateResponse.Event portletEvent :
stateResponse.getEvents())
{
- Event producedEvent = new Event(portletEvent.getName(),
portletEvent.getPayload(), portletRequest.getWindowId());
- srcEventQueue.add(producedEvent);
+ session.producedEvents.add(new Event(portletEvent.getName(),
portletEvent.getPayload(), portletRequest.getWindowId()));
}
+ //
+ int eventDistributionStatus = PortletResponse.DISTRIBUTION_DONE;
+
// Deliver events
- while (srcEventQueue.size() > 0)
+ while (session.producedEvents.size() > 0)
{
- Event srcEvent = srcEventQueue.removeFirst();
+ Event producedEvent = session.producedEvents.removeFirst();
//
- String srcId = srcEvent.getWindowId();
+ String producerId = producedEvent.getWindowId();
+ PortletInfo producerPortletInfo = context.getPortletInfo(producerId);
//
- PortletInfo srcPortletInfo = context.getPortletInfo(srcId);
-
- //
- if (srcPortletInfo == null)
+ if (producerPortletInfo == null)
{
- log.trace("Cannot deliver event " + srcEvent +" because the
source does not have portlet info");
-
- //
+ log.trace("Cannot deliver event " + producedEvent +"
because the producer does not have portlet info");
continue;
}
//
if (!controller.getDistributeNonProduceableEvents())
{
- if
(!srcPortletInfo.getEventing().getProducedEvents().containsKey(srcEvent.getName()))
+ if
(!producerPortletInfo.getEventing().getProducedEvents().containsKey(producedEvent.getName()))
{
- log.trace("Cannot deliver event " + srcEvent +" because
the source of the event does not produce the event name");
-
- //
+ log.trace("Cannot deliver event " + producedEvent +"
because the producer of the event does not produce the event name");
continue;
}
}
- //
- List<Event> dstEvents = eventCC.getConsumedEvents(srcEvent);
+ // Apply produced event quota if necessary
+ int producedEventThreshold = controller.getProducedEventThreshold();
+ if (producedEventThreshold >= 0)
+ {
+ if (session.producedEventHistory.size() + 1 > producedEventThreshold)
+ {
+ log.trace("Event distribution interrupted because the maximum
number of produced event is reached");
+ eventDistributionStatus = PortletResponse.PRODUCED_EVENT_FLOODED;
+ break;
+ }
+ }
+ // Give control to the event context
+ try
+ {
+ eventCC.handleEvent(session, producedEvent);
+ }
+ catch (Exception e)
+ {
+ log.trace("Cannot deliver produced event " + producedEvent +
" because the event controller context " +
+ "threw a runtime exception", e);
+ continue;
+ }
+
+ // Perform flow control
+ if (session.interruped)
+ {
+ log.trace("Event distribution interrupted by controller
context");
+ eventDistributionStatus = PortletResponse.INTERRUPTED;
+ break;
+ }
+
//
- for (Event dstEvent : dstEvents)
+ while (session.toConsumeEvents.size() > 0)
{
- String dstId = dstEvent.getWindowId();
+ Event toConsumeEvent = session.toConsumeEvents.removeFirst();
//
- PortletInfo dstPortletInfo = context.getPortletInfo(dstId);
+ String consumedId = toConsumeEvent.getWindowId();
+ //
+ PortletInfo consumerPortletInfo = context.getPortletInfo(consumedId);
//
- if (dstPortletInfo == null)
+ if (consumerPortletInfo == null)
{
if (log.isTraceEnabled())
{
- log.trace("Cannot deliver event " + srcEvent +"
because the target of the event does not have a portlet info");
+ log.trace("Cannot deliver event " + producedEvent +"
because the consumer of the event does not have a portlet info");
}
-
- //
continue;
}
//
if (!controller.getDistributeNonConsumableEvents())
{
- if
(!dstPortletInfo.getEventing().getConsumedEvents().containsKey(dstEvent.getName()))
+ if
(!consumerPortletInfo.getEventing().getConsumedEvents().containsKey(toConsumeEvent.getName()))
{
if (log.isTraceEnabled())
{
- log.trace("Cannot deliver event " + srcEvent +"
because the target of the event does not accept the event name");
+ log.trace("Cannot deliver event " + producedEvent
+" because the consumer of the event does not accept the event name");
}
-
- //
continue;
}
}
+ // Apply consumed event quota if necessary
+ int consumedEventThreshold = controller.getConsumedEventThreshold();
+ if (consumedEventThreshold >= 0)
+ {
+ if (session.consumedEventHistory.size() + 1 >
consumedEventThreshold)
+ {
+ log.trace("Event distribution interrupted because the maximum
number of consumed event is reached");
+ eventDistributionStatus = PortletResponse.CONSUMED_EVENT_FLOODED;
+ break;
+ }
+ }
+
//
- PortletInvocationResponse eventResponse = deliverEvent(context, dstEvent,
pageState, requestProperties.getCookies());
+ PortletInvocationResponse eventResponse = deliverEvent(context,
toConsumeEvent, pageState, requestProperties.getCookies());
+ // Now it is consumed we add it to the history
+ session.consumedEventHistory.addFirst(toConsumeEvent);
+
//
if (eventResponse instanceof UpdateNavigationalStateResponse)
{
UpdateNavigationalStateResponse eventStateResponse =
(UpdateNavigationalStateResponse)eventResponse;
// Update ns
- updateNavigationalState(context, dstEvent.getWindowId(),
eventStateResponse, pageState);
+ updateNavigationalState(context, toConsumeEvent.getWindowId(),
eventStateResponse, pageState);
// Add events to source event queue
for (UpdateNavigationalStateResponse.Event portletEvent :
eventStateResponse.getEvents())
{
- srcEventQueue.add(new Event(portletEvent.getName(),
portletEvent.getPayload(), dstEvent.getWindowId()));
+ session.producedEvents.add(new Event(portletEvent.getName(),
portletEvent.getPayload(), toConsumeEvent.getWindowId()));
}
//
@@ -218,14 +257,17 @@
// Do something here !!!!
}
}
+
+ // We archive the consumed event in the history
+ session.producedEventHistory.addFirst(producedEvent);
}
//
- return new PageUpdateResponse(updateResponse, requestProperties, pageState);
+ return new PageUpdateResponse(updateResponse, requestProperties, pageState,
eventDistributionStatus);
}
else
{
- return new PortletResponse(response);
+ return new PortletResponse(response, PortletResponse.DISTRIBUTION_DONE);
}
}
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventControllerContext.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventControllerContext.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventControllerContext.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -22,8 +22,6 @@
******************************************************************************/
package org.jboss.portal.portlet.controller.event;
-import java.util.List;
-
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 630 $
@@ -32,11 +30,22 @@
{
/**
- * Obtain a list of consumed event for a produced event.
+ * <p>Give control to the context when an event is produced. The session
+ * argument gives to the context the capability to queue events in response
+ * of the produced event or to interrupt the session. It has also access
+ * to the full history of distributed events in order to provide advanced
+ * implementation of event cycle detection.</p>
*
+ * <p>During the invocation of this method, any runtime exception thrown will
signal
+ * a failure and the produced event will be discarded although the event
+ * distribution will continue.</p>
+ *
+ * <p>During the invocation of this method, any error thrown will be propagated
+ * to the portlet controller invoker.</p>
+ *
+ * @param session the session
* @param producedEvent the produced event
- * @return the list of event to be consumed
*/
- List<Event> getConsumedEvents(Event producedEvent);
+ void handleEvent(EventPhaseSession session, Event producedEvent);
}
Added:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventPhaseSession.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventPhaseSession.java
(rev 0)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/event/EventPhaseSession.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * JBoss, a division of Red Hat *
+ * Copyright 2008, Red Hat Middleware, LLC, and individual *
+ * contributors as indicated by the @authors tag. See the *
+ * copyright.txt in the distribution for a full listing of *
+ * individual contributors. *
+ * *
+ * This is free software; you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation; either version 2.1 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This software is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this software; if not, write to the Free *
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org. *
+ ******************************************************************************/
+package org.jboss.portal.portlet.controller.event;
+
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien@jboss.org">Julien Viet</a>
+ * @version $Revision: 630 $
+ */
+public interface EventPhaseSession
+{
+
+ /**
+ * Returns an iterator for browsing the history of the produced events.
+ * The iterator returns the produced events from the most recent to the oldest.
+ *
+ * @return all the events produced during the session
+ */
+ Iterator<Event> browseProducedEventHistory();
+
+ /**
+ * Returns an iterator for browsing the history of the consumed events.
+ * The iterator returns the consumed events from the most recent to the oldest.
+ *
+ * @return all the events consumed during the session
+ */
+ Iterator<Event> browseConsumedEventHistory();
+
+ /**
+ * Queue an event for consumption. The queue is a FIFO queue.
+ *
+ * @param event an event
+ * @throws IllegalArgumentException if the event is null
+ * @throws IllegalStateException if the event phase is interrupted
+ */
+ void queueEvent(Event event) throws IllegalArgumentException, IllegalStateException;
+
+ /**
+ * Stop processing of all events and returns from the controller.
+ */
+ void interrupt();
+
+}
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/impl/event/EventControllerContextImpl.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/impl/event/EventControllerContextImpl.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/impl/event/EventControllerContextImpl.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -27,12 +27,9 @@
import org.jboss.portal.portlet.PortletInvokerException;
import org.jboss.portal.portlet.controller.event.Event;
import org.jboss.portal.portlet.controller.event.EventControllerContext;
+import org.jboss.portal.portlet.controller.event.EventPhaseSession;
import org.jboss.portal.portlet.info.PortletInfo;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
* @version $Revision: 630 $
@@ -48,28 +45,24 @@
this.invoker = invoker;
}
- public List<Event> getConsumedEvents(Event producedEvent)
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
{
try
{
- ArrayList<Event> consumedEvents = new ArrayList<Event>();
for (Portlet portlet : invoker.getPortlets())
{
PortletInfo portletInfo = portlet.getInfo();
if
(portletInfo.getEventing().getConsumedEvents().containsKey(producedEvent.getName()))
{
Event consumedEvent = new Event(producedEvent.getName(),
producedEvent.getPayload(), portlet.getContext().getId());
- consumedEvents.add(consumedEvent);
+ session.queueEvent(consumedEvent);
}
}
- return consumedEvents;
}
catch (PortletInvokerException e)
{
System.out.println("e = " + e);
-
- //
- return Collections.emptyList();
+ session.interrupt();
}
}
}
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PageUpdateResponse.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PageUpdateResponse.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PageUpdateResponse.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -42,9 +42,10 @@
public PageUpdateResponse(
UpdateNavigationalStateResponse update,
ResponseProperties properties,
- PageNavigationalState pageState)
+ PageNavigationalState pageState,
+ int eventCycleStatus)
{
- super(update);
+ super(update, eventCycleStatus);
//
this.properties = properties;
Modified:
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PortletResponse.java
===================================================================
---
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PortletResponse.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/main/java/org/jboss/portal/portlet/controller/response/PortletResponse.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -31,11 +31,32 @@
public class PortletResponse extends ControllerResponse
{
+ /** The event distribution was properly done. */
+ public static final int DISTRIBUTION_DONE = 0;
+
+ /** The event distribution lead to a cycle. */
+ public static final int INTERRUPTED = 1;
+
+ /** The event distribution did flood. */
+ public static final int PRODUCED_EVENT_FLOODED = 2;
+
+ /** The event distribution did flood. */
+ public static final int CONSUMED_EVENT_FLOODED = 3;
+
/** . */
public final PortletInvocationResponse response;
- public PortletResponse(PortletInvocationResponse response)
+ /** . */
+ private final int eventDistributionStatus;
+
+ public PortletResponse(PortletInvocationResponse response, int
eventDistributionStatus)
{
this.response = response;
+ this.eventDistributionStatus = eventDistributionStatus;
}
+
+ public int getEventDistributionStatus()
+ {
+ return eventDistributionStatus;
+ }
}
Modified:
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/EventControllerContextSupport.java
===================================================================
---
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/EventControllerContextSupport.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/EventControllerContextSupport.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -24,12 +24,12 @@
import org.jboss.portal.portlet.controller.event.EventControllerContext;
import org.jboss.portal.portlet.controller.event.Event;
+import org.jboss.portal.portlet.controller.event.EventPhaseSession;
import javax.xml.namespace.QName;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
/**
@@ -42,22 +42,18 @@
/** . */
private final Map<Point, List<Point>> wires = new HashMap<Point,
List<Point>>();
- public List<Event> getConsumedEvents(Event producedEvent)
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
{
List<Point> dsts = wires.get(new Point(producedEvent.getName(),
producedEvent.getWindowId()));
//
- List<Event> consumedEvents = new ArrayList<Event>();
if (dsts != null)
{
for (Point dst : dsts)
{
- consumedEvents.add(new Event(dst.name, producedEvent.getPayload(),
dst.windowId));
+ session.queueEvent(new Event(dst.name, producedEvent.getPayload(),
dst.windowId));
}
}
-
- //
- return Collections.unmodifiableList(consumedEvents);
}
public void createWire(QName srcName, String srcWindowId, QName dstName, String
dstWindowId)
Modified:
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerContextSupport.java
===================================================================
---
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerContextSupport.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerContextSupport.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -27,6 +27,7 @@
import org.jboss.portal.portlet.controller.state.PageNavigationalState;
import org.jboss.portal.portlet.controller.state.StateControllerContext;
import org.jboss.portal.portlet.controller.impl.state.StateControllerContextImpl;
+import org.jboss.portal.portlet.controller.event.EventControllerContext;
import org.jboss.portal.portlet.invocation.response.PortletInvocationResponse;
import org.jboss.portal.portlet.invocation.ActionInvocation;
import org.jboss.portal.portlet.invocation.EventInvocation;
@@ -51,7 +52,7 @@
private final StateControllerContext stateControllerContext = new
StateControllerContextImpl(this);
/** . */
- private final EventControllerContextSupport eventControllerContext = new
EventControllerContextSupport();
+ private EventControllerContext eventControllerContext;
/** . */
private final PortletInvokerSupport invoker = new PortletInvokerSupport();
@@ -116,11 +117,16 @@
return invoke((PortletInvocation)resourceInvocation);
}
- public EventControllerContextSupport getEventControllerContext()
+ public EventControllerContext getEventControllerContext()
{
return eventControllerContext;
}
+ public void setEventControllerContext(EventControllerContext eventControllerContext)
+ {
+ this.eventControllerContext = eventControllerContext;
+ }
+
public StateControllerContext getStateControllerContext()
{
return stateControllerContext;
Modified:
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerTestCase.java
===================================================================
---
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerTestCase.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/controller/src/test/java/org/jboss/portal/portlet/controller/PortletControllerTestCase.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -28,6 +28,10 @@
import org.jboss.portal.portlet.controller.state.PageNavigationalState;
import org.jboss.portal.portlet.controller.response.ControllerResponse;
import org.jboss.portal.portlet.controller.response.PageUpdateResponse;
+import org.jboss.portal.portlet.controller.response.PortletResponse;
+import org.jboss.portal.portlet.controller.event.EventControllerContext;
+import org.jboss.portal.portlet.controller.event.EventPhaseSession;
+import org.jboss.portal.portlet.controller.event.Event;
import org.jboss.portal.portlet.OpaqueStateString;
import org.jboss.portal.portlet.PortletInvokerException;
import org.jboss.portal.portlet.support.PortletSupport;
@@ -40,6 +44,7 @@
import org.jboss.portal.common.util.ParameterMap;
import org.jboss.portal.common.util.Tools;
import org.jboss.unit.api.pojo.annotations.Test;
+import org.jboss.unit.api.pojo.annotations.Create;
import static org.jboss.unit.api.Assert.*;
import javax.xml.namespace.QName;
@@ -60,8 +65,17 @@
PortletControllerContextSupport context = new PortletControllerContextSupport();
/** . */
+ EventControllerContextSupport eventControllerContext = new
EventControllerContextSupport();
+
+ /** . */
PortletInvokerSupport invoker = context.getInvoker();
+ @Create
+ public void create()
+ {
+ context.setEventControllerContext(eventControllerContext);
+ }
+
@Test
public void testActionReturnsUpdateNavigationalState() throws PortletInvokerException
{
@@ -139,11 +153,11 @@
PortletSupport barPortlet = invoker.addPortlet("bar");
//
- EventProducerAction eventProducer = new EventProducerAction(srcName);
+ EventProducerActionHandler eventProducerHandler = new
EventProducerActionHandler(srcName);
NoOpEventProcessor eventConsumer = new NoOpEventProcessor();
// Create wire
- context.getEventControllerContext().createWire(srcName, "foo", dstName,
"bar");
+ eventControllerContext.createWire(srcName, "foo", dstName,
"bar");
//
ControllerRequest request = new PortletActionRequest(
@@ -157,7 +171,7 @@
//
controller.setDistributeNonProduceableEvents(true);
controller.setDistributeNonConsumableEvents(true);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
barPortlet.addHandler(eventConsumer);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(1);
@@ -166,7 +180,7 @@
//
controller.setDistributeNonProduceableEvents(true);
controller.setDistributeNonConsumableEvents(false);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(2);
barPortlet.assertInvocationCountIs(1);
@@ -177,7 +191,7 @@
//
controller.setDistributeNonProduceableEvents(true);
controller.setDistributeNonConsumableEvents(true);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
barPortlet.addHandler(eventConsumer);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(3);
@@ -186,7 +200,7 @@
//
controller.setDistributeNonProduceableEvents(true);
controller.setDistributeNonConsumableEvents(false);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
barPortlet.addHandler(eventConsumer);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(4);
@@ -195,7 +209,7 @@
//
controller.setDistributeNonProduceableEvents(false);
controller.setDistributeNonConsumableEvents(true);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(5);
barPortlet.assertInvocationCountIs(3);
@@ -203,7 +217,7 @@
//
controller.setDistributeNonProduceableEvents(false);
controller.setDistributeNonConsumableEvents(false);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(6);
barPortlet.assertInvocationCountIs(3);
@@ -214,7 +228,7 @@
//
controller.setDistributeNonProduceableEvents(false);
controller.setDistributeNonConsumableEvents(true);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
barPortlet.addHandler(eventConsumer);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(7);
@@ -223,20 +237,157 @@
//
controller.setDistributeNonProduceableEvents(false);
controller.setDistributeNonConsumableEvents(false);
- fooPortlet.addHandler(eventProducer);
+ fooPortlet.addHandler(eventProducerHandler);
barPortlet.addHandler(eventConsumer);
controller.process(context, request);
fooPortlet.assertInvocationCountIs(8);
barPortlet.assertInvocationCountIs(5);
}
- private static class EventProducerAction extends PortletSupport.ActionHandler
+ @Test
+ public void testEventFloodDetection() throws PortletInvokerException
{
+ QName srcName = new QName("juu", "foo");
+ //
+ PortletSupport fooPortlet = invoker.addPortlet("foo");
+
+ // Create wire
+ eventControllerContext.createWire(srcName, "foo", srcName,
"foo");
+
+ ControllerRequest request = new PortletActionRequest(
+ "foo",
+ new OpaqueStateString(""),
+ new ParameterMap(),
+ new WindowNavigationalState(),
+ context.getStateControllerContext().createPageState(false)
+ );
+
+ EventProducerActionHandler eventProducerActionHandler = new
EventProducerActionHandler(srcName);
+ EventProducerEventHandler eventProducerEventHandler = new
EventProducerEventHandler(srcName);
+
+ //
+ controller.setConsumedEventThreshold(10);
+ controller.setProducedEventThreshold(1);
+ fooPortlet.addHandler(eventProducerActionHandler);
+ fooPortlet.addHandler(eventProducerEventHandler);
+ ControllerResponse response = controller.process(context, request);
+ PageUpdateResponse updateResponse = assertInstanceOf(response,
PageUpdateResponse.class);
+ assertEquals(PortletResponse.PRODUCED_EVENT_FLOODED,
updateResponse.getEventDistributionStatus());
+
+ //
+ controller.setConsumedEventThreshold(1);
+ controller.setProducedEventThreshold(10);
+ fooPortlet.addHandler(eventProducerActionHandler);
+ fooPortlet.addHandler(eventProducerEventHandler);
+ response = controller.process(context, request);
+ updateResponse = assertInstanceOf(response, PageUpdateResponse.class);
+ assertEquals(PortletResponse.CONSUMED_EVENT_FLOODED,
updateResponse.getEventDistributionStatus());
+ }
+
+ @Test
+ public void testEventFloodInterruption() throws PortletInvokerException
+ {
+ QName srcName = new QName("juu", "foo");
+
+ //
+ PortletSupport fooPortlet = invoker.addPortlet("foo");
+
+ // Create wire
+ eventControllerContext.createWire(srcName, "foo", srcName,
"foo");
+
+ ControllerRequest request = new PortletActionRequest(
+ "foo",
+ new OpaqueStateString(""),
+ new ParameterMap(),
+ new WindowNavigationalState(),
+ context.getStateControllerContext().createPageState(false)
+ );
+
+ //
+ EventProducerActionHandler eventProducerActionHandler = new
EventProducerActionHandler(srcName);
+
+ //
+ controller.setConsumedEventThreshold(10);
+ controller.setProducedEventThreshold(10);
+ context.setEventControllerContext(new EventControllerContext()
+ {
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
+ {
+ session.interrupt();
+ }
+ });
+ fooPortlet.addHandler(eventProducerActionHandler);
+ ControllerResponse response = controller.process(context, request);
+ PageUpdateResponse updateResponse = assertInstanceOf(response,
PageUpdateResponse.class);
+ assertEquals(PortletResponse.INTERRUPTED,
updateResponse.getEventDistributionStatus());
+ }
+
+ @Test
+ public void testEventControllerContextFails() throws PortletInvokerException
+ {
+ QName srcName = new QName("juu", "foo");
+
+ //
+ PortletSupport fooPortlet = invoker.addPortlet("foo");
+
+ // Create wire
+ eventControllerContext.createWire(srcName, "foo", srcName,
"foo");
+
+ ControllerRequest request = new PortletActionRequest(
+ "foo",
+ new OpaqueStateString(""),
+ new ParameterMap(),
+ new WindowNavigationalState(),
+ context.getStateControllerContext().createPageState(false)
+ );
+
+ //
+ EventProducerActionHandler eventProducerActionHandler = new
EventProducerActionHandler(srcName);
+
+ //
+ controller.setConsumedEventThreshold(10);
+ controller.setProducedEventThreshold(10);
+ context.setEventControllerContext(new EventControllerContext()
+ {
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
+ {
+ throw new RuntimeException();
+ }
+ });
+ fooPortlet.addHandler(eventProducerActionHandler);
+ ControllerResponse response = controller.process(context, request);
+ PageUpdateResponse updateResponse = assertInstanceOf(response,
PageUpdateResponse.class);
+ assertEquals(PortletResponse.DISTRIBUTION_DONE,
updateResponse.getEventDistributionStatus());
+
+ //
+ final Error error = new Error();
+ context.setEventControllerContext(new EventControllerContext()
+ {
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
+ {
+ throw error;
+ }
+ });
+ fooPortlet.addHandler(eventProducerActionHandler);
+ try
+ {
+ controller.process(context, request);
+ fail();
+ }
+ catch (Error ignore)
+ {
+ assertSame(error, ignore);
+ }
+ }
+
+ private static class EventProducerActionHandler extends PortletSupport.ActionHandler
+ {
+
/** . */
private final QName name;
- private EventProducerAction(QName name)
+ private EventProducerActionHandler(QName name)
{
this.name = name;
}
@@ -249,6 +400,25 @@
}
}
+ private static class EventProducerEventHandler extends PortletSupport.EventHandler
+ {
+
+ /** . */
+ private final QName name;
+
+ private EventProducerEventHandler(QName name)
+ {
+ this.name = name;
+ }
+
+ protected PortletInvocationResponse invoke(EventInvocation action) throws
PortletInvokerException
+ {
+ UpdateNavigationalStateResponse update = new UpdateNavigationalStateResponse();
+ update.queueEvent(new UpdateNavigationalStateResponse.Event(name, null));
+ return update;
+ }
+ }
+
private static class NoOpEventProcessor extends PortletSupport.EventHandler
{
Modified:
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/PortalServlet.java
===================================================================
---
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/PortalServlet.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/PortalServlet.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -31,7 +31,6 @@
import org.jboss.portal.portlet.test.controller.PageRenderer;
import org.jboss.portal.portlet.test.controller.PortletControllerContextImpl;
import org.jboss.portal.portlet.test.controller.Renderer;
-import org.jboss.portal.portlet.test.controller.AbstractRendererContext;
import org.jboss.portal.portlet.test.controller.RendererContextImpl;
import org.jboss.portal.web.WebRequest;
Modified:
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/jsp/PageEventControllerContext.java
===================================================================
---
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/jsp/PageEventControllerContext.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/jsp/PageEventControllerContext.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -24,6 +24,7 @@
import org.jboss.portal.portlet.controller.event.EventControllerContext;
import org.jboss.portal.portlet.controller.event.Event;
+import org.jboss.portal.portlet.controller.event.EventPhaseSession;
import org.jboss.portal.portlet.Portlet;
import org.jboss.portal.portlet.PortletInvokerException;
import org.jboss.portal.portlet.info.PortletInfo;
@@ -55,11 +56,8 @@
this.prepareResponse = prepareResponse;
}
- public List<Event> getConsumedEvents(Event producedEvent)
+ public void handleEvent(EventPhaseSession session, Event producedEvent)
{
- ArrayList<Event> consumedEvents = new ArrayList<Event>();
-
- //
for (String windowId : prepareResponse.getWindowIds())
{
try
@@ -74,18 +72,17 @@
//
if
(portletInfo.getEventing().getConsumedEvents().containsKey(producedEvent.getName()))
{
- Event consumedEvent = new Event(producedEvent.getName(),
producedEvent.getPayload(), windowId);
- consumedEvents.add(consumedEvent);
+ session.queueEvent(new Event(producedEvent.getName(),
producedEvent.getPayload(), windowId));
}
}
}
catch (PortletInvokerException e)
{
e.printStackTrace();
+
+ //
+ session.interrupt();
}
}
-
- //
- return consumedEvents;
}
}
Modified:
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/tck/TCKRendererContext.java
===================================================================
---
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/tck/TCKRendererContext.java 2008-02-27
20:42:50 UTC (rev 10138)
+++
modules/portlet/trunk/test/src/main/java/org/jboss/portal/portlet/test/tck/TCKRendererContext.java 2008-02-27
22:06:45 UTC (rev 10139)
@@ -25,6 +25,7 @@
import org.jboss.portal.portlet.test.controller.AbstractRendererContext;
import org.jboss.portal.portlet.Portlet;
import org.jboss.portal.portlet.PortletInvokerException;
+import org.jboss.portal.portlet.NoSuchPortletException;
import java.util.Collection;
import java.util.ArrayList;
@@ -53,8 +54,18 @@
{
for (String involvedPortletId : pageState.getInvolvedPortlets())
{
- Portlet involvedPortlet =
portletControllerContext.getPortlet(involvedPortletId);
- involvedPortlets.add(involvedPortlet);
+ try
+ {
+ Portlet involvedPortlet =
portletControllerContext.getPortlet(involvedPortletId);
+ involvedPortlets.add(involvedPortlet);
+ }
+ catch (NoSuchPortletException e)
+ {
+ // It happen when a portlet becomes unavailable and
+ // therefore is removed from the available portlet
+ // in that case it should not prevent the other portlets to be
+ // rendered
+ }
}
}