You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ak...@apache.org on 2007/09/19 09:19:22 UTC
svn commit: r577181 - in /directory/apacheds/trunk:
core-unit/src/main/java/org/apache/directory/server/core/unit/
core/src/main/java/org/apache/directory/server/core/changelog/
server-tools/src/main/java/org/apache/directory/server/tools/commands/impo...
Author: akarasulu
Date: Wed Sep 19 00:19:21 2007
New Revision: 577181
URL: http://svn.apache.org/viewvc?rev=577181&view=rev
Log:
adding initial change log interceptor and various interfaces
Added:
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java (with props)
directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html (with props)
Modified:
directory/apacheds/trunk/core-unit/src/main/java/org/apache/directory/server/core/unit/AbstractPerformanceTest.java
directory/apacheds/trunk/server-tools/src/main/java/org/apache/directory/server/tools/commands/importcmd/ImportCommandExecutor.java
Modified: directory/apacheds/trunk/core-unit/src/main/java/org/apache/directory/server/core/unit/AbstractPerformanceTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-unit/src/main/java/org/apache/directory/server/core/unit/AbstractPerformanceTest.java?rev=577181&r1=577180&r2=577181&view=diff
==============================================================================
--- directory/apacheds/trunk/core-unit/src/main/java/org/apache/directory/server/core/unit/AbstractPerformanceTest.java (original)
+++ directory/apacheds/trunk/core-unit/src/main/java/org/apache/directory/server/core/unit/AbstractPerformanceTest.java Wed Sep 19 00:19:21 2007
@@ -40,6 +40,7 @@
import org.apache.directory.server.core.partition.PartitionNexus;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.ldif.Entry;
+import org.apache.directory.shared.ldap.ldif.ChangeType;
import org.apache.directory.shared.ldap.ldif.LdifReader;
import org.apache.directory.shared.ldap.message.AttributesImpl;
import org.apache.directory.shared.ldap.name.LdapDN;
@@ -99,7 +100,7 @@
*/
public class AbstractPerformanceTest extends AbstractTestCase
{
- private final Class subclass;
+ private final Class<?> subclass;
private boolean isExternal = false;
private String prepareCommand = null;
private File outputDirectory = null;
@@ -113,7 +114,7 @@
*
* @param subclass
*/
- protected AbstractPerformanceTest( Class subclass ) throws IOException
+ protected AbstractPerformanceTest( Class<?> subclass ) throws IOException
{
super( PartitionNexus.ADMIN_PRINCIPAL, "secret" );
this.subclass = subclass;
@@ -225,9 +226,9 @@
*/
protected boolean applyEntry( Entry entry ) throws Exception
{
- switch ( entry.getChangeType() )
+ switch ( entry.getChangeType().getChangeType() )
{
- case( Entry.ADD ):
+ case( ChangeType.ADD_ORDINAL ):
LdapDN ancestor = new LdapDN( testRoot.getNameInNamespace() );
LdapDN descendant = new LdapDN( entry.getDn() );
LdapDN relative = ( LdapDN ) NamespaceTools.getRelativeName( ancestor, descendant );
@@ -250,7 +251,7 @@
LdifReader reader = new LdifReader( in );
start = System.currentTimeMillis();
log( "Started LDIF Import: " + ldifResource );
- for ( Iterator ii = reader.iterator(); ii.hasNext(); /**/ )
+ for ( Iterator<Entry> ii = reader.iterator(); ii.hasNext(); /**/ )
{
long startEntry = System.currentTimeMillis();
if ( applyEntry( ( Entry ) ii.next() ) )
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,107 @@
+/*
+ * 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 java.io.Serializable;
+
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.shared.ldap.ldif.Entry;
+
+
+/**
+ * A loggable directory change event.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class ChangeLogEvent implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+ private final String zuluTime;
+ private final long revision;
+ private final Entry forwardLdif;
+ private final Entry reverseLdif;
+ private final LdapPrincipal committer;
+
+
+ /**
+ * Creates a new instance of ChangeLogEvent.
+ *
+ * @param the revision 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
+ */
+ public ChangeLogEvent( long commitId, String zuluTime, LdapPrincipal committer,
+ Entry forwardLdif, Entry reverseLdif )
+ {
+ this.zuluTime = zuluTime;
+ this.revision = commitId;
+ this.forwardLdif = forwardLdif;
+ this.reverseLdif = reverseLdif;
+ this.committer = committer;
+ }
+
+
+ /**
+ * @return the forwardLdif
+ */
+ public Entry getForwardLdif()
+ {
+ return forwardLdif;
+ }
+
+
+ /**
+ * @return the reverseLdif
+ */
+ public Entry getReverseLdif()
+ {
+ return reverseLdif;
+ }
+
+
+ /**
+ * @return the committer
+ */
+ public LdapPrincipal getCommitter()
+ {
+ return committer;
+ }
+
+
+ /**
+ * @return the revision
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+
+
+ /**
+ * @return the zuluTime
+ */
+ public String getZuluTime()
+ {
+ return zuluTime;
+ }
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogEvent.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,568 @@
+package org.apache.directory.server.core.changelog;
+
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.apache.directory.server.core.DirectoryServiceConfiguration;
+import org.apache.directory.server.core.configuration.InterceptorConfiguration;
+import org.apache.directory.server.core.interceptor.BaseInterceptor;
+import org.apache.directory.server.core.interceptor.NextInterceptor;
+import org.apache.directory.server.core.interceptor.context.AddOperationContext;
+import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
+import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
+import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
+import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
+import org.apache.directory.server.core.invocation.InvocationStack;
+import org.apache.directory.server.core.jndi.ServerContext;
+import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+
+import org.apache.directory.shared.ldap.util.Base64;
+import org.apache.directory.shared.ldap.util.DateUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An interceptor which maintains a change log as it intercepts changes to the
+ * directory. It mainains a changes.log file using the LDIF format for changes.
+ * It appends changes to this file so the entire LDIF file can be loaded to
+ * replicate the state of the server.
+ *
+ */
+public class ChangeLogInterceptor extends BaseInterceptor implements Runnable
+{
+ /** time to wait before automatically waking up the writer thread */
+ private static final long WAIT_TIMEOUT_MILLIS = 1000;
+ private static final Logger log = LoggerFactory.getLogger( ChangeLogInterceptor.class );
+
+ /** the changes.log file's stream which we append change log messages to */
+ PrintWriter out = null;
+ /** queue of string buffers awaiting serialization to the log file */
+ Queue<StringBuffer> queue = new LinkedList<StringBuffer>();
+ /** a handle on the attributeType registry to determine the binary nature of attributes */
+ AttributeTypeRegistry registry = null;
+ /** determines if this service has been activated */
+ boolean isActive = false;
+ /** thread used to asynchronously write change logs to disk */
+ Thread writer = null;
+
+
+ // -----------------------------------------------------------------------
+ // Overridden init() and destroy() methods
+ // -----------------------------------------------------------------------
+
+
+ public void init( DirectoryServiceConfiguration dsConfig, InterceptorConfiguration iConfig ) throws NamingException
+ {
+ super.init( dsConfig, iConfig );
+
+ // Get a handle on the attribute registry to check if attributes are binary
+ registry = dsConfig.getRegistries().getAttributeTypeRegistry();
+
+ // Open a print stream to use for flushing LDIFs into
+ File changes = new File( dsConfig.getStartupConfiguration().getWorkingDirectory(), "changes.log" );
+ try
+ {
+ if ( changes.exists() )
+ {
+ out = new PrintWriter( new FileWriter( changes, true ) );
+ }
+ else
+ {
+ out = new PrintWriter( new FileWriter( changes ) );
+ }
+ }
+ catch( Exception e )
+ {
+ log.error( "Failed to open the change log file: " + changes, e );
+ }
+
+ out.println( "# -----------------------------------------------------------------------------" );
+ out.println( "# Initializing changelog service: " + DateUtils.getGeneralizedTime() );
+ out.println( "# -----------------------------------------------------------------------------" );
+ out.flush();
+
+ writer = new Thread( this );
+ isActive = true;
+ writer.start();
+ }
+
+
+ public void destroy()
+ {
+ // Gracefully stop writer thread and push remaining enqueued buffers ourselves
+ isActive = false;
+ do
+ {
+ // Let's notify the writer thread to make it die faster
+ synchronized( queue )
+ {
+ queue.notifyAll();
+ }
+
+ // Sleep tiny bit waiting for the writer to die
+ try
+ {
+ Thread.sleep( 50 );
+ }
+ catch ( InterruptedException e )
+ {
+ log.error( "Failed to sleep while waiting for writer to die", e );
+ }
+ } while ( writer.isAlive() );
+
+ // Ok lock down queue and start draining it
+ synchronized( queue )
+ {
+ while ( ! queue.isEmpty() )
+ {
+ StringBuffer buf = queue.poll();
+ if ( buf != null )
+ {
+ out.println( buf );
+ }
+ }
+ }
+
+ // Print message that we're stopping log service, flush and close
+ out.println( "# -----------------------------------------------------------------------------" );
+ out.println( "# Deactivating changelog service: " + DateUtils.getGeneralizedTime() );
+ out.println( "# -----------------------------------------------------------------------------" );
+ out.flush();
+ out.close();
+
+ super.destroy();
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Implementation for Runnable.run() for writer Thread
+ // -----------------------------------------------------------------------
+
+
+ public void run()
+ {
+ while ( isActive )
+ {
+ StringBuffer buf = null;
+
+ // Grab semphore to queue and dequeue from it
+ synchronized( queue )
+ {
+ try
+ {
+ queue.wait( WAIT_TIMEOUT_MILLIS );
+ }
+ catch ( InterruptedException e )
+ {
+ log.error( "Failed to to wait() on queue", e );
+ }
+
+ buf = queue.poll();
+ queue.notifyAll();
+ }
+
+ // Do writing outside of synch block to allow other threads to enqueue
+ if ( buf != null )
+ {
+ out.println( buf );
+ out.flush();
+ }
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Overridden (only change inducing) intercepted methods
+ // -----------------------------------------------------------------------
+
+
+ public void add( NextInterceptor next, AddOperationContext opContext ) throws NamingException
+ {
+ StringBuffer buf;
+ next.add( opContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! creatorsName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! createTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF entry now
+ buf.append( "\ndn: " );
+ buf.append( opContext.getDn().getUpName() );
+ buf.append( "\nchangetype: add" );
+ append( buf, opContext.getEntry() );
+ buf.append( "\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ public void delete( NextInterceptor next, DeleteOperationContext opContext ) throws NamingException
+ {
+ StringBuffer buf;
+ next.delete( opContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! deletorsName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! deleteTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF record now
+ buf.append( "\ndn: " );
+ buf.append( opContext.getDn() );
+ buf.append( "\nchangetype: delete\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ public void modify( NextInterceptor next, ModifyOperationContext opContext ) throws NamingException
+ {
+ StringBuffer buf;
+ next.modify( opContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! modifiersName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! modifyTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF record now
+ buf.append( "\ndn: " );
+ buf.append( opContext.getDn() );
+ buf.append( "\nchangetype: modify" );
+
+ ModificationItem[] mods = opContext.getModItems();
+ for ( int ii = 0; ii < mods.length; ii++ )
+ {
+ append( buf, mods[ii].getAttribute(), getModOpStr( mods[ii].getModificationOp() ) );
+ }
+ buf.append( "\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Though part left as an exercise (Not Any More!)
+ // -----------------------------------------------------------------------
+
+
+ public void rename ( NextInterceptor next, RenameOperationContext renameContext ) throws NamingException
+ {
+ next.rename( renameContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ StringBuffer buf;
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! principleName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! operationTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF record now
+ buf.append( "\ndn: " );
+ buf.append( renameContext.getDn() );
+ buf.append( "\nchangetype: modrdn" );
+ buf.append( "\nnewrdn: " + renameContext.getNewRdn() );
+ buf.append( "\ndeleteoldrdn: " + ( renameContext.getDelOldDn() ? "1" : "0" ) );
+
+ buf.append( "\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ public void moveAndRename( NextInterceptor next, MoveAndRenameOperationContext moveAndRenameOperationContext )
+ throws NamingException
+ {
+ next.moveAndRename( moveAndRenameOperationContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ StringBuffer buf;
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! principleName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! operationTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF record now
+ buf.append( "\ndn: " );
+ buf.append( moveAndRenameOperationContext.getDn() );
+ buf.append( "\nchangetype: modrdn" ); // FIXME: modrdn --> moddn ?
+ buf.append( "\nnewrdn: " + moveAndRenameOperationContext.getNewRdn() );
+ buf.append( "\ndeleteoldrdn: " + ( moveAndRenameOperationContext.getDelOldDn() ? "1" : "0" ) );
+ buf.append( "\nnewsperior: " + moveAndRenameOperationContext.getParent() );
+
+ buf.append( "\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ public void move ( NextInterceptor next, MoveOperationContext moveOperationContext ) throws NamingException
+ {
+ next.move( moveOperationContext );
+
+ if ( ! isActive )
+ {
+ return;
+ }
+
+ StringBuffer buf;
+
+ // Append comments that can be used to track the user and time this operation occurred
+ buf = new StringBuffer();
+ buf.append( "\n#! principleName: " );
+ buf.append( getPrincipalName() );
+ buf.append( "\n#! operationTimestamp: " );
+ buf.append( DateUtils.getGeneralizedTime() );
+
+ // Append the LDIF record now
+ buf.append( "\ndn: " );
+ buf.append( moveOperationContext.getDn() );
+ buf.append( "\nchangetype: moddn" );
+ buf.append( "\nnewsperior: " + moveOperationContext.getParent() );
+
+ buf.append( "\n" );
+
+ // Enqueue the buffer onto a queue that is emptied by another thread asynchronously.
+ synchronized ( queue )
+ {
+ queue.offer( buf );
+ queue.notifyAll();
+ }
+ }
+
+
+ // -----------------------------------------------------------------------
+ // Private utility methods used by interceptor methods
+ // -----------------------------------------------------------------------
+
+
+ /**
+ * Appends an Attribute and its values to a buffer containing an LDIF entry taking
+ * into account whether or not the attribute's syntax is binary or not.
+ *
+ * @param buf the buffer written to and returned (for chaining)
+ * @param attr the attribute written to the buffer
+ * @return the buffer argument to allow for call chaining.
+ * @throws NamingException if the attribute is not identified by the registry
+ */
+ private StringBuffer append( StringBuffer buf, Attribute attr ) throws NamingException
+ {
+ String id = ( String ) attr.getID();
+ int sz = attr.size();
+ boolean isBinary = ! registry.lookup( id ).getSyntax().isHumanReadable();
+
+ if ( isBinary )
+ {
+ for ( int ii = 0; ii < sz; ii++ )
+ {
+ buf.append( "\n" );
+ buf.append( id );
+ buf.append( ":: " );
+ Object value = attr.get( ii );
+ String encoded;
+ if ( value instanceof String )
+ {
+ encoded = ( String ) value;
+ try
+ {
+ encoded = new String( Base64.encode( encoded.getBytes( "UTF-8" ) ) );
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ log.error( "can't convert to UTF-8: " + encoded, e );
+ }
+ }
+ else
+ {
+ encoded = new String( Base64.encode( ( byte[] ) attr.get( ii ) ) );
+ }
+ buf.append( encoded );
+ }
+ }
+ else
+ {
+ for ( int ii = 0; ii < sz; ii++ )
+ {
+ buf.append( "\n" );
+ buf.append( id );
+ buf.append( ": " );
+ buf.append( attr.get( ii ) );
+ }
+ }
+
+ return buf;
+ }
+
+
+ /**
+ * Appends a set of attributes to a buffer for an LDIF record. The Dn is presumed
+ * to be added some time before.
+ *
+ * @param buf the buffer to add the attributes to
+ * @param attrs the attributes to append to the buffer
+ * @return the buffer argument passed in for chaining
+ * @throws NamingException if some attribute identifiers are not defined
+ */
+ private StringBuffer append( StringBuffer buf, Attributes attrs ) throws NamingException
+ {
+ NamingEnumeration<String> ids = attrs.getIDs();
+ while ( ids.hasMore() )
+ {
+ String id = ids.next();
+ append( buf, attrs.get( id ) );
+ }
+ return buf;
+ }
+
+
+ /**
+ * Gets the DN of the user currently bound to the server executing this operation. If
+ * the user is anonymous "" is returned.
+ *
+ * @return the DN of the user executing the current intercepted operation
+ * @throws NamingException if we cannot access the interceptor stack
+ */
+ private String getPrincipalName() throws NamingException
+ {
+ ServerContext ctx = ( ServerContext ) InvocationStack.getInstance().peek().getCaller();
+ return ctx.getPrincipal().getName();
+ }
+
+
+ /**
+ * Gets a String representation of the JNDI attribute modificaion flag. Here are the mappings:
+ * <table>
+ * <tr><th>JNDI Constant</th><th>Returned String</th></tr>
+ * <tr><td>DirContext.ADD_ATTRIBUTE</td><td>'add: '</td></tr>
+ * <tr><td>DirContext.REMOVE_ATTRIBUTE</td><td>'delete: '</td></tr>
+ * <tr><td>DirContext.REPLACE_ATTRIBUTE</td><td>'replace: '</td></tr>
+ * </table>
+ * <ul><li>
+ * Note that the String in right hand column is quoted to show trailing space.
+ * </li></ul>
+ *
+ * @param modOp the int value of the JNDI modification operation
+ * @return the string representation of the JNDI Modification operation
+ */
+ private String getModOpStr( int modOp )
+ {
+ String opStr;
+ switch( modOp )
+ {
+ case( DirContext.ADD_ATTRIBUTE ):
+ opStr = "add: ";
+ break;
+ case( DirContext.REMOVE_ATTRIBUTE ):
+ opStr = "delete: ";
+ break;
+ case( DirContext.REPLACE_ATTRIBUTE ):
+ opStr = "replace: ";
+ break;
+ default:
+ throw new IllegalArgumentException( "Undefined attribute modify operation: " + modOp );
+ }
+ return opStr;
+ }
+
+
+ /**
+ * Appends a modification delta instruction to an LDIF: i.e.
+ * <pre>
+ * add: telephoneNumber
+ * telephoneNumber: +1 408 555 1234
+ * telephoneNumber: +1 408 444 9999
+ * -
+ * </pre>
+ *
+ * @param buf the buffer to append the attribute delta to
+ * @param mod the modified values if any for that attribute
+ * @param modOp the modification operation as a string followd by ": "
+ * @return the buffer argument provided for chaining
+ * @throws NamingException if the modification attribute id is undefined
+ */
+ private StringBuffer append( StringBuffer buf, Attribute mod, String modOp ) throws NamingException
+ {
+ buf.append( "\n" );
+ buf.append( modOp );
+ buf.append( mod.getID() );
+ append( buf, mod );
+ buf.append( "\n-" );
+ return buf;
+ }
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogInterceptor.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,227 @@
+/*
+ * 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 javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.ldif.ChangeType;
+import org.apache.directory.shared.ldap.name.LdapDN;
+import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.schema.ObjectClass;
+
+
+/**
+ * A custom search engine designed for optimized searching across ChangeLogEvents
+ * within the ChangeLogStore. The following lookup and search operations are
+ * provided:
+ *
+ * <ul>
+ * <li>lookup change by revision</li>
+ * <li>lookup change by date</li>
+ * <li>find all changes</li>
+ * <li>find all changes before or after a revision</li>
+ * <li>find all changes in a revision range</li>
+ * <li>find changes by LDAP namespace scope on DN</li>
+ * <li>find changes by DN</li>
+ * <li>find changes by principal</li>
+ * <li>find changes by change type</li>
+ * <li>find changes by attribute</li>
+ * <li>find changes using a restricted LDAP filter on all of the above factors</li>
+ * </ul>
+ *
+ * Note change lookups by date can be conducted by first looking up a revision
+ * using a generalizedTime descriptor to find a revision. Then these revisions
+ * can be plugged into the revision based find and lookup methods.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ChangeLogSearchEngine
+{
+ /**
+ * Looks up the revision in effect at some time specified by a generalized
+ * time descriptor.
+ *
+ * @param generalizedTime the generalized time descriptor to find the effective revision for
+ * @return the revision that was in effect at a certain time
+ * @throws NamingException if there are failures accessing the store
+ */
+ long lookup( String generalizedTime ) 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
+ */
+ ChangeLogEvent lookup( long revision ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents within the system since revision 0.
+ *
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return an enumeration of all the ChangeLogEvents
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> 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
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> findBefore( long revision, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds the ChangeLogEvents that occurred after a revision inclusive.
+ *
+ * @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
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> 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)
+ * @return an enumeration of all the ChangeLogEvents within some revision range inclusive
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( long startRevision, long endRevision, RevisionOrder order )
+ throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents on an entry.
+ *
+ * @param dn the normalized DN of the entry to get ChangeLogEvents for
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of changes that occurred on an entry
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( LdapDN dn, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents on an entry base and/or it's children/descendants.
+ *
+ * @param base the normalized DN of the entry base to get ChangeLogEvents for
+ * @param scope the scope of the search under the base similar to LDAP search scope
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of changes that occurred on an entry and/or it's descendants depending on the scope
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( LdapDN base, Scope scope, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents triggered by a principal in the system.
+ *
+ * @param principal the LDAP principal who triggered the events
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of changes that were triggered by a specific LDAP user
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( LdapPrincipal principal, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents of a particular change type.
+ *
+ * @param changeType the change type of the ChangeLogEvents to search for
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of ChangeLogEvents of a particular ChangeType
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( ChangeType changeType, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents altering a particular attributeType.
+ *
+ * @param attributeType the attributeType definition for the changed attribute to search changes for
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of ChangeLogEvents on a particular attributeType
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( AttributeType attributeType, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents altering a particular objectClass.
+ *
+ * @param objectClass the objectClass definition for the entries to search changes for
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of ChangeLogEvents on a particular attributeType
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( ObjectClass objectClass, RevisionOrder order ) throws NamingException;
+
+
+ /**
+ * Finds all the ChangeLogEvents matched by the filter expression tree parameter.
+ *
+ * The following attributes can be used in the constrained LDAP filter expression
+ * tree. The expression must be normalized and can contain only ATA pairs with the
+ * following set of attributes:
+ *
+ * <ul>
+ * <li>ndn: normalized distinguishedName syntax (defaults to matching a string)</li>
+ * <li>date: generalizedTime syntax</li>
+ * <li>revision: integer syntax</li>
+ * <li>attributeType: numeric OID</li>
+ * <li>objectClass: numeric OID</li>
+ * <li>changeType: new changeType syntax</li>
+ * <li>principal: normalized distinguishedName syntax (defaults to matching a string)</li>
+ * </ul>
+ *
+ * The following are the only kinds of AVA node types allowed:
+ *
+ * <ul>
+ * <li>equality (=) </li>
+ * <li>greaterThanEq (>=) </li>
+ * <li>lessThanEq (<=) </li>
+ * <li>scope (specialized) </li>
+ * </ul>
+ *
+ * @param objectClass the objectClass definition for the entries to search changes for
+ * @param order the order in which to return ChangeLogEvents (ordered by revision number)
+ * @return the set of ChangeLogEvents on entries of a particular objectClass
+ * @throws NamingException if there are failures accessing the store
+ */
+ NamingEnumeration<ChangeLogEvent> find( ExprNode filter, RevisionOrder order ) throws NamingException;
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogSearchEngine.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+
+/**
+ * TODO ChangeLogService.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ChangeLogService
+{
+
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogService.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,55 @@
+/*
+ * 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 javax.naming.NamingException;
+
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.shared.ldap.ldif.Entry;
+
+
+/**
+ * A store for change events on the directory which exposes methods for
+ * managing, querying and in general performing legal operations on the log.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface ChangeLogStore
+{
+ /**
+ * Get's the current revision of the server (a.k.a. the HEAD revision).
+ *
+ * @return the current revision of the server
+ */
+ long getCurrentRevision();
+
+ /**
+ * Records a change as a forward LDIF, a reverse change to revert the change and
+ * the authorized principal triggering the revertable change event.
+ *
+ * @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
+ * @throws NamingException
+ */
+ long log( LdapPrincipal principal, Entry forward, Entry reverse ) throws NamingException;
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/ChangeLogStore.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+
+/**
+ * The order, based on revision numbers, in which to return log changes or
+ * tags.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public enum RevisionOrder
+{
+ AscendingOrder( true ),
+ DescendingOrder( false );
+
+
+ private final boolean ascending;
+
+
+ private RevisionOrder( boolean ascending )
+ {
+ this.ascending = ascending;
+ }
+
+
+ /**
+ * @return the ascending
+ */
+ public boolean isAscending()
+ {
+ return ascending;
+ }
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/RevisionOrder.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,55 @@
+/*
+ * 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 javax.naming.directory.SearchControls;
+
+
+/**
+ * TODO Scope.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public enum Scope
+{
+ Subtree( SearchControls.SUBTREE_SCOPE ),
+ OneLevel( SearchControls.ONELEVEL_SCOPE ),
+ Object( SearchControls.OBJECT_SCOPE );
+
+
+ private final int scope;
+
+
+ private Scope( int scope )
+ {
+ this.scope = scope;
+ }
+
+
+ /**
+ * @return the scope
+ */
+ public int getScope()
+ {
+ return scope;
+ }
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Scope.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+
+/**
+ * TODO SearchableChangeLogStore.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface SearchableChangeLogStore extends ChangeLogStore
+{
+ /**
+ * Get's the search engine for this SearchableChangeLogStore.
+ *
+ * @return the search engine for this SearchableChangeLogStore
+ */
+ ChangeLogSearchEngine getChangeLogSearchEngine();
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/SearchableChangeLogStore.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+
+/**
+ * A tag on a revision representing a snapshot of the directory server's
+ * state.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public class Tag
+{
+ /*
+ * TODO should we have date in which tag was taken
+ * TODO should we have the date of the revision
+ */
+ private final long revision;
+ private final String description;
+
+
+ public Tag( long revision, String description )
+ {
+ this.revision = revision;
+ this.description = description;
+ }
+
+
+ /**
+ * @return the revision
+ */
+ public long getRevision()
+ {
+ return revision;
+ }
+
+
+ /**
+ * @return the description
+ */
+ public String getDescription()
+ {
+ return description;
+ }
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/Tag.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,129 @@
+/*
+ * 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 javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+
+/**
+ * An optional search interface supported by TaggableChangeLogStores. This
+ * interface enables the:
+ *
+ * <ul>
+ * <li>lookup of tags by revision</li>
+ * <li>finding all tags</li>
+ * <li>finding tags before or after a revision</li>
+ * <li>finding tags in some revision range</li>
+ * </ul>
+ *
+ * While investigating these interface methods keep in mind that only one
+ * tag can exist on a revision. Unlike subversion which allows multiple
+ * tags on a revision we only allow at most one: more than one is pointless.
+ *
+ * Date wise searches for tags are not present within this interface since
+ * they should be used in conjunction with the ChangeLogSearchEngine which
+ * is by default supported by TaggableSearchableChangeLogStores. The
+ * ChangeLogSearchEngine can find revisions based on time descriptors and
+ * returned revisions can be checked for the presence of tags using this
+ * interface. The whole point to enabling both search engines in a single
+ * interfaces is because if you can search for tags you should be able to
+ * search for revisions: however the converse may not be the case.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface TagSearchEngine
+{
+
+ // -----------------------------------------------------------------------
+ // Tag Lookup Operations
+ // -----------------------------------------------------------------------
+
+
+ /**
+ * Gets the tag for a specific snapshot if that snapshot exists.
+ *
+ * @param revision the revision number to use to check for a snapshot
+ * @return the snapshot at the revision if one exists, otherwise null
+ * @throws NamingException if there is a problem accessing the store
+ */
+ Tag lookup( long revision ) throws NamingException;
+
+ /**
+ * Checks to see if a snapshot exists for a specific revision.
+ *
+ * @param revision the revision number to use to check for a snapshot
+ * @return true if a snapshot exists at the revision, false otherwise
+ * @throws NamingException if there is a problem accessing the store
+ */
+ boolean has( long revision ) throws NamingException;
+
+
+ // -----------------------------------------------------------------------
+ // Tag Search Operations
+ // -----------------------------------------------------------------------
+
+
+ /**
+ * Finds all the snapshot tags taken since revision 0 until the current
+ * revision.
+ *
+ * @param order the revision order in which to return snapshot tags
+ * @return an enumeration over the tags of all snapshots taken since revision 0
+ * @throws NamingException if there is a problem accessing the store
+ */
+ NamingEnumeration<Tag> find( RevisionOrder order ) throws NamingException;
+
+ /**
+ * Finds all the snapshot tags taken before a specific revision. If a tag
+ * exists at the revision parameter it will be returned as well.
+ *
+ * @param revision the revision number to get snapshots before
+ * @param order the revision order in which to return snapshot tags
+ * @return an enumeration over the tags of all snapshots taken before a revision inclusive
+ * @throws NamingException if there is a problem accessing the store
+ */
+ NamingEnumeration<Tag> findBefore( long revision, RevisionOrder order ) throws NamingException;
+
+ /**
+ * Finds all the snapshot tags taken after a specific revision. If a tag
+ * exists at the revision parameter it will be returned as well.
+ *
+ * @param revision the revision number to get snapshots after
+ * @param order the revision order in which to return snapshot tags
+ * @return an enumeration over the tags of all snapshots taken after a revision inclusive
+ * @throws NamingException if there is a problem accessing the store
+ */
+ NamingEnumeration<Tag> findAfter( long revision, RevisionOrder order ) throws NamingException;
+
+ /**
+ * Enumerates over the tags of all snapshots taken between a specific revision
+ * range inclusive. The first revision parameter should be less than or equal
+ * to the second revision parameter.
+ *
+ * @param order the revision order in which to return snapshot tags
+ * @return enumeration over all the snapshots taken in a revision range inclusive
+ * @throws NamingException if there is a problem accessing the store
+ */
+ NamingEnumeration<Tag> find( long startRevision, long endRevision, RevisionOrder order )
+ throws NamingException;
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TagSearchEngine.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,50 @@
+/*
+ * 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 javax.naming.NamingException;
+
+
+/**
+ * A ChangeLogStore which allows tagging for tracking server state snapshots.
+ * At most one tag per revision can be created. There is no point to creating
+ * more than one tag on a revision in our case for snapshotting server state.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface TaggableChangeLogStore extends ChangeLogStore
+{
+ /**
+ * Creates a tag for a snapshot of the server in a specific state at a revision.
+ *
+ * @param the revision to tag the snapshot
+ * @throws NamingException
+ */
+ Tag tag( long revision ) throws NamingException;
+
+ /**
+ * Creates a snapshot of the server at the current revision.
+ *
+ * @return the revision at which the tag is created
+ * @throws NamingException
+ */
+ Tag tag() throws NamingException;
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableChangeLogStore.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java Wed Sep 19 00:19:21 2007
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+
+/**
+ * TODO TaggableSearchableChangeLogStore.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @version $Rev$, $Date$
+ */
+public interface TaggableSearchableChangeLogStore extends TaggableChangeLogStore, SearchableChangeLogStore
+{
+ /**
+ * Get's the tag search engine for this TaggableSearchableChangeLogStore.
+ *
+ * @return the snapshot query engine for this store.
+ */
+ TagSearchEngine getTagSearchEngine();
+}
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/TaggableSearchableChangeLogStore.java
------------------------------------------------------------------------------
svn:executable = *
Added: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html?rev=577181&view=auto
==============================================================================
--- directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html (added)
+++ directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html Wed Sep 19 00:19:21 2007
@@ -0,0 +1,28 @@
+
+
+<h1>Ideas</h1>
+
+Use AdminModel to control what goes into the changelog ? Or use admin model to identify
+scopes/concerns which are put into different channels in the changelog? Cool idea perhaps,
+perhaps not. To some degree the DN does the scope thingy for us. There really is no point
+to having an additional scope parameter.
+
+Perhaps we can also inject a new revisions (multi-valued) operational attribute into
+entries to track the revisions of changes in the changeLog to that entry. This can
+be used to ask the server for a log of changes that have been performed on a specific
+entry. Whoa that's really hot for auditing!
+
+We could try to do the same thing (meaning having a tags operational attribute) with revisions.
+However this is pointless since the tag revision would already be in the revisions attribute. Also
+a tag would select entries dynamically: all entries with revisions below the tag revision would be
+selected in the tag. This leads to a neat idea: you can easily regenerate not only the revision
+history of an entry, you can do it for an entire subtree, and furthermore you might even be able
+to conduct search operations based on a tag and the state of the server in the past. This would be
+pretty wild.
+
+Another neat thing that could be done is to request an attribute by revision using the protocol
+based tagging mechanism in LDAP. For example we have language based tags like cn;lang-en so why
+not have version based tags like cn;revision-23. When requested in this mannar the server can
+reconstruct the state of the attribute at a specific revision and return it to the user. This is
+an incredible capability when storing the configurations of systems in LDAP. Being able to rollback
+to a previous configuration or just inquire about a previous state is a powerful feature to have.
Propchange: directory/apacheds/trunk/core/src/main/java/org/apache/directory/server/core/changelog/package.html
------------------------------------------------------------------------------
svn:executable = *
Modified: directory/apacheds/trunk/server-tools/src/main/java/org/apache/directory/server/tools/commands/importcmd/ImportCommandExecutor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/server-tools/src/main/java/org/apache/directory/server/tools/commands/importcmd/ImportCommandExecutor.java?rev=577181&r1=577180&r2=577181&view=diff
==============================================================================
--- directory/apacheds/trunk/server-tools/src/main/java/org/apache/directory/server/tools/commands/importcmd/ImportCommandExecutor.java (original)
+++ directory/apacheds/trunk/server-tools/src/main/java/org/apache/directory/server/tools/commands/importcmd/ImportCommandExecutor.java Wed Sep 19 00:19:21 2007
@@ -67,6 +67,7 @@
import org.apache.directory.shared.ldap.codec.modify.ModifyRequest;
import org.apache.directory.shared.ldap.codec.modifyDn.ModifyDNRequest;
import org.apache.directory.shared.ldap.codec.unbind.UnBindRequest;
+import org.apache.directory.shared.ldap.ldif.ChangeType;
import org.apache.directory.shared.ldap.ldif.Entry;
import org.apache.directory.shared.ldap.ldif.LdifReader;
import org.apache.directory.shared.ldap.message.ModificationItemImpl;
@@ -516,20 +517,20 @@
private int changeEntry( Entry entry, int messageId ) throws IOException, DecoderException, InvalidNameException,
NamingException, EncoderException
{
- switch ( entry.getChangeType() )
+ switch ( entry.getChangeType().getChangeType() )
{
- case Entry.ADD:
+ case ChangeType.ADD_ORDINAL:
// No difference with the injection of new entries
return addEntry( entry, messageId );
- case Entry.DELETE:
+ case ChangeType.DELETE_ORDINAL:
return deleteEntry( entry, messageId );
- case Entry.MODIFY:
+ case ChangeType.MODIFY_ORDINAL:
return changeModifyEntry( entry, messageId );
- case Entry.MODDN:
- case Entry.MODRDN:
+ case ChangeType.MODDN_ORDINAL:
+ case ChangeType.MODRDN_ORDINAL:
return changeModRDNEntry( entry, messageId );
default: