You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by "Ate Douma (JIRA)" <je...@portals.apache.org> on 2009/03/20 22:15:50 UTC
[jira] Created: (JS2-938) Create flyweight PortletWindow instances
for each request, the handle to access and store all portlet interaction
data and drop the PortletEntityImpl usage
Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: JS2-938
URL: https://issues.apache.org/jira/browse/JS2-938
Project: Jetspeed 2
Issue Type: Improvement
Components: Components Core, Container, Portlet Entities and Preferences
Affects Versions: 2.2
Reporter: Ate Douma
Assignee: Ate Douma
Priority: Critical
Fix For: 2.2
With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
The following steps are planned to implement this:
- No more caching of PortletWindow instances:
For each request and for each "fragment" a new PortletWindow will be created on the fly
- Replace the portletWindowCache with a PortletDefinitionCache
In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
- Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
- PortletDefinition
- ContentFragment (and thereby also PortletContent)
- (request) attributes map
- implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
- When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
- Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
- Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
- Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
[jira] Commented: (JS2-938) Create flyweight PortletWindow
instances for each request, the handle to access and store all portlet
interaction data and drop the PortletEntityImpl usage
Posted by "Ate Douma (JIRA)" <je...@portals.apache.org>.
[ https://issues.apache.org/jira/browse/JS2-938?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12685365#action_12685365 ]
Ate Douma commented on JS2-938:
-------------------------------
To make the initial implementation of the above steps easier, I'll begin with dropping the PortletWindow cache handling completely.
Once all other features are completed and properly functionally tested, the PortletDefinition cache will be put in place.
> Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JS2-938
> URL: https://issues.apache.org/jira/browse/JS2-938
> Project: Jetspeed 2
> Issue Type: Improvement
> Components: Components Core, Container, Portlet Entities and Preferences
> Affects Versions: 2.2
> Reporter: Ate Douma
> Assignee: Ate Douma
> Priority: Critical
> Fix For: 2.2
>
>
> With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
> By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
> This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
> The following steps are planned to implement this:
> - No more caching of PortletWindow instances:
> For each request and for each "fragment" a new PortletWindow will be created on the fly
> - Replace the portletWindowCache with a PortletDefinitionCache
> In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
> The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
> - Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
> - PortletDefinition
> - ContentFragment (and thereby also PortletContent)
> - (request) attributes map
> - implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
> - When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
> - Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
> - Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
> - Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
> Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
> The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
> Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
> The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
> With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
> Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
> The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
> Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
[jira] Resolved: (JS2-938) Create flyweight PortletWindow instances
for each request, the handle to access and store all portlet interaction
data and drop the PortletEntityImpl usage
Posted by "Ate Douma (JIRA)" <je...@portals.apache.org>.
[ https://issues.apache.org/jira/browse/JS2-938?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Ate Douma resolved JS2-938.
---------------------------
Resolution: Fixed
Completed
> Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JS2-938
> URL: https://issues.apache.org/jira/browse/JS2-938
> Project: Jetspeed 2
> Issue Type: Improvement
> Components: Components Core, Container, Portlet Entities and Preferences
> Affects Versions: 2.2.0
> Reporter: Ate Douma
> Assignee: Ate Douma
> Priority: Critical
> Fix For: 2.2.0
>
>
> With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
> By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
> This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
> The following steps are planned to implement this:
> - No more caching of PortletWindow instances:
> For each request and for each "fragment" a new PortletWindow will be created on the fly
> - Replace the portletWindowCache with a PortletDefinitionCache
> In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
> The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
> - Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
> - PortletDefinition
> - ContentFragment (and thereby also PortletContent)
> - (request) attributes map
> - implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
> - When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
> - Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
> - Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
> - Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
> Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
> The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
> Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
> The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
> With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
> Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
> The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
> Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
[jira] Commented: (JS2-938) Create flyweight PortletWindow
instances for each request, the handle to access and store all portlet
interaction data and drop the PortletEntityImpl usage
Posted by "Ate Douma (JIRA)" <je...@portals.apache.org>.
[ https://issues.apache.org/jira/browse/JS2-938?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12685379#action_12685379 ]
Ate Douma commented on JS2-938:
-------------------------------
Areas which explicitly need to be visited again to check for and possibly PortletDefinition cache management are:
- PortletApplicationManager.unregisterPortletApplication which currently invokes PortletWindowsAccessor.removeWindows(PortletEntity)
> Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JS2-938
> URL: https://issues.apache.org/jira/browse/JS2-938
> Project: Jetspeed 2
> Issue Type: Improvement
> Components: Components Core, Container, Portlet Entities and Preferences
> Affects Versions: 2.2
> Reporter: Ate Douma
> Assignee: Ate Douma
> Priority: Critical
> Fix For: 2.2
>
>
> With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
> By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
> This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
> The following steps are planned to implement this:
> - No more caching of PortletWindow instances:
> For each request and for each "fragment" a new PortletWindow will be created on the fly
> - Replace the portletWindowCache with a PortletDefinitionCache
> In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
> The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
> - Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
> - PortletDefinition
> - ContentFragment (and thereby also PortletContent)
> - (request) attributes map
> - implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
> - When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
> - Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
> - Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
> - Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
> Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
> The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
> Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
> The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
> With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
> Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
> The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
> Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
[jira] Resolved: (JS2-938) Create flyweight PortletWindow instances
for each request, the handle to access and store all portlet interaction
data and drop the PortletEntityImpl usage
Posted by "Ate Douma (JIRA)" <je...@portals.apache.org>.
[ https://issues.apache.org/jira/browse/JS2-938?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Ate Douma resolved JS2-938.
---------------------------
Resolution: Fixed
The task remaining was providing a new solution for the previously used PortletWindowCache, specifically with respect to caching PortletDefinitions
This now is implemented by leveraging the OJB cache itself (backed by a ehcache) as a shared/global (readonly) cache, both for PortletApplication and PortletDefinition instances.
As instances retrieved through this cache are shared, they should only be used for readonly purposes, like as for the PortletWindow.
To distinguish between the readonly and writing use-cases, I've added additional registry methods for retrieving a PortletApplication or PortletDefinition with a extra boolean parameter fromCache.
This way, current API usages will still (like before) retrieve fresh instances directly from the database, but with these new methods the much more optimal cache based retrieval is now possible.
For common usages, like the flyweight PortletWindows but also simple read checks I've already updated the current API usages where applicable.
Possibly other usages might be reviewed if they also could leverage the more optimal cache based retrieval methods.
> Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JS2-938
> URL: https://issues.apache.org/jira/browse/JS2-938
> Project: Jetspeed 2
> Issue Type: Improvement
> Components: Components Core, Container, Portlet Entities and Preferences
> Affects Versions: 2.2.0
> Reporter: Ate Douma
> Assignee: Ate Douma
> Priority: Critical
> Fix For: 2.2.0
>
>
> With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
> By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
> This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
> The following steps are planned to implement this:
> - No more caching of PortletWindow instances:
> For each request and for each "fragment" a new PortletWindow will be created on the fly
> - Replace the portletWindowCache with a PortletDefinitionCache
> In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
> The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
> - Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
> - PortletDefinition
> - ContentFragment (and thereby also PortletContent)
> - (request) attributes map
> - implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
> - When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
> - Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
> - Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
> - Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
> Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
> The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
> Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
> The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
> With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
> Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
> The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
> Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org
[jira] Reopened: (JS2-938) Create flyweight PortletWindow instances
for each request, the handle to access and store all portlet interaction
data and drop the PortletEntityImpl usage
Posted by "Ate Douma (JIRA)" <je...@portals.apache.org>.
[ https://issues.apache.org/jira/browse/JS2-938?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Ate Douma reopened JS2-938:
---------------------------
Hmm, I was a bit too hasty here.
The PortletDefinition cache is indeed properly cleared upon removal (unregistering) of a Portlet Application.
However, simply hooking into the current PortletDefinitionName and/or PortletDefinitionOid caches is dangerous as its a single/shared cache.
This means any change to a PortletDefinition retrieved from the cache would immediately be reflected through every other usage.
For this, we need to decide how to properly "isolate" modifications, either through a second level cache, or using a more lightweight readonly and/or locking strategy.
> Create flyweight PortletWindow instances for each request, the handle to access and store all portlet interaction data and drop the PortletEntityImpl usage
> ------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: JS2-938
> URL: https://issues.apache.org/jira/browse/JS2-938
> Project: Jetspeed 2
> Issue Type: Improvement
> Components: Components Core, Container, Portlet Entities and Preferences
> Affects Versions: 2.2.0
> Reporter: Ate Douma
> Assignee: Ate Douma
> Priority: Critical
> Fix For: 2.2.0
>
>
> With the new Pluto container API and the upgrade process to integrate it in Jetspeed, see: JS2-871, it has become clear that we now can improve and simplify the portlet request state management enormously.
> By now managing the request state separate from the request/response (wrapper) objects, we can almost completely get rid of all potential concurrency problems and drop all the specialized code dealing with that.
> This requires some extensive refactoring but will in the end make the logic and management of the portlet invocations and renderjobs much more straightforward.
> The following steps are planned to implement this:
> - No more caching of PortletWindow instances:
> For each request and for each "fragment" a new PortletWindow will be created on the fly
> - Replace the portletWindowCache with a PortletDefinitionCache
> In the current PortletWindow object model tree, the real model data is primarily the PortletDefinition itself and the cache is foremost used for quick access to that
> The PortletEntity referenced from the PortletWindow only provides access to the PortletDefinition and its logical ID value which is (currently) equal to the window id
> - Extend PortletWindow to provide access to and store all (and only) the PortletWindow specific state:
> - PortletDefinition
> - ContentFragment (and thereby also PortletContent)
> - (request) attributes map
> - implement also the Pluto PortletEntity interface (which only provides access to PortletDefinition) and have it point back to window.getPortletDefinition()
> - When a PortletWindow is created (or better: when its related Fragment is determined) the fragment will provide the key (name==appName::portletName) into the portletDefinitionCache to retrieve its PortletDefinition
> - Create a PortletWindow factory on the JetspeedRequestContext which keeps a map of current request PortletWindows keyed on windowId
> - Store the currently invoked PortletWindow in a single (non-static) ThreadLocal on the JetspeedRequestContext to support the container interaction and callback access from dispatched portlets
> - Merge the current PortletWindowRequestContext interface also into PortletWindow to support the container invocation process
> Pluto container passes the PortletWindow around everywhere, so Jetspeed also will have direct access to the request/response state anywhere we're called back, without even having to go through the ThreadLocal to access it
> The resulting new PortletWindow is completely thread save and thus all the current code needed to keep the request state in sync can be dropped.
> Finally, by merging the PortletEntity with the PortletWindow we technically no longer need the PortletEntityImpl itself.
> The PortletEntity (ID) used to needed for preferences lookup because a PortletEntity really is just that: a handle to a preferences set.
> With the already completed refactoring of the portlet preferences however we already are actually storing the PortletEntity ID directly with the preferences (set) itself in the database.
> Because of that, the PortletEntity object and database table actually have become redundant now, except for the current usage and reference from the PortletWindow.
> The end result of all this therefore is expected to allow us to drop the PortletEntityImpl and everything tied to it from Jetspeed.
> Note: the *logical* meaning and usage of a PortletEntity (ID) will remain of course.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org