Author: chris.laprun(a)jboss.com
Date: 2006-12-19 21:25:10 -0500 (Tue, 19 Dec 2006)
New Revision: 5909
Modified:
trunk/registration/src/main/org/jboss/portal/registration/InvalidConsumerDataException.java
trunk/wsrp/src/main/org/jboss/portal/test/wsrp/framework/TestWSRPProducerImpl.java
trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/InvocationHandler.java
trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java
Log:
- Re-wrote (again) registration handling in Consumer. Should be good now.
- Implemented clone, destroy and getPortletProperties. Still need to implement
setProperties. NOT TESTED AT ALL!!!
- Updated test producer to return a RegistrationContext on register. This needs to be
fixed as well.
Modified:
trunk/registration/src/main/org/jboss/portal/registration/InvalidConsumerDataException.java
===================================================================
---
trunk/registration/src/main/org/jboss/portal/registration/InvalidConsumerDataException.java 2006-12-20
00:56:54 UTC (rev 5908)
+++
trunk/registration/src/main/org/jboss/portal/registration/InvalidConsumerDataException.java 2006-12-20
02:25:10 UTC (rev 5909)
@@ -30,4 +30,23 @@
*/
public class InvalidConsumerDataException extends RegistrationException
{
+
+ public InvalidConsumerDataException()
+ {
+ }
+
+ public InvalidConsumerDataException(String message)
+ {
+ super(message);
+ }
+
+ public InvalidConsumerDataException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ public InvalidConsumerDataException(Throwable cause)
+ {
+ super(cause);
+ }
}
Modified:
trunk/wsrp/src/main/org/jboss/portal/test/wsrp/framework/TestWSRPProducerImpl.java
===================================================================
---
trunk/wsrp/src/main/org/jboss/portal/test/wsrp/framework/TestWSRPProducerImpl.java 2006-12-20
00:56:54 UTC (rev 5908)
+++
trunk/wsrp/src/main/org/jboss/portal/test/wsrp/framework/TestWSRPProducerImpl.java 2006-12-20
02:25:10 UTC (rev 5909)
@@ -31,6 +31,7 @@
import org.jboss.portal.test.wsrp.v1.consumer.behaviors.NullMarkupBehavior;
import org.jboss.portal.test.wsrp.v1.consumer.behaviors.SessionMarkupBehavior;
import org.jboss.portal.wsrp.WSRPConstants;
+import org.jboss.portal.wsrp.WSRPTypeFactory;
import org.jboss.portal.wsrp.core.AccessDeniedFault;
import org.jboss.portal.wsrp.core.BlockingInteractionResponse;
import org.jboss.portal.wsrp.core.ClonePortlet;
@@ -281,7 +282,7 @@
public RegistrationContext register(RegistrationData register) throws
MissingParametersFault, OperationFailedFault, RemoteException
{
incrementBehaviorCallCount();
- return null;
+ return WSRPTypeFactory.createRegistrationContext("registration");
}
public ReturnAny deregister(RegistrationContext deregister) throws
OperationFailedFault, InvalidRegistrationFault, RemoteException
Modified: trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/InvocationHandler.java
===================================================================
--- trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/InvocationHandler.java 2006-12-20
00:56:54 UTC (rev 5908)
+++ trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/InvocationHandler.java 2006-12-20
02:25:10 UTC (rev 5909)
@@ -94,7 +94,7 @@
}
protected Object performRequest(Object request, PortletInvocation invocation)
- throws ServiceDescriptionUnavailableException
+ throws ServiceDescriptionUnavailableException, PortletInvokerException
{
int retryCount = 0;
Object response = null;
@@ -159,7 +159,7 @@
* handled
*/
private ErrorResponse dealWithError(Exception error, PortletInvocation invocation,
RuntimeContext runtimeContext)
- throws ServiceDescriptionUnavailableException
+ throws ServiceDescriptionUnavailableException, PortletInvokerException
{
log.error("The portlet threw an exception", error);
Modified: trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java
===================================================================
--- trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java 2006-12-20
00:56:54 UTC (rev 5908)
+++ trunk/wsrp/src/main/org/jboss/portal/wsrp/consumer/WSRPConsumerImpl.java 2006-12-20
02:25:10 UTC (rev 5909)
@@ -24,6 +24,7 @@
import org.jboss.portal.common.invocation.InvocationException;
import org.jboss.portal.common.util.ParameterValidation;
+import org.jboss.portal.common.value.StringValue;
import org.jboss.portal.jems.as.system.AbstractJBossService;
import org.jboss.portal.portlet.InvokerUnavailableException;
import org.jboss.portal.portlet.NoSuchPortletException;
@@ -36,20 +37,29 @@
import org.jboss.portal.portlet.invocation.RenderInvocation;
import org.jboss.portal.portlet.invocation.response.PortletInvocationResponse;
import org.jboss.portal.portlet.spi.UserContext;
+import org.jboss.portal.portlet.state.DestroyCloneFailure;
import org.jboss.portal.portlet.state.PropertyChange;
import org.jboss.portal.portlet.state.PropertyMap;
+import org.jboss.portal.portlet.state.SimplePropertyMap;
import org.jboss.portal.wsrp.UserContextConverter;
import org.jboss.portal.wsrp.WSRPConstants;
import org.jboss.portal.wsrp.WSRPConsumer;
import org.jboss.portal.wsrp.WSRPTypeFactory;
+import org.jboss.portal.wsrp.WSRPUtils;
import org.jboss.portal.wsrp.consumer.portlet.WSRPPortlet;
import org.jboss.portal.wsrp.consumer.portlet.info.WSRPPortletInfo;
+import org.jboss.portal.wsrp.core.ClonePortlet;
+import org.jboss.portal.wsrp.core.DestroyFailed;
+import org.jboss.portal.wsrp.core.DestroyPortlets;
+import org.jboss.portal.wsrp.core.DestroyPortletsResponse;
+import org.jboss.portal.wsrp.core.GetPortletProperties;
import org.jboss.portal.wsrp.core.GetServiceDescription;
-import org.jboss.portal.wsrp.core.InvalidRegistrationFault;
import org.jboss.portal.wsrp.core.LocalizedString;
import org.jboss.portal.wsrp.core.ModelDescription;
import org.jboss.portal.wsrp.core.PortletDescription;
+import org.jboss.portal.wsrp.core.Property;
import org.jboss.portal.wsrp.core.PropertyDescription;
+import org.jboss.portal.wsrp.core.PropertyList;
import org.jboss.portal.wsrp.core.RegistrationContext;
import org.jboss.portal.wsrp.core.RegistrationData;
import org.jboss.portal.wsrp.core.RuntimeContext;
@@ -62,9 +72,11 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -146,7 +158,7 @@
{
return new LinkedHashSet(getPortletMap().values());
}
- catch (ServiceDescriptionUnavailableException e)
+ catch (Exception e)
{
throw new InvokerUnavailableException(e.getMessage(), e.getCause());
}
@@ -203,22 +215,107 @@
public PortletContext createClone(PortletContext portletContext) throws
IllegalArgumentException, PortletInvokerException, UnsupportedOperationException
{
- throw new UnsupportedOperationException("createClone currently
unsupported.");
+ ParameterValidation.throwIllegalArgExceptionIfNull(portletContext,
"PortletContext");
+
+ registerIfNeeded();
+
+ // todo: deal with user context
+ ClonePortlet clonePortlet =
WSRPTypeFactory.createClonePortlet(registrationContext,
+ WSRPUtils.convertToWSRPPortletContext(portletContext), null);
+ try
+ {
+ return
WSRPUtils.convertToPortalPortletContext(getPortletManagementService().clonePortlet(clonePortlet));
+ }
+ catch (Exception e)
+ {
+ throw new PortletInvokerException("Couldn't clone portlet '" +
portletContext.getId() + "'", e);
+ }
}
public List destroyClones(List portletIds) throws IllegalArgumentException,
PortletInvokerException, UnsupportedOperationException
{
- throw new UnsupportedOperationException("destroyClone currently
unsupported.");
+ ParameterValidation.throwIllegalArgExceptionIfNull(portletIds, "Portlet
identifiers");
+
+ registerIfNeeded();
+
+ DestroyPortlets destroyPortlets =
WSRPTypeFactory.createDestroyPortlets(registrationContext,
+ (String[])portletIds.toArray(new String[0]));
+
+ try
+ {
+ DestroyPortletsResponse response =
getPortletManagementService().destroyPortlets(destroyPortlets);
+ DestroyFailed[] failures = response.getDestroyFailed();
+ if (failures != null)
+ {
+ List result = new ArrayList(failures.length);
+ for (int i = 0; i < failures.length; i++)
+ {
+ DestroyFailed failure = failures[i];
+ result.add(new DestroyCloneFailure(failure.getPortletHandle(),
failure.getReason()));
+ }
+ return result;
+ }
+ else
+ {
+ return Collections.EMPTY_LIST;
+ }
+ }
+ catch (Exception e)
+ {
+ throw new PortletInvokerException("Couldn't destroy clones.", e);
+ }
}
public PropertyMap getProperties(PortletContext portletContext, Set keys) throws
IllegalArgumentException, PortletInvokerException, UnsupportedOperationException
{
- throw new UnsupportedOperationException("getProperties currently
unsupported.");
+ ParameterValidation.throwIllegalArgExceptionIfNull(keys, "Portlet ids");
+
+ return getProperties(portletContext, (String[])keys.toArray(new String[0]));
}
+ private PropertyMap getProperties(PortletContext portletContext, String[] keys) throws
PortletInvokerException
+ {
+ ParameterValidation.throwIllegalArgExceptionIfNull(portletContext,
"PortletContext");
+
+ registerIfNeeded();
+
+ GetPortletProperties getPortletProperties =
WSRPTypeFactory.createGetPortletProperties(registrationContext, portletContext.getId());
+ getPortletProperties.setNames(keys);
+
+ try
+ {
+ PropertyList response =
getPortletManagementService().getPortletProperties(getPortletProperties);
+ Property[] props = response.getProperties();
+
+ if (props != null)
+ {
+ int propNumber = props.length;
+ PropertyMap result = new SimplePropertyMap(propNumber);
+
+ for (int i = 0; i < propNumber; i++)
+ {
+ Property prop = props[i];
+ String name = prop.getName();
+ String value = prop.getStringValue();
+ result.put(name, new StringValue(value)); // todo: is that all?!?
+ }
+
+ return result;
+ }
+ else
+ {
+ return new SimplePropertyMap();
+ }
+ }
+ catch (Exception e)
+ {
+ throw new PortletInvokerException("Couldn't get properties for portlet
'" + portletContext.getId() + "'", e);
+ }
+ }
+
public PropertyMap getProperties(PortletContext portletContext) throws
IllegalArgumentException, PortletInvokerException, UnsupportedOperationException
{
- throw new UnsupportedOperationException("getProperties currently
unsupported.");
+ return getProperties(portletContext, (String[])null);
}
public PortletContext setProperties(PortletContext portletContext, PropertyChange[]
changes) throws IllegalArgumentException, PortletInvokerException,
UnsupportedOperationException
@@ -245,7 +342,7 @@
// Portlet-related methods
******************************************************************************************
- public Map getPortletGroupMap() throws ServiceDescriptionUnavailableException
+ public Map getPortletGroupMap() throws ServiceDescriptionUnavailableException,
PortletInvokerException
{
if (useCache())
{
@@ -282,7 +379,7 @@
return (WSRPPortlet)getPortlet(portletId);
}
- private Map getPortletMap() throws ServiceDescriptionUnavailableException
+ private Map getPortletMap() throws ServiceDescriptionUnavailableException,
PortletInvokerException
{
if (useCache())
{
@@ -376,7 +473,7 @@
}
private void updateCachesIfNeeded()
- throws ServiceDescriptionUnavailableException
+ throws ServiceDescriptionUnavailableException, PortletInvokerException
{
if (System.currentTimeMillis() > expirationTimeMillis || cachedPortletMap ==
null || portletGroups == null)
{
@@ -415,12 +512,13 @@
// Registration
*****************************************************************************************************
- void handleInvalidRegistrationFault()
- throws ServiceDescriptionUnavailableException
+ void handleInvalidRegistrationFault() throws ServiceDescriptionUnavailableException,
PortletInvokerException
{
log.debug("Trying to re-register after InvalidRegistrationFault");
- // get the service description again and try to register
- getServiceDescriptionAndRegisterIfNeeded();
+
+ // reset registration data and try again
+ resetRegistration();
+ registerIfNeeded();
}
RegistrationContext getRegistrationContext()
@@ -506,12 +604,11 @@
// Service description support methods
******************************************************************************
- public ServiceDescription getServiceDescriptionAndRegisterIfNeeded() throws
ServiceDescriptionUnavailableException
+ private ServiceDescription getServiceDescriptionAndRegisterIfNeeded() throws
ServiceDescriptionUnavailableException, PortletInvokerException
{
- GetServiceDescription request = getServiceDescriptionRequest();
-
// try initial registration if needed
registerIfNeeded();
+ GetServiceDescription request = getServiceDescriptionRequest();
request.setRegistrationContext(registrationContext);
final String producerId = getProducerId();
@@ -523,12 +620,6 @@
if (serviceDescription != null)
{
- boolean shouldRetry = informUserIfMissingRegistrationInfo(serviceDescription,
producerId);
- if (shouldRetry)
- {
- serviceDescription = getServiceDescriptionAndRegisterIfNeeded();
- }
-
// do we need to call initCookie or not?
sessionHandler.setRequiresInitCookie(serviceDescription.getRequiresInitCookie());
@@ -542,16 +633,6 @@
throw new NullPointerException("null service description: deal with
it!");
}
}
- catch (InvalidRegistrationFault e)
- {
- // our registration was not accepted, invalidate our registration data and
retrieve registration data from producer
- registrationContext = null;
- registrationData = null;
- request.setRegistrationContext(null);
-
- // try again
- serviceDescription = getServiceDescriptionAndRegisterIfNeeded();
- }
catch (Exception e)
{
log.debug("Caught Exception in
getServiceDescriptionAndRegisterIfNeeded:\n", e);
@@ -559,27 +640,66 @@
throw new ServiceDescriptionUnavailableException("Problem getting service
description for producer "
+ producerId, cause == null ? e : cause);
}
+ }
- return serviceDescription;
+ /**
+ * Attempts to register if our producer configuration provides registration data and
we don't have a valid
+ * RegistrationContext yet.
+ *
+ * @throws org.jboss.portal.portlet.PortletInvokerException
+ *
+ * @since 2.6
+ */
+ private void registerIfNeeded() throws PortletInvokerException
+ {
+ // no registrationContext = we might need to register
+ if (registrationContext == null)
+ {
+ // we don't have any registration data, check if need one and inform user if
needed
+ if (registrationData == null)
+ {
+ checkRegistrationDataAgainstInitialServiceDescription();
+ }
+
+ try
+ {
+ registrationContext = getRegistrationService().register(registrationData);
+ if (registrationContext == null)
+ {
+ throw new PortletInvokerException("Received null response from
producer '" + producerId + "'");
+ }
+
+ log.info("Successfully registered with handle: '" +
registrationContext.getRegistrationHandle() + "'");
+ }
+ catch (Exception e)
+ {
+ resetRegistration();
+ throw new PortletInvokerException("Couldn't register with producer
'" + producerId + "'", e);
+ }
+ }
}
/**
- * Extract required registration information from the service description and informs
the user if we are not
- * registered and the Producer requires registration. This can happen if we
haven't registered yet or after a retry
- * if our initial registration information was rejected.
+ * @throws ServiceDescriptionUnavailableException
*
- * @param serviceDescription
- * @param producerId
- * @return <code>true</code> if we should retry to get the service
description, <code>false</code> otherwise
- * @throws ServiceDescriptionUnavailableException
- * if we need to inform the user of missing required registration data
+ * @throws PortletInvokerException
* @since 2.6
*/
- private boolean informUserIfMissingRegistrationInfo(ServiceDescription
serviceDescription, String producerId)
- throws ServiceDescriptionUnavailableException
+ private void checkRegistrationDataAgainstInitialServiceDescription() throws
PortletInvokerException
{
- if (serviceDescription.isRequiresRegistration() && registrationContext ==
null)
+ ServiceDescription serviceDescription;
+ try
{
+ serviceDescription =
getServiceDescriptionService().getServiceDescription(getUnregisteredServiceDescriptionRequest());
+ }
+ catch (Exception e)
+ {
+ throw new PortletInvokerException("Couldn't access service description
for producer '"
+ + getProducerId() + "'", e);
+ }
+
+ if (serviceDescription.isRequiresRegistration())
+ {
StringBuffer message = new StringBuffer("Producer
'").append(producerId)
.append("' requires registration. Configuration for this producer
might need to be updated to register.");
log.info(message);
@@ -588,61 +708,106 @@
if (registrationProperties != null)
{
PropertyDescription[] propertyDescriptions =
registrationProperties.getPropertyDescriptions();
- if (propertyDescriptions != null)
+ Map descriptionsMap = getNamedMappingFrom(propertyDescriptions, false);
+ Property[] regProps;
+ if (registrationData != null)
{
- message.append("\nThe producer required the following registration
information: ");
- for (int i = 0; i < propertyDescriptions.length; i++)
+ regProps = registrationData.getRegistrationProperties();
+ }
+ else
+ {
+ regProps = null;
+ }
+ Map propertiesMap = getNamedMappingFrom(regProps, true);
+
+ if (descriptionsMap.size() < propertiesMap.size())
+ {
+ resetRegistration();
+ throw new PortletInvokerException("The provided registration contains
more information than required by producer '"
+ + producerId + "'");
+ }
+
+ StringBuffer missingProps = new StringBuffer();
+ for (Iterator descriptionNames = descriptionsMap.keySet().iterator();
descriptionNames.hasNext();)
+ {
+ String name = (String)descriptionNames.next();
+ Object prop = propertiesMap.get(name);
+ if (prop == null)
{
- PropertyDescription propertyDescription = propertyDescriptions[i];
- String name = propertyDescription.getName();
+ PropertyDescription propertyDescription =
(PropertyDescription)descriptionsMap.get(name);
String type = propertyDescription.getType().toString();
LocalizedString nillableLabel = propertyDescription.getLabel();
String label = nillableLabel == null ? null :
nillableLabel.getValue();
LocalizedString nillableHint = propertyDescription.getHint();
String hint = nillableHint == null ? null : nillableHint.getValue();
- message.append("propertyDescription =\n-
name:\t").append(name).append("\n- type:\t")
- .append(type).append("\n-
label:\t").append(label).append("\n- hint:\t").append(hint)
- .append("\n");
+ missingProps.append("Missing value for registration property named
'").append(name).append("' with type '")
+ .append(type).append("' (label:
'").append(label).append("', hint: '").append(hint)
+ .append("')\n");
}
}
- throw new ServiceDescriptionUnavailableException(message.toString(), null);
+
+ if (missingProps.length() > 0)
+ {
+ log.info(missingProps);
+ resetRegistration();
+ throw new PortletInvokerException("Provided registration data is
invalid:\n" + missingProps);
+ }
}
else
{
- log.info("The producer didn't require any specific registration
properties. Attempting to register with minimal information.");
+ log.info("The producer didn't require any specific registration
properties.");
+ if (registrationData != null)
+ {
+ resetRegistration();
+ throw new PortletInvokerException("Registration data is available for
producer '"
+ + producerId + "' when none is expected by the
producer.");
+ }
+ log.info("Using default registration data for producer '" +
producerId + "'");
registrationData = WSRPTypeFactory.createDefaultRegistrationData();
- return true;
}
}
- return false;
}
+ /** @since 2.6 */
+ private void resetRegistration()
+ {
+ registrationData = null;
+ registrationContext = null;
+ }
+
/**
- * Attempts to register if our producer configuration provides registration data and
we don't have a valid
- * RegistrationContext yet.
- *
- * @throws ServiceDescriptionUnavailableException
- *
+ * @param propertiesOrDescriptions
+ * @param isProperty
+ * @return
+ * @since 2.6
*/
- private void registerIfNeeded() throws ServiceDescriptionUnavailableException
+ private Map getNamedMappingFrom(Object[] propertiesOrDescriptions, boolean
isProperty)
{
- // producer configuration with registration data + no registrationContext = we need
to register!
- if (registrationData != null && registrationContext == null)
+ if (propertiesOrDescriptions != null)
{
- RegistrationContext registrationContext;
- try
+ Map result = new HashMap(propertiesOrDescriptions.length);
+ for (int i = 0; i < propertiesOrDescriptions.length; i++)
{
- registrationContext = getRegistrationService().register(registrationData);
+ Object propertyOrDescription = propertiesOrDescriptions[i];
+ String name;
+ if (isProperty)
+ {
+ name = ((Property)propertyOrDescription).getName();
+ }
+ else
+ {
+ name = ((PropertyDescription)propertyOrDescription).getName();
+ }
+
+ result.put(name, propertyOrDescription);
}
- catch (Exception e)
- {
- throw new ServiceDescriptionUnavailableException("Couldn't register
with producer '" + getProducerId() + "'", e);
- }
- // if we reach this point, registration was successful so remember the returned
registration context
- log.info("Successfully registered with handle: '" +
registrationContext.getRegistrationHandle() + "'");
- this.registrationContext = registrationContext;
+ return result;
}
+ else
+ {
+ return Collections.EMPTY_MAP;
+ }
}
private void setServiceDescriptionRequest(GetServiceDescription request)