Author: thomas.heute(a)jboss.com
Date: 2010-11-26 05:13:55 -0500 (Fri, 26 Nov 2010)
New Revision: 5288
Added:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/IntegrationCache.java
Modified:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/GroupDAOImpl.java
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMCacheService.java
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMOrganizationServiceImpl.java
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMServiceImpl.java
Log:
JBEPP-683: Performance improvements in PicketLink IDM integration
Modified:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/GroupDAOImpl.java
===================================================================
---
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/GroupDAOImpl.java 2010-11-26
10:11:16 UTC (rev 5287)
+++
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/GroupDAOImpl.java 2010-11-26
10:13:55 UTC (rev 5288)
@@ -212,6 +212,7 @@
try
{
getIdentitySession().getPersistenceManager().removeGroup(jbidGroup, true);
+
}
catch (Exception e)
{
@@ -588,9 +589,26 @@
private String getGroupId(org.picketlink.idm.api.Group jbidGroup,
List<org.picketlink.idm.api.Group> processed) throws
Exception
{
+ // Check in cache
+ if (getIntegrationCache() != null)
+ {
+ String cachedId = getIntegrationCache().getGtnGroupId(getCacheNS(),
jbidGroup.getKey());
+ if (cachedId != null)
+ {
+ return cachedId;
+ }
+ }
+
if (jbidGroup.equals(getRootGroup()))
{
- return "";
+ String calculatedId = "";
+
+ if (getIntegrationCache() != null)
+ {
+ getIntegrationCache().putGtnGroupId(getCacheNS(), jbidGroup.getKey(),
calculatedId);
+ }
+
+ return calculatedId;
}
if (processed == null)
@@ -628,8 +646,16 @@
"defined by type mappings or just place it under root /");
}
- return obtainMappedId(jbidGroup, gtnGroupName);
+ String calculatedId = obtainMappedId(jbidGroup, gtnGroupName);
+ if (getIntegrationCache() != null)
+ {
+ getIntegrationCache().putGtnGroupId(getCacheNS(), jbidGroup.getKey(),
calculatedId);
+ }
+
+ return calculatedId;
+
+
}
processed.add(jbidGroup);
@@ -648,13 +674,27 @@
// mappings or connect it to the root
else
{
- return obtainMappedId(jbidGroup, gtnGroupName);
+ String calculatedId = obtainMappedId(jbidGroup, gtnGroupName);
+
+ if (getIntegrationCache() != null)
+ {
+ getIntegrationCache().putGtnGroupId(getCacheNS(), jbidGroup.getKey(),
calculatedId);
+ }
+
+ return calculatedId;
}
}
- return parentGroupId + "/" + gtnGroupName;
+ String calculatedId = parentGroupId + "/" + gtnGroupName;
+ if (getIntegrationCache() != null)
+ {
+ getIntegrationCache().putGtnGroupId(getCacheNS(), jbidGroup.getKey(),
calculatedId);
+ }
+
+ return calculatedId;
+
}
/**
@@ -761,8 +801,61 @@
return service_.getIdentitySession();
}
- private org.picketlink.idm.api.Group getRootGroup() throws Exception
+ private IntegrationCache getIntegrationCache()
{
+ // TODO: refactor to remove cast. For now to avoid adding new config option and
share existing cache instannce
+ // TODO: it should be there.
+ return ((PicketLinkIDMServiceImpl)service_).getIntegrationCache();
+ }
+
+ /**
+ * Returns namespace to be used with integration cache
+ * @return
+ */
+ private String getCacheNS()
+ {
+ // TODO: refactor to remove cast. For now to avoid adding new config option and
share existing cache instannce
+ // TODO: it should be there.
+ return ((PicketLinkIDMServiceImpl)service_).getRealmName();
+ }
+
+
+ /**
+ * Returns mock of PLIDM group representing "/" group. This method uses
cache and delegates to obtainRootGroup().
+ *
+ * @return
+ * @throws Exception
+ */
+ protected org.picketlink.idm.api.Group getRootGroup() throws Exception
+ {
+ org.picketlink.idm.api.Group rootGroup = null;
+
+ if (getIntegrationCache() != null)
+ {
+ rootGroup = getIntegrationCache().getRootGroup(getCacheNS());
+ }
+
+ if (rootGroup == null)
+ {
+ rootGroup = obtainRootGroup();
+
+ if (getIntegrationCache() != null)
+ {
+ getIntegrationCache().putRootGroup(getCacheNS(), rootGroup);
+ }
+ }
+
+ return rootGroup;
+
+ }
+
+ /**
+ * Obtains PLIDM group representing "/" group. If such group doens't
exist it creates one.
+ * @return
+ * @throws Exception
+ */
+ protected org.picketlink.idm.api.Group obtainRootGroup() throws Exception
+ {
org.picketlink.idm.api.Group rootGroup = null;
try
{
Copied:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/IntegrationCache.java
(from rev 5221,
portal/trunk/component/identity/src/main/java/org/exoplatform/services/organization/idm/IntegrationCache.java)
===================================================================
---
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/IntegrationCache.java
(rev 0)
+++
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/IntegrationCache.java 2010-11-26
10:13:55 UTC (rev 5288)
@@ -0,0 +1,241 @@
+package org.exoplatform.services.organization.idm;
+
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.CacheStatus;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Node;
+import org.picketlink.idm.api.Group;
+import org.picketlink.idm.api.User;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/*
+* JBoss, a division of Red Hat
+* Copyright 2010, Red Hat Middleware, LLC, and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+*/
+
+/**
+ * Provides cache for some data used in integration layer between PicketLink IDM and
GateIn
+ */
+public class IntegrationCache
+{
+ private static Logger log = Logger.getLogger(IntegrationCache.class.getName());
+
+ private Cache cache;
+
+ public static final String NODE_GTN_GROUP_ID = "NODE_GTN_GROUP_ID";
+
+ public static final String NODE_PLIDM_ROOT_GROUP = "NODE_PLIDM_ROOT_GROUP";
+
+ public static final String NULL_NS_NODE = "GTN_IC_COMMON_NS";
+
+ public static final String MAIN_ROOT =
"NODE_GTN_ORG_SERVICE_INT_CACHE_MAIN_ROOT";
+
+ public static final String NODE_OBJECT_KEY = "object";
+
+ private Fqn getRootNode()
+ {
+ return Fqn.fromString("/" + MAIN_ROOT);
+ }
+
+ private Fqn getNamespacedFqn(String ns)
+ {
+ String namespace = ns != null ? ns : NULL_NS_NODE;
+ namespace = namespace.replaceAll("/", "_");
+ return Fqn.fromString(getRootNode() + "/" + namespace);
+ }
+
+ private Fqn getFqn(String ns, String node, Object o)
+ {
+ return Fqn.fromString(getNamespacedFqn(ns) + "/" + node + "/" +
o);
+ }
+
+ private Fqn getFqn(String ns, String node)
+ {
+ return Fqn.fromString(getNamespacedFqn(ns) + "/" + node);
+ }
+
+ public void initialize(InputStream jbossCacheConfiguration)
+ {
+ CacheFactory factory = new DefaultCacheFactory();
+
+ if (jbossCacheConfiguration == null)
+ {
+ throw new IllegalArgumentException("JBoss Cache configuration InputStream
is null");
+ }
+
+ this.cache = factory.createCache(jbossCacheConfiguration);
+
+ this.cache.create();
+ this.cache.start();
+
+ }
+
+ public void initialize(Cache cache)
+ {
+ this.cache = cache;
+
+ CacheStatus status = cache.getCacheStatus();
+
+ if (status.createAllowed())
+ {
+ this.cache.create();
+ }
+ if (status.startAllowed())
+ {
+ this.cache.start();
+ }
+
+ }
+
+ Cache getCache()
+ {
+ return cache;
+ }
+
+
+ public void invalidate(String ns)
+ {
+
+ boolean success = cache.getRoot().removeChild(getNamespacedFqn(ns));
+
+ if (log.isLoggable(Level.FINER))
+ {
+ log.finer(this.toString() + "Invalidating namespace:" + ns + ";
success=" + success);
+ }
+ }
+
+ public void invalidateAll()
+ {
+ boolean success = cache.getRoot().removeChild(getRootNode());
+
+ if (log.isLoggable(Level.FINER))
+ {
+ log.finer(this.toString() + "Invalidating whole cache - success=" +
success);
+ }
+ }
+
+ /**
+ * Store gatein group id
+ * @param ns
+ * @param pLIDMId
+ * @param id
+ */
+ void putGtnGroupId(String ns, String pLIDMId, String id)
+ {
+ Fqn nodeFqn = getFqn(ns, NODE_GTN_GROUP_ID, pLIDMId);
+
+ Node ioNode = getCache().getRoot().addChild(nodeFqn);
+
+ ioNode.put(NODE_OBJECT_KEY, id);
+
+ if (log.isLoggable(Level.FINER))
+ {
+
+ log.finer(this.toString() + "GateIn group id cached. PLIDM group id: "
+ pLIDMId +
+ "GateIn group id: " + id + ";namespace=" + ns);
+ }
+
+ }
+
+ /**
+ * Retrieve gatein group id
+ * @param ns
+ * @param pLIDMId
+ * @return
+ */
+ String getGtnGroupId(String ns, String pLIDMId)
+ {
+
+ Fqn nodeFqn = getFqn(ns, NODE_GTN_GROUP_ID, pLIDMId);
+
+ Node node = getCache().getRoot().getChild(nodeFqn);
+
+ if (node != null)
+ {
+ String id = (String)node.get(NODE_OBJECT_KEY);
+
+ if (log.isLoggable(Level.FINER) && id != null)
+ {
+ log.finer(this.toString() + "GateIn group id found in cache. PLIDM group
id: " + pLIDMId +
+ "GateIn group id: " + id + ";namespace=" + ns);
+ }
+
+ return id;
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Store PLIDM root group
+ * @param ns
+ * @param rootGroup
+ */
+ void putRootGroup(String ns, Group rootGroup)
+ {
+ Fqn nodeFqn = getFqn(ns, NODE_PLIDM_ROOT_GROUP);
+
+ Node ioNode = getCache().getRoot().addChild(nodeFqn);
+
+ ioNode.put(NODE_OBJECT_KEY, rootGroup);
+
+ if (log.isLoggable(Level.FINER))
+ {
+
+ log.finer(this.toString() + "GateIn root group stored in cache" +
";namespace=" + ns);
+ }
+
+ }
+
+ /**
+ * Retrieve PLIDM root group
+ * @param ns
+ * @return
+ */
+ Group getRootGroup(String ns)
+ {
+ Fqn nodeFqn = getFqn(ns, NODE_PLIDM_ROOT_GROUP);
+
+ Node node = getCache().getRoot().getChild(nodeFqn);
+
+ if (node != null)
+ {
+ Group rootGroup = (Group)node.get(NODE_OBJECT_KEY);
+
+ if (log.isLoggable(Level.FINER) && rootGroup != null)
+ {
+ log.finer(this.toString() + "GateIn root group found in cache" +
";namespace=" + ns);
+ }
+
+ return rootGroup;
+ }
+
+ return null;
+
+ }
+
+}
Modified:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMCacheService.java
===================================================================
---
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMCacheService.java 2010-11-26
10:11:16 UTC (rev 5287)
+++
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMCacheService.java 2010-11-26
10:13:55 UTC (rev 5288)
@@ -51,6 +51,8 @@
public class PicketLinkIDMCacheService
{
+ private final List<IntegrationCache> integrationCache = new
LinkedList<IntegrationCache>();
+
private final List<APICacheProvider> apiCacheProviders = new
LinkedList<APICacheProvider>();
private final List<IdentityStoreCacheProvider> storeCacheProviders = new
LinkedList<IdentityStoreCacheProvider>();
@@ -59,6 +61,16 @@
{
}
+ public void register(IntegrationCache cacheProvider)
+ {
+
+ if (cacheProvider != null)
+ {
+ integrationCache.add(cacheProvider);
+ }
+
+ }
+
public void register(APICacheProvider cacheProvider)
{
@@ -101,6 +113,11 @@
@Impact(ImpactType.WRITE)
public void invalidateAll()
{
+ for (IntegrationCache cacheProvider : integrationCache)
+ {
+ cacheProvider.invalidateAll();
+ }
+
for (APICacheProvider cacheProvider : apiCacheProviders)
{
cacheProvider.invalidateAll();
Modified:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMOrganizationServiceImpl.java
===================================================================
---
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMOrganizationServiceImpl.java 2010-11-26
10:11:16 UTC (rev 5287)
+++
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMOrganizationServiceImpl.java 2010-11-26
10:13:55 UTC (rev 5288)
@@ -76,7 +76,7 @@
}
- public final org.picketlink.idm.api.Group getJBIDMGroup(String groupId) throws
Exception
+ public final org.picketlink.idm.api.Group getJBIDMGroup(String groupId) throws
Exception
{
String[] ids = groupId.split("/");
String name = ids[ids.length - 1];
Modified:
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMServiceImpl.java
===================================================================
---
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMServiceImpl.java 2010-11-26
10:11:16 UTC (rev 5287)
+++
epp/portal/branches/EPP_5_1_Branch/component/identity/src/main/java/org/exoplatform/services/organization/idm/PicketLinkIDMServiceImpl.java 2010-11-26
10:13:55 UTC (rev 5288)
@@ -26,6 +26,9 @@
import org.exoplatform.services.log.Log;
import org.exoplatform.services.database.HibernateService;
import org.exoplatform.services.naming.InitialContextInitializer;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheFactory;
+import org.jboss.cache.DefaultCacheFactory;
import org.picketlink.idm.api.IdentitySession;
import org.picketlink.idm.api.IdentitySessionFactory;
import org.picketlink.idm.api.cfg.IdentityConfiguration;
@@ -75,6 +78,8 @@
private IdentityConfiguration identityConfiguration;
+ private IntegrationCache integrationCache;
+
private PicketLinkIDMServiceImpl()
{
}
@@ -125,13 +130,31 @@
{
InputStream configStream =
confManager.getInputStream(apiCacheConfig.getValue());
+ // Create common JBoss Cache instance
+ CacheFactory factory = new DefaultCacheFactory();
+ if (configStream == null)
+ {
+ throw new IllegalArgumentException("JBoss Cache configuration
InputStream is null");
+ }
+
+ Cache cache = factory.createCache(configStream);
+
+ cache.create();
+ cache.start();
+
+ configStream.close();
+
+ // PLIDM API cache
JBossCacheAPICacheProviderImpl apiCacheProvider = new
JBossCacheAPICacheProviderImpl();
- apiCacheProvider.initialize(configStream);
+ apiCacheProvider.initialize(cache);
picketLinkIDMCache.register(apiCacheProvider);
identityConfiguration.getIdentityConfigurationRegistry().register(apiCacheProvider,
"apiCacheProvider");
- configStream.close();
+ //Integration cache
+ integrationCache = new IntegrationCache();
+ integrationCache.initialize(cache);
+ picketLinkIDMCache.register(apiCacheProvider);
}
if (storeCacheConfig != null)
@@ -192,4 +215,14 @@
}
return getIdentitySessionFactory().getCurrentIdentitySession(realm);
}
+
+ public IntegrationCache getIntegrationCache()
+ {
+ return integrationCache;
+ }
+
+ public String getRealmName()
+ {
+ return realmName;
+ }
}