You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by at...@apache.org on 2010/05/28 00:19:11 UTC

svn commit: r949023 - in /portals/pluto: branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/ trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/

Author: ate
Date: Thu May 27 22:19:10 2010
New Revision: 949023

URL: http://svn.apache.org/viewvc?rev=949023&view=rev
Log:
PLUTO-569: Threading issue in DefaulltPortletInvoker
See: https://issues.apache.org/jira/browse/PLUTO-569
Disabling the multi-threaded event delivery as its implementation is too simplistic and fundamentally unreliable and beyond the intended scope and purpose of the Pluto Portal Driver.
Replace it with a plain in-process event delivery solution by copying the logic from the PortletWindowThread.run() method inline in the EventProcessingServiceImpl.

Modified:
    portals/pluto/branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java
    portals/pluto/trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java

Modified: portals/pluto/branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java?rev=949023&r1=949022&r2=949023&view=diff
==============================================================================
--- portals/pluto/branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java (original)
+++ portals/pluto/branches/pluto-2.0.x/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java Thu May 27 22:19:10 2010
@@ -38,10 +38,23 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.portlet.Event;
+import javax.portlet.PortletException;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
 import javax.xml.namespace.QName;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringReader;
 import java.util.*;
 
 public class EventCoordinationServiceImpl implements EventCoordinationService
@@ -71,9 +84,9 @@ public class EventCoordinationServiceImp
 
 		PortalURL portalURL = PortalURLParserImpl.getParser().parse(request);
 
-	    Map<String, PortletWindowThread> portletWindowThreads = new HashMap<String, PortletWindowThread>();
+//	    Map<String, PortletWindowThread> portletWindowThreads = new HashMap<String, PortletWindowThread>();
 
-	    ThreadGroup threadGroup = new ThreadGroup("FireEventThreads");
+//	    ThreadGroup threadGroup = new ThreadGroup("FireEventThreads");
 
 		for (Event event : events)
 		{
@@ -88,6 +101,10 @@ public class EventCoordinationServiceImp
 				if (portletNames != null) {
 					for (String portlet : portletNames) {
 						if (portlet.equals(config.getId())) {
+/* PLUTO-569: multi-threaded (event) request processing isn't thread save with the Pluto Portal Driver handling of request attributes
+   as they all are stored/managed within the single underlying HttpServletRequest.
+   Providing proper thread save parallel request processing would require extensive enhancements to the Pluto Portal Driver and as
+   such is out-of-scope for the purpose of the Portal Driver itself.
 
 							// the thread now is a new one, with possible
 							// waiting,
@@ -101,6 +118,7 @@ public class EventCoordinationServiceImp
 							portletWindowThread.addEvent(event);
 
 							portletWindowThread.start();
+							
 						}
 					}
 				}
@@ -113,8 +131,88 @@ public class EventCoordinationServiceImp
 			}
 		}
 		waitForEventExecution(threadGroup);
+*/							
+							doEvent(container, window, event, request, response);
+						}
+					}
+				}
+			}
+		}
 	}
+    
+    protected void doEvent(PortletContainer container, PortletWindow portletWindow, Event event, 
+                               HttpServletRequest request, HttpServletResponse response ) {
+    	try {
+	        Object value = event.getValue();
+	        
+	        XMLStreamReader xml = null;
+			try {
+				if (value instanceof String) {
+					String in = (String) value; 
+					xml = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(in));
+				}			
+			}  
+			catch (XMLStreamException e1) {
+				throw new IllegalStateException(e1);
+			} catch (FactoryConfigurationError e1) {
+				throw new IllegalStateException(e1);
+			}
+	        
+	        if (xml != null) {
+	        	//XMLStreamReader xml = (XMLStreamReader) event.getValue();
+	        	
+	        		//provider.getEventDefinition(event.getQName());
+	        	try {
+	        		// now test if object is jaxb
+	        		EventDefinition eventDefinitionDD = getEventDefintion(portletWindow, event.getQName()); 
+	        		
+	        		ClassLoader loader = portletContextService.getClassLoader(portletWindow.getPortletDefinition().getApplication().getName());
+	        		Class<? extends Serializable> clazz = loader.loadClass(eventDefinitionDD.getValueType()).asSubclass(Serializable.class);
+
+	        		JAXBContext jc = JAXBContext.newInstance(clazz);
+	        		Unmarshaller unmarshaller  = jc.createUnmarshaller();
+
+//	        		unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
+
+	        		JAXBElement result = unmarshaller.unmarshal(xml,clazz);
+
+	        		event =  new EventImpl(event.getQName(),(Serializable) result.getValue());
+	        	} catch (JAXBException e) {
+	        		throw new IllegalStateException(e);
+	        	} catch (ClassCastException e) {
+	        		throw new IllegalStateException(e);
+	        	} catch (ClassNotFoundException e) {
+	        		throw new IllegalStateException(e);
+	        	} catch (PortletContainerException e) {
+	        		throw new IllegalStateException(e);
+				}
+	        }					
+			container.doEvent(portletWindow, request, response, event);	
+    	} catch (PortletException e) {
+    		LOG.warn(e.getMessage(),e);
+    	} catch (IOException e) {
+    		LOG.warn(e.getMessage(),e);
+    	} catch (PortletContainerException e) {
+    		LOG.warn(e.getMessage(),e);
+    	}	
+    }
 
