5 Replies Latest reply on Jan 22, 2008 7:23 AM by David Corrales

    conversationId and IPC Portlets

    Frank Rabitsch Newbie

      I have two portlets (PortletA and B) communicating using IPC where B is listening for events coming from A. Both portlets are using the same controller component and this component is set to conversation scope. PortletA contains a bunch of commandLinks that invoke action methods on the controller component and the view outcome is displayed in PortletB.

      If I click any commandLink in PortletB, the conversation is correctly maintained, however if I click in PortletA the conversation is lost and a new one is created. The problem with this is that the number of conversations grows with every click which is not the most scalable solution ;-)


      The commandLink URL in portletB contains the conversationId=8. When I click this link, the portlet renders correctly back to conversationId=8.

      Debug out put confirms this:

      ...
      2006-11-20 23:52:57,396 INFO [test.TestPortlet] conversationId on renderRequest: 8
      2006-11-20 23:52:57,396 DEBUG [org.jboss.portal.portlet.container.info.PortletResourceBundleManager] Want to load bundle null for locale en_US
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.util.Naming] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.jsf.SeamExtendedManagedPersistencePortletPhaseListener] beginning transaction prior to phase: RENDER_RESPONSE(6)
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.util.Naming] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.contexts.Lifecycle] >>> Begin web request
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.Component] instantiating Seam component: org.jboss.seam.core.manager
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.core.Manager] Found conversation id in request parameter: 8
      2006-11-20 23:52:57,396 DEBUG [org.jboss.seam.core.Manager] Restoring conversation with id: 8
      ...
      


      After this the commandLink still contain conversationId=8, however when I click in the command link in PortletA:

      ...
      2006-11-20 23:54:50,528 INFO [test.TestPortlet] conversationId on renderRequest: 19
      2006-11-20 23:54:50,528 DEBUG [org.jboss.portal.portlet.container.info.PortletResourceBundleManager] Want to load bundle null for locale en_US
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.util.Naming] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.jsf.SeamExtendedManagedPersistencePortletPhaseListener] beginning transaction prior to phase: RENDER_RESPONSE(6)
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.util.Naming] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.contexts.Lifecycle] >>> Begin web request
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.Component] instantiating Seam component: org.jboss.seam.core.manager
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.core.Manager] Found conversation id in request parameter: 19
      2006-11-20 23:54:50,528 DEBUG [org.jboss.seam.core.Manager] Restoring conversation with id: 19
      ...
      2006-11-20 23:54:50,549 DEBUG [org.jboss.seam.core.Manager] Storing conversation state: 19
      2006-11-20 23:54:50,549 DEBUG [org.jboss.seam.contexts.Lifecycle] flushing page context
      2006-11-20 23:54:50,549 DEBUG [org.jboss.seam.core.Manager] Storing conversation state: 19
      2006-11-20 23:54:50,549 DEBUG [org.jboss.seam.contexts.Lifecycle] flushing page context
      ...
      2006-11-20 23:54:50,669 DEBUG [org.jboss.seam.core.Manager] Discarding conversation state: 20
      2006-11-20 23:54:50,669 DEBUG [org.jboss.seam.contexts.Lifecycle] flushing page context
      2006-11-20 23:54:50,669 DEBUG [org.jboss.seam.core.Manager] Discarding conversation state: 20
      2006-11-20 23:54:50,669 DEBUG [org.jboss.seam.contexts.Lifecycle] flushing page context
      ...
      


      If I click the commandLink in PortletA for the second time it jumps two numbers to 21. I'm guessing this is because Seam assigns a temporary conversation by default for each portlet and I have two portlets.

      How can I ensure that conversation propagation works properly using IPC? Is there someway I can restore the previous (correct) state in the portlet? Feedback appreciated.


        • 1. Re: conversationId and IPC Portlets
          Gavin King Master

          Seam conversations are local to the portlet. There are no page-global conversations.

          • 2. Re: conversationId and IPC Portlets
            Frank Rabitsch Newbie

            In principle I do not need page global conversations. PortletA contains a couple of links that are invoked on PortletB which runs in a long running conversation. The side-effect of this is that PortletA creates a new long running conversation for each click. If I could only cancel or discard these conversations for PortletA, that would be sufficient.

            • 3. Re: conversationId and IPC Portlets
              Gavin King Master

              I guess I don't really understand what you are saying here. What code are you using to render the link? Exactly how does PortletB start conversations?

              Merely passing a conversationId to JSF is *not* enough to start a long-running conversation.

              • 4. Re: conversationId and IPC Portlets
                Frank Rabitsch Newbie

                Both PortletA and B render a page that contain command links:

                <h:commandLink action="#{controller.showContent}">
                 #{portal_messages['clickme']}
                </h:commandLink>
                


                Because of IPC all actions of PortletA and B are invoked on PortletB (the listening portlet). IPC is implemented using the standard example included in JBoss Portal.

                The action method in the controller begins or joins the conversation:

                @Begin(join = true)
                public String showContent() {
                 ...
                 return "show_content";
                }
                


                If I click the command link on PortletB, the behavior is as expected: the conversation starts and it stays in the same conversation on subsequent clicks, nothing wrong here.

                When I click on the command link in PortletA, the content renders correctly in PortletB but with a new conversation ID which is again long running. After this also PortletB uses the new conversation ID. So this means every time I click a link in PortletA I get one extra long running conversation.

                I either need a way to invoke the action in the controller from A without starting the new conversation or, as a work around, a way to cancel the new conversation and switch back to the old conversation again.

                • 5. Re: conversationId and IPC Portlets
                  David Corrales Newbie

                  Hi everyone!

                  Please, help me. I have a problem with IPC Portlets. I have similar case.
                  But my problem is that I cannot rerender portlet B. I have a listener in portlet B, and it works fine.

                  My problem is that I have a <h:commandLink ...> in Portlet A, and I want to recibe a data in portlet B, when I push link in portlet A.

                  I am really new in JBoss Seam and portlets and I am not very sure, what is wrong...

                  Portlet A: (BuscadorOperacionesWindow)

                  
                  <h:dataTable id="tablaOperaciones" value="#{expedientes}" rows="10" class="blue-table" border="1" var="op">
                   <h:column>
                   <f:facet name="header">#{messages.expediente}</f:facet>
                   <h:commandLink value="#{op.operacionId}" action="#gestorexpediente.enviaDatos(op.operacionId)}" >
                   <f:param name="datoOp" value="#{op.operacionId}" />
                   </h:commandLink>
                   </h:column>
                   ...
                  


                  Portlet B: (VisorOperacionWindow)

                  <h:panelGrid columns="2">
                   <h:outputLabel value="#{messages.operacion}"/>
                   <h:outputLabel id="datoOp"/>
                   ...
                  


                  Listener - Portlet B


                  public class PortletB extends GenericPortlet
                  {
                   public static class Listener implements PortalNodeEventListener
                   {
                   public PortalNodeEvent onEvent(PortalNodeEventContext context, PortalNodeEvent event)
                   {
                   PortalNode node = event.getNode();
                   String nodeName = node.getName();
                  
                   WindowActionEvent newEvent = null;
                  
                   if (nodeName.equals("BuscadorOperacionesWindow") && event instanceof WindowActionEvent)
                   {
                  
                   WindowActionEvent wae = (WindowActionEvent) event;
                   PortalNode windowB = node.resolve("../VisorOperacionWindow");
                   if (windowB != null)
                   {
                   newEvent = new WindowActionEvent(windowB);
                   newEvent.setMode(wae.getMode());
                   newEvent.setWindowState(wae.getWindowState());
                  
                   Map parametros = (Map)wae.getParameters();
                   for (Iterator keyValuePairs = parametros.entrySet().iterator(); keyValuePairs.hasNext();)
                   {
                   Map.Entry entry = (Map.Entry) keyValuePairs.next();
                   Object key = entry.getKey();
                   Object value = entry.getValue();
                   if(key.equals("datoOp"))
                   {
                   HashMap param = new HashMap();
                   param.put(key, value);
                   newEvent.setParameters(param);
                   return newEvent;
                   }
                   }
                   return context.dispatch();
                   }
                   }
                   return context.dispatch();
                   }
                   }
                  }
                  


                  Anyone, can give me an example of JSF portlet + IPC + Seam

                  Thanks very much