Author: akarasulu Date: Sat Nov 10 15:58:02 2007 New Revision: 593828 URL: http://svn.apache.org/viewvc?rev=593828&view=rev Log: changes to changelog ... o seems we need some minimal means to at least iterate through log entries this is needed for the change log service to revert state back to a revision o moved minimal set of methods from search engine adding them to the store o started using a Cursor instead of a NamingEnumeration Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLogService.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStoreTest.java Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java?rev=593828&r1=593827&r2=593828&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java (original) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java Sat Nov 10 15:58:02 2007 @@ -46,13 +46,10 @@ * Creates a new instance of ChangeLogEvent. * * @param revision the revision number for the change - * @param committer the authorized user which triggered the change - * @param forwardLdif the LDIF representing the change forward in time - * @param reverseLdif an LDIF which reverts the change going reverse in time to an earlier revision * @param zuluTime the timestamp for when the change occurred in generalizedTime format */ public ChangeLogEvent( long revision, String zuluTime, LdapPrincipal committer, - Entry forwardLdif, Entry reverseLdif ) + Entry forwardLdif, Entry reverseLdif ) { this.zuluTime = zuluTime; this.revision = revision; Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java?rev=593828&r1=593827&r2=593828&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java (original) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java Sat Nov 10 15:58:02 2007 @@ -68,8 +68,8 @@ * @throws NamingException if there are failures accessing the store */ long lookup( String generalizedTime ) throws NamingException; - - + + /** * Looks up the ChangeLogEvent for a revision. * @@ -80,21 +80,25 @@ * and greater than the current revision) */ ChangeLogEvent lookup( long revision ) throws NamingException; - - + + /** * Finds all the ChangeLogEvents within the system since revision 0. - * + * + * This method should exhibit isolation characteristics: meaning if the request is + * initiated at revision 100 then any subsequent log entries increasing the revision + * should not be seen. + * * @param order the order in which to return ChangeLogEvents (ordered by revision number) - * @return an enumeration of all the ChangeLogEvents + * @return an enumeration of all the ChangeLogEvents * @throws NamingException if there are failures accessing the store */ NamingEnumeration find( RevisionOrder order ) throws NamingException; - + /** * Finds the ChangeLogEvents that occurred before a revision inclusive. - * + * * @param revision the revision number to get the ChangeLogEvents before * @param order the order in which to return ChangeLogEvents (ordered by revision number) * @return an enumeration of all the ChangeLogEvents before and including some revision @@ -103,11 +107,15 @@ * and greater than the current revision) */ NamingEnumeration findBefore( long revision, RevisionOrder order ) throws NamingException; - - + + /** * Finds the ChangeLogEvents that occurred after a revision inclusive. - * + * + * This method should exhibit isolation characteristics: meaning if the request is + * initiated at revision 100 then any subsequent log entries increasing the revision + * should not be seen. + * * @param revision the revision number to get the ChangeLogEvents after * @param order the order in which to return ChangeLogEvents (ordered by revision number) * @return an enumeration of all the ChangeLogEvents after and including the revision @@ -116,11 +124,11 @@ * and greater than the current revision) */ NamingEnumeration findAfter( long revision, RevisionOrder order ) throws NamingException; - - + + /** * Finds the ChangeLogEvents that occurred between a revision range inclusive. - * + * * @param startRevision the revision number to start getting the ChangeLogEvents above * @param endRevision the revision number to start getting the ChangeLogEvents below * @param order the order in which to return ChangeLogEvents (ordered by revision number) @@ -129,9 +137,9 @@ * @throws IllegalArgumentException if the start and end revisions are out of range * (less than 0 and greater than the current revision), or if startRevision > endRevision */ - NamingEnumeration find( long startRevision, long endRevision, RevisionOrder order ) + NamingEnumeration find( long startRevision, long endRevision, RevisionOrder order ) throws NamingException; - + /** * Finds all the ChangeLogEvents on an entry. Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java?rev=593828&r1=593827&r2=593828&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java (original) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java Sat Nov 10 15:58:02 2007 @@ -99,6 +99,30 @@ Tag tag( long revision ) throws NamingException; /** + * Creates a tag for a snapshot of the server in a specific state at a revision. + * If the ChangeLog has a TaggableChangeLogStore then the tag is stored. If it + * does not then it's up to callers to track this tag since it will not be stored + * by this service. + * + * @param revision the revision to tag the snapshot + * @param description some information about what the snapshot tag represents + * @return the Tag associated with the revision + * @throws NamingException if there is a problem taking a tag + * @throws IllegalArgumentException if the revision is out of range (less than 0 + * and greater than the current revision) + */ + Tag tag( long revision, String description ) throws NamingException; + + /** + * Creates a snapshot of the server at the current revision. + * + * @param description some information about what the snapshot tag represents + * @return the revision at which the tag is created + * @throws NamingException if there is a problem taking a tag + */ + Tag tag( String description ) throws NamingException; + + /** * Creates a snapshot of the server at the current revision. * * @return the revision at which the tag is created Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java?rev=593828&r1=593827&r2=593828&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java (original) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java Sat Nov 10 15:58:02 2007 @@ -20,11 +20,13 @@ package org.apache.directory.server.core.changelog; -import javax.naming.NamingException; - import org.apache.directory.server.core.authn.LdapPrincipal; +import org.apache.directory.server.core.cursor.Cursor; import org.apache.directory.shared.ldap.ldif.Entry; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; + /** * A store for change events on the directory which exposes methods for @@ -49,8 +51,76 @@ * @param principal the authorized LDAP principal triggering the change * @param forward LDIF of the change going to the next state * @param reverse LDIF (anti-operation): the change required to revert this change - * @return the commit id or revision representing the change within the log + * @return the new revision reached after having applied the forward LDIF * @throws NamingException if there are problems logging the change */ long log( LdapPrincipal principal, Entry forward, Entry reverse ) throws NamingException; + + + /** + * Looks up the ChangeLogEvent for a revision. + * + * @param revision to get a ChangeLogEvent for + * @return the ChangeLogEvent associated with the revision + * @throws NamingException if there are failures accessing the store + * @throws IllegalArgumentException if the revision is out of range (less than 0 + * and greater than the current revision) + */ + ChangeLogEvent lookup( long revision ) throws NamingException; + + + /** + * Gets a Cursor over all the ChangeLogEvents within the system since + * revision 0. + * + * This method should exhibit isolation characteristics: meaning if the + * request is initiated at revision 100, then any subsequent log entries + * increasing the revision should not be seen. + * + * @return a Cursor over all the ChangeLogEvents + * @throws NamingException if there are failures accessing the store + */ + Cursor find() throws NamingException; + + + /** + * Gets a Cursor over the ChangeLogEvents that occurred before a revision + * exclusive. + * + * @param revision the revision number to get the ChangeLogEvents before + * @return a Cursor over the ChangeLogEvents before a revision + * @throws NamingException if there are failures accessing the store + * @throws IllegalArgumentException if the revision is out of range (less than 0 + * and greater than the current revision) + */ + Cursor findBefore( long revision ) throws NamingException; + + + /** + * Finds the ChangeLogEvents that occurred after a revision exclusive. + * + * This method should exhibit isolation characteristics: meaning if the request is + * initiated at revision 100 then any subsequent log entries increasing the revision + * should not be seen. + * + * @param revision the revision number to get the ChangeLogEvents after + * @return a Cursor of all the ChangeLogEvents after and including the revision + * @throws NamingException if there are failures accessing the store + * @throws IllegalArgumentException if the revision is out of range (less than 0 + * and greater than the current revision) + */ + Cursor findAfter( long revision ) throws NamingException; + + + /** + * Finds the ChangeLogEvents that occurred between a revision range inclusive. + * + * @param startRevision the revision number to start getting the ChangeLogEvents above + * @param endRevision the revision number to start getting the ChangeLogEvents below + * @return an enumeration of all the ChangeLogEvents within some revision range inclusive + * @throws NamingException if there are failures accessing the store + * @throws IllegalArgumentException if the start and end revisions are out of range + * (less than 0 and greater than the current revision), or if startRevision > endRevision + */ + Cursor find( long startRevision, long endRevision ) throws NamingException; } Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLogService.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLogService.java?rev=593828&view=auto ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLogService.java (added) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/DefaultChangeLogService.java Sat Nov 10 15:58:02 2007 @@ -0,0 +1,151 @@ +/* + * 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.changelog; + + +import org.apache.directory.shared.ldap.NotImplementedException; + +import javax.naming.NamingException; + + +/** + * The default ChangeLog service implementation. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class DefaultChangeLogService implements ChangeLogService +{ + private ChangeLogStore store; + + + public ChangeLogStore getChangeLogStore() + { + return store; + } + + + public void setChangeLogStore( ChangeLogStore store ) + { + this.store = store; + } + + + public long getCurrentRevision() throws NamingException + { + return store.getCurrentRevision(); + } + + + public boolean isLogSearchSupported() + { + return store instanceof SearchableChangeLogStore; + } + + + public boolean isTagSearchSupported() + { + return store instanceof TaggableSearchableChangeLogStore; + } + + + public boolean isTagStorageSupported() + { + return store instanceof TaggableChangeLogStore; + } + + + public ChangeLogSearchEngine getChangeLogSearchEngine() + { + if ( isLogSearchSupported() ) + { + return ( ( SearchableChangeLogStore ) store ).getChangeLogSearchEngine(); + } + + throw new UnsupportedOperationException( + "The underlying changelog store does not support searching through it's logs" ); + } + + + public TagSearchEngine getTagSearchEngine() + { + if ( isTagSearchSupported() ) + { + return ( ( TaggableSearchableChangeLogStore ) store ).getTagSearchEngine(); + } + + throw new UnsupportedOperationException( + "The underlying changelog store does not support searching through it's tags" ); + } + + + public Tag tag( long revision, String description ) throws NamingException + { + if ( revision < 0 ) + { + throw new IllegalArgumentException( "revision must be greater than or equal to 0" ); + } + + if ( revision <= store.getCurrentRevision() ) + { + throw new IllegalArgumentException( "revision must be less than or equal to the current revision" ); + } + + if ( store instanceof TaggableChangeLogStore ) + { + return ( ( TaggableChangeLogStore ) store ).tag( revision ); + } + + return new Tag( revision, description ); + } + + + public Tag tag( long revision ) throws NamingException + { + return tag( revision, null ); + } + + + public Tag tag( String description ) throws NamingException + { + return tag( store.getCurrentRevision(), description ); + } + + + public Tag tag() throws NamingException + { + return tag( store.getCurrentRevision(), null ); + } + + + public long revert( long revision ) throws NamingException + { + if ( revision < 0 ) + { + throw new IllegalArgumentException( "revision must be greater than or equal to 0" ); + } + + if ( revision >= store.getCurrentRevision() ) + { + throw new IllegalArgumentException( "revision must be less than the current revision" ); + } + + throw new NotImplementedException(); + } +} Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java?rev=593828&view=auto ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java (added) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStore.java Sat Nov 10 15:58:02 2007 @@ -0,0 +1,121 @@ +/* + * 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.changelog; + +import org.apache.directory.server.core.authn.LdapPrincipal; +import org.apache.directory.server.core.cursor.Cursor; +import org.apache.directory.server.core.cursor.ListCursor; +import org.apache.directory.shared.ldap.ldif.Entry; +import org.apache.directory.shared.ldap.util.DateUtils; + +import javax.naming.NamingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * A change log store that keeps it's information in memory. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class MemoryChangeLogStore implements TaggableChangeLogStore +{ + private long currentRevision; + private final Map tags = new HashMap( 100 ); + private final List events = new ArrayList(); + + + public Tag tag( long revision ) throws NamingException + { + return tags.get( revision ); + } + + + public Tag tag() throws NamingException + { + return new Tag( currentRevision, null ); + } + + + public Tag tag( String description ) throws NamingException + { + Tag tag = new Tag( currentRevision, description ); + tags.put( currentRevision, tag ); + return tag; + } + + + public long getCurrentRevision() + { + return currentRevision; + } + + + public long log( LdapPrincipal principal, Entry forward, Entry reverse ) throws NamingException + { + currentRevision++; + ChangeLogEvent event = new ChangeLogEvent( currentRevision, DateUtils.getGeneralizedTime(), + principal, forward, reverse ); + events.add( event ); + return currentRevision; + } + + + public ChangeLogEvent lookup( long revision ) throws NamingException + { + if ( revision < 0 ) + { + throw new IllegalArgumentException( "revision must be greater than or equal to 0" ); + } + + if ( revision > getCurrentRevision() ) + { + throw new IllegalArgumentException( "The revision must not be greater than the current revision" ); + } + + return events.get( ( int ) revision ); + } + + + public Cursor find() throws NamingException + { + return new ListCursor( events ); + } + + + public Cursor findBefore( long revision ) throws NamingException + { + return new ListCursor( events, ( int ) revision ); + } + + + public Cursor findAfter( long revision ) throws NamingException + { + return new ListCursor( ( int ) ( revision + 1 ), events ); + } + + + public Cursor find( long startRevision, long endRevision ) throws NamingException + { + return new ListCursor( ( int ) startRevision, events, ( int ) ( endRevision + 1 ) ); + } +} Added: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStoreTest.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStoreTest.java?rev=593828&view=auto ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStoreTest.java (added) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/MemoryChangeLogStoreTest.java Sat Nov 10 15:58:02 2007 @@ -0,0 +1,77 @@ +/* + * 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.changelog; + + +import junit.framework.TestCase; +import org.apache.directory.server.core.authn.LdapPrincipal; +import org.apache.directory.shared.ldap.ldif.ChangeType; +import org.apache.directory.shared.ldap.ldif.Entry; +import org.apache.directory.shared.ldap.ldif.LdifUtils; +import org.apache.directory.shared.ldap.message.AddRequest; +import org.apache.directory.shared.ldap.message.AddRequestImpl; +import org.apache.directory.shared.ldap.name.LdapDN; + +import javax.naming.InvalidNameException; +import javax.naming.NamingException; + + +/** + * Tests the MemoryChangeLogStore. + * + * @author Apache Directory Project + * @version $Rev$, $Date$ + */ +public class MemoryChangeLogStoreTest extends TestCase +{ + MemoryChangeLogStore store; + + + public void setUp() throws Exception + { + super.setUp(); + store = new MemoryChangeLogStore(); + } + + + public void tearDown() throws Exception + { + super.tearDown(); + store = null; + } + + + public void testLogCheckRevision() throws NamingException + { + assertEquals( "first revision is always 0", 0, store.getCurrentRevision() ); + + Entry forward = new Entry(); + forward.setDn( "ou=system" ); + forward.setChangeType( ChangeType.Add ); + forward.putAttribute( "objectClass", "organizationalUnit" ); + forward.putAttribute( "ou", "system" ); + + AddRequest addRequest = new AddRequestImpl( 0 ); + addRequest.setAttributes( forward.getAttributes() ); + addRequest.setEntry( new LdapDN( forward.getDn() ) ); + Entry reverse = LdifUtils.reverseAdd( addRequest ); + assertEquals( 1, store.log( new LdapPrincipal(), forward, reverse ) ); + assertEquals( 1, store.getCurrentRevision() ); + } +} \ No newline at end of file Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java?rev=593828&r1=593827&r2=593828&view=diff ============================================================================== --- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java (original) +++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java Sat Nov 10 15:58:02 2007 @@ -49,4 +49,13 @@ * @throws NamingException if there is a problem taking a tag */ Tag tag() throws NamingException; + + /** + * Creates a snapshot of the server at the current revision with a description + * of the snapshot tag. + * + * @return the revision at which the tag is created + * @throws NamingException if there is a problem taking a tag + */ + Tag tag( String description ) throws NamingException; }