+	private EventDefinition getEventDefintion(PortletWindow portletWindow, QName name) {
+		PortletApplicationDefinition appDD = portletWindow.getPortletDefinition().getApplication();
+		for (EventDefinition def : appDD.getEventDefinitions()){
+			if (def.getQName() != null){
+				if (def.getQName().equals(name))
+					return def;
+			}
+			else{
+				QName tmp = new QName(appDD.getDefaultNamespace(),def.getName());
+				if (tmp.equals(name))
+					return def;
+			}
+		}
+		throw new IllegalStateException();
+	}
+	
 	private List<String> getAllPortletsRegisteredForEvent(Event event,
 			DriverConfiguration driverConfig, ServletContext containerServletContext) {
 		Set<String> resultSet = new HashSet<String>();

Modified: portals/pluto/trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java
URL: http://svn.apache.org/viewvc/portals/pluto/trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java?rev=949023&r1=949022&r2=949023&view=diff
==============================================================================
--- portals/pluto/trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java (original)
+++ portals/pluto/trunk/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/EventCoordinationServiceImpl.java Thu May 27 22:19:10 2010
@@ -38,10 +38,23 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.portlet.Event;
+import javax.portlet.PortletException;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
 import javax.xml.namespace.QName;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.StringReader;
 import java.util.*;
 
 public class EventCoordinationServiceImpl implements EventCoordinationService
@@ -66,55 +79,140 @@ public class EventCoordinationServiceImp
                               HttpServletResponse response, List<Event> events)
     {
         ServletContext containerServletContext = PortalRequestContext.getContext(request).getServletContext();
-		DriverConfiguration driverConfig = (DriverConfiguration) containerServletContext
-				.getAttribute(AttributeKeys.DRIVER_CONFIG);
+        DriverConfiguration driverConfig = (DriverConfiguration) containerServletContext
+                .getAttribute(AttributeKeys.DRIVER_CONFIG);
 
-		PortalURL portalURL = PortalURLParserImpl.getParser().parse(request);
+        PortalURL portalURL = PortalURLParserImpl.getParser().parse(request);
 
-	    Map<String, PortletWindowThread> portletWindowThreads = new HashMap<String, PortletWindowThread>();
+//      Map<String, PortletWindowThread> portletWindowThreads = new HashMap<String, PortletWindowThread>();
 
-	    ThreadGroup threadGroup = new ThreadGroup("FireEventThreads");
+//      ThreadGroup threadGroup = new ThreadGroup("FireEventThreads");
 
-		for (Event event : events)
-		{
-			List<String> portletNames = getAllPortletsRegisteredForEvent(
-					event, driverConfig, containerServletContext);
+        for (Event event : events)
+        {
+            List<String> portletNames = getAllPortletsRegisteredForEvent(
+                    event, driverConfig, containerServletContext);
+
+            Collection<PortletWindowConfig> portlets = getAllPortlets(driverConfig);
+
+            // iterate all portlets in the portal
+            for (PortletWindowConfig config : portlets) {
+                PortletWindow window = new PortletWindowImpl(container, config, portalURL);
+                if (portletNames != null) {
+                    for (String portlet : portletNames) {
+                        if (portlet.equals(config.getId())) {
+/* PLUTO-569: multi-threaded (event) request processing isn't thread save with the Pluto Portal Driver handling of request attributes
+   as they all are stored/managed within the single underlying HttpServletRequest.
+   Providing proper thread save parallel request processing would require extensive enhancements to the Pluto Portal Driver and as
+   such is out-of-scope for the purpose of the Portal Driver itself.
+
+                            // the thread now is a new one, with possible
+                            // waiting,
+                            // for the old to exit
+                            
 
-			Collection<PortletWindowConfig> portlets = getAllPortlets(driverConfig);
+                            PortletWindowThread portletWindowThread = getPortletWindowThread(portletWindowThreads,
+                                    threadGroup, container, config, window, request, response, containerServletContext);
 
-			// iterate all portlets in the portal
-			for (PortletWindowConfig config : portlets) {
-				PortletWindow window = new PortletWindowImpl(container, config, portalURL);
-				if (portletNames != null) {
-					for (String portlet : portletNames) {
-						if (portlet.equals(config.getId())) {
+                            // is this event
+                            portletWindowThread.addEvent(event);
 
-							// the thread now is a new one, with possible
-							// waiting,
-							// for the old to exit
-							
-
-							PortletWindowThread portletWindowThread = getPortletWindowThread(portletWindowThreads,
-									threadGroup, container, config, window, request, response, containerServletContext);
-
-							// is this event
-							portletWindowThread.addEvent(event);
-
-							portletWindowThread.start();
-						}
-					}
-				}
-			}
-			waitForEventExecution(threadGroup);
-			try {
-				Thread.sleep(WAITING_CYCLE);
-			} catch (InterruptedException e) {
-				LOG.warn(e.getMessage(),e);
-			}
-		}
-		waitForEventExecution(threadGroup);
-	}
+                            portletWindowThread.start();
+                            
+                        }
+                    }
+                }
+            }
+            waitForEventExecution(threadGroup);
+            try {
+                Thread.sleep(WAITING_CYCLE);
+            } catch (InterruptedException e) {
+                LOG.warn(e.getMessage(),e);
+            }
+        }
+        waitForEventExecution(threadGroup);
+*/                          
+                            doEvent(container, window, event, request, response);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    protected void doEvent(PortletContainer container, PortletWindow portletWindow, Event event, 
+                               HttpServletRequest request, HttpServletResponse response ) {
+        try {
+            Object value = event.getValue();
+            
+            XMLStreamReader xml = null;
+            try {
+                if (value instanceof String) {
+                    String in = (String) value; 
+                    xml = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(in));
+                }           
+            }  
+            catch (XMLStreamException e1) {
+                throw new IllegalStateException(e1);
+            } catch (FactoryConfigurationError e1) {
+                throw new IllegalStateException(e1);
+            }
+            
+            if (xml != null) {
+                //XMLStreamReader xml = (XMLStreamReader) event.getValue();
+                
+                    //provider.getEventDefinition(event.getQName());
+                try {
+                    // now test if object is jaxb
+                    EventDefinition eventDefinitionDD = getEventDefintion(portletWindow, event.getQName()); 
+                    
+                    ClassLoader loader = portletContextService.getClassLoader(portletWindow.getPortletDefinition().getApplication().getName());
+                    Class<? extends Serializable> clazz = loader.loadClass(eventDefinitionDD.getValueType()).asSubclass(Serializable.class);
+
+                    JAXBContext jc = JAXBContext.newInstance(clazz);
+                    Unmarshaller unmarshaller  = jc.createUnmarshaller();
+
+//                  unmarshaller.setEventHandler(new javax.xml.bind.helpers.DefaultValidationEventHandler());
+
+                    JAXBElement result = unmarshaller.unmarshal(xml,clazz);
+
+                    event =  new EventImpl(event.getQName(),(Serializable) result.getValue());
+                } catch (JAXBException e) {
+                    throw new IllegalStateException(e);
+                } catch (ClassCastException e) {
+                    throw new IllegalStateException(e);
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException(e);
+                } catch (PortletContainerException e) {
+                    throw new IllegalStateException(e);
+                }
+            }                   
+            container.doEvent(portletWindow, request, response, event); 
+        } catch (PortletException e) {
+            LOG.warn(e.getMessage(),e);
+        } catch (IOException e) {
+            LOG.warn(e.getMessage(),e);
+        } catch (PortletContainerException e) {
+            LOG.warn(e.getMessage(),e);
+        }   
+    }
 
+    private EventDefinition getEventDefintion(PortletWindow portletWindow, QName name) {
+        PortletApplicationDefinition appDD = portletWindow.getPortletDefinition().getApplication();
+        for (EventDefinition def : appDD.getEventDefinitions()){
+            if (def.getQName() != null){
+                if (def.getQName().equals(name))
+                    return def;
+            }
+            else{
+                QName tmp = new QName(appDD.getDefaultNamespace(),def.getName());
+                if (tmp.equals(name))
+                    return def;
+            }
+        }
+        throw new IllegalStateException();
+    }
+    
 	private List<String> getAllPortletsRegisteredForEvent(Event event,
 			DriverConfiguration driverConfig, ServletContext containerServletContext) {
 		Set<String> resultSet = new HashSet<String>();