You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ka...@apache.org on 2010/07/23 22:49:15 UTC
svn commit: r967256 - in
/directory/apacheds/branches/apacheds-cache-experiment: core-api/
core-api/src/main/java/org/apache/directory/server/core/
core-api/src/main/java/org/apache/directory/server/core/cache/
core-api/src/main/resources/ core-api/src...
Author: kayyagari
Date: Fri Jul 23 20:49:14 2010
New Revision: 967256
URL: http://svn.apache.org/viewvc?rev=967256&view=rev
Log:
o added ehcache based cache service
o moved GroupCache to core-api
o added a new method to DirectoryService interface to get the cache service
o added a default cache configuration file
o updated AciAuthorizationInterceptor to use the new ehcache based GroupCache
o added dependency on ehcache-core
Added:
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/CacheService.java
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/GroupCache.java
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/directory-cacheservice.xml
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/ehcache.xsd
Removed:
directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/GroupCache.java
Modified:
directory/apacheds/branches/apacheds-cache-experiment/core-api/pom.xml
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/DirectoryService.java
directory/apacheds/branches/apacheds-cache-experiment/core-api/src/test/java/org/apache/directory/server/core/MockDirectoryService.java
directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java
Modified: directory/apacheds/branches/apacheds-cache-experiment/core-api/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/pom.xml?rev=967256&r1=967255&r2=967256&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/pom.xml (original)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/pom.xml Fri Jul 23 20:49:14 2010
@@ -35,6 +35,10 @@
Contains interfaces and helper classes that are part of the ApacheDS Core API.
</description>
+ <properties>
+ <ehcache-version>2.2.0</ehcache-version>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.apache.directory.junit</groupId>
@@ -116,6 +120,13 @@
<groupId>org.apache.directory.client.ldap</groupId>
<artifactId>ldap-client-api</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache-core</artifactId>
+ <version>${ehcache-version}</version>
+ </dependency>
+
</dependencies>
<build>
Modified: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/DirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/DirectoryService.java?rev=967256&r1=967255&r2=967256&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/DirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/DirectoryService.java Fri Jul 23 20:49:14 2010
@@ -24,6 +24,7 @@ import java.io.File;
import java.util.List;
import java.util.Set;
+import org.apache.directory.server.core.cache.CacheService;
import org.apache.directory.server.core.changelog.ChangeLog;
import org.apache.directory.server.core.entry.ServerEntryFactory;
import org.apache.directory.server.core.event.EventService;
@@ -517,4 +518,9 @@ public interface DirectoryService extend
* @return the syncPeriodMillis
*/
long getSyncPeriodMillis();
+
+ /**
+ * @return the cache service
+ */
+ CacheService getCacheService();
}
Added: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/CacheService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/CacheService.java?rev=967256&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/CacheService.java (added)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/CacheService.java Fri Jul 23 20:49:14 2010
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.directory.server.core.cache;
+
+
+import java.io.File;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Status;
+
+import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A ehcache based cache service to be used for various caching requirement in the server.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class CacheService
+{
+
+ private static final Logger LOG = LoggerFactory.getLogger( CacheService.class );
+
+ /** the ehcache configuration file */
+ private File configFile;
+
+ /** the ehcache cache manager */
+ private CacheManager cacheManager;
+
+ /** directory service */
+ private DirectoryService dirService;
+
+ /** group cache */
+ private GroupCache groupCache;
+
+
+ public CacheService()
+ {
+ }
+
+
+ public void initialize( DirectoryService dirService )
+ {
+ if ( ( cacheManager != null ) && ( cacheManager.getStatus() == Status.STATUS_ALIVE ) )
+ {
+ LOG.warn( "cache service was already initialized and is alive" );
+ return;
+ }
+
+ if ( configFile == null || !configFile.exists() )
+ {
+ LOG.info( "no custom cache configuration was set, loading the default cache configuration" );
+
+ cacheManager = new CacheManager( getClass().getClassLoader().getResource( "directory-cacheservice.xml" ) );
+ }
+ else
+ {
+ LOG.info( "loading cache configuration from the file {}", configFile );
+
+ cacheManager = new CacheManager( configFile.getAbsolutePath() );
+ }
+
+ this.dirService = dirService;
+ }
+
+
+ public void destroy()
+ {
+ if( cacheManager.getStatus() == Status.STATUS_ALIVE )
+ {
+ LOG.info( "destroying the cache service" );
+
+ groupCache = null;
+
+ cacheManager.removalAll();
+
+ cacheManager.shutdown();
+ }
+ }
+
+
+ public GroupCache getGroupCache() throws LdapException
+ {
+ if ( groupCache != null )
+ {
+ LOG.info( "returning the old group cache" );
+ return groupCache;
+ }
+
+ Cache ehCache = cacheManager.getCache( "groupCache" );
+ LOG.info( "creating a new group cache {}", ehCache.getStatus() );
+
+ groupCache = new GroupCache( dirService.getAdminSession(), ehCache );
+
+ return groupCache;
+ }
+
+
+ public void setConfigFile( File configFile )
+ {
+ if ( configFile == null )
+ {
+ throw new IllegalArgumentException( "invalid configuration file, null" );
+ }
+
+ this.configFile = configFile;
+ }
+
+}
Added: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/GroupCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/GroupCache.java?rev=967256&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/GroupCache.java (added)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/java/org/apache/directory/server/core/cache/GroupCache.java Fri Jul 23 20:49:14 2010
@@ -0,0 +1,582 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.cache;
+
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.directory.SearchControls;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.directory.server.constants.ServerDNConstants;
+import org.apache.directory.server.core.CoreSession;
+import org.apache.directory.server.core.filtering.EntryFilteringCursor;
+import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.partition.PartitionNexus;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.entry.Entry;
+import org.apache.directory.shared.ldap.entry.EntryAttribute;
+import org.apache.directory.shared.ldap.entry.Modification;
+import org.apache.directory.shared.ldap.entry.ModificationOperation;
+import org.apache.directory.shared.ldap.entry.StringValue;
+import org.apache.directory.shared.ldap.entry.Value;
+import org.apache.directory.shared.ldap.exception.LdapException;
+import org.apache.directory.shared.ldap.exception.LdapOperationException;
+import org.apache.directory.shared.ldap.filter.BranchNode;
+import org.apache.directory.shared.ldap.filter.EqualityNode;
+import org.apache.directory.shared.ldap.filter.OrNode;
+import org.apache.directory.shared.ldap.message.AliasDerefMode;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.SchemaManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A cache for tracking static group membership.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class GroupCache
+{
+ /** the logger for this class */
+ private static final Logger LOG = LoggerFactory.getLogger( GroupCache.class );
+
+ /** Speedup for logs */
+ private static final boolean IS_DEBUG = LOG.isDebugEnabled();
+
+ /** String key for the DN of a group to a Set (HashSet) for the Strings of member DNs */
+// private final Map<String, Set<String>> groups = new HashMap<String, Set<String>>();
+
+ /** a handle on the partition nexus */
+ private final PartitionNexus nexus;
+
+ /** A storage for the ObjectClass attributeType */
+ private AttributeType OBJECT_CLASS_AT;
+
+ /** A storage for the member attributeType */
+ private AttributeType MEMBER_AT;
+
+ /** A storage for the uniqueMember attributeType */
+ private AttributeType UNIQUE_MEMBER_AT;
+
+ /**
+ * the schema manager
+ */
+ private SchemaManager schemaManager;
+
+ /** the normalized dn of the administrators group */
+ private DN administratorsGroupDn;
+
+ private static final Set<DN> EMPTY_GROUPS = new HashSet<DN>();
+
+ private Cache ehCache;
+
+ /**
+ * Creates a static group cache.
+ *
+ * @param directoryService the directory service core
+ * @throws LdapException if there are failures on initialization
+ */
+ protected GroupCache( CoreSession session, Cache ehCache ) throws LdapException
+ {
+ schemaManager = session.getDirectoryService().getSchemaManager();
+ nexus = session.getDirectoryService().getPartitionNexus();
+ OBJECT_CLASS_AT = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
+ MEMBER_AT = schemaManager.getAttributeType( SchemaConstants.MEMBER_AT );
+ UNIQUE_MEMBER_AT = schemaManager.getAttributeType( SchemaConstants.UNIQUE_MEMBER_AT );
+
+ // stuff for dealing with the admin group
+ administratorsGroupDn = parseNormalized( ServerDNConstants.ADMINISTRATORS_GROUP_DN );
+
+ this.ehCache = ehCache;
+
+ initialize( session );
+ }
+
+
+ private DN parseNormalized( String name ) throws LdapException
+ {
+ DN dn = new DN( name, schemaManager );
+ return dn;
+ }
+
+
+ private void initialize( CoreSession session ) throws LdapException
+ {
+ // search all naming contexts for static groups and generate
+ // normalized sets of members to cache within the map
+
+ Set<String> suffixes = nexus.listSuffixes();
+
+ for ( String suffix:suffixes )
+ {
+ // moving the filter creation to inside loop to fix DIRSERVER-1121
+ // didn't use clone() cause it is creating List objects, which IMO is not worth calling
+ // in this initialization phase
+ BranchNode filter = new OrNode();
+ filter.addNode( new EqualityNode<String>( OBJECT_CLASS_AT, new StringValue(
+ SchemaConstants.GROUP_OF_NAMES_OC ) ) );
+ filter.addNode( new EqualityNode<String>( OBJECT_CLASS_AT, new StringValue(
+ SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC ) ) );
+
+ DN baseDn = new DN( suffix, schemaManager );
+ SearchControls ctls = new SearchControls();
+ ctls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+ SearchOperationContext searchOperationContext = new SearchOperationContext( session,
+ baseDn, filter, ctls );
+ searchOperationContext.setAliasDerefMode( AliasDerefMode.DEREF_ALWAYS );
+ EntryFilteringCursor results = nexus.search( searchOperationContext );
+
+ try
+ {
+ while ( results.next() )
+ {
+ Entry result = results.get();
+ DN groupDn = result.getDn().normalize( schemaManager.getNormalizerMapping() );
+ EntryAttribute members = getMemberAttribute( result );
+
+ if ( members != null )
+ {
+ Set<String> memberSet = new HashSet<String>( members.size() );
+ addMembers( memberSet, members );
+
+ Element cacheElement = new Element( groupDn.getNormName(), memberSet );
+ ehCache.put( cacheElement );
+ }
+ else
+ {
+ LOG.warn( "Found group '{}' without any member or uniqueMember attributes", groupDn.getName() );
+ }
+ }
+
+ results.close();
+ }
+ catch ( Exception e )
+ {
+ LdapOperationException le = new LdapOperationException( e.getMessage() );
+ le.initCause( e );
+ throw le;
+ }
+ }
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents on startup:\n {}", ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+ }
+
+
+ /**
+ * Gets the member attribute regardless of whether groupOfNames or
+ * groupOfUniqueNames is used.
+ *
+ * @param entry the entry inspected for member attributes
+ * @return the member attribute
+ */
+ private EntryAttribute getMemberAttribute( Entry entry ) throws LdapException
+ {
+ EntryAttribute oc = entry.get( OBJECT_CLASS_AT );
+
+ if ( oc == null )
+ {
+ EntryAttribute member = entry.get( MEMBER_AT );
+
+ if ( member != null )
+ {
+ return member;
+ }
+
+ EntryAttribute uniqueMember = entry.get( UNIQUE_MEMBER_AT );
+
+ if ( uniqueMember != null )
+ {
+ return uniqueMember;
+ }
+
+ return null;
+ }
+
+ if ( oc.contains( SchemaConstants.GROUP_OF_NAMES_OC ) || oc.contains( SchemaConstants.GROUP_OF_NAMES_OC_OID ) )
+ {
+ return entry.get( MEMBER_AT );
+ }
+
+ if ( oc.contains( SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC )
+ || oc.contains( SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC_OID ) )
+ {
+ return entry.get( UNIQUE_MEMBER_AT );
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Adds normalized member DNs to the set of normalized member names.
+ *
+ * @param memberSet the set of member Dns (Strings)
+ * @param members the member attribute values being added
+ * @throws LdapException if there are problems accessing the attr values
+ */
+ private void addMembers( Set<String> memberSet, EntryAttribute members ) throws LdapException
+ {
+ for ( Value<?> value : members )
+ {
+
+ // get and normalize the DN of the member
+ String memberDn = value.getString();
+
+ try
+ {
+ memberDn = parseNormalized( memberDn ).getNormName();
+ }
+ catch ( LdapException e )
+ {
+ LOG.warn( "Malformed member DN in groupOf[Unique]Names entry. Member not added to GroupCache.", e );
+ }
+
+ memberSet.add( memberDn );
+ }
+ }
+
+
+ /**
+ * Removes a set of member names from an existing set.
+ *
+ * @param memberSet the set of normalized member DNs
+ * @param members the set of member values
+ * @throws LdapException if there are problems accessing the attr values
+ */
+ private void removeMembers( Set<String> memberSet, EntryAttribute members ) throws LdapException
+ {
+ for ( Value<?> value : members )
+ {
+ // get and normalize the DN of the member
+ String memberDn = value.getString();
+
+ try
+ {
+ memberDn = parseNormalized( memberDn ).getNormName();
+ }
+ catch ( LdapException e )
+ {
+ LOG.warn( "Malformed member DN in groupOf[Unique]Names entry. Member not removed from GroupCache.", e );
+ }
+
+ memberSet.remove( memberDn );
+ }
+ }
+
+
+ /**
+ * Adds a groups members to the cache. Called by interceptor to account for new
+ * group additions.
+ *
+ * @param name the user provided name for the group entry
+ * @param entry the group entry's attributes
+ * @throws LdapException if there are problems accessing the attr values
+ */
+ public void groupAdded( DN name, Entry entry ) throws LdapException
+ {
+ EntryAttribute members = getMemberAttribute( entry );
+
+ if ( members == null )
+ {
+ return;
+ }
+
+ Set<String> memberSet = new HashSet<String>( members.size() );
+ addMembers( memberSet, members );
+
+ Element cacheElement = new Element( name.getNormName(), memberSet );
+ ehCache.put( cacheElement );
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents after adding '{}' :\n {}", name.getName(), ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+ }
+
+
+ /**
+ * Deletes a group's members from the cache. Called by interceptor to account for
+ * the deletion of groups.
+ *
+ * @param name the normalized DN of the group entry
+ * @param entry the attributes of entry being deleted
+ */
+ public void groupDeleted( DN name, Entry entry ) throws LdapException
+ {
+ EntryAttribute members = getMemberAttribute( entry );
+
+ if ( members == null )
+ {
+ return;
+ }
+
+ ehCache.remove( name.getNormName() );
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents after deleting '{}' :\n {}", name.getName(), ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+ }
+
+
+ /**
+ * Utility method to modify a set of member names based on a modify operation
+ * that changes the members of a group.
+ *
+ * @param memberSet the set of members to be altered
+ * @param modOp the type of modify operation being performed
+ * @param members the members being added, removed or replaced
+ * @throws LdapException if there are problems accessing attribute values
+ */
+ private void modify( Set<String> memberSet, ModificationOperation modOp, EntryAttribute members )
+ throws LdapException
+ {
+
+ switch ( modOp )
+ {
+ case ADD_ATTRIBUTE:
+ addMembers( memberSet, members );
+ break;
+
+ case REPLACE_ATTRIBUTE:
+ if ( members.size() > 0 )
+ {
+ memberSet.clear();
+ addMembers( memberSet, members );
+ }
+
+ break;
+
+ case REMOVE_ATTRIBUTE:
+ removeMembers( memberSet, members );
+ break;
+
+ default:
+ throw new InternalError( I18n.err( I18n.ERR_235, modOp ) );
+ }
+ }
+
+
+ /**
+ * Modifies the cache to reflect changes via modify operations to the group entries.
+ * Called by the interceptor to account for modify ops on groups.
+ *
+ * @param name the normalized name of the group entry modified
+ * @param mods the modification operations being performed
+ * @param entry the group entry being modified
+ * @throws LdapException if there are problems accessing attribute values
+ */
+ public void groupModified( DN name, List<Modification> mods, Entry entry, SchemaManager schemaManager )
+ throws LdapException
+ {
+ EntryAttribute members = null;
+ String memberAttrId = null;
+ EntryAttribute oc = entry.get( OBJECT_CLASS_AT );
+
+ if ( oc.contains( SchemaConstants.GROUP_OF_NAMES_OC ) )
+ {
+ members = entry.get( MEMBER_AT );
+ memberAttrId = SchemaConstants.MEMBER_AT;
+ }
+
+ if ( oc.contains( SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC ) )
+ {
+ members = entry.get( UNIQUE_MEMBER_AT );
+ memberAttrId = SchemaConstants.UNIQUE_MEMBER_AT;
+ }
+
+ if ( members == null )
+ {
+ return;
+ }
+
+ for ( Modification modification : mods )
+ {
+ if ( memberAttrId.equalsIgnoreCase( modification.getAttribute().getId() ) )
+ {
+ Set<String> memberSet = ( Set<String> ) ehCache.get( name.getNormName() ).getValue();
+
+ if ( memberSet != null )
+ {
+ modify( memberSet, modification.getOperation(), modification.getAttribute() );
+ }
+
+ break;
+ }
+ }
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents after modifying '{}' :\n {}", name.getName(), ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+ }
+
+
+ /**
+ * Modifies the cache to reflect changes via modify operations to the group entries.
+ * Called by the interceptor to account for modify ops on groups.
+ *
+ * @param name the normalized name of the group entry modified
+ * @param modOp the modify operation being performed
+ * @param mods the modifications being performed
+ * @throws LdapException if there are problems accessing attribute values
+ */
+ public void groupModified( DN name, ModificationOperation modOp, Entry mods ) throws LdapException
+ {
+ EntryAttribute members = getMemberAttribute( mods );
+
+ if ( members == null )
+ {
+ return;
+ }
+
+ Set<String> memberSet = ( Set<String> ) ehCache.get( name.getNormName() ).getValue();
+
+ if ( memberSet != null )
+ {
+ modify( memberSet, modOp, members );
+ }
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents after modifying '{}' :\n {}", name.getName(), ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+ }
+
+
+ /**
+ * An optimization. By having this method here we can directly access the group
+ * membership information and lookup to see if the principalDn is contained within.
+ *
+ * @param principalDn the normalized DN of the user to check if they are an admin
+ * @return true if the principal is an admin or the admin
+ */
+ public final boolean isPrincipalAnAdministrator( DN principalDn )
+ {
+ if ( principalDn.getNormName().equals( ServerDNConstants.ADMIN_SYSTEM_DN_NORMALIZED ) )
+ {
+ return true;
+ }
+
+ Set<String> members = ( Set<String> ) ehCache.get( administratorsGroupDn.getNormName() ).getValue();
+
+ if ( members == null )
+ {
+ LOG.warn( "What do you mean there is no administrators group? This is bad news." );
+ return false;
+ }
+
+ return members.contains( principalDn.getNormName() );
+ }
+
+
+ /**
+ * Gets the set of groups a user is a member of. The groups are returned
+ * as normalized Name objects within the set.
+ *
+ * @param member the member (user) to get the groups for
+ * @return a Set of Name objects representing the groups
+ * @throws LdapException if there are problems accessing attribute values
+ */
+ public Set<DN> getGroups( String member ) throws LdapException
+ {
+ DN normMember;
+
+ try
+ {
+ normMember = parseNormalized( member );
+ }
+ catch ( LdapException e )
+ {
+ LOG
+ .warn(
+ "Malformed member DN. Could not find groups for member '{}' in GroupCache. Returning empty set for groups!",
+ member, e );
+ return EMPTY_GROUPS;
+ }
+
+ Set<DN> memberGroups = null;
+
+ for ( Object obj : ehCache.getKeys() )
+ {
+ String group = ( String ) obj;
+ Set<String> members = ( Set<String> ) ehCache.get( group ).getValue();
+
+ if ( members == null )
+ {
+ continue;
+ }
+
+ if ( members.contains( normMember.getNormName() ) )
+ {
+ if ( memberGroups == null )
+ {
+ memberGroups = new HashSet<DN>();
+ }
+
+ memberGroups.add( parseNormalized( group ) );
+ }
+ }
+
+ if ( memberGroups == null )
+ {
+ return EMPTY_GROUPS;
+ }
+
+ return memberGroups;
+ }
+
+
+ public boolean groupRenamed( DN oldName, DN newName )
+ {
+ Element membersElement = ehCache.get( oldName.getNormName() );
+
+ if ( membersElement != null )
+ {
+ Set<String> members = ( Set<String> ) membersElement.getValue();
+
+ ehCache.remove( oldName.getNormName() );
+
+ Element cacheElement = new Element( newName.getNormName(), members );
+ ehCache.put( cacheElement );
+
+ if ( IS_DEBUG )
+ {
+ LOG.debug( "group cache contents after renaming '{}' :\n{}", oldName.getName(), ehCache.getAllWithLoader( ehCache.getKeys(), null ) );
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+}
Added: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/directory-cacheservice.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/directory-cacheservice.xml?rev=967256&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/directory-cacheservice.xml (added)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/directory-cacheservice.xml Fri Jul 23 20:49:14 2010
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="ehcache.xsd"
+ updateCheck="false" monitoring="autodetect"
+ dynamicConfig="true" >
+
+ <diskStore path="java.io.tmpdir"/>
+
+ <cacheManagerEventListenerFactory class="" properties=""/>
+
+ <!--
+ Mandatory Default Cache configuration. These settings will be applied to caches
+ created programmtically using CacheManager.add(String cacheName).
+
+ The defaultCache has an implicit name "default" which is a reserved cache name.
+ -->
+ <defaultCache
+ maxElementsInMemory="0"
+ eternal="false"
+ overflowToDisk="true"
+ timeToIdleSeconds="1200"
+ timeToLiveSeconds="1200">
+ </defaultCache>
+
+ <!--
+ Sample cache named sampleCache1
+ This cache contains a maximum in memory of 10000 elements, and will expire
+ an element if it is idle for more than 5 minutes and lives for more than
+ 10 minutes.
+
+ If there are more than 10000 elements it will overflow to the
+ disk cache, which in this configuration will go to wherever java.io.tmp is
+ defined on your system. On a standard Linux system this will be /tmp"
+ -->
+ <cache name="groupCache"
+ maxElementsInMemory="10000"
+ maxElementsOnDisk="1000"
+ eternal="true"
+ overflowToDisk="true"
+ diskSpoolBufferSizeMB="20"
+ timeToIdleSeconds="300"
+ timeToLiveSeconds="600"/>
+</ehcache>
\ No newline at end of file
Added: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/ehcache.xsd
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/ehcache.xsd?rev=967256&view=auto
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/ehcache.xsd (added)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/main/resources/ehcache.xsd Fri Jul 23 20:49:14 2010
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.7">
+
+ <xs:element name="ehcache">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="1" minOccurs="0" ref="diskStore"/>
+ <xs:element maxOccurs="1" minOccurs="0" ref="transactionManagerLookup"/>
+ <xs:element maxOccurs="1" minOccurs="0" ref="cacheManagerEventListenerFactory"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerProviderFactory"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="cacheManagerPeerListenerFactory"/>
+ <xs:element maxOccurs="1" minOccurs="0" ref="terracottaConfig"/>
+ <xs:element ref="defaultCache"/>
+ <xs:element maxOccurs="unbounded" minOccurs="0" ref="cache"/>
+ </xs:sequence>
+ <xs:attribute name="name" use="optional"/>
+ <xs:attribute default="true" name="updateCheck" type="xs:boolean" use="optional"/>
+ <xs:attribute default="autodetect" name="monitoring" type="monitoringType" use="optional"/>
+ <xs:attribute default="true" name="dynamicConfig" type="xs:boolean" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="diskStore">
+ <xs:complexType>
+ <xs:attribute name="path" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="transactionManagerLookup">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheManagerEventListenerFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheManagerPeerProviderFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheManagerPeerListenerFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="terracottaConfig">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element maxOccurs="1" minOccurs="0" name="tc-config">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute default="localhost:9510" name="url" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <!-- add clone support for addition of cacheExceptionHandler. Important! -->
+ <xs:element name="defaultCache">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
+ </xs:sequence>
+ <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
+ <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
+ <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
+ <xs:attribute name="eternal" type="xs:boolean" use="required"/>
+ <xs:attribute name="maxElementsInMemory" type="xs:integer" use="required"/>
+ <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
+ <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
+ <xs:attribute name="overflowToDisk" type="xs:boolean" use="required"/>
+ <xs:attribute name="timeToIdleSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="timeToLiveSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="maxElementsOnDisk" type="xs:integer" use="optional"/>
+ <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/>
+ <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cache">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheLoaderFactory"/>
+ <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheDecoratorFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="terracotta"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriter"/>
+ <xs:element minOccurs="0" maxOccurs="1" ref="copyStrategy"/>
+ </xs:sequence>
+ <xs:attribute name="diskExpiryThreadIntervalSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="diskSpoolBufferSizeMB" type="xs:integer" use="optional"/>
+ <xs:attribute name="diskPersistent" type="xs:boolean" use="optional"/>
+ <xs:attribute name="diskAccessStripes" type="xs:integer" use="optional" default="1"/>
+ <xs:attribute name="eternal" type="xs:boolean" use="required"/>
+ <xs:attribute name="maxElementsInMemory" type="xs:integer" use="required"/>
+ <xs:attribute name="memoryStoreEvictionPolicy" type="xs:string" use="optional"/>
+ <xs:attribute name="clearOnFlush" type="xs:boolean" use="optional"/>
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="overflowToDisk" type="xs:boolean" use="required"/>
+ <xs:attribute name="timeToIdleSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="timeToLiveSeconds" type="xs:integer" use="optional"/>
+ <xs:attribute name="maxElementsOnDisk" type="xs:integer" use="optional"/>
+ <xs:attribute name="transactionalMode" type="transactionalMode" use="optional" default="off"/>
+ <xs:attribute name="statistics" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="copyOnRead" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="copyOnWrite" type="xs:boolean" use="optional" default="false"/>
+ <xs:attribute name="logging" type="xs:boolean" use="optional" default="false"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheEventListenerFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ <xs:attribute name="listenFor" use="optional" type="notificationScope" default="all"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="bootstrapCacheLoaderFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheExtensionFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheExceptionHandlerFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheLoaderFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="cacheDecoratorFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="terracotta">
+ <xs:complexType>
+ <xs:attribute name="clustered" use="optional" type="xs:boolean" default="true"/>
+ <xs:attribute name="valueMode" use="optional" type="terracottaCacheValueType" default="serialization"/>
+ <xs:attribute name="coherentReads" use="optional" type="xs:boolean" default="true"/>
+ <xs:attribute name="localKeyCache" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="localKeyCacheSize" use="optional" type="xs:positiveInteger" default="300000"/>
+ <xs:attribute name="orphanEviction" use="optional" type="xs:boolean" default="true"/>
+ <xs:attribute name="orphanEvictionPeriod" use="optional" type="xs:positiveInteger" default="4"/>
+ <xs:attribute name="copyOnRead" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="coherent" use="optional" type="xs:boolean" default="true"/>
+ <xs:attribute name="synchronousWrites" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="storageStrategy" use="optional" type="storageStrategyType" default="classic"/>
+ <xs:attribute name="concurrency" use="optional" type="xs:nonNegativeInteger" default="0"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:simpleType name="monitoringType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="autodetect"/>
+ <xs:enumeration value="on"/>
+ <xs:enumeration value="off"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="terracottaCacheValueType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="serialization"/>
+ <xs:enumeration value="identity"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="storageStrategyType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="classic"/>
+ <xs:enumeration value="DCV2"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name="transactionalMode">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="off"/>
+ <xs:enumeration value="xa"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="cacheWriter">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="1" ref="cacheWriterFactory"/>
+ </xs:sequence>
+ <xs:attribute name="writeMode" use="optional" type="writeModeType" default="write-through"/>
+ <xs:attribute name="notifyListenersOnException" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="minWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
+ <xs:attribute name="maxWriteDelay" use="optional" type="xs:nonNegativeInteger" default="1"/>
+ <xs:attribute name="rateLimitPerSecond" use="optional" type="xs:nonNegativeInteger" default="0"/>
+ <xs:attribute name="writeCoalescing" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="writeBatching" use="optional" type="xs:boolean" default="false"/>
+ <xs:attribute name="writeBatchSize" use="optional" type="xs:positiveInteger" default="1"/>
+ <xs:attribute name="retryAttempts" use="optional" type="xs:nonNegativeInteger" default="0"/>
+ <xs:attribute name="retryAttemptDelaySeconds" use="optional" type="xs:nonNegativeInteger" default="1"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:simpleType name="writeModeType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="write-through"/>
+ <xs:enumeration value="write-behind"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="cacheWriterFactory">
+ <xs:complexType>
+ <xs:attribute name="class" use="required"/>
+ <xs:attribute name="properties" use="optional"/>
+ <xs:attribute name="propertySeparator" use="optional"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:element name="copyStrategy">
+ <xs:complexType>
+ <xs:attribute name="class" use="required" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+
+ <xs:simpleType name="notificationScope">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="local"/>
+ <xs:enumeration value="remote"/>
+ <xs:enumeration value="all"/>
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
\ No newline at end of file
Modified: directory/apacheds/branches/apacheds-cache-experiment/core-api/src/test/java/org/apache/directory/server/core/MockDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core-api/src/test/java/org/apache/directory/server/core/MockDirectoryService.java?rev=967256&r1=967255&r2=967256&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core-api/src/test/java/org/apache/directory/server/core/MockDirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-cache-experiment/core-api/src/test/java/org/apache/directory/server/core/MockDirectoryService.java Fri Jul 23 20:49:14 2010
@@ -27,6 +27,7 @@ import java.util.Set;
import javax.naming.ldap.LdapContext;
+import org.apache.directory.server.core.cache.CacheService;
import org.apache.directory.server.core.changelog.ChangeLog;
import org.apache.directory.server.core.event.EventService;
import org.apache.directory.server.core.interceptor.Interceptor;
@@ -485,4 +486,10 @@ public class MockDirectoryService implem
// TODO Auto-generated method stub
}
+
+
+ public CacheService getCacheService()
+ {
+ return null;
+ }
}
Modified: directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java?rev=967256&r1=967255&r2=967256&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java (original)
+++ directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/DefaultDirectoryService.java Fri Jul 23 20:49:14 2010
@@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -38,6 +37,7 @@ import org.apache.directory.server.const
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authz.AciAuthorizationInterceptor;
import org.apache.directory.server.core.authz.DefaultAuthorizationInterceptor;
+import org.apache.directory.server.core.cache.CacheService;
import org.apache.directory.server.core.changelog.ChangeLog;
import org.apache.directory.server.core.changelog.ChangeLogEvent;
import org.apache.directory.server.core.changelog.ChangeLogInterceptor;
@@ -92,7 +92,6 @@ import org.apache.directory.shared.ldap.
import org.apache.directory.shared.ldap.name.DN;
import org.apache.directory.shared.ldap.name.RDN;
import org.apache.directory.shared.ldap.schema.SchemaManager;
-import org.apache.directory.shared.ldap.schema.normalizers.OidNormalizer;
import org.apache.directory.shared.ldap.util.DateUtils;
import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
@@ -232,6 +231,9 @@ public class DefaultDirectoryService imp
/** the value of last successful add/update operation's CSN */
private String contextCsn;
+ /** the ehcache based cache service */
+ private CacheService cacheService;
+
/**
* The synchronizer thread. It flush data on disk periodically.
*/
@@ -998,6 +1000,7 @@ public class DefaultDirectoryService imp
// And shutdown the server
// --------------------------------------------------------------------
interceptorChain.destroy();
+ cacheService.destroy();
started = false;
setDefaultInterceptorConfigurations();
}
@@ -1410,6 +1413,9 @@ public class DefaultDirectoryService imp
firstStart = createBootstrapEntries();
+ cacheService = new CacheService();
+ cacheService.initialize( this );
+
interceptorChain = new InterceptorChain();
interceptorChain.init( this );
@@ -1698,4 +1704,10 @@ public class DefaultDirectoryService imp
{
this.contextCsn = lastKnownCsn;
}
+
+
+ public CacheService getCacheService()
+ {
+ return cacheService;
+ }
}
Modified: directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java?rev=967256&r1=967255&r2=967256&view=diff
==============================================================================
--- directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java (original)
+++ directory/apacheds/branches/apacheds-cache-experiment/core/src/main/java/org/apache/directory/server/core/authz/AciAuthorizationInterceptor.java Fri Jul 23 20:49:14 2010
@@ -37,6 +37,7 @@ import org.apache.directory.server.core.
import org.apache.directory.server.core.LdapPrincipal;
import org.apache.directory.server.core.authz.support.ACDFEngine;
import org.apache.directory.server.core.authz.support.AciContext;
+import org.apache.directory.server.core.cache.GroupCache;
import org.apache.directory.server.core.entry.ClonedServerEntry;
import org.apache.directory.server.core.entry.ServerEntryUtils;
import org.apache.directory.server.core.filtering.EntryFilter;
@@ -197,7 +198,7 @@ public class AciAuthorizationInterceptor
// Create the caches
tupleCache = new TupleCache( adminSession );
- groupCache = new GroupCache( adminSession );
+ groupCache = directoryService.getCacheService().getGroupCache();
// look up some constant information
OBJECT_CLASS_AT = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT );