Author: chris.laprun(a)jboss.com
Date: 2011-09-01 12:13:48 -0400 (Thu, 01 Sep 2011)
New Revision: 7279
Modified:
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/FederatingPortletInvoker.java
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/NullInvokerHandler.java
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/impl/FederatingPortletInvokerService.java
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/FederatingPortletInvokerTestCase.java
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/NoInvokersTestCase.java
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/OneInvokerNoPortletsTestCase.java
Log:
- GTNPC-71: first steps towards making FederatingPortletInvoker work in a distributed
context: make it go through NullInvokerHandler (which should be renamed to something more
appropriate) to resolve non-locally present invokers. Might replace Map by distributed
cache at some point, though it might not be needed with appropriate implementation of
NullInvokerHandler.
Modified:
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/FederatingPortletInvoker.java
===================================================================
---
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/FederatingPortletInvoker.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/FederatingPortletInvoker.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -49,7 +49,10 @@
FederatedPortletInvoker registerInvoker(String federatedId, PortletInvoker
registeredInvoker) throws IllegalArgumentException;
/**
- * Return a portlet invoker registered or null if not found
+ * Returns the registered FederatedPortletInvoker associated with the specified
identifier, delegating to the {@link
+ * NullInvokerHandler} specified using {@link
#setNullInvokerHandler(NullInvokerHandler)} if it's not initially
+ * resolved or returns <code>null</code> if a FederatedPortletInvoker is
not found after going through the specified
+ * NullInvokerHandler resolution mechanism.
*
* @param federatedId the id
* @return the invoker
@@ -58,13 +61,34 @@
FederatedPortletInvoker getFederatedInvoker(String federatedId) throws
IllegalArgumentException;
/**
- * Return the registered portlet invokers.
+ * Returns the known portlet invoker identifiers, including resolvable ones (though
they might not have been already
+ * resolved).
*
- * @return a collection that contains the portlet invokers
+ * @return a collection of all the resolvable portlet invoker identifiers
*/
- Collection<FederatedPortletInvoker> getFederatedInvokers();
+ Collection<String> getFederatedInvokerIds();
/**
+ * Returns only the portlet invoker identifiers of the currently resolved invokers,
which might be different from
+ * the
+ * set potentially resolvable invokers as returned by {@link
#getFederatedInvokerIds()}.
+ *
+ * @return a collection of the currently resolved portlet invoker identifiers
+ */
+ Collection<String> getResolvedInvokerIds();
+
+ /**
+ * Determines whether the FederatedPortletInvoker with the specified identifier has
already been resolved.
+ *
+ * @param federatedId the identifier of the FederatedPortletInvoker to test for
resolution status
+ * @return <code>true</code> if the specified invoker is already resolved,
<code>false</code> otherwise
+ * @throws IllegalArgumentException if the specified invoker identifier is not among
the known resolvable
+ * identifiers
+ * as returned by {@link #getFederatedInvokerIds()}
+ */
+ boolean isResolved(String federatedId) throws IllegalArgumentException;
+
+ /**
* Unregisters the invoker associated with the specified identifier.
*
* @param federatedId the identifier of the invoker to unregister
Modified:
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/NullInvokerHandler.java
===================================================================
---
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/NullInvokerHandler.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/NullInvokerHandler.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -25,6 +25,9 @@
import org.gatein.pc.api.NoSuchPortletException;
+import java.util.Collection;
+import java.util.Collections;
+
/**
* Encapsulates behavior to resolve FederatedPortletInvokers in the context of a
FederatingPortletInvoker when the
* default resolution mechanism fails to retrieve an associated FederatedPortletInvoker.
@@ -40,25 +43,47 @@
*/
NullInvokerHandler DEFAULT_HANDLER = new NullInvokerHandler()
{
- public FederatedPortletInvoker resolvePortletInvokerFor(String compoundPortletId,
String invokerId,
- FederatingPortletInvoker
callingInvoker) throws NoSuchPortletException
+ public FederatedPortletInvoker resolvePortletInvokerFor(String invokerId,
FederatingPortletInvoker callingInvoker, String compoundPortletId) throws
NoSuchPortletException
{
- throw new NoSuchPortletException(compoundPortletId);
+ if (compoundPortletId != null)
+ {
+ throw new NoSuchPortletException(compoundPortletId);
+ }
+ else
+ {
+ return null;
+ }
}
+
+ public boolean knows(String invokerId)
+ {
+ return false;
+ }
+
+ public Collection<String> getKnownInvokerIds()
+ {
+ return Collections.emptyList();
+ }
};
/**
- * Attempts to resolve a FederatedPortletInvoker for the specified compound portlet id
in the context of the
- * specified calling FederatingPortletInvoker.
+ * Attempts to resolve a FederatedPortletInvoker with the specified identifier in the
context of the specified
+ * calling FederatingPortletInvoker, optionally trying to perform resolution to invoke
an action on the specified
+ * portlet identifier.
*
- * @param compoundPortletId the portlet identifier for which we're trying to
resolve a FederatedPortletInvoker
- * @param invokerId the identifier of the FederatedPortletInvoker to be
retrieved as parsed from the compound
- * portlet id by the calling FederatingPortletInvoker
+ * @param invokerId the identifier of the FederatedPortletInvoker to be
retrieved. Should match the optional
+ * compound portlet identifier if one is specified.
* @param callingInvoker the calling FederatingPortletInvoker which failed to
resolve a FederatedPortletInvoker
- * for the specified portlet id
+ * for the specified invoker identifier
+ * @param compoundPortletId an optional portlet identifier for which we are trying to
resolve an invoker, if no such
+ * portlet identifier is required for the resolution, this
argument should be
+ * <code>null</code> and implementations should
be prepared for that case.
* @return
* @throws NoSuchPortletException
*/
- FederatedPortletInvoker resolvePortletInvokerFor(String compoundPortletId, String
invokerId,
- FederatingPortletInvoker
callingInvoker) throws NoSuchPortletException;
+ FederatedPortletInvoker resolvePortletInvokerFor(String invokerId,
FederatingPortletInvoker callingInvoker, String compoundPortletId) throws
NoSuchPortletException;
+
+ boolean knows(String invokerId);
+
+ Collection<String> getKnownInvokerIds();
}
Modified:
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/impl/FederatingPortletInvokerService.java
===================================================================
---
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/impl/FederatingPortletInvokerService.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/main/java/org/gatein/pc/federation/impl/FederatingPortletInvokerService.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -32,7 +32,6 @@
import org.gatein.pc.api.PortletInvokerException;
import org.gatein.pc.api.PortletStateType;
import org.gatein.pc.api.PortletStatus;
-import org.gatein.pc.api.StatefulPortletContext;
import org.gatein.pc.api.invocation.PortletInvocation;
import org.gatein.pc.api.invocation.response.PortletInvocationResponse;
import org.gatein.pc.api.state.DestroyCloneFailure;
@@ -45,6 +44,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -63,7 +63,7 @@
private static final Logger log =
LoggerFactory.getLogger(FederatingPortletInvokerService.class);
/** The registred FederatedPortletInvokers. */
- private volatile Map<String, FederatedPortletInvoker> registry = new
HashMap<String, FederatedPortletInvoker>();
+ private volatile Map<String, FederatedPortletInvoker> invokerCache = new
HashMap<String, FederatedPortletInvoker>();
private NullInvokerHandler nullHandler = NullInvokerHandler.DEFAULT_HANDLER;
@@ -77,14 +77,15 @@
{
throw new IllegalArgumentException("No null invoker");
}
- if (registry.containsKey(federatedId))
+ if (invokerCache.containsKey(federatedId))
{
throw new IllegalArgumentException("Attempting dual registration of "
+ federatedId);
}
- Map<String, FederatedPortletInvoker> copy = new HashMap<String,
FederatedPortletInvoker>(registry);
+
+ Map<String, FederatedPortletInvoker> copy = new HashMap<String,
FederatedPortletInvoker>(invokerCache);
FederatedPortletInvokerService invoker = new FederatedPortletInvokerService(this,
federatedId, federatedInvoker);
copy.put(federatedId, invoker);
- registry = copy;
+ invokerCache = copy;
return invoker;
}
@@ -94,13 +95,13 @@
{
throw new IllegalArgumentException("No null id accepted");
}
- if (!registry.containsKey(federatedId))
+ if (!invokerCache.containsKey(federatedId) &&
!nullHandler.knows(federatedId))
{
throw new IllegalArgumentException("Attempting to unregister unknown
invoker " + federatedId);
}
- Map<String, FederatedPortletInvoker> copy = new HashMap<String,
FederatedPortletInvoker>(registry);
+ Map<String, FederatedPortletInvoker> copy = new HashMap<String,
FederatedPortletInvoker>(invokerCache);
copy.remove(federatedId);
- registry = copy;
+ invokerCache = copy;
}
public FederatedPortletInvoker getFederatedInvoker(String federatedId) throws
IllegalArgumentException
@@ -109,31 +110,83 @@
{
throw new IllegalArgumentException("No null id provided");
}
- return registry.get(federatedId);
+
+ try
+ {
+ return getOrResolveFederatedInvoker(federatedId, null);
+ }
+ catch (NoSuchPortletException e)
+ {
+ return null;
+ }
}
- public Collection<FederatedPortletInvoker> getFederatedInvokers()
+ private FederatedPortletInvoker getOrResolveFederatedInvoker(String federatedId,
String compoundPortletId) throws NoSuchPortletException
{
- return registry.values();
+ // check cache first and then see if we can resolve the invoker if we didn't
hit the cache
+ FederatedPortletInvoker federatedPortletInvoker = invokerCache.get(federatedId);
+ if (federatedPortletInvoker == null)
+ {
+ federatedPortletInvoker = nullHandler.resolvePortletInvokerFor(federatedId,
this, compoundPortletId);
+ synchronized (this)
+ {
+ invokerCache.put(federatedId, federatedPortletInvoker); // put newly resolved
invoker in cache
+ }
+ }
+ return federatedPortletInvoker;
}
+ public Collection<String> getFederatedInvokerIds()
+ {
+ final Collection<String> ids = getResolvedInvokerIds();
+ ids.addAll(nullHandler.getKnownInvokerIds());
+
+ return ids;
+ }
+
+ public Collection<String> getResolvedInvokerIds()
+ {
+ Set<String> ids = new HashSet<String>(invokerCache.size() * 2);
+ ids.addAll(invokerCache.keySet());
+
+ return ids;
+ }
+
+ public boolean isResolved(String federatedId) throws IllegalArgumentException
+ {
+ return invokerCache.containsKey(federatedId);
+ }
+
// PortletInvoker implementation
************************************************************************************
public Set<Portlet> getPortlets() throws PortletInvokerException
{
- return getPortlets(false);
+ return getPortlets(true, true);
}
- private Set<Portlet> getPortlets(boolean remoteOnly) throws
PortletInvokerException
+ private Set<Portlet> getPortlets(boolean includeRemotePortlets, boolean
includeLocalPortlets) throws PortletInvokerException
{
LinkedHashSet<Portlet> portlets = new LinkedHashSet<Portlet>();
- for (FederatedPortletInvoker federated : registry.values())
+ for (String invokerId : getFederatedInvokerIds())
{
- // if we're only interested in remote portlets, skip the local invoker.
- if (remoteOnly && LOCAL_PORTLET_INVOKER_ID.equals(federated.getId()))
+ final FederatedPortletInvoker federated = getFederatedInvoker(invokerId);
+
+ if (LOCAL_PORTLET_INVOKER_ID.equals(federated.getId()))
{
- continue;
+ // skip invoker if it's local and we don't want local portlets
+ if (!includeLocalPortlets)
+ {
+ continue;
+ }
}
+ else
+ {
+ // skip invoker if it's remote and we don't want remote portlets
+ if (!includeRemotePortlets)
+ {
+ continue;
+ }
+ }
try
{
@@ -144,23 +197,22 @@
{
Throwable cause = e.getCause();
log.debug(e.fillInStackTrace());
- log.warn("PortletInvoker with id: " + federated.getId() + " is
not available.\nReason: " + e.getMessage()
+ log.warn("PortletInvoker with id: " + invokerId + " is not
available.\nReason: " + e.getMessage()
+ "\nCaused by:\n" + (cause == null ? e : cause));
}
}
+
return portlets;
}
public Set<Portlet> getLocalPortlets() throws PortletInvokerException
{
- PortletInvoker local = registry.get(PortletInvoker.LOCAL_PORTLET_INVOKER_ID);
-
- return local.getPortlets();
+ return getPortlets(false, true);
}
public Set<Portlet> getRemotePortlets() throws PortletInvokerException
{
- return getPortlets(true);
+ return getPortlets(true, false);
}
public Portlet getPortlet(PortletContext compoundPortletContext) throws
IllegalArgumentException, PortletInvokerException
@@ -294,13 +346,6 @@
throw new IllegalArgumentException("Bad portlet id format " +
compoundPortletId);
}
- FederatedPortletInvoker federated = registry.get(invokerId);
- if (federated == null)
- {
- return nullHandler.resolvePortletInvokerFor(compoundPortletId, invokerId,
this);
- }
-
- //
- return federated;
+ return getOrResolveFederatedInvoker(invokerId, compoundPortletId);
}
}
Modified:
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/FederatingPortletInvokerTestCase.java
===================================================================
---
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/FederatingPortletInvokerTestCase.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/FederatingPortletInvokerTestCase.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -37,6 +37,7 @@
import org.gatein.pc.portlet.support.info.PortletInfoSupport;
import java.util.Collection;
+import java.util.Collections;
import java.util.Locale;
import java.util.Set;
@@ -126,7 +127,7 @@
public void testFederation() throws PortletInvokerException
{
- Collection federateds = federatingInvoker.getFederatedInvokers();
+ Collection federateds = federatingInvoker.getFederatedInvokerIds();
assertNotNull(federateds);
assertEquals(2, federateds.size());
@@ -209,11 +210,21 @@
federatingInvoker.setNullInvokerHandler(new NullInvokerHandler()
{
- public FederatedPortletInvoker resolvePortletInvokerFor(String
compoundPortletId, String invokerId, FederatingPortletInvoker callingInvoker) throws
NoSuchPortletException
+ public FederatedPortletInvoker resolvePortletInvokerFor(String invokerId,
FederatingPortletInvoker callingInvoker, String compoundPortletId) throws
NoSuchPortletException
{
assertEquals(federatingInvoker, callingInvoker);
return remote;
}
+
+ public boolean knows(String invokerId)
+ {
+ return federatedId.equals(invokerId);
+ }
+
+ public Collection<String> getKnownInvokerIds()
+ {
+ return Collections.singletonList(federatedId);
+ }
});
assertEquals(portlet,
federatingInvoker.getPortlet(PortletContext.createPortletContext(federatedId +
PortletContext.INVOKER_SEPARATOR + context.getId())));
Modified:
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/NoInvokersTestCase.java
===================================================================
---
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/NoInvokersTestCase.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/NoInvokersTestCase.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -26,8 +26,8 @@
import org.gatein.pc.api.PortletInvokerException;
import org.gatein.pc.federation.impl.FederatingPortletInvokerService;
+import java.util.ArrayList;
import java.util.HashSet;
-import java.util.ArrayList;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -43,6 +43,6 @@
assertEquals(new HashSet(), federating.getPortlets());
//
- assertEquals(new ArrayList(), new ArrayList(federating.getFederatedInvokers()));
+ assertEquals(new ArrayList(), new ArrayList(federating.getFederatedInvokerIds()));
}
}
Modified:
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/OneInvokerNoPortletsTestCase.java
===================================================================
---
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/OneInvokerNoPortletsTestCase.java 2011-09-01
14:51:53 UTC (rev 7278)
+++
components/pc/trunk/federation/src/test/java/org/gatein/pc/federation/OneInvokerNoPortletsTestCase.java 2011-09-01
16:13:48 UTC (rev 7279)
@@ -24,11 +24,11 @@
import junit.framework.TestCase;
import org.gatein.pc.api.PortletInvokerException;
+import org.gatein.pc.federation.impl.FederatingPortletInvokerService;
import org.gatein.pc.portlet.support.PortletInvokerSupport;
-import org.gatein.pc.federation.impl.FederatingPortletInvokerService;
+import java.util.Collection;
import java.util.HashSet;
-import java.util.Collection;
/**
* @author <a href="mailto:julien@jboss.org">Julien Viet</a>
@@ -47,11 +47,12 @@
assertEquals(new HashSet(), federating.getPortlets());
//
- Collection federateds = federating.getFederatedInvokers();
+ Collection<String> federateds = federating.getFederatedInvokerIds();
assertNotNull(federateds);
assertEquals(1, federateds.size());
- FederatedPortletInvoker federated =
(FederatedPortletInvoker)federateds.iterator().next();
- assertEquals("foo", federated.getId());
- assertEquals(support, federated.getPortletInvoker());
+
+ String id = federateds.iterator().next();
+ assertEquals("foo", id);
+ assertEquals(support, federating.getFederatedInvoker(id).getPortletInvoker());
}
